Merge pull request #4427 from FinnStutzenstein/motionProjectionMode
motion projection mode is optional and sensitive for the config
This commit is contained in:
commit
573cdd88a2
@ -19,6 +19,7 @@ import { BaseModel } from 'app/shared/models/base/base-model';
|
||||
import { ViewModelStoreService } from './view-model-store.service';
|
||||
import { BaseProjectableViewModel } from 'app/site/base/base-projectable-view-model';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { ConfigService } from '../ui-services/config.service';
|
||||
|
||||
/**
|
||||
* This service cares about Projectables being projected and manage all projection-related
|
||||
@ -41,7 +42,8 @@ export class ProjectorService {
|
||||
private http: HttpService,
|
||||
private slideManager: SlideManager,
|
||||
private viewModelStore: ViewModelStoreService,
|
||||
private translate: TranslateService
|
||||
private translate: TranslateService,
|
||||
private configService: ConfigService
|
||||
) {}
|
||||
|
||||
/**
|
||||
@ -54,7 +56,7 @@ export class ProjectorService {
|
||||
obj: Projectable | ProjectorElementBuildDeskriptor | IdentifiableProjectorElement
|
||||
): IdentifiableProjectorElement {
|
||||
if (isProjectable(obj)) {
|
||||
return obj.getSlide().getBasicProjectorElement({});
|
||||
return obj.getSlide(this.configService).getBasicProjectorElement({});
|
||||
} else if (isProjectorElementBuildDeskriptor(obj)) {
|
||||
return obj.getBasicProjectorElement({});
|
||||
} else {
|
||||
|
@ -69,8 +69,11 @@ export class ViewModelStoreService {
|
||||
* @param callback The function to check
|
||||
* @returns all matched view models of the collection
|
||||
*/
|
||||
public filter<T extends BaseViewModel>(collectionString: string, callback: (model: T) => boolean): T[] {
|
||||
return this.getAll<T>(collectionString).filter(callback);
|
||||
public filter<T extends BaseViewModel>(
|
||||
collectionType: ViewModelConstructor<T> | string,
|
||||
callback: (model: T) => boolean
|
||||
): T[] {
|
||||
return this.getAll<T>(collectionType).filter(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,7 +83,10 @@ export class ViewModelStoreService {
|
||||
* @param callback THe callback to satisfy
|
||||
* @returns a found view model or null, if nothing was found.
|
||||
*/
|
||||
public find<T extends BaseViewModel>(collectionString: string, callback: (model: T) => boolean): T {
|
||||
return this.getAll<T>(collectionString).find(callback);
|
||||
public find<T extends BaseViewModel>(
|
||||
collectionType: ViewModelConstructor<T> | string,
|
||||
callback: (model: T) => boolean
|
||||
): T {
|
||||
return this.getAll<T>(collectionType).find(callback);
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ _('Amendment to');
|
||||
_('Statute amendment for');
|
||||
_('Creation date');
|
||||
_('Last modified');
|
||||
_('Which version?');
|
||||
|
||||
// motion workflow 1
|
||||
_('Simple Workflow');
|
||||
|
@ -88,7 +88,8 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
|
||||
Item,
|
||||
MotionBlock,
|
||||
Mediafile,
|
||||
Tag
|
||||
Tag,
|
||||
MotionChangeRecommendation
|
||||
]);
|
||||
}
|
||||
|
||||
@ -148,6 +149,10 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
|
||||
const attachments = this.viewModelStoreService.getMany(ViewMediafile, motion.attachments_id);
|
||||
const tags = this.viewModelStoreService.getMany(ViewTag, motion.tags_id);
|
||||
const parent = this.viewModelStoreService.get(ViewMotion, motion.parent_id);
|
||||
const changeRecommendations = this.viewModelStoreService.filter(
|
||||
ViewMotionChangeRecommendation,
|
||||
cr => cr.motion_id === motion.id
|
||||
);
|
||||
let state: WorkflowState = null;
|
||||
if (workflow) {
|
||||
state = workflow.getStateById(motion.state_id);
|
||||
@ -163,7 +168,8 @@ export class MotionRepositoryService extends BaseAgendaContentObjectRepository<V
|
||||
block,
|
||||
attachments,
|
||||
tags,
|
||||
parent
|
||||
parent,
|
||||
changeRecommendations
|
||||
);
|
||||
viewMotion.getIdentifierOrTitle = () => this.getIdentifierOrTitle(viewMotion);
|
||||
viewMotion.getTitle = () => this.getTitle(viewMotion);
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
ProjectionDialogReturnType
|
||||
} from 'app/shared/components/projection-dialog/projection-dialog.component';
|
||||
import { ProjectorService } from '../core-services/projector.service';
|
||||
import { ConfigService } from './config.service';
|
||||
|
||||
/**
|
||||
* Manages the projection dialog. Projects the result of the user's choice.
|
||||
@ -21,7 +22,11 @@ export class ProjectionDialogService {
|
||||
* @param dialog
|
||||
* @param projectorService
|
||||
*/
|
||||
public constructor(private dialog: MatDialog, private projectorService: ProjectorService) {}
|
||||
public constructor(
|
||||
private dialog: MatDialog,
|
||||
private projectorService: ProjectorService,
|
||||
private configService: ConfigService
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Opens the projection dialog for the given projectable. After the user's choice,
|
||||
@ -32,7 +37,7 @@ export class ProjectionDialogService {
|
||||
public async openProjectDialogFor(obj: Projectable | ProjectorElementBuildDeskriptor): Promise<void> {
|
||||
let descriptor: ProjectorElementBuildDeskriptor;
|
||||
if (isProjectable(obj)) {
|
||||
descriptor = obj.getSlide();
|
||||
descriptor = obj.getSlide(this.configService);
|
||||
} else {
|
||||
descriptor = obj;
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
h2 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.element-name {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { Projectable, ProjectorElementBuildDeskriptor } from './projectable';
|
||||
import { BaseViewModel } from './base-view-model';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
|
||||
/**
|
||||
* Base view class for projectable models.
|
||||
*/
|
||||
export abstract class BaseProjectableViewModel extends BaseViewModel implements Projectable {
|
||||
public abstract getSlide(): ProjectorElementBuildDeskriptor;
|
||||
public abstract getSlide(configService?: ConfigService): ProjectorElementBuildDeskriptor;
|
||||
|
||||
/**
|
||||
* @returns the projector title used for managing projector elements.
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Displayable } from 'app/site/base/displayable';
|
||||
import { IdentifiableProjectorElement, ProjectorElementOptions } from 'app/shared/models/core/projector';
|
||||
import { SlideOptions } from './slide-options';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
|
||||
export function isProjectorElementBuildDeskriptor(obj: any): obj is ProjectorElementBuildDeskriptor {
|
||||
const deskriptor = <ProjectorElementBuildDeskriptor>obj;
|
||||
@ -35,5 +36,5 @@ export function isProjectable(obj: any): obj is Projectable {
|
||||
* Interface for every model, that should be projectable.
|
||||
*/
|
||||
export interface Projectable extends Displayable {
|
||||
getSlide(): ProjectorElementBuildDeskriptor;
|
||||
getSlide(configSerice?: ConfigService): ProjectorElementBuildDeskriptor;
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ import { ViewWorkflow } from './view-workflow';
|
||||
import { ViewCategory } from './view-category';
|
||||
import { ViewMotionBlock } from './view-motion-block';
|
||||
import { BaseViewModel } from 'app/site/base/base-view-model';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
import { ViewMotionChangeRecommendation } from './view-change-recommendation';
|
||||
|
||||
/**
|
||||
* The line numbering mode for the motion detail view.
|
||||
@ -58,6 +60,7 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
protected _attachments: ViewMediafile[];
|
||||
protected _tags: ViewTag[];
|
||||
protected _parent: ViewMotion;
|
||||
protected _changeRecommendations: ViewMotionChangeRecommendation[];
|
||||
public personalNote: PersonalNoteContent;
|
||||
|
||||
/**
|
||||
@ -157,6 +160,10 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
return this._state;
|
||||
}
|
||||
|
||||
public get changeRecommendations(): ViewMotionChangeRecommendation[] {
|
||||
return this._changeRecommendations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current state of thw workflow is final
|
||||
*
|
||||
@ -356,7 +363,8 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
block?: ViewMotionBlock,
|
||||
attachments?: ViewMediafile[],
|
||||
tags?: ViewTag[],
|
||||
parent?: ViewMotion
|
||||
parent?: ViewMotion,
|
||||
changeRecommendations?: ViewMotionChangeRecommendation[]
|
||||
) {
|
||||
super(Motion.COLLECTIONSTRING);
|
||||
this._motion = motion;
|
||||
@ -370,6 +378,7 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
this._attachments = attachments;
|
||||
this._tags = tags;
|
||||
this._parent = parent;
|
||||
this._changeRecommendations = changeRecommendations;
|
||||
}
|
||||
|
||||
public getAgendaItem(): ViewItem {
|
||||
@ -429,6 +438,8 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
this.updateTags(update);
|
||||
} else if (update instanceof ViewMotion && update.id !== this.id) {
|
||||
this.updateParent(update);
|
||||
} else if (update instanceof ViewMotionChangeRecommendation) {
|
||||
this.updateChangeRecommendation(update);
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,7 +448,7 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
*
|
||||
* @param workflow potentially the (changed workflow (state). Needs manual verification
|
||||
*/
|
||||
public updateWorkflow(workflow: ViewWorkflow): void {
|
||||
private updateWorkflow(workflow: ViewWorkflow): void {
|
||||
if (workflow.id === this.motion.workflow_id) {
|
||||
this._workflow = workflow;
|
||||
this._state = workflow.getStateById(this.state_id);
|
||||
@ -449,7 +460,7 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
*
|
||||
* @param category potentially the changed category. Needs manual verification
|
||||
*/
|
||||
public updateCategory(category: ViewCategory): void {
|
||||
private updateCategory(category: ViewCategory): void {
|
||||
if (this.category_id && category.id === this.motion.category_id) {
|
||||
this._category = category;
|
||||
}
|
||||
@ -460,7 +471,7 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
*
|
||||
* @param item potentially the changed agenda Item. Needs manual verification
|
||||
*/
|
||||
public updateItem(item: ViewItem): void {
|
||||
private updateItem(item: ViewItem): void {
|
||||
if (item.id === this.motion.agenda_item_id) {
|
||||
this._item = item;
|
||||
}
|
||||
@ -471,7 +482,7 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
*
|
||||
* @param block potentially the changed motion block. Needs manual verification
|
||||
*/
|
||||
public updateMotionBlock(block: ViewMotionBlock): void {
|
||||
private updateMotionBlock(block: ViewMotionBlock): void {
|
||||
if (this.motion_block_id && block.id === this.motion.motion_block_id) {
|
||||
this._block = block;
|
||||
}
|
||||
@ -482,7 +493,7 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
*
|
||||
* @param update potentially the changed agenda Item. Needs manual verification
|
||||
*/
|
||||
public updateUser(update: ViewUser): void {
|
||||
private updateUser(update: ViewUser): void {
|
||||
if (this.motion.submitters && this.motion.submitters.find(user => user.user_id === update.id)) {
|
||||
const userIndex = this.motion.submitters.findIndex(submitter => submitter.user_id === update.id);
|
||||
this.submitters[userIndex] = update;
|
||||
@ -502,7 +513,7 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
*
|
||||
* @param mediafile
|
||||
*/
|
||||
public updateAttachments(mediafile: ViewMediafile): void {
|
||||
private updateAttachments(mediafile: ViewMediafile): void {
|
||||
if (this.attachments_id && this.attachments_id.includes(mediafile.id)) {
|
||||
const attachmentIndex = this.attachments.findIndex(_mediafile => _mediafile.id === mediafile.id);
|
||||
if (attachmentIndex < 0) {
|
||||
@ -513,7 +524,7 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
}
|
||||
}
|
||||
|
||||
public updateTags(tag: ViewTag): void {
|
||||
private updateTags(tag: ViewTag): void {
|
||||
if (this.tags_id && this.tags_id.includes(tag.id)) {
|
||||
const tagIndex = this.tags.findIndex(_tag => _tag.id === tag.id);
|
||||
if (tagIndex < 0) {
|
||||
@ -524,12 +535,23 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
}
|
||||
}
|
||||
|
||||
public updateParent(parent: ViewMotion): void {
|
||||
private updateParent(parent: ViewMotion): void {
|
||||
if (this.parent_id && this.parent_id === parent.id) {
|
||||
this._parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
private updateChangeRecommendation(cr: ViewMotionChangeRecommendation): void {
|
||||
if (cr.motion_id === this.id) {
|
||||
const index = this.changeRecommendations.findIndex(_cr => _cr.id === cr.id);
|
||||
if (index < 0) {
|
||||
this.changeRecommendations.push(cr);
|
||||
} else {
|
||||
this.changeRecommendations[index] = cr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public hasSupporters(): boolean {
|
||||
return !!(this.supporters && this.supporters.length > 0);
|
||||
}
|
||||
@ -561,26 +583,30 @@ export class ViewMotion extends BaseAgendaViewModel implements Searchable {
|
||||
return this.amendment_paragraphs.length > 0;
|
||||
}
|
||||
|
||||
public getSlide(): ProjectorElementBuildDeskriptor {
|
||||
public getSlide(configService: ConfigService): ProjectorElementBuildDeskriptor {
|
||||
const slideOptions = [];
|
||||
|
||||
if (this.changeRecommendations && this.changeRecommendations.length) {
|
||||
slideOptions.push({
|
||||
key: 'mode',
|
||||
displayName: 'Which version?',
|
||||
default: configService.instant('motions_recommendation_text_mode'),
|
||||
choices: [
|
||||
{ value: 'original', displayName: 'Original version' },
|
||||
{ value: 'changed', displayName: 'Changed version' },
|
||||
{ value: 'diff', displayName: 'Diff version' },
|
||||
{ value: 'agreed', displayName: 'Final version' }
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
getBasicProjectorElement: options => ({
|
||||
name: Motion.COLLECTIONSTRING,
|
||||
id: this.id,
|
||||
getIdentifiers: () => ['name', 'id']
|
||||
}),
|
||||
slideOptions: [
|
||||
{
|
||||
key: 'mode',
|
||||
displayName: 'Change recommendations',
|
||||
default: 'original',
|
||||
choices: [
|
||||
{ value: 'original', displayName: 'Original version' },
|
||||
{ value: 'changed', displayName: 'Changed version' },
|
||||
{ value: 'diff', displayName: 'Diff version' },
|
||||
{ value: 'agreed', displayName: 'Final version' }
|
||||
]
|
||||
}
|
||||
],
|
||||
slideOptions: slideOptions,
|
||||
projectionDefaultName: 'motions',
|
||||
getDialogTitle: this.getAgendaTitle
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user