Merge pull request #4164 from MaximilianKrambach/stateRecExtensions
set/read state+recommendation extensions
This commit is contained in:
commit
7b8839f4fa
@ -26,7 +26,7 @@ export class WorkflowState extends Deserializer {
|
|||||||
public allow_create_poll: boolean;
|
public allow_create_poll: boolean;
|
||||||
public allow_submitter_edit: boolean;
|
public allow_submitter_edit: boolean;
|
||||||
public dont_set_identifier: boolean;
|
public dont_set_identifier: boolean;
|
||||||
public show_state_extension_field: number;
|
public show_state_extension_field: boolean;
|
||||||
public merge_amendment_into_final: MergeAmendment;
|
public merge_amendment_into_final: MergeAmendment;
|
||||||
public show_recommendation_extension_field: boolean;
|
public show_recommendation_extension_field: boolean;
|
||||||
public next_states_id: number[];
|
public next_states_id: number[];
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
lightblue: motion.state.css_class === 'primary'
|
lightblue: motion.state.css_class === 'primary'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ motion.state.name | translate }}
|
{{ getStateLabel(motion) }}
|
||||||
</mat-basic-chip>
|
</mat-basic-chip>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@ -72,11 +72,7 @@
|
|||||||
<mat-header-cell *matHeaderCellDef> <span translate>Recommendation</span> </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef> <span translate>Recommendation</span> </mat-header-cell>
|
||||||
<mat-cell class="chip-container" *matCellDef="let motion">
|
<mat-cell class="chip-container" *matCellDef="let motion">
|
||||||
<mat-basic-chip disableRipple class="bluegrey">
|
<mat-basic-chip disableRipple class="bluegrey">
|
||||||
{{
|
{{ getRecommendationLabel(motion) }}
|
||||||
motion.recommendation
|
|
||||||
? (motion.recommendation.recommendation_label | translate)
|
|
||||||
: ('not set' | translate)
|
|
||||||
}}
|
|
||||||
</mat-basic-chip>
|
</mat-basic-chip>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { FormGroup, FormControl, Validators } from '@angular/forms';
|
import { FormGroup, FormControl, Validators } from '@angular/forms';
|
||||||
import { Title } from '@angular/platform-browser';
|
|
||||||
import { MatSnackBar } from '@angular/material';
|
import { MatSnackBar } from '@angular/material';
|
||||||
|
import { Title } from '@angular/platform-browser';
|
||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { ListViewBaseComponent } from 'app/site/base/list-view-base';
|
import { ListViewBaseComponent } from 'app/site/base/list-view-base';
|
||||||
import { MotionBlockRepositoryService } from '../../services/motion-block-repository.service';
|
|
||||||
import { MotionBlock } from 'app/shared/models/motions/motion-block';
|
import { MotionBlock } from 'app/shared/models/motions/motion-block';
|
||||||
|
import { MotionBlockRepositoryService } from '../../services/motion-block-repository.service';
|
||||||
|
import { MotionRepositoryService } from '../../services/motion-repository.service';
|
||||||
import { ViewMotionBlock } from '../../models/view-motion-block';
|
import { ViewMotionBlock } from '../../models/view-motion-block';
|
||||||
import { ViewMotion } from '../../models/view-motion';
|
|
||||||
import { PromptService } from 'app/core/services/prompt.service';
|
import { PromptService } from 'app/core/services/prompt.service';
|
||||||
|
import { ViewMotion } from '../../models/view-motion';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detail component to display one motion block
|
* Detail component to display one motion block
|
||||||
@ -52,6 +53,7 @@ export class MotionBlockDetailComponent extends ListViewBaseComponent<ViewMotion
|
|||||||
* @param router navigating
|
* @param router navigating
|
||||||
* @param route determine the blocks ID by the route
|
* @param route determine the blocks ID by the route
|
||||||
* @param repo the motion blocks repository
|
* @param repo the motion blocks repository
|
||||||
|
* @param motionRepo the motion repository
|
||||||
* @param promptService the displaying prompts before deleting
|
* @param promptService the displaying prompts before deleting
|
||||||
*/
|
*/
|
||||||
public constructor(
|
public constructor(
|
||||||
@ -61,6 +63,7 @@ export class MotionBlockDetailComponent extends ListViewBaseComponent<ViewMotion
|
|||||||
private router: Router,
|
private router: Router,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private repo: MotionBlockRepositoryService,
|
private repo: MotionBlockRepositoryService,
|
||||||
|
private motionRepo: MotionRepositoryService,
|
||||||
private promptService: PromptService
|
private promptService: PromptService
|
||||||
) {
|
) {
|
||||||
super(titleService, translate, matSnackBar);
|
super(titleService, translate, matSnackBar);
|
||||||
@ -199,4 +202,24 @@ export class MotionBlockDetailComponent extends ListViewBaseComponent<ViewMotion
|
|||||||
public toggleEditMode(): void {
|
public toggleEditMode(): void {
|
||||||
this.editBlock = !this.editBlock;
|
this.editBlock = !this.editBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a motion's current recommendation label
|
||||||
|
*
|
||||||
|
* @param motion
|
||||||
|
* @returns the current recommendation label (with extension)
|
||||||
|
*/
|
||||||
|
public getRecommendationLabel(motion: ViewMotion): string {
|
||||||
|
return this.motionRepo.getExtendedRecommendationLabel(motion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a motion's current state label
|
||||||
|
*
|
||||||
|
* @param motion
|
||||||
|
* @returns the current state label (with extension)
|
||||||
|
*/
|
||||||
|
public getStateLabel(motion: ViewMotion): string {
|
||||||
|
return this.motionRepo.getExtendedStateLabel(motion);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,25 +220,32 @@
|
|||||||
<mat-menu #stateMenu="matMenu">
|
<mat-menu #stateMenu="matMenu">
|
||||||
<button *ngFor="let state of motion.nextStates" mat-menu-item (click)="setState(state.id)">
|
<button *ngFor="let state of motion.nextStates" mat-menu-item (click)="setState(state.id)">
|
||||||
{{ state.name | translate }}
|
{{ state.name | translate }}
|
||||||
|
<span *ngIf="state.show_state_extension_field"> ...</span>
|
||||||
</button>
|
</button>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<button mat-menu-item (click)="setState(null)" *ngIf="perms.isAllowed('change_metadata', motion)">
|
<button mat-menu-item (click)="setState(null)" *ngIf="perms.isAllowed('change_metadata', motion)">
|
||||||
<mat-icon>replay</mat-icon> {{ 'Reset state' | translate }}
|
<mat-icon>replay</mat-icon> {{ 'Reset state' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
<mat-basic-chip
|
<div *ngIf="perms.isAllowed('change_metadata', motion)">
|
||||||
*ngIf="perms.isAllowed('change_metadata', motion)"
|
<mat-basic-chip [matMenuTriggerFor]="stateMenu" [ngClass]="getStateCssColor()">
|
||||||
[matMenuTriggerFor]="stateMenu"
|
{{ stateLabel }}
|
||||||
[ngClass]="getStateCssColor()"
|
</mat-basic-chip>
|
||||||
>
|
<div *ngIf="motion.state.show_state_extension_field" class="spacer-top-10">
|
||||||
{{ motion.state.name | translate }}
|
<mat-form-field>
|
||||||
</mat-basic-chip>
|
<input matInput placeholder="{{ 'Extension' | translate }}"
|
||||||
<mat-basic-chip
|
[(ngModel)]="newStateExtension"/>
|
||||||
*ngIf="!perms.isAllowed('change_metadata', motion)"
|
</mat-form-field>
|
||||||
[ngClass]="getStateCssColor()"
|
<button mat-icon-button (click)="setStateExtension()">
|
||||||
>
|
<mat-icon>check</mat-icon>
|
||||||
{{ motion.state.name | translate }}
|
</button>
|
||||||
</mat-basic-chip>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="!perms.isAllowed('change_metadata', motion)">
|
||||||
|
<mat-basic-chip [ngClass]="getStateCssColor()" >
|
||||||
|
{{ stateLabel }}
|
||||||
|
</mat-basic-chip>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Recommendation -->
|
<!-- Recommendation -->
|
||||||
@ -251,6 +258,7 @@
|
|||||||
(click)="setRecommendation(recommendation.id)"
|
(click)="setRecommendation(recommendation.id)"
|
||||||
>
|
>
|
||||||
{{ recommendation.recommendation_label | translate }}
|
{{ recommendation.recommendation_label | translate }}
|
||||||
|
<span *ngIf="recommendation.show_recommendation_extension_field"> ...</span>
|
||||||
</button>
|
</button>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<button mat-menu-item *ngIf="perms.isAllowed('change_metadata', motion)"
|
<button mat-menu-item *ngIf="perms.isAllowed('change_metadata', motion)"
|
||||||
@ -258,28 +266,26 @@
|
|||||||
<mat-icon>replay</mat-icon> {{ 'Reset recommendation' | translate }}
|
<mat-icon>replay</mat-icon> {{ 'Reset recommendation' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
<mat-basic-chip
|
<div *ngIf="perms.isAllowed('change_metadata', motion)">
|
||||||
*ngIf="perms.isAllowed('change_metadata', motion)"
|
<mat-basic-chip [matMenuTriggerFor]="recommendationMenu" class="bluegrey">
|
||||||
[matMenuTriggerFor]="recommendationMenu"
|
{{ recommendationLabel }}
|
||||||
class="bluegrey"
|
</mat-basic-chip>
|
||||||
>
|
<div *ngIf="motion.recommendation && motion.recommendation.show_recommendation_extension_field"
|
||||||
{{
|
class="spacer-top-10">
|
||||||
motion.recommendation
|
<mat-form-field>
|
||||||
? (motion.recommendation.recommendation_label | translate)
|
<input matInput placeholder="{{ 'Extension' | translate }}"
|
||||||
: ('not set' | translate)
|
[(ngModel)]="newRecommendationExtension"/>
|
||||||
}}
|
</mat-form-field>
|
||||||
</mat-basic-chip>
|
<button mat-icon-button (click)="setRecommendationExtension()">
|
||||||
<mat-basic-chip
|
<mat-icon>check</mat-icon>
|
||||||
*ngIf="!perms.isAllowed('change_metadata', motion)"
|
</button>
|
||||||
class="bluegrey"
|
</div>
|
||||||
>
|
</div>
|
||||||
{{
|
<div *ngIf="!perms.isAllowed('change_metadata', motion)">
|
||||||
motion.recommendation
|
<mat-basic-chip class="bluegrey">
|
||||||
? (motion.recommendation.recommendation_label | translate)
|
{{ recommendationLabel }}
|
||||||
: ('not set' | translate)
|
</mat-basic-chip>
|
||||||
}}
|
</div>
|
||||||
</mat-basic-chip>
|
|
||||||
|
|
||||||
<button mat-button *ngIf="canFollowRecommendation()" (click)="onFollowRecButton()">
|
<button mat-button *ngIf="canFollowRecommendation()" (click)="onFollowRecButton()">
|
||||||
<span translate>Follow recommendation</span>
|
<span translate>Follow recommendation</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -114,6 +114,20 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the current recommendation label (with extension)
|
||||||
|
*/
|
||||||
|
public get recommendationLabel(): string {
|
||||||
|
return this.repo.getExtendedRecommendationLabel(this.motion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the current state label (with extension)
|
||||||
|
*/
|
||||||
|
public get stateLabel(): string {
|
||||||
|
return this.repo.getExtendedStateLabel(this.motion);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the target motion. Accessed via the getter and setter.
|
* Saves the target motion. Accessed via the getter and setter.
|
||||||
*/
|
*/
|
||||||
@ -286,6 +300,16 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
public personalNoteContent: PersonalNoteContent;
|
public personalNoteContent: PersonalNoteContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* new state extension label to be submitted, if state extensions can be set
|
||||||
|
*/
|
||||||
|
public newStateExtension = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* new recommendation extension label to be submitted, if recommendation extensions can be set
|
||||||
|
*/
|
||||||
|
public newRecommendationExtension = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constuct the detail view.
|
* Constuct the detail view.
|
||||||
*
|
*
|
||||||
@ -460,6 +484,8 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
this.repo.getViewModelObservable(motionId).subscribe(newViewMotion => {
|
this.repo.getViewModelObservable(motionId).subscribe(newViewMotion => {
|
||||||
if (newViewMotion) {
|
if (newViewMotion) {
|
||||||
this.motion = newViewMotion;
|
this.motion = newViewMotion;
|
||||||
|
this.newStateExtension = this.motion.stateExtension;
|
||||||
|
this.newRecommendationExtension = this.motion.recommendationExtension;
|
||||||
this.personalNoteService.getPersonalNoteObserver(this.motion.motion).subscribe(pn => {
|
this.personalNoteService.getPersonalNoteObserver(this.motion.motion).subscribe(pn => {
|
||||||
this.personalNoteContent = pn;
|
this.personalNoteContent = pn;
|
||||||
});
|
});
|
||||||
@ -906,6 +932,14 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
this.repo.setState(this.motion, id);
|
this.repo.setState(this.motion, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* triggers the update this motion's state extension according to the current string
|
||||||
|
* in {@link newStateExtension}
|
||||||
|
*/
|
||||||
|
public setStateExtension(): void {
|
||||||
|
this.repo.setStateExtension(this.motion, this.newStateExtension);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the recommendation
|
* Sets the recommendation
|
||||||
*
|
*
|
||||||
@ -915,6 +949,14 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit {
|
|||||||
this.repo.setRecommendation(this.motion, id);
|
this.repo.setRecommendation(this.motion, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* triggers the update this motion's recommendation extension according to the current string
|
||||||
|
* in {@link newRecommendationExtension}
|
||||||
|
*/
|
||||||
|
public setRecommendationExtension(): void {
|
||||||
|
this.repo.setRecommendationExtension(this.motion, this.newRecommendationExtension);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the category for current motion
|
* Sets the category for current motion
|
||||||
*
|
*
|
||||||
|
@ -17,8 +17,11 @@
|
|||||||
</os-head-bar>
|
</os-head-bar>
|
||||||
|
|
||||||
<mat-drawer-container class="on-transition-fade">
|
<mat-drawer-container class="on-transition-fade">
|
||||||
<os-sort-filter-bar [filterService]="filterService" [sortService]="sortService"
|
<os-sort-filter-bar
|
||||||
(searchFieldChange)="searchFilter($event)">
|
[filterService]="filterService"
|
||||||
|
[sortService]="sortService"
|
||||||
|
(searchFieldChange)="searchFilter($event)"
|
||||||
|
>
|
||||||
</os-sort-filter-bar>
|
</os-sort-filter-bar>
|
||||||
|
|
||||||
<mat-table class="os-listview-table on-transition-fade" [dataSource]="dataSource" matSort>
|
<mat-table class="os-listview-table on-transition-fade" [dataSource]="dataSource" matSort>
|
||||||
@ -30,7 +33,7 @@
|
|||||||
</mat-cell>
|
</mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- Projector column -->
|
<!-- Projector column -->
|
||||||
<ng-container matColumnDef="projector">
|
<ng-container matColumnDef="projector">
|
||||||
<mat-header-cell *matHeaderCellDef mat-sort-header class="icon-cell">Projector</mat-header-cell>
|
<mat-header-cell *matHeaderCellDef mat-sort-header class="icon-cell">Projector</mat-header-cell>
|
||||||
<mat-cell *matCellDef="let motion" class="icon-cell">
|
<mat-cell *matCellDef="let motion" class="icon-cell">
|
||||||
@ -82,14 +85,12 @@
|
|||||||
lightblue: motion.state.css_class === 'primary'
|
lightblue: motion.state.css_class === 'primary'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ motion.state.name | translate }}
|
{{ getStateLabel(motion) }}
|
||||||
</mat-basic-chip>
|
</mat-basic-chip>
|
||||||
|
|
||||||
<!-- recommendation -->
|
<!-- recommendation -->
|
||||||
<span *ngIf="motion.recommendation">
|
<span *ngIf="motion.recommendation">
|
||||||
<mat-basic-chip class="bluegrey">{{
|
<mat-basic-chip class="bluegrey"> {{ getRecommendationLabel(motion) }} </mat-basic-chip>
|
||||||
motion.recommendation.recommendation_label | translate
|
|
||||||
}}</mat-basic-chip>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
@ -198,20 +199,29 @@
|
|||||||
<mat-icon>label</mat-icon>
|
<mat-icon>label</mat-icon>
|
||||||
<span translate>Set status</span>
|
<span translate>Set status</span>
|
||||||
</button>
|
</button>
|
||||||
<button *ngIf="recomendationEnabled" mat-menu-item
|
<button
|
||||||
(click)="multiselectWrapper(multiselectService.setRecommendation(selectedRows))">
|
*ngIf="recomendationEnabled"
|
||||||
|
mat-menu-item
|
||||||
|
(click)="multiselectWrapper(multiselectService.setRecommendation(selectedRows))"
|
||||||
|
>
|
||||||
<mat-icon>report</mat-icon>
|
<mat-icon>report</mat-icon>
|
||||||
<!-- TODO: better icon -->
|
<!-- TODO: better icon -->
|
||||||
<span translate>Set recommendation</span>
|
<span translate>Set recommendation</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item *ngIf="categories.length"
|
<button
|
||||||
(click)="multiselectWrapper(multiselectService.setCategory(selectedRows))">
|
mat-menu-item
|
||||||
|
*ngIf="categories.length"
|
||||||
|
(click)="multiselectWrapper(multiselectService.setCategory(selectedRows))"
|
||||||
|
>
|
||||||
<mat-icon>device_hub</mat-icon>
|
<mat-icon>device_hub</mat-icon>
|
||||||
<!-- TODO: icon -->
|
<!-- TODO: icon -->
|
||||||
<span translate>Set category</span>
|
<span translate>Set category</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item *ngIf="motionBlocks.length"
|
<button
|
||||||
(click)="multiselectWrapper(multiselectService.setMotionBlock(selectedRows))">
|
mat-menu-item
|
||||||
|
*ngIf="motionBlocks.length"
|
||||||
|
(click)="multiselectWrapper(multiselectService.setMotionBlock(selectedRows))"
|
||||||
|
>
|
||||||
<mat-icon>widgets</mat-icon>
|
<mat-icon>widgets</mat-icon>
|
||||||
<!-- TODO: icon -->
|
<!-- TODO: icon -->
|
||||||
<span translate>Set motion block</span>
|
<span translate>Set motion block</span>
|
||||||
@ -222,8 +232,11 @@
|
|||||||
<!-- TODO: icon -->
|
<!-- TODO: icon -->
|
||||||
<span translate>Add/remove submitters</span>
|
<span translate>Add/remove submitters</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item *ngIf="tags.length"
|
<button
|
||||||
(click)="multiselectWrapper(multiselectService.changeTags(selectedRows))">
|
mat-menu-item
|
||||||
|
*ngIf="tags.length"
|
||||||
|
(click)="multiselectWrapper(multiselectService.changeTags(selectedRows))"
|
||||||
|
>
|
||||||
<mat-icon>bookmarks</mat-icon>
|
<mat-icon>bookmarks</mat-icon>
|
||||||
<!-- TODO: icon -->
|
<!-- TODO: icon -->
|
||||||
<span translate>Add/remove tags</span>
|
<span translate>Add/remove tags</span>
|
||||||
@ -247,4 +260,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import { MotionBlockRepositoryService } from '../../services/motion-block-reposi
|
|||||||
import { MotionCsvExportService } from '../../services/motion-csv-export.service';
|
import { MotionCsvExportService } from '../../services/motion-csv-export.service';
|
||||||
import { MotionFilterListService } from '../../services/motion-filter-list.service';
|
import { MotionFilterListService } from '../../services/motion-filter-list.service';
|
||||||
import { MotionMultiselectService } from '../../services/motion-multiselect.service';
|
import { MotionMultiselectService } from '../../services/motion-multiselect.service';
|
||||||
|
import { MotionRepositoryService } from '../../services/motion-repository.service';
|
||||||
import { MotionSortListService } from '../../services/motion-sort-list.service';
|
import { MotionSortListService } from '../../services/motion-sort-list.service';
|
||||||
import { TagRepositoryService } from 'app/site/tags/services/tag-repository.service';
|
import { TagRepositoryService } from 'app/site/tags/services/tag-repository.service';
|
||||||
import { ViewCategory } from '../../models/view-category';
|
import { ViewCategory } from '../../models/view-category';
|
||||||
@ -90,6 +91,7 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
|
|||||||
private motionBlockRepo: MotionBlockRepositoryService,
|
private motionBlockRepo: MotionBlockRepositoryService,
|
||||||
private categoryRepo: CategoryRepositoryService,
|
private categoryRepo: CategoryRepositoryService,
|
||||||
private workflowRepo: WorkflowRepositoryService,
|
private workflowRepo: WorkflowRepositoryService,
|
||||||
|
private motionRepo: MotionRepositoryService,
|
||||||
private motionCsvExport: MotionCsvExportService,
|
private motionCsvExport: MotionCsvExportService,
|
||||||
public multiselectService: MotionMultiselectService,
|
public multiselectService: MotionMultiselectService,
|
||||||
public sortService: MotionSortListService,
|
public sortService: MotionSortListService,
|
||||||
@ -212,4 +214,24 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion> imple
|
|||||||
this.raiseError(e);
|
this.raiseError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a motion's current recommendation label
|
||||||
|
*
|
||||||
|
* @param motion
|
||||||
|
* @returns the current recommendation label (with extension)
|
||||||
|
*/
|
||||||
|
public getRecommendationLabel(motion: ViewMotion): string {
|
||||||
|
return this.motionRepo.getExtendedRecommendationLabel(motion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a motion's current state label
|
||||||
|
*
|
||||||
|
* @param motion
|
||||||
|
* @returns the current state label (with extension)
|
||||||
|
*/
|
||||||
|
public getStateLabel(motion: ViewMotion): string {
|
||||||
|
return this.motionRepo.getExtendedStateLabel(motion);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,6 +241,28 @@ export class ViewMotion extends BaseProjectableModel {
|
|||||||
return new Date(this.motion.last_modified);
|
return new Date(this.motion.last_modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the current state extension if the workwlof allows for extenstion fields
|
||||||
|
*/
|
||||||
|
public get stateExtension(): string {
|
||||||
|
if (this.state && this.state.show_state_extension_field) {
|
||||||
|
return this.motion.state_extension;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the current recommendation extension if the workwlof allows for extenstion fields
|
||||||
|
*/
|
||||||
|
public get recommendationExtension(): string {
|
||||||
|
if (this.recommendation && this.recommendation.show_recommendation_extension_field) {
|
||||||
|
return this.motion.recommendation_extension;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the comments' section ids of a motion. Used in filter by motionComment
|
* Gets the comments' section ids of a motion. Used in filter by motionComment
|
||||||
*
|
*
|
||||||
|
@ -146,7 +146,7 @@ export class MotionPdfService {
|
|||||||
style: 'boldText'
|
style: 'boldText'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: this.translate.instant(motion.state.name)
|
text: this.motionRepo.getExtendedStateLabel(motion)
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ export class MotionPdfService {
|
|||||||
style: 'boldText'
|
style: 'boldText'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: this.translate.instant(motion.recommendation.recommendation_label)
|
text: this.motionRepo.getExtendedRecommendationLabel(motion)
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { tap, map } from 'rxjs/operators';
|
import { tap, map } from 'rxjs/operators';
|
||||||
@ -67,7 +68,8 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
|
|||||||
private readonly lineNumbering: LinenumberingService,
|
private readonly lineNumbering: LinenumberingService,
|
||||||
private readonly diff: DiffService,
|
private readonly diff: DiffService,
|
||||||
private treeService: TreeService,
|
private treeService: TreeService,
|
||||||
private personalNoteService: PersonalNoteService
|
private personalNoteService: PersonalNoteService,
|
||||||
|
private translate: TranslateService
|
||||||
) {
|
) {
|
||||||
super(DS, mapperService, Motion, [Category, User, Workflow, Item, MotionBlock, Mediafile]);
|
super(DS, mapperService, Motion, [Category, User, Workflow, Item, MotionBlock, Mediafile]);
|
||||||
}
|
}
|
||||||
@ -701,4 +703,84 @@ export class MotionRepositoryService extends BaseRepository<ViewMotion, Motion>
|
|||||||
public hasAmendments(motion: ViewMotion): boolean {
|
public hasAmendments(motion: ViewMotion): boolean {
|
||||||
return this.getViewModelList().filter(allMotions => allMotions.parent_id === motion.id).length > 0;
|
return this.getViewModelList().filter(allMotions => allMotions.parent_id === motion.id).length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the state Extension with the string given, if the current workflow allows for it
|
||||||
|
*
|
||||||
|
* @param viewMotion
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
public async setStateExtension(viewMotion: ViewMotion, value: string): Promise<void> {
|
||||||
|
if (viewMotion.state.show_state_extension_field) {
|
||||||
|
return this.update({ state_extension: value }, viewMotion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updates the recommendation extension with the string given, if the current workflow allows for it
|
||||||
|
*
|
||||||
|
* @param viewMotion
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
public async setRecommendationExtension(viewMotion: ViewMotion, value: string): Promise<void> {
|
||||||
|
if (viewMotion.recommendation.show_recommendation_extension_field) {
|
||||||
|
return this.update({ recommendation_extension: value }, viewMotion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the label for the motion's current state with the extension
|
||||||
|
* attached (if present). For cross-referencing other motions, `[motion:id]`
|
||||||
|
* will replaced by the referenced motion's identifier (see {@link solveExtensionPlaceHolder})
|
||||||
|
*
|
||||||
|
* @param motion
|
||||||
|
* @returns the translated state with the extension attached
|
||||||
|
*/
|
||||||
|
public getExtendedStateLabel(motion: ViewMotion): string {
|
||||||
|
let rec = this.translate.instant(motion.state.name);
|
||||||
|
if (motion.stateExtension && motion.state.show_state_extension_field) {
|
||||||
|
rec += ' ' + this.solveExtensionPlaceHolder(motion.stateExtension);
|
||||||
|
}
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the label for the motion's current recommendation with the extension
|
||||||
|
* attached (if present)
|
||||||
|
*
|
||||||
|
* @param motion
|
||||||
|
* @returns the translated extension with the extension attached, 'not set'
|
||||||
|
* if no recommendation si set
|
||||||
|
*/
|
||||||
|
public getExtendedRecommendationLabel(motion: ViewMotion): string {
|
||||||
|
if (!motion.recommendation) {
|
||||||
|
return this.translate.instant('not set');
|
||||||
|
}
|
||||||
|
let rec = this.translate.instant(motion.recommendation.recommendation_label);
|
||||||
|
if (motion.recommendationExtension && motion.recommendation.show_recommendation_extension_field) {
|
||||||
|
rec += ' ' + this.solveExtensionPlaceHolder(motion.recommendationExtension);
|
||||||
|
}
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces any motion placeholder (`[motion:id]`) with the motion's title(s)
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @returns the string with the motion titles replacing the placeholders, '??' strings for errors
|
||||||
|
*/
|
||||||
|
public solveExtensionPlaceHolder(value: string): string {
|
||||||
|
const beg = value.indexOf('[motion:');
|
||||||
|
const end = value.indexOf(']');
|
||||||
|
if (beg > -1 && (end > -1 && end > beg)) {
|
||||||
|
const id = Number(value.substring(beg + 8, end));
|
||||||
|
const referedMotion = Number.isNaN(id) ? null : this.getViewModel(id);
|
||||||
|
const title = referedMotion ? referedMotion.identifier : '??';
|
||||||
|
value = value.substring(0, beg) + title + value.substring(end + 1);
|
||||||
|
// recursively check for additional occurrences
|
||||||
|
return this.solveExtensionPlaceHolder(value);
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user