Merge pull request #4927 from tsiegleauq/better-motion-detail-ui
Overwork motion detail UI
This commit is contained in:
commit
1d1ddbd6e4
@ -1,3 +1,4 @@
|
|||||||
|
import { Location } from '@angular/common';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Router, RoutesRecognized } from '@angular/router';
|
import { Router, RoutesRecognized } from '@angular/router';
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ export class RoutingStateService {
|
|||||||
/**
|
/**
|
||||||
* Hold the previous URL
|
* Hold the previous URL
|
||||||
*/
|
*/
|
||||||
private _previousUrl: string;
|
private previousUrl: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsafe paths that the user should not go "back" to
|
* Unsafe paths that the user should not go "back" to
|
||||||
@ -23,14 +24,11 @@ export class RoutingStateService {
|
|||||||
private unsafeUrls: string[] = ['/login', '/privacypolicy', '/legalnotice'];
|
private unsafeUrls: string[] = ['/login', '/privacypolicy', '/legalnotice'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Get the previous URL
|
* Checks if the previous URL is safe to navigate to.
|
||||||
|
* If this fails, the open nav button should be shown
|
||||||
*/
|
*/
|
||||||
public get previousUrl(): string {
|
|
||||||
return this._previousUrl ? this._previousUrl : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get isSafePrevUrl(): boolean {
|
public get isSafePrevUrl(): boolean {
|
||||||
return !!this.previousUrl && !this.unsafeUrls.includes(this.previousUrl);
|
return !this.previousUrl || !this.unsafeUrls.includes(this.previousUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,14 +36,18 @@ export class RoutingStateService {
|
|||||||
*
|
*
|
||||||
* @param router Angular Router
|
* @param router Angular Router
|
||||||
*/
|
*/
|
||||||
public constructor(private router: Router) {
|
public constructor(private router: Router, private location: Location) {
|
||||||
this.router.events
|
this.router.events
|
||||||
.pipe(
|
.pipe(
|
||||||
filter(e => e instanceof RoutesRecognized),
|
filter(e => e instanceof RoutesRecognized),
|
||||||
pairwise()
|
pairwise()
|
||||||
)
|
)
|
||||||
.subscribe((event: any[]) => {
|
.subscribe((event: any[]) => {
|
||||||
this._previousUrl = event[0].urlAfterRedirects;
|
this.previousUrl = event[0].urlAfterRedirects;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public goBack(): void {
|
||||||
|
this.location.back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Cancel edit button -->
|
<!-- Cancel edit button -->
|
||||||
<button mat-icon-button *ngIf="editMode" (click)="sendMainEvent()">
|
<button mat-icon-button *ngIf="editMode" (click)="cancelEditEvent ? sendCancelEditEvent() : sendMainEvent()">
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@ -35,21 +35,17 @@
|
|||||||
<!-- Main action button - desktop -->
|
<!-- Main action button - desktop -->
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
*ngIf="mainButtonIcon == 'add' && mainButton && !editMode && !vp.isMobile && !multiSelectMode"
|
*ngIf="mainButton && !editMode && !vp.isMobile && !multiSelectMode"
|
||||||
(click)="sendMainEvent()"
|
(click)="sendMainEvent()"
|
||||||
|
matTooltip="{{ mainActionTooltip | translate }}"
|
||||||
>
|
>
|
||||||
<mat-icon>add_circle</mat-icon>
|
<mat-icon>{{ mainButtonIcon }}</mat-icon>
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
mat-icon-button
|
|
||||||
*ngIf="mainButtonIcon == 'edit' && mainButton && !editMode && !vp.isMobile && !multiSelectMode"
|
|
||||||
(click)="sendMainEvent()"
|
|
||||||
>
|
|
||||||
<mat-icon>edit</mat-icon>
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Save button -->
|
<!-- Save button -->
|
||||||
<button mat-button *ngIf="editMode" [disabled]="!isSaveButtonEnabled" (click)="save()"><strong translate class="upper">Save</strong></button>
|
<button mat-button *ngIf="editMode" [disabled]="!isSaveButtonEnabled" (click)="save()">
|
||||||
|
<strong translate class="upper">Save</strong>
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Menu button slot -->
|
<!-- Menu button slot -->
|
||||||
<ng-content *ngIf="!editMode" select=".menu-slot"></ng-content>
|
<ng-content *ngIf="!editMode" select=".menu-slot"></ng-content>
|
||||||
@ -60,9 +56,10 @@
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
mat-fab
|
mat-fab
|
||||||
class="head-button "
|
class="head-button"
|
||||||
*ngIf="mainButton && !editMode && vp.isMobile && !multiSelectMode"
|
*ngIf="mainButton && !editMode && vp.isMobile && !multiSelectMode"
|
||||||
(click)="sendMainEvent()"
|
(click)="sendMainEvent()"
|
||||||
|
matTooltip="{{ mainActionTooltip | translate }}"
|
||||||
>
|
>
|
||||||
<mat-icon>{{ mainButtonIcon }}</mat-icon>
|
<mat-icon>{{ mainButtonIcon }}</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
@ -63,7 +63,7 @@ export class HeadBarComponent {
|
|||||||
* Custom icon if necessary
|
* Custom icon if necessary
|
||||||
*/
|
*/
|
||||||
@Input()
|
@Input()
|
||||||
public mainButtonIcon = 'add';
|
public mainButtonIcon = 'add_circle';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine edit mode
|
* Determine edit mode
|
||||||
@ -105,12 +105,24 @@ export class HeadBarComponent {
|
|||||||
@Input()
|
@Input()
|
||||||
public prevUrl = '../';
|
public prevUrl = '../';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional tooltip for the main action
|
||||||
|
*/
|
||||||
|
@Input()
|
||||||
|
public mainActionTooltip: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emit a signal to the parent component if the main button was clicked
|
* Emit a signal to the parent component if the main button was clicked
|
||||||
*/
|
*/
|
||||||
@Output()
|
@Output()
|
||||||
public mainEvent = new EventEmitter<void>();
|
public mainEvent = new EventEmitter<void>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional custom event for cancel the edit
|
||||||
|
*/
|
||||||
|
@Output()
|
||||||
|
public cancelEditEvent = new EventEmitter<void>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a signal if a detail view should be saved
|
* Sends a signal if a detail view should be saved
|
||||||
*/
|
*/
|
||||||
@ -139,6 +151,13 @@ export class HeadBarComponent {
|
|||||||
this.mainEvent.next();
|
this.mainEvent.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emits a signal to for custom cancel edits
|
||||||
|
*/
|
||||||
|
public sendCancelEditEvent(): void {
|
||||||
|
this.cancelEditEvent.next();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clicking the burger-menu-icon should toggle the menu
|
* Clicking the burger-menu-icon should toggle the menu
|
||||||
*/
|
*/
|
||||||
@ -159,7 +178,7 @@ export class HeadBarComponent {
|
|||||||
*/
|
*/
|
||||||
public onBackButton(): void {
|
public onBackButton(): void {
|
||||||
if (this.goBack) {
|
if (this.goBack) {
|
||||||
this.router.navigateByUrl(this.routingState.previousUrl);
|
this.routingState.goBack();
|
||||||
} else {
|
} else {
|
||||||
this.router.navigate([this.prevUrl], { relativeTo: this.route });
|
this.router.navigate([this.prevUrl], { relativeTo: this.route });
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
<button type="button" *ngIf="menuItem" mat-menu-item [routerLink]="listOfSpeakers.listOfSpeakersUrl">
|
<button type="button" *ngIf="menuItem" mat-menu-item [routerLink]="listOfSpeakers.listOfSpeakersUrl">
|
||||||
<mat-icon>{{ icon }}</mat-icon>
|
<mat-icon>{{ icon }}</mat-icon>
|
||||||
<span translate>List of speakers</span>
|
<span translate>List of speakers</span>
|
||||||
|
<span> </span>
|
||||||
|
<mat-basic-chip disableRipple class="lightblue" *ngIf="listOfSpeakers.waitingSpeakerAmount > 0">
|
||||||
|
<span>{{ listOfSpeakers.waitingSpeakerAmount }}</span>
|
||||||
|
</mat-basic-chip>
|
||||||
</button>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<os-head-bar [nav]="false">
|
<os-head-bar [nav]="false" [goBack]="false">
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<div class="title-slot"><h2 translate>New amendment</h2></div>
|
<div class="title-slot"><h2 translate>New amendment</h2></div>
|
||||||
<div class="menu-slot">
|
<div class="menu-slot">
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<div *ngIf="!isEditMode || !perms.isAllowed('change_metadata')">
|
<div *ngIf="!isEditMode || !perms.isAllowed('change_metadata')">
|
||||||
<mat-chip-list *ngFor="let user of motion.submittersAsUsers" class="user">
|
<mat-chip-list *ngFor="let user of motion.submittersAsUsers" class="user">
|
||||||
<mat-chip disableRipple *ngIf="user">{{ user.getTitle() }}</mat-chip>
|
<mat-basic-chip disableRipple *ngIf="user">{{ user.getTitle() }}</mat-basic-chip>
|
||||||
</mat-chip-list>
|
</mat-chip-list>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -19,3 +19,11 @@ h4 {
|
|||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user .mat-chip {
|
||||||
|
border-radius: 16px !important;
|
||||||
|
padding: 5px 15px !important;
|
||||||
|
margin: 5px 0;
|
||||||
|
border: 1px solid #dddddd;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
<os-head-bar
|
<os-head-bar
|
||||||
[mainButton]="perms.isAllowed('update', motion)"
|
[mainButton]="perms.isAllowed('can_create_amendments', motion)"
|
||||||
mainButtonIcon="edit"
|
mainActionTooltip="New amendment"
|
||||||
[prevUrl]="getPrevUrl()"
|
prevUrl="../.."
|
||||||
|
[goBack]="motion && !!motion.parent_id"
|
||||||
[nav]="false"
|
[nav]="false"
|
||||||
[editMode]="editMotion"
|
[editMode]="editMotion"
|
||||||
[isSaveButtonEnabled]="contentForm.valid"
|
[isSaveButtonEnabled]="contentForm.valid"
|
||||||
(mainEvent)="setEditMode(!editMotion)"
|
(mainEvent)="createAmendment()"
|
||||||
|
(cancelEditEvent)="setEditMode(false)"
|
||||||
(saveEvent)="saveMotion()"
|
(saveEvent)="saveMotion()"
|
||||||
>
|
>
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
@ -24,15 +26,6 @@
|
|||||||
<div *ngIf="!editMotion && !vp.isMobile" class="extra-controls-slot">
|
<div *ngIf="!editMotion && !vp.isMobile" class="extra-controls-slot">
|
||||||
<div *ngIf="previousMotion">
|
<div *ngIf="previousMotion">
|
||||||
<button mat-button (click)="navigateToMotion(previousMotion)">
|
<button mat-button (click)="navigateToMotion(previousMotion)">
|
||||||
<!-- possible icons:
|
|
||||||
arrow_left
|
|
||||||
chevron_left
|
|
||||||
first_page
|
|
||||||
arrow_back
|
|
||||||
arrow_back_ios
|
|
||||||
navigate_before
|
|
||||||
fast_rewind
|
|
||||||
-->
|
|
||||||
<mat-icon>chevron_left</mat-icon>
|
<mat-icon>chevron_left</mat-icon>
|
||||||
<span>{{ previousMotion.identifier }}</span>
|
<span>{{ previousMotion.identifier }}</span>
|
||||||
</button>
|
</button>
|
||||||
@ -40,15 +33,6 @@
|
|||||||
<div *ngIf="nextMotion">
|
<div *ngIf="nextMotion">
|
||||||
<button mat-button (click)="navigateToMotion(nextMotion)">
|
<button mat-button (click)="navigateToMotion(nextMotion)">
|
||||||
<span>{{ nextMotion.identifier }}</span>
|
<span>{{ nextMotion.identifier }}</span>
|
||||||
<!-- possible icons:
|
|
||||||
arrow_right
|
|
||||||
chevron_right
|
|
||||||
last_page
|
|
||||||
arrow_forward
|
|
||||||
arrow_forward_ios
|
|
||||||
navigate_next
|
|
||||||
fast_forward
|
|
||||||
-->
|
|
||||||
<mat-icon>chevron_right</mat-icon>
|
<mat-icon>chevron_right</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -63,13 +47,25 @@
|
|||||||
|
|
||||||
<mat-menu #motionExtraMenu="matMenu">
|
<mat-menu #motionExtraMenu="matMenu">
|
||||||
<div *ngIf="motion">
|
<div *ngIf="motion">
|
||||||
|
<div *ngIf="vp.isMobile">
|
||||||
|
<button mat-menu-item (click)="navigateToMotion(previousMotion)" *ngIf="previousMotion">
|
||||||
|
<mat-icon>chevron_left</mat-icon>
|
||||||
|
<span>{{ 'Motion' | translate }} {{ previousMotion.identifier }}</span>
|
||||||
|
</button>
|
||||||
|
<button mat-menu-item (click)="navigateToMotion(nextMotion)" *ngIf="nextMotion">
|
||||||
|
<mat-icon>chevron_right</mat-icon>
|
||||||
|
<span>{{ 'Motion' | translate }} {{ nextMotion.identifier }}</span>
|
||||||
|
</button>
|
||||||
|
<mat-divider *ngIf="previousMotion || nextMotion"></mat-divider>
|
||||||
|
</div>
|
||||||
|
<!-- List of speakers -->
|
||||||
|
<os-speaker-button [object]="motion" [menuItem]="true"></os-speaker-button>
|
||||||
<!-- PDF -->
|
<!-- PDF -->
|
||||||
<button mat-menu-item (click)="onDownloadPdf()">
|
<button mat-menu-item (click)="onDownloadPdf()">
|
||||||
<mat-icon>picture_as_pdf</mat-icon>
|
<mat-icon>picture_as_pdf</mat-icon>
|
||||||
<span translate>PDF</span>
|
<span translate>PDF</span>
|
||||||
</button>
|
</button>
|
||||||
<!-- List of speakers -->
|
<mat-divider></mat-divider>
|
||||||
<os-speaker-button [object]="motion" [menuItem]="true"></os-speaker-button>
|
|
||||||
<!-- Project -->
|
<!-- Project -->
|
||||||
<os-projector-button
|
<os-projector-button
|
||||||
[object]="motion"
|
[object]="motion"
|
||||||
@ -87,21 +83,6 @@
|
|||||||
<span translate>Remove from agenda</span>
|
<span translate>Remove from agenda</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- New amendment -->
|
|
||||||
<button mat-menu-item (click)="createAmendment()" *ngIf="perms.isAllowed('can_create_amendments', motion)">
|
|
||||||
<mat-icon>add</mat-icon>
|
|
||||||
<span translate>New amendment</span>
|
|
||||||
</button>
|
|
||||||
<!-- Show entire motion text -->
|
|
||||||
<button
|
|
||||||
mat-menu-item
|
|
||||||
(click)="showAmendmentContext = !showAmendmentContext"
|
|
||||||
*ngIf="motion && motion.isParagraphBasedAmendment()"
|
|
||||||
>
|
|
||||||
<mat-icon>{{ !showAmendmentContext ? 'check_box_outline_blank' : 'check_box' }}</mat-icon>
|
|
||||||
<span translate>Show entire motion text</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
*osPerms="'core.can_see_history'"
|
*osPerms="'core.can_see_history'"
|
||||||
@ -113,15 +94,22 @@
|
|||||||
History
|
History
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
<div *ngIf="perms.isAllowed('manage')">
|
<!-- Edit-->
|
||||||
<mat-divider></mat-divider>
|
<button mat-menu-item (click)="setEditMode(true)" *ngIf="perms.isAllowed('update', motion)">
|
||||||
<!-- Delete -->
|
<mat-icon>edit</mat-icon>
|
||||||
<button mat-menu-item class="red-warning-text" (click)="deleteMotionButton()">
|
<span translate>Edit</span>
|
||||||
<mat-icon>delete</mat-icon>
|
</button>
|
||||||
<span translate>Delete</span>
|
<!-- Delete -->
|
||||||
</button>
|
<button
|
||||||
</div>
|
mat-menu-item
|
||||||
|
class="red-warning-text"
|
||||||
|
(click)="deleteMotionButton()"
|
||||||
|
*ngIf="perms.isAllowed('manage')"
|
||||||
|
>
|
||||||
|
<mat-icon>delete</mat-icon>
|
||||||
|
<span translate>Delete</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</os-head-bar>
|
</os-head-bar>
|
||||||
@ -901,6 +889,17 @@
|
|||||||
<div class="paragraphcontext" [innerHtml]="sanitizedText(paragraph.textPost)"></div>
|
<div class="paragraphcontext" [innerHtml]="sanitizedText(paragraph.textPost)"></div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- Show entire motion text -->
|
||||||
|
<div>
|
||||||
|
<mat-checkbox
|
||||||
|
(change)="showAmendmentContext = !showAmendmentContext"
|
||||||
|
*ngIf="motion && motion.isParagraphBasedAmendment()"
|
||||||
|
class="show-entire-text-check"
|
||||||
|
>
|
||||||
|
<span translate>Show entire motion text</span>
|
||||||
|
</mat-checkbox>
|
||||||
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<!-- Line number Menu -->
|
<!-- Line number Menu -->
|
||||||
|
@ -231,3 +231,8 @@ span {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.show-entire-text-check {
|
||||||
|
font-size: 70%;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
@ -520,13 +520,6 @@ mat-expansion-panel {
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-chip-list.user .mat-chip {
|
|
||||||
border-radius: 16px !important;
|
|
||||||
padding: 5px 15px !important;
|
|
||||||
border: 1px solid;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
// to display quantities. Use in span or div
|
// to display quantities. Use in span or div
|
||||||
.os-amount-chip {
|
.os-amount-chip {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
Loading…
Reference in New Issue
Block a user