Overwork motion detail UI

set Default action to "create amendment" (if permitted)
put edit in the menu
put next and prev motion in the menu (mobile)
resort motion menu
move "show enitre motion text" under the motion-preview
change "show entire motion text" from button to checkbox
create a custom tooltip for the main action in os-head-bar
create a custom "cancel edit" function in os-head-bar
overwork location.back logic
This commit is contained in:
Sean Engelhardt 2019-08-20 12:42:50 +02:00
parent bbe294a1ad
commit d739b982bb
10 changed files with 107 additions and 80 deletions

View File

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

View File

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

View File

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

View File

@ -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>&nbsp;</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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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