Merge pull request #4380 from FinnStutzenstein/motionBlockSlide
Motion block slide
This commit is contained in:
commit
c0cd3bc252
@ -3,7 +3,7 @@
|
|||||||
[ngClass]="isProjected() ? 'projector-active' : 'projector-inactive'">
|
[ngClass]="isProjected() ? 'projector-active' : 'projector-inactive'">
|
||||||
<mat-icon>videocam</mat-icon>
|
<mat-icon>videocam</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" *ngIf="menuItem" mat-menu-item (click)="onClick($event)"
|
<button type="button" *ngIf="menuItem" mat-menu-item (click)="onClick()"
|
||||||
[ngClass]="isProjected() ? 'projector-active' : 'projector-inactive'">
|
[ngClass]="isProjected() ? 'projector-active' : 'projector-inactive'">
|
||||||
<mat-icon>videocam</mat-icon>
|
<mat-icon>videocam</mat-icon>
|
||||||
<span translate>Project</span>
|
<span translate>Project</span>
|
||||||
|
@ -63,8 +63,10 @@ export class ProjectorButtonComponent implements OnInit {
|
|||||||
*
|
*
|
||||||
* @param event the click event
|
* @param event the click event
|
||||||
*/
|
*/
|
||||||
public onClick(event: Event): void {
|
public onClick(event?: Event): void {
|
||||||
event.stopPropagation();
|
if (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
if (this.object) {
|
if (this.object) {
|
||||||
this.projectionDialogService.openProjectDialogFor(this.object);
|
this.projectionDialogService.openProjectDialogFor(this.object);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
z-index: 1;
|
z-index: 9;
|
||||||
|
|
||||||
.projector-logo-main {
|
.projector-logo-main {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
@ -59,7 +59,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 1;
|
z-index: 9;
|
||||||
|
|
||||||
.footertext {
|
.footertext {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
@ -104,10 +104,8 @@
|
|||||||
<span translate>List of speakers</span>
|
<span translate>List of speakers</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-menu-item *osPerms="'core.can_manage_projector'">
|
<os-projector-button *ngIf="block" [object]="block" [menuItem]="true"></os-projector-button>
|
||||||
<mat-icon>videocam</mat-icon>
|
|
||||||
<span translate>Project</span>
|
|
||||||
</button>
|
|
||||||
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
|
||||||
<button mat-menu-item (click)="toggleEditMode()">
|
<button mat-menu-item (click)="toggleEditMode()">
|
||||||
<mat-icon>edit</mat-icon>
|
<mat-icon>edit</mat-icon>
|
||||||
|
@ -52,6 +52,14 @@
|
|||||||
<!-- Table -->
|
<!-- Table -->
|
||||||
<mat-card class="os-card">
|
<mat-card class="os-card">
|
||||||
<table class="os-headed-listview-table on-transition-fade" mat-table [dataSource]="dataSource" matSort>
|
<table class="os-headed-listview-table on-transition-fade" mat-table [dataSource]="dataSource" matSort>
|
||||||
|
<!-- Projector column -->
|
||||||
|
<ng-container matColumnDef="projector">
|
||||||
|
<mat-header-cell *matHeaderCellDef mat-sort-header>Projector</mat-header-cell>
|
||||||
|
<mat-cell *matCellDef="let block">
|
||||||
|
<os-projector-button [object]="block"></os-projector-button>
|
||||||
|
</mat-cell>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<!-- title column -->
|
<!-- title column -->
|
||||||
<ng-container matColumnDef="title">
|
<ng-container matColumnDef="title">
|
||||||
<mat-header-cell *matHeaderCellDef mat-sort-header> <span translate>Title</span> </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef mat-sort-header> <span translate>Title</span> </mat-header-cell>
|
||||||
|
@ -122,7 +122,11 @@ export class MotionBlockListComponent extends ListViewBaseComponent<ViewMotionBl
|
|||||||
* @returns an array of strings building the column definition
|
* @returns an array of strings building the column definition
|
||||||
*/
|
*/
|
||||||
public getColumnDefinition(): string[] {
|
public getColumnDefinition(): string[] {
|
||||||
return ['title', 'amount', 'menu'];
|
let columns = ['title', 'amount', 'menu'];
|
||||||
|
if (this.operator.hasPerms('core.can_manage_projector')) {
|
||||||
|
columns = ['projector'].concat(columns);
|
||||||
|
}
|
||||||
|
return columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,7 +41,7 @@ import { LinenumberingService } from 'app/core/ui-services/linenumbering.service
|
|||||||
import { Tag } from 'app/shared/models/core/tag';
|
import { Tag } from 'app/shared/models/core/tag';
|
||||||
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
|
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
|
||||||
import { ViewMotionBlock } from '../../models/view-motion-block';
|
import { ViewMotionBlock } from '../../models/view-motion-block';
|
||||||
import { ViewWorkflow } from '../../models/view-workflow';
|
import { ViewWorkflow, StateCssClassMapping } from '../../models/view-workflow';
|
||||||
import { ViewUser } from 'app/site/users/models/view-user';
|
import { ViewUser } from 'app/site/users/models/view-user';
|
||||||
import { ViewCategory } from '../../models/view-category';
|
import { ViewCategory } from '../../models/view-category';
|
||||||
import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile';
|
import { ViewMediafile } from 'app/site/mediafiles/models/view-mediafile';
|
||||||
@ -1280,17 +1280,6 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (this.motion.state.css_class) {
|
return StateCssClassMapping[this.motion.state.css_class] || '';
|
||||||
case 'success':
|
|
||||||
return 'green';
|
|
||||||
case 'danger':
|
|
||||||
return 'red';
|
|
||||||
case 'default':
|
|
||||||
return 'grey';
|
|
||||||
case 'primary':
|
|
||||||
return 'lightblue';
|
|
||||||
default:
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion, Motio
|
|||||||
/**
|
/**
|
||||||
* Columns to display in table when desktop view is available
|
* Columns to display in table when desktop view is available
|
||||||
*/
|
*/
|
||||||
public displayedColumnsDesktop: string[] = ['identifier', 'title', 'state', 'speakers'];
|
public displayedColumnsDesktop: string[] = ['identifier', 'title', 'state'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Columns to display in table when mobile view is available
|
* Columns to display in table when mobile view is available
|
||||||
@ -237,6 +237,9 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion, Motio
|
|||||||
if (this.isMultiSelect) {
|
if (this.isMultiSelect) {
|
||||||
columns = ['selector'].concat(columns);
|
columns = ['selector'].concat(columns);
|
||||||
}
|
}
|
||||||
|
if (this.operator.hasPerms('agenda.can_see')) {
|
||||||
|
columns = columns.concat(['speakers']);
|
||||||
|
}
|
||||||
return columns;
|
return columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +82,15 @@ export class ViewMotionBlock extends BaseAgendaViewModel implements Searchable {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public getSlide(): ProjectorElementBuildDeskriptor {
|
public getSlide(): ProjectorElementBuildDeskriptor {
|
||||||
throw new Error('todo');
|
return {
|
||||||
|
getBasicProjectorElement: options => ({
|
||||||
|
name: MotionBlock.COLLECTIONSTRING,
|
||||||
|
id: this.id,
|
||||||
|
getIdentifiers: () => ['name', 'id']
|
||||||
|
}),
|
||||||
|
slideOptions: [],
|
||||||
|
projectionDefaultName: 'motionBlocks',
|
||||||
|
getDialogTitle: () => this.getTitle()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,13 @@ import { Workflow } from 'app/shared/models/motions/workflow';
|
|||||||
import { WorkflowState } from 'app/shared/models/motions/workflow-state';
|
import { WorkflowState } from 'app/shared/models/motions/workflow-state';
|
||||||
import { BaseViewModel } from '../../base/base-view-model';
|
import { BaseViewModel } from '../../base/base-view-model';
|
||||||
|
|
||||||
|
export const StateCssClassMapping = {
|
||||||
|
success: 'green',
|
||||||
|
danger: 'red',
|
||||||
|
default: 'grey',
|
||||||
|
primary: 'lightblue'
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class for the ViewWorkflow.
|
* class for the ViewWorkflow.
|
||||||
* @ignore
|
* @ignore
|
||||||
|
@ -15,6 +15,11 @@ export const allSlidesDynamicConfiguration: (SlideDynamicConfiguration & Slide)[
|
|||||||
scaleable: true,
|
scaleable: true,
|
||||||
scrollable: true
|
scrollable: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
slide: 'motions/motion-block',
|
||||||
|
scaleable: true,
|
||||||
|
scrollable: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
slide: 'users/user',
|
slide: 'users/user',
|
||||||
scaleable: true,
|
scaleable: true,
|
||||||
|
@ -19,11 +19,19 @@ export const allSlides: SlideManifest[] = [
|
|||||||
{
|
{
|
||||||
slide: 'motions/motion',
|
slide: 'motions/motion',
|
||||||
path: 'motions/motion',
|
path: 'motions/motion',
|
||||||
loadChildren: './slides/motions/motion/motions-motion-slide.module#MotionsMotionSlideModule',
|
loadChildren: './slides/motions/motion/motion-slide.module#MotionSlideModule',
|
||||||
verboseName: 'Motion',
|
verboseName: 'Motion',
|
||||||
elementIdentifiers: ['name', 'id'],
|
elementIdentifiers: ['name', 'id'],
|
||||||
canBeMappedToModel: true
|
canBeMappedToModel: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
slide: 'motions/motion-block',
|
||||||
|
path: 'motions/motion-block',
|
||||||
|
loadChildren: './slides/motions/motion-block/motion-block-slide.module#MotionBlockSlideModule',
|
||||||
|
verboseName: 'Motion block',
|
||||||
|
elementIdentifiers: ['name', 'id'],
|
||||||
|
canBeMappedToModel: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
slide: 'users/user',
|
slide: 'users/user',
|
||||||
path: 'users/user',
|
path: 'users/user',
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
export interface MotionBlockSlideMotionRepresentation {
|
||||||
|
title: string;
|
||||||
|
identifier?: string;
|
||||||
|
recommendation?: {
|
||||||
|
name: string;
|
||||||
|
css_class: string;
|
||||||
|
};
|
||||||
|
recommendation_extension?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MotionBlockSlideData {
|
||||||
|
title: string;
|
||||||
|
motions: MotionBlockSlideMotionRepresentation[];
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
<div *ngIf="data">
|
||||||
|
<div class="slidetitle">
|
||||||
|
<h1>{{ data.data.title }}</h1>
|
||||||
|
<h2><span translate>Motion block</span> – {{ data.data.motions.length }} <span translate>motions</span></h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngFor="let motion of data.data.motions">
|
||||||
|
<div class="ellipsis-overflow">
|
||||||
|
{{ motion.identifier }}: {{ motion.title }}
|
||||||
|
</div>
|
||||||
|
<div class="white ellipsis-overflow">
|
||||||
|
<mat-basic-chip *ngIf="motion.recommendation" disableRipple [ngClass]="getStateCssColor(motion)">
|
||||||
|
{{ getRecommendationLabel(motion) }}
|
||||||
|
</mat-basic-chip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,26 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { MotionBlockSlideComponent } from './motion-block-slide.component';
|
||||||
|
import { E2EImportsModule } from '../../../../e2e-imports.module';
|
||||||
|
|
||||||
|
describe('MotionBlockSlideComponent', () => {
|
||||||
|
let component: MotionBlockSlideComponent;
|
||||||
|
let fixture: ComponentFixture<MotionBlockSlideComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [E2EImportsModule],
|
||||||
|
declarations: [MotionBlockSlideComponent]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(MotionBlockSlideComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,35 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
import { BaseSlideComponent } from 'app/slides/base-slide-component';
|
||||||
|
import { MotionBlockSlideData, MotionBlockSlideMotionRepresentation } from './motion-block-slide-data';
|
||||||
|
import { Motion } from 'app/shared/models/motions/motion';
|
||||||
|
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
|
||||||
|
import { StateCssClassMapping } from 'app/site/motions/models/view-workflow';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'os-motion-block-slide',
|
||||||
|
templateUrl: './motion-block-slide.component.html',
|
||||||
|
styleUrls: ['./motion-block-slide.component.scss']
|
||||||
|
})
|
||||||
|
export class MotionBlockSlideComponent extends BaseSlideComponent<MotionBlockSlideData> {
|
||||||
|
public constructor(private motionRepo: MotionRepositoryService, private translate: TranslateService) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public getMotionTitle(motion: Partial<Motion>): string {
|
||||||
|
return this.motionRepo.getAgendaTitle(motion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getStateCssColor(motion: MotionBlockSlideMotionRepresentation): string {
|
||||||
|
return StateCssClassMapping[motion.recommendation.css_class] || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRecommendationLabel(motion: MotionBlockSlideMotionRepresentation): string {
|
||||||
|
let recommendation = this.translate.instant(motion.recommendation.name);
|
||||||
|
if (motion.recommendation_extension) {
|
||||||
|
recommendation += ' ' + this.motionRepo.solveExtensionPlaceHolder(motion.recommendation_extension);
|
||||||
|
}
|
||||||
|
return recommendation;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
import { MotionBlockSlideModule } from './motion-block-slide.module';
|
||||||
|
|
||||||
|
describe('MotionBlockSlideModule', () => {
|
||||||
|
let motionBlockSlideModule: MotionBlockSlideModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
motionBlockSlideModule = new MotionBlockSlideModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(motionBlockSlideModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,7 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
|
import { makeSlideModule } from 'app/slides/base-slide-module';
|
||||||
|
import { MotionBlockSlideComponent } from './motion-block-slide.component';
|
||||||
|
|
||||||
|
@NgModule(makeSlideModule(MotionBlockSlideComponent))
|
||||||
|
export class MotionBlockSlideModule {}
|
@ -5,7 +5,7 @@ import { MergeAmendment } from '../../../shared/models/motions/workflow-state';
|
|||||||
* This interface describes the data returned by the server about an amendment.
|
* This interface describes the data returned by the server about an amendment.
|
||||||
* This object is used if actually the motion is shown and the amendment is shown in the context of the motion.
|
* This object is used if actually the motion is shown and the amendment is shown in the context of the motion.
|
||||||
*/
|
*/
|
||||||
export interface MotionsMotionSlideDataAmendment {
|
export interface MotionSlideDataAmendment {
|
||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
amendment_paragraphs: string[];
|
amendment_paragraphs: string[];
|
||||||
@ -16,7 +16,7 @@ export interface MotionsMotionSlideDataAmendment {
|
|||||||
* This interface describes the data returned by the server about a motion that is changed by an amendment.
|
* This interface describes the data returned by the server about a motion that is changed by an amendment.
|
||||||
* It only contains the data necessary for rendering the amendment's diff.
|
* It only contains the data necessary for rendering the amendment's diff.
|
||||||
*/
|
*/
|
||||||
export interface MotionsMotionSlideDataBaseMotion {
|
export interface MotionSlideDataBaseMotion {
|
||||||
identifier: string;
|
identifier: string;
|
||||||
title: string;
|
title: string;
|
||||||
text: string;
|
text: string;
|
||||||
@ -26,7 +26,7 @@ export interface MotionsMotionSlideDataBaseMotion {
|
|||||||
* This interface describes the data returned by the server about a statute paragraph that is changed by an amendment.
|
* This interface describes the data returned by the server about a statute paragraph that is changed by an amendment.
|
||||||
* It only contains the data necessary for rendering the amendment's diff.
|
* It only contains the data necessary for rendering the amendment's diff.
|
||||||
*/
|
*/
|
||||||
export interface MotionsMotionSlideDataBaseStatute {
|
export interface MotionSlideDataBaseStatute {
|
||||||
title: string;
|
title: string;
|
||||||
text: string;
|
text: string;
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ export interface MotionsMotionSlideDataBaseStatute {
|
|||||||
/**
|
/**
|
||||||
* This interface describes the data returned by the server about a change recommendation.
|
* This interface describes the data returned by the server about a change recommendation.
|
||||||
*/
|
*/
|
||||||
export interface MotionsMotionSlideDataChangeReco {
|
export interface MotionSlideDataChangeReco {
|
||||||
creation_time: string;
|
creation_time: string;
|
||||||
id: number;
|
id: number;
|
||||||
internal: boolean;
|
internal: boolean;
|
||||||
@ -53,7 +53,7 @@ export interface MotionsMotionSlideDataChangeReco {
|
|||||||
* This interface describes either an motion (with all amendments and change recommendations enbedded)
|
* This interface describes either an motion (with all amendments and change recommendations enbedded)
|
||||||
* or an amendment (with the bas motion embedded).
|
* or an amendment (with the bas motion embedded).
|
||||||
*/
|
*/
|
||||||
export interface MotionsMotionSlideData {
|
export interface MotionSlideData {
|
||||||
identifier: string;
|
identifier: string;
|
||||||
title: string;
|
title: string;
|
||||||
preamble: string;
|
preamble: string;
|
||||||
@ -65,11 +65,11 @@ export interface MotionsMotionSlideData {
|
|||||||
recommender?: string;
|
recommender?: string;
|
||||||
recommendation?: string;
|
recommendation?: string;
|
||||||
recommendation_extension?: string;
|
recommendation_extension?: string;
|
||||||
base_motion?: MotionsMotionSlideDataBaseMotion;
|
base_motion?: MotionSlideDataBaseMotion;
|
||||||
base_statute?: MotionsMotionSlideDataBaseStatute;
|
base_statute?: MotionSlideDataBaseStatute;
|
||||||
amendment_paragraphs: string[];
|
amendment_paragraphs: string[];
|
||||||
change_recommendations: MotionsMotionSlideDataChangeReco[];
|
change_recommendations: MotionSlideDataChangeReco[];
|
||||||
amendments: MotionsMotionSlideDataAmendment[];
|
amendments: MotionSlideDataAmendment[];
|
||||||
modified_final_version?: string;
|
modified_final_version?: string;
|
||||||
line_length: number;
|
line_length: number;
|
||||||
line_numbering_mode: LineNumberingMode;
|
line_numbering_mode: LineNumberingMode;
|
@ -1,5 +1,5 @@
|
|||||||
import { ViewUnifiedChange, ViewUnifiedChangeType } from '../../../shared/models/motions/view-unified-change';
|
import { ViewUnifiedChange, ViewUnifiedChangeType } from '../../../shared/models/motions/view-unified-change';
|
||||||
import { MotionsMotionSlideDataAmendment } from './motions-motion-slide-data';
|
import { MotionSlideDataAmendment } from './motion-slide-data';
|
||||||
import { MergeAmendment } from '../../../shared/models/motions/workflow-state';
|
import { MergeAmendment } from '../../../shared/models/motions/workflow-state';
|
||||||
import { LineRange } from '../../../core/ui-services/diff.service';
|
import { LineRange } from '../../../core/ui-services/diff.service';
|
||||||
|
|
||||||
@ -7,13 +7,13 @@ import { LineRange } from '../../../core/ui-services/diff.service';
|
|||||||
* This class adds methods to the MotionsMotionSlideDataChangeReco data object
|
* This class adds methods to the MotionsMotionSlideDataChangeReco data object
|
||||||
* necessary for use it as a UnifiedChange in the Diff-Functions
|
* necessary for use it as a UnifiedChange in the Diff-Functions
|
||||||
*/
|
*/
|
||||||
export class MotionsMotionSlideObjAmendmentParagraph implements ViewUnifiedChange {
|
export class MotionSlideObjAmendmentParagraph implements ViewUnifiedChange {
|
||||||
public id: number;
|
public id: number;
|
||||||
public type: number;
|
public type: number;
|
||||||
public merge_amendment_into_final: MergeAmendment;
|
public merge_amendment_into_final: MergeAmendment;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
data: MotionsMotionSlideDataAmendment,
|
data: MotionSlideDataAmendment,
|
||||||
private paragraphNo: number,
|
private paragraphNo: number,
|
||||||
private newText: string,
|
private newText: string,
|
||||||
private lineRange: LineRange
|
private lineRange: LineRange
|
@ -1,11 +1,11 @@
|
|||||||
import { ViewUnifiedChange, ViewUnifiedChangeType } from '../../../shared/models/motions/view-unified-change';
|
import { ViewUnifiedChange, ViewUnifiedChangeType } from '../../../shared/models/motions/view-unified-change';
|
||||||
import { MotionsMotionSlideDataChangeReco } from './motions-motion-slide-data';
|
import { MotionSlideDataChangeReco } from './motion-slide-data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class adds methods to the MotionsMotionSlideDataChangeReco data object
|
* This class adds methods to the MotionsMotionSlideDataChangeReco data object
|
||||||
* necessary for use it as a UnifiedChange in the Diff-Functions
|
* necessary for use it as a UnifiedChange in the Diff-Functions
|
||||||
*/
|
*/
|
||||||
export class MotionsMotionSlideObjChangeReco implements MotionsMotionSlideDataChangeReco, ViewUnifiedChange {
|
export class MotionSlideObjChangeReco implements MotionSlideDataChangeReco, ViewUnifiedChange {
|
||||||
public creation_time: string;
|
public creation_time: string;
|
||||||
public id: number;
|
public id: number;
|
||||||
public internal: boolean;
|
public internal: boolean;
|
||||||
@ -17,7 +17,7 @@ export class MotionsMotionSlideObjChangeReco implements MotionsMotionSlideDataCh
|
|||||||
public text: string;
|
public text: string;
|
||||||
public type: number;
|
public type: number;
|
||||||
|
|
||||||
public constructor(data: MotionsMotionSlideDataChangeReco) {
|
public constructor(data: MotionSlideDataChangeReco) {
|
||||||
Object.assign(this, data);
|
Object.assign(this, data);
|
||||||
}
|
}
|
||||||
|
|
@ -1,21 +1,21 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { MotionsMotionSlideComponent } from './motions-motion-slide.component';
|
import { MotionSlideComponent } from './motion-slide.component';
|
||||||
import { E2EImportsModule } from '../../../../e2e-imports.module';
|
import { E2EImportsModule } from '../../../../e2e-imports.module';
|
||||||
|
|
||||||
describe('MotionsMotionSlideComponent', () => {
|
describe('MotionsMotionSlideComponent', () => {
|
||||||
let component: MotionsMotionSlideComponent;
|
let component: MotionSlideComponent;
|
||||||
let fixture: ComponentFixture<MotionsMotionSlideComponent>;
|
let fixture: ComponentFixture<MotionSlideComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [E2EImportsModule],
|
imports: [E2EImportsModule],
|
||||||
declarations: [MotionsMotionSlideComponent]
|
declarations: [MotionSlideComponent]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(MotionsMotionSlideComponent);
|
fixture = TestBed.createComponent(MotionSlideComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
@ -2,21 +2,21 @@ import { Component, Input } from '@angular/core';
|
|||||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||||
|
|
||||||
import { BaseSlideComponent } from 'app/slides/base-slide-component';
|
import { BaseSlideComponent } from 'app/slides/base-slide-component';
|
||||||
import { MotionsMotionSlideData, MotionsMotionSlideDataAmendment } from './motions-motion-slide-data';
|
import { MotionSlideData, MotionSlideDataAmendment } from './motion-slide-data';
|
||||||
import { ChangeRecoMode, LineNumberingMode } from '../../../site/motions/models/view-motion';
|
import { ChangeRecoMode, LineNumberingMode } from '../../../site/motions/models/view-motion';
|
||||||
import { DiffLinesInParagraph, DiffService, LineRange } from '../../../core/ui-services/diff.service';
|
import { DiffLinesInParagraph, DiffService, LineRange } from '../../../core/ui-services/diff.service';
|
||||||
import { LinenumberingService } from '../../../core/ui-services/linenumbering.service';
|
import { LinenumberingService } from '../../../core/ui-services/linenumbering.service';
|
||||||
import { ViewUnifiedChange } from '../../../shared/models/motions/view-unified-change';
|
import { ViewUnifiedChange } from '../../../shared/models/motions/view-unified-change';
|
||||||
import { MotionsMotionSlideObjChangeReco } from './motions-motion-slide-obj-change-reco';
|
import { MotionSlideObjChangeReco } from './motion-slide-obj-change-reco';
|
||||||
import { SlideData } from '../../../site/projector/services/projector-data.service';
|
import { SlideData } from '../../../site/projector/services/projector-data.service';
|
||||||
import { MotionsMotionSlideObjAmendmentParagraph } from './motions-motion-slide-obj-amendment-paragraph';
|
import { MotionSlideObjAmendmentParagraph } from './motion-slide-obj-amendment-paragraph';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'os-motions-motion-slide',
|
selector: 'os-motion-slide',
|
||||||
templateUrl: './motions-motion-slide.component.html',
|
templateUrl: './motion-slide.component.html',
|
||||||
styleUrls: ['./motions-motion-slide.component.scss']
|
styleUrls: ['./motion-slide.component.scss']
|
||||||
})
|
})
|
||||||
export class MotionsMotionSlideComponent extends BaseSlideComponent<MotionsMotionSlideData> {
|
export class MotionSlideComponent extends BaseSlideComponent<MotionSlideData> {
|
||||||
/**
|
/**
|
||||||
* Indicates the LineNumberingMode Mode.
|
* Indicates the LineNumberingMode Mode.
|
||||||
*/
|
*/
|
||||||
@ -48,10 +48,10 @@ export class MotionsMotionSlideComponent extends BaseSlideComponent<MotionsMotio
|
|||||||
*/
|
*/
|
||||||
public allChangingObjects: ViewUnifiedChange[];
|
public allChangingObjects: ViewUnifiedChange[];
|
||||||
|
|
||||||
private _data: SlideData<MotionsMotionSlideData>;
|
private _data: SlideData<MotionSlideData>;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
public set data(value: SlideData<MotionsMotionSlideData>) {
|
public set data(value: SlideData<MotionSlideData>) {
|
||||||
this._data = value;
|
this._data = value;
|
||||||
this.lnMode = value.data.line_numbering_mode;
|
this.lnMode = value.data.line_numbering_mode;
|
||||||
this.lineLength = value.data.line_length;
|
this.lineLength = value.data.line_length;
|
||||||
@ -62,7 +62,7 @@ export class MotionsMotionSlideComponent extends BaseSlideComponent<MotionsMotio
|
|||||||
this.recalcUnifiedChanges();
|
this.recalcUnifiedChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get data(): SlideData<MotionsMotionSlideData> {
|
public get data(): SlideData<MotionSlideData> {
|
||||||
return this._data;
|
return this._data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,19 +77,17 @@ export class MotionsMotionSlideComponent extends BaseSlideComponent<MotionsMotio
|
|||||||
/**
|
/**
|
||||||
* Returns all paragraphs that are affected by the given amendment as unified change objects.
|
* Returns all paragraphs that are affected by the given amendment as unified change objects.
|
||||||
*
|
*
|
||||||
* @param {MotionsMotionSlideDataAmendment} amendment
|
* @param {MotionSlideDataAmendment} amendment
|
||||||
* @returns {MotionsMotionSlideObjAmendmentParagraph[]}
|
* @returns {MotionSlideObjAmendmentParagraph[]}
|
||||||
*/
|
*/
|
||||||
public getAmendmentAmendedParagraphs(
|
public getAmendmentAmendedParagraphs(amendment: MotionSlideDataAmendment): MotionSlideObjAmendmentParagraph[] {
|
||||||
amendment: MotionsMotionSlideDataAmendment
|
|
||||||
): MotionsMotionSlideObjAmendmentParagraph[] {
|
|
||||||
let baseHtml = this.data.data.text;
|
let baseHtml = this.data.data.text;
|
||||||
baseHtml = this.lineNumbering.insertLineNumbers(baseHtml, this.lineLength);
|
baseHtml = this.lineNumbering.insertLineNumbers(baseHtml, this.lineLength);
|
||||||
const baseParagraphs = this.lineNumbering.splitToParagraphs(baseHtml);
|
const baseParagraphs = this.lineNumbering.splitToParagraphs(baseHtml);
|
||||||
|
|
||||||
return amendment.amendment_paragraphs
|
return amendment.amendment_paragraphs
|
||||||
.map(
|
.map(
|
||||||
(newText: string, paraNo: number): MotionsMotionSlideObjAmendmentParagraph => {
|
(newText: string, paraNo: number): MotionSlideObjAmendmentParagraph => {
|
||||||
if (newText === null) {
|
if (newText === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -114,10 +112,10 @@ export class MotionsMotionSlideComponent extends BaseSlideComponent<MotionsMotio
|
|||||||
this.diff.extractRangeByLineNumbers(newTextLines, affectedLines.from, affectedLines.to)
|
this.diff.extractRangeByLineNumbers(newTextLines, affectedLines.from, affectedLines.to)
|
||||||
);
|
);
|
||||||
|
|
||||||
return new MotionsMotionSlideObjAmendmentParagraph(amendment, paraNo, newTextLines, affectedLines);
|
return new MotionSlideObjAmendmentParagraph(amendment, paraNo, newTextLines, affectedLines);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.filter((para: MotionsMotionSlideObjAmendmentParagraph) => para !== null);
|
.filter((para: MotionSlideObjAmendmentParagraph) => para !== null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,7 +127,7 @@ export class MotionsMotionSlideComponent extends BaseSlideComponent<MotionsMotio
|
|||||||
|
|
||||||
if (this.data.data.change_recommendations) {
|
if (this.data.data.change_recommendations) {
|
||||||
this.data.data.change_recommendations.forEach(change => {
|
this.data.data.change_recommendations.forEach(change => {
|
||||||
this.allChangingObjects.push(new MotionsMotionSlideObjChangeReco(change));
|
this.allChangingObjects.push(new MotionSlideObjChangeReco(change));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this.data.data.amendments) {
|
if (this.data.data.amendments) {
|
@ -0,0 +1,13 @@
|
|||||||
|
import { MotionSlideModule } from './motion-slide.module';
|
||||||
|
|
||||||
|
describe('MotionSlideModule', () => {
|
||||||
|
let motionSlideModule: MotionSlideModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
motionSlideModule = new MotionSlideModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(motionSlideModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,7 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
|
import { MotionSlideComponent } from './motion-slide.component';
|
||||||
|
import { makeSlideModule } from 'app/slides/base-slide-module';
|
||||||
|
|
||||||
|
@NgModule(makeSlideModule(MotionSlideComponent))
|
||||||
|
export class MotionSlideModule {}
|
@ -1,13 +0,0 @@
|
|||||||
import { MotionsMotionSlideModule } from './motions-motion-slide.module';
|
|
||||||
|
|
||||||
describe('MotionsMotionSlideModule', () => {
|
|
||||||
let motionsMotionSlideModule: MotionsMotionSlideModule;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
motionsMotionSlideModule = new MotionsMotionSlideModule();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create an instance', () => {
|
|
||||||
expect(motionsMotionSlideModule).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,7 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
|
|
||||||
import { MotionsMotionSlideComponent } from './motions-motion-slide.component';
|
|
||||||
import { makeSlideModule } from 'app/slides/base-slide-module';
|
|
||||||
|
|
||||||
@NgModule(makeSlideModule(MotionsMotionSlideComponent))
|
|
||||||
export class MotionsMotionSlideModule {}
|
|
@ -617,7 +617,7 @@ button.mat-menu-item.selected {
|
|||||||
margin-bottom: 40px;
|
margin-bottom: 40px;
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 2em;
|
font-size: 1.8em;
|
||||||
line-height: 1.1em;
|
line-height: 1.1em;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
|
@ -206,9 +206,45 @@ def motion_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
|
|||||||
|
|
||||||
def motion_block_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
|
def motion_block_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Motion slide.
|
Motion block slide.
|
||||||
"""
|
"""
|
||||||
return {"error": "TODO"}
|
motion_block_id = element.get("id")
|
||||||
|
|
||||||
|
if motion_block_id is None:
|
||||||
|
raise ProjectorElementException("id is required for motion block slide")
|
||||||
|
|
||||||
|
try:
|
||||||
|
motion_block = all_data["motions/motion-block"][motion_block_id]
|
||||||
|
except KeyError:
|
||||||
|
raise ProjectorElementException(
|
||||||
|
f"motion block with id {motion_block_id} does not exist"
|
||||||
|
)
|
||||||
|
|
||||||
|
motions = []
|
||||||
|
for motion in all_data["motions/motion"].values():
|
||||||
|
if motion["motion_block_id"] == motion_block_id:
|
||||||
|
motion_object = {
|
||||||
|
"title": motion["title"],
|
||||||
|
"identifier": motion["identifier"],
|
||||||
|
}
|
||||||
|
|
||||||
|
recommendation_id = motion["recommendation_id"]
|
||||||
|
if recommendation_id is not None:
|
||||||
|
recommendation = get_state(
|
||||||
|
all_data, motion, motion["recommendation_id"]
|
||||||
|
)
|
||||||
|
motion_object["recommendation"] = {
|
||||||
|
"name": recommendation["recommendation_label"],
|
||||||
|
"css_class": recommendation["css_class"],
|
||||||
|
}
|
||||||
|
if recommendation["show_recommendation_extension_field"]:
|
||||||
|
motion_object["recommendation_extension"] = motion[
|
||||||
|
"recommendation_extension"
|
||||||
|
]
|
||||||
|
|
||||||
|
motions.append(motion_object)
|
||||||
|
|
||||||
|
return {"title": motion_block["title"], "motions": motions}
|
||||||
|
|
||||||
|
|
||||||
def register_projector_slides() -> None:
|
def register_projector_slides() -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user