Merge pull request #4833 from tsiegleauq/add-extension-to-label
Enhance motion extension field
This commit is contained in:
commit
6e8aa75162
@ -2,17 +2,22 @@
|
|||||||
<div>
|
<div>
|
||||||
<h4 *ngIf="title">{{ title }}</h4>
|
<h4 *ngIf="title">{{ title }}</h4>
|
||||||
<mat-menu #triggerMenu="matMenu">
|
<mat-menu #triggerMenu="matMenu">
|
||||||
<ng-container
|
<ng-container [ngTemplateOutlet]="triggerTemplate"> </ng-container>
|
||||||
[ngTemplateOutlet]="triggerTemplate">
|
|
||||||
</ng-container>
|
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
<os-icon-container
|
<os-icon-container
|
||||||
iconTooltip="{{ 'Edit' | translate }}"
|
iconTooltip="{{ 'Edit' | translate }}"
|
||||||
icon="create"
|
icon="create"
|
||||||
[swap]="true"
|
[swap]="true"
|
||||||
[showIcon]="!editMode && canBeEdited && hasExtension"
|
[showIcon]="!editMode && canBeEdited && hasExtension"
|
||||||
(iconAction)="changeEditMode()">
|
(iconAction)="changeEditMode()"
|
||||||
<mat-basic-chip *ngIf="canBeEdited" [matMenuTriggerFor]="triggerMenu" [ngClass]="classes" class="pointer" disableRipple>
|
>
|
||||||
|
<mat-basic-chip
|
||||||
|
*ngIf="canBeEdited"
|
||||||
|
[matMenuTriggerFor]="triggerMenu"
|
||||||
|
[ngClass]="classes"
|
||||||
|
class="pointer"
|
||||||
|
disableRipple
|
||||||
|
>
|
||||||
{{ chipValue || '–' }}
|
{{ chipValue || '–' }}
|
||||||
</mat-basic-chip>
|
</mat-basic-chip>
|
||||||
<mat-basic-chip *ngIf="!canBeEdited" [ngClass]="classes" disableRipple>
|
<mat-basic-chip *ngIf="!canBeEdited" [ngClass]="classes" disableRipple>
|
||||||
@ -22,15 +27,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Extension field -->
|
<!-- Extension field -->
|
||||||
<div
|
<div *ngIf="hasExtension && editMode" class="spacer-top-10 extension-container">
|
||||||
*ngIf="hasExtension && editMode"
|
|
||||||
class="spacer-top-10 extension-container"
|
|
||||||
>
|
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input
|
<input
|
||||||
matInput
|
matInput
|
||||||
|
osAutofocus
|
||||||
[(ngModel)]="inputControl"
|
[(ngModel)]="inputControl"
|
||||||
placeholder="{{ extensionLabel }}"
|
placeholder="{{ extensionLabel }}"
|
||||||
|
(keydown)="keyDownFunction($event)"
|
||||||
/>
|
/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<os-search-value-selector
|
<os-search-value-selector
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, Input, Output, EventEmitter, OnDestroy } from '@angular/core';
|
import { Component, OnInit, Input, Output, EventEmitter, OnDestroy, AfterViewInit } from '@angular/core';
|
||||||
import { BehaviorSubject, Subscription } from 'rxjs';
|
import { BehaviorSubject, Subscription } from 'rxjs';
|
||||||
import { FormGroup, FormBuilder } from '@angular/forms';
|
import { FormGroup, FormBuilder } from '@angular/forms';
|
||||||
import { Router, NavigationEnd } from '@angular/router';
|
import { Router, NavigationEnd } from '@angular/router';
|
||||||
@ -8,7 +8,7 @@ import { Router, NavigationEnd } from '@angular/router';
|
|||||||
templateUrl: './extension-field.component.html',
|
templateUrl: './extension-field.component.html',
|
||||||
styleUrls: ['./extension-field.component.scss']
|
styleUrls: ['./extension-field.component.scss']
|
||||||
})
|
})
|
||||||
export class ExtensionFieldComponent implements OnInit, OnDestroy {
|
export class ExtensionFieldComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
/**
|
/**
|
||||||
* Optional additional classes for the `mat-chip`.
|
* Optional additional classes for the `mat-chip`.
|
||||||
*/
|
*/
|
||||||
@ -27,11 +27,33 @@ export class ExtensionFieldComponent implements OnInit, OnDestroy {
|
|||||||
@Input()
|
@Input()
|
||||||
public chipValue: string;
|
public chipValue: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow automatically jump into autoEdit
|
||||||
|
*/
|
||||||
|
private allowAutoEdit = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Boolean, whether the extension should be shown.
|
* Boolean, whether the extension should be shown.
|
||||||
*/
|
*/
|
||||||
@Input()
|
private _hasExtension = false;
|
||||||
public hasExtension = false;
|
|
||||||
|
/**
|
||||||
|
* Setter for the extension condition
|
||||||
|
*/
|
||||||
|
@Input() public set hasExtension(extension: boolean) {
|
||||||
|
this._hasExtension = extension;
|
||||||
|
|
||||||
|
if (this.hasExtension && this.allowAutoEdit) {
|
||||||
|
this.editMode = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the extension condition
|
||||||
|
*/
|
||||||
|
public get hasExtension(): boolean {
|
||||||
|
return this._hasExtension;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional label for the input.
|
* Optional label for the input.
|
||||||
@ -119,6 +141,11 @@ export class ExtensionFieldComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
private navigationSubscription: Subscription;
|
private navigationSubscription: Subscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscription for the search value selector
|
||||||
|
*/
|
||||||
|
private searchValueSubscription: Subscription;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@ -133,33 +160,63 @@ export class ExtensionFieldComponent implements OnInit, OnDestroy {
|
|||||||
this.navigationSubscription = this.router.events.subscribe(navEvent => {
|
this.navigationSubscription = this.router.events.subscribe(navEvent => {
|
||||||
if (navEvent instanceof NavigationEnd) {
|
if (navEvent instanceof NavigationEnd) {
|
||||||
this.editMode = false;
|
this.editMode = false;
|
||||||
|
|
||||||
|
if (this.extensionFieldForm) {
|
||||||
this.extensionFieldForm.reset();
|
this.extensionFieldForm.reset();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.initInput();
|
this.initInput();
|
||||||
|
|
||||||
|
if (this.searchList) {
|
||||||
this.extensionFieldForm = this.fb.group({
|
this.extensionFieldForm = this.fb.group({
|
||||||
list: this.searchList ? [[]] : undefined
|
list: [[]]
|
||||||
});
|
});
|
||||||
|
|
||||||
this.extensionFieldForm.get('list').valueChanges.subscribe((value: number) => {
|
this.searchValueSubscription = this.extensionFieldForm
|
||||||
|
.get('list')
|
||||||
|
.valueChanges.subscribe((value: number) => {
|
||||||
|
if (!!value) {
|
||||||
if (this.listSubmitOnChange) {
|
if (this.listSubmitOnChange) {
|
||||||
this.listChange.emit(value);
|
this.listChange.emit(value);
|
||||||
}
|
}
|
||||||
if (this.appendValueToInput && this.inputControl.length) {
|
if (this.appendValueToInput) {
|
||||||
this.inputControl = this.inputControl.concat(
|
if (!this.inputControl) {
|
||||||
`[${this.listValuePrefix}${value}${this.listValueSuffix}]`
|
this.inputControl = '';
|
||||||
);
|
}
|
||||||
|
this.inputControl += `[${this.listValuePrefix}${value}${this.listValueSuffix}]`;
|
||||||
|
}
|
||||||
|
this.extensionFieldForm.reset();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On destroy unsubscribe from the nav subscription
|
* After view inits, allow to automatically open the edit view
|
||||||
|
*/
|
||||||
|
public ngAfterViewInit(): void {
|
||||||
|
this.allowAutoEdit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On destroy unsubscribe from the subscriptions
|
||||||
*/
|
*/
|
||||||
public ngOnDestroy(): void {
|
public ngOnDestroy(): void {
|
||||||
this.navigationSubscription.unsubscribe();
|
this.navigationSubscription.unsubscribe();
|
||||||
|
if (this.searchValueSubscription) {
|
||||||
|
this.searchValueSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hitting enter on the input field should save the content
|
||||||
|
*/
|
||||||
|
public keyDownFunction(event: any): void {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
this.changeEditMode(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
<div (window:keydown)="onKeyNavigation($event)"></div>
|
||||||
<os-head-bar
|
<os-head-bar
|
||||||
[mainButton]="perms.isAllowed('update', motion)"
|
[mainButton]="perms.isAllowed('update', motion)"
|
||||||
mainButtonIcon="edit"
|
mainButtonIcon="edit"
|
||||||
@ -101,7 +102,12 @@
|
|||||||
<span translate>Show entire motion text</span>
|
<span translate>Show entire motion text</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-menu-item *osPerms="'core.can_see_history'" [routerLink]="['/history']" [queryParams]="{element: motion.elementId}">
|
<button
|
||||||
|
mat-menu-item
|
||||||
|
*osPerms="'core.can_see_history'"
|
||||||
|
[routerLink]="['/history']"
|
||||||
|
[queryParams]="{ element: motion.elementId }"
|
||||||
|
>
|
||||||
<mat-icon>history</mat-icon>
|
<mat-icon>history</mat-icon>
|
||||||
<span translate>
|
<span translate>
|
||||||
History
|
History
|
||||||
@ -126,10 +132,16 @@
|
|||||||
<div class="title-line">
|
<div class="title-line">
|
||||||
<h1 class="motion-title">
|
<h1 class="motion-title">
|
||||||
<span *ngIf="titleCanBeChanged()">
|
<span *ngIf="titleCanBeChanged()">
|
||||||
<span class="title-change-indicator" *ngIf="getTitleChangingObject()"
|
<span
|
||||||
(click)="gotoChangeRecommendation(getTitleChangingObject())"></span>
|
class="title-change-indicator"
|
||||||
<span class="change-title" *osPerms="'motions.can_manage'; and: !getTitleChangingObject()"
|
*ngIf="getTitleChangingObject()"
|
||||||
(click)="createTitleChangeRecommendation()"></span>
|
(click)="gotoChangeRecommendation(getTitleChangingObject())"
|
||||||
|
></span>
|
||||||
|
<span
|
||||||
|
class="change-title"
|
||||||
|
*osPerms="'motions.can_manage'; and: !getTitleChangingObject()"
|
||||||
|
(click)="createTitleChangeRecommendation()"
|
||||||
|
></span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{{ getTitleWithChanges() }}
|
{{ getTitleWithChanges() }}
|
||||||
@ -250,7 +262,8 @@
|
|||||||
[inputValue]="newStateExtension"
|
[inputValue]="newStateExtension"
|
||||||
[classes]="motion.stateCssColor"
|
[classes]="motion.stateCssColor"
|
||||||
extensionLabel="{{ 'Extension' | translate }}"
|
extensionLabel="{{ 'Extension' | translate }}"
|
||||||
(success)="setStateExtension($event)">
|
(success)="setStateExtension($event)"
|
||||||
|
>
|
||||||
<span class="trigger-menu">
|
<span class="trigger-menu">
|
||||||
<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 }} <span *ngIf="state.show_state_extension_field"> ...</span>
|
{{ state.name | translate }} <span *ngIf="state.show_state_extension_field"> ...</span>
|
||||||
@ -281,7 +294,8 @@
|
|||||||
[searchList]="motionObserver"
|
[searchList]="motionObserver"
|
||||||
searchListLabel="{{ 'Motions' | translate }}"
|
searchListLabel="{{ 'Motions' | translate }}"
|
||||||
listValuePrefix="motion:"
|
listValuePrefix="motion:"
|
||||||
(success)="setRecommendationExtension($event)">
|
(success)="setRecommendationExtension($event)"
|
||||||
|
>
|
||||||
<span class="trigger-menu">
|
<span class="trigger-menu">
|
||||||
<button
|
<button
|
||||||
*ngFor="let recommendation of motion.possibleRecommendations"
|
*ngFor="let recommendation of motion.possibleRecommendations"
|
||||||
@ -292,10 +306,7 @@
|
|||||||
<span *ngIf="recommendation.show_recommendation_extension_field"> ...</span>
|
<span *ngIf="recommendation.show_recommendation_extension_field"> ...</span>
|
||||||
</button>
|
</button>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<button
|
<button mat-menu-item (click)="setRecommendation(null)">
|
||||||
mat-menu-item
|
|
||||||
(click)="setRecommendation(null)"
|
|
||||||
>
|
|
||||||
<mat-icon>replay</mat-icon> {{ 'Reset recommendation' | translate }}
|
<mat-icon>replay</mat-icon> {{ 'Reset recommendation' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
@ -781,7 +792,10 @@
|
|||||||
</mat-list>
|
</mat-list>
|
||||||
</div>
|
</div>
|
||||||
<div *osPerms="'motions.can_manage'; and: editMotion">
|
<div *osPerms="'motions.can_manage'; and: editMotion">
|
||||||
<os-attachment-control (errorHandler)="showUploadError($event)" [controlName]="contentForm.get('attachments_id')"></os-attachment-control>
|
<os-attachment-control
|
||||||
|
(errorHandler)="showUploadError($event)"
|
||||||
|
[controlName]="contentForm.get('attachments_id')"
|
||||||
|
></os-attachment-control>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -745,6 +745,20 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using Meta, Alt + the arrow keys will navigate between the motions
|
||||||
|
*
|
||||||
|
* @param event has the key code
|
||||||
|
*/
|
||||||
|
public onKeyNavigation(event: KeyboardEvent): void {
|
||||||
|
if (event.key === 'ArrowLeft' && event.altKey && event.metaKey) {
|
||||||
|
this.navigateToMotion(this.previousMotion);
|
||||||
|
}
|
||||||
|
if (event.key === 'ArrowRight' && event.altKey && event.metaKey) {
|
||||||
|
this.navigateToMotion(this.nextMotion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Before updating or creating, the motions needs to be prepared for paragraph based amendments.
|
* Before updating or creating, the motions needs to be prepared for paragraph based amendments.
|
||||||
* A motion of type T is created, prepared and deserialized from the given motionValues
|
* A motion of type T is created, prepared and deserialized from the given motionValues
|
||||||
|
Loading…
Reference in New Issue
Block a user