Merge pull request #4427 from FinnStutzenstein/motionProjectionMode

motion projection mode is optional and sensitive for the config
This commit is contained in:
Emanuel Schütze 2019-03-01 10:23:55 +01:00 committed by GitHub
commit 573cdd88a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 86 additions and 36 deletions

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -167,6 +167,7 @@ _('Amendment to');
_('Statute amendment for');
_('Creation date');
_('Last modified');
_('Which version?');
// motion workflow 1
_('Simple Workflow');

View File

@ -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);

View File

@ -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;
}

View File

@ -1,7 +1,9 @@
h2 {
margin-bottom: 5px;
}
h3 {
margin-bottom: 5px;
}
.element-name {
margin-bottom: 10px;
}

View File

@ -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.

View File

@ -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;
}

View File

@ -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
};