Merge pull request #4757 from GabrielInTheWorld/tile-layout

Enhances the tile view
This commit is contained in:
Emanuel Schütze 2019-06-05 16:33:57 +02:00 committed by GitHub
commit eb1f1c3b53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 146 additions and 85 deletions

View File

@ -4,7 +4,7 @@
(click)="onClick($event)" (click)="onClick($event)"
> >
<div [ngSwitch]="blockType" class="block-node-container"> <div [ngSwitch]="blockType" class="block-node-container">
<div *ngSwitchCase="'text'" class="tile-text stretch-to-fill-parent" [style.border-radius]="orientation === 'horizontal' ? '4px 0 0 4px' : '4px 4px 0 0'"> <div *ngSwitchCase="'text'" class="tile-text stretch-to-fill-parent tile-color" [style.border-radius]="orientation === 'horizontal' ? '4px 0 0 4px' : '4px 4px 0 0'">
<table> <table>
<tbody> <tbody>
<tr> <tr>
@ -18,7 +18,7 @@
<div *ngSwitchCase="'image'"> <div *ngSwitchCase="'image'">
<img mat-card-image [src]="block" alt="" /> <img mat-card-image [src]="block" alt="" />
</div> </div>
<div *ngSwitchCase="'node'" class="tile-text stretch-to-fill-parent" [style.border-radius]="orientation === 'horizontal' ? '4px 0 0 4px' : '4px 4px 0 0'"> <div *ngSwitchCase="'node'" class="tile-text stretch-to-fill-parent tile-color" [style.border-radius]="orientation === 'horizontal' ? '4px 0 0 4px' : '4px 4px 0 0'">
<ng-container <ng-container
[ngTemplateOutlet]="blockNode" [ngTemplateOutlet]="blockNode"
[ngTemplateOutletContext]="data"></ng-container> [ngTemplateOutletContext]="data"></ng-container>

View File

@ -1,12 +1,4 @@
@import '~@angular/material/theming'; .block-tile {
@mixin os-block-tile-style($theme) {
$primary: map-get(
$map: $theme,
$key: primary
);
.block-tile {
padding: 0; padding: 0;
.block-node-container { .block-node-container {
@ -16,7 +8,6 @@
.tile-text { .tile-text {
padding: 8px 16px; padding: 8px 16px;
background-color: mat-color($primary, lighter);
table { table {
height: 100%; height: 100%;
@ -56,5 +47,4 @@
box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 5px 8px 0px rgba(0, 0, 0, 0.14), box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 5px 8px 0px rgba(0, 0, 0, 0.14),
0px 1px 14px 0px rgba(0, 0, 0, 0.12) !important; 0px 1px 14px 0px rgba(0, 0, 0, 0.12) !important;
} }
}
} }

View File

@ -1,9 +1,12 @@
<div class="custom-table-header flex-spaced on-transition-fade"> <div class="custom-table-header flex-spaced on-transition-fade">
<div class="filter-count" *ngIf="filterService"> <div class="filter-count" *ngIf="filterService && showFilterSort">
<span>{{ displayedCount }}&nbsp;</span><span translate>of</span> <span>{{ displayedCount }}&nbsp;</span><span translate>of</span>
<span>&nbsp;{{ totalCount }}</span> <span>&nbsp;{{ totalCount }}</span>
<span *ngIf="extraItemInfo">&nbsp;·&nbsp;{{ extraItemInfo }}</span> <span *ngIf="extraItemInfo">&nbsp;·&nbsp;{{ extraItemInfo }}</span>
</div> </div>
<div class="filter-count" *ngIf="!showFilterSort && itemsVerboseName">
<span>{{ totalCount }}&nbsp;</span><span translate>{{ itemsVerboseName }}</span>
</div>
<div class="current-filters" *ngIf="filterService && filterService.activeFilterCount"> <div class="current-filters" *ngIf="filterService && filterService.activeFilterCount">
<div><span translate>Active filters</span>:&nbsp;</div> <div><span translate>Active filters</span>:&nbsp;</div>
<div> <div>
@ -24,7 +27,7 @@
<ng-content select=".extra-controls-slot"></ng-content> <ng-content select=".extra-controls-slot"></ng-content>
</span> </span>
<button mat-button *ngIf="hasFilters" (click)="filterMenu.opened ? filterMenu.close() : filterMenu.open()"> <button mat-button *ngIf="hasFilters && showFilterSort" (click)="filterMenu.opened ? filterMenu.close() : filterMenu.open()">
<span *ngIf="!filterService.activeFilterCount" class="upper" translate> Filter </span> <span *ngIf="!filterService.activeFilterCount" class="upper" translate> Filter </span>
<span *ngIf="filterService.activeFilterCount"> <span *ngIf="filterService.activeFilterCount">
{{ filterService.activeFilterCount }}&nbsp; {{ filterService.activeFilterCount }}&nbsp;
@ -32,10 +35,10 @@
<span *ngIf="filterService.activeFilterCount > 1" class="upper" translate>Filters</span> <span *ngIf="filterService.activeFilterCount > 1" class="upper" translate>Filters</span>
</span> </span>
</button> </button>
<button mat-button *ngIf="vp.isMobile && hasSorting" (click)="openSortDropDown()"> <button mat-button *ngIf="vp.isMobile && hasSorting && showFilterSort" (click)="openSortDropDown()">
<span class="upper" translate>Sort</span> <span class="upper" translate>Sort</span>
</button> </button>
<button mat-button *ngIf="!vp.isMobile && hasSorting" [matMenuTriggerFor]="menu"> <button mat-button *ngIf="!vp.isMobile && hasSorting && showFilterSort" [matMenuTriggerFor]="menu">
<span class="upper" translate>Sort</span> <span class="upper" translate>Sort</span>
</button> </button>
<mat-form-field *ngIf="isSearchBar"> <mat-form-field *ngIf="isSearchBar">

View File

@ -56,6 +56,12 @@ export class SortFilterBarComponent<V extends BaseViewModel> {
@Input() @Input()
public extraItemInfo: string; public extraItemInfo: string;
/**
* Optional string to tell the verbose name of the filtered items. This string is displayed, if no filter service is given.
*/
@Input()
public itemsVerboseName: string;
@Output() @Output()
public searchFieldChange = new EventEmitter<string>(); public searchFieldChange = new EventEmitter<string>();
@ -71,6 +77,11 @@ export class SortFilterBarComponent<V extends BaseViewModel> {
@ViewChild('sortBottomSheet') @ViewChild('sortBottomSheet')
public sortBottomSheet: SortBottomSheetComponent<V>; public sortBottomSheet: SortBottomSheetComponent<V>;
/**
* Optional boolean, whether the filter and sort service should be shown.
*/
private _showFilterSort = true;
/** /**
* The 'opened/active' state of the fulltext filter input field * The 'opened/active' state of the fulltext filter input field
*/ */
@ -88,6 +99,21 @@ export class SortFilterBarComponent<V extends BaseViewModel> {
} }
} }
/**
* Setter for `showFilterSort`
*/
@Input()
public set showFilterSort(show: boolean) {
this._showFilterSort = show;
}
/**
* Getter for `showFilterSort`
*/
public get showFilterSort(): boolean {
return this._showFilterSort;
}
/** /**
* Return the total count of potential filters * Return the total count of potential filters
*/ */

View File

@ -21,6 +21,8 @@
[filterCount]="filteredCount" [filterCount]="filteredCount"
[filterService]="filterService" [filterService]="filterService"
[sortService]="sortService" [sortService]="sortService"
[showFilterSort]="selectedView === 'list'"
[itemsVerboseName]="motionsVerboseName"
(searchFieldChange)="searchFilter($event)" (searchFieldChange)="searchFilter($event)"
> >
<mat-button-toggle-group *ngIf="isCategoryAvailable()" #group="matButtonToggleGroup" [value]="selectedView" (change)="onChangeView(group.value)" appearance="legacy" aria-label="Select view" class="extra-controls-slot select-view-wrapper"> <mat-button-toggle-group *ngIf="isCategoryAvailable()" #group="matButtonToggleGroup" [value]="selectedView" (change)="onChangeView(group.value)" appearance="legacy" aria-label="Select view" class="extra-controls-slot select-view-wrapper">
@ -160,7 +162,14 @@
</span> </span>
<span *ngSwitchCase="'tiles'"> <span *ngSwitchCase="'tiles'">
<os-grid-layout> <os-grid-layout>
<os-block-tile *ngFor="let tileCategory of tileCategories" (clicked)="changeToViewWithTileCategory(tileCategory)" [orientation]="'horizontal'" [only]="'title'" [blockType]="'node'" [data]="tileCategory" title="{{ tileCategory.name | translate }}"> <os-block-tile
*ngFor="let tileCategory of tileCategories"
(clicked)="changeToViewWithTileCategory(tileCategory)"
[orientation]="'horizontal'"
[only]="'title'"
[blockType]="'node'"
[data]="tileCategory"
title="{{ tileCategory.name | translate }}">
<ng-container class="block-node"> <ng-container class="block-node">
<table matTooltip="{{ tileCategory.amountOfMotions }} {{ 'Motions' | translate }} {{ tileCategory.name | translate }}"> <table matTooltip="{{ tileCategory.amountOfMotions }} {{ 'Motions' | translate }} {{ tileCategory.name | translate }}">
<tbody> <tbody>

View File

@ -85,6 +85,10 @@
} }
os-grid-layout { os-grid-layout {
.color-select {
width: 100%;
padding: 0 8px;
}
.tile-block-title { .tile-block-title {
font-size: 36px; font-size: 36px;
@ -93,5 +97,14 @@ os-grid-layout {
width: 36px; width: 36px;
height: 36px; height: 36px;
} }
.mat-badge-content {
right: -22px;
top: -11px;
font-size: 16px;
width: 30px;
height: 30px;
line-height: 30px;
}
} }
} }

View File

@ -127,6 +127,16 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion, Motio
*/ */
public informationOfMotionsInTileCategories: { [id: number]: TileCategoryInformation } = {}; public informationOfMotionsInTileCategories: { [id: number]: TileCategoryInformation } = {};
/**
* The verbose name for the motions.
*/
public motionsVerboseName: string;
/**
* Store the view as member - if the user changes the view, this member is as well changed.
*/
private storedView: string;
/** /**
* Constructor implements title and translation Module. * Constructor implements title and translation Module.
* *
@ -190,31 +200,33 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion, Motio
public async ngOnInit(): Promise<void> { public async ngOnInit(): Promise<void> {
super.setTitle('Motions'); super.setTitle('Motions');
this.initTable(); this.initTable();
const storedView = await this.storage.get<string>('motionListView'); this.storedView = await this.storage.get<string>('motionListView');
this.subscriptions.push(
this.configService this.configService
.get<boolean>('motions_statutes_enabled') .get<boolean>('motions_statutes_enabled')
.subscribe(enabled => (this.statutesEnabled = enabled)); .subscribe(enabled => (this.statutesEnabled = enabled)),
this.configService.get<string>('motions_recommendations_by').subscribe(recommender => { this.configService.get<string>('motions_recommendations_by').subscribe(recommender => {
this.recommendationEnabled = !!recommender; this.recommendationEnabled = !!recommender;
}); }),
this.motionBlockRepo.getViewModelListObservable().subscribe(mBs => { this.motionBlockRepo.getViewModelListObservable().subscribe(mBs => {
this.motionBlocks = mBs; this.motionBlocks = mBs;
this.updateStateColumnVisibility(); this.updateStateColumnVisibility();
}); }),
this.categoryRepo.getViewModelListObservable().subscribe(cats => { this.categoryRepo.getViewModelListObservable().subscribe(cats => {
this.categories = cats; this.categories = cats;
if (cats.length > 0) { if (cats.length > 0) {
this.selectedView = storedView || 'tiles'; this.selectedView = this.storedView || 'tiles';
} else { } else {
this.selectedView = 'list'; this.selectedView = 'list';
} }
this.updateStateColumnVisibility(); this.updateStateColumnVisibility();
}); }),
this.tagRepo.getViewModelListObservable().subscribe(tags => { this.tagRepo.getViewModelListObservable().subscribe(tags => {
this.tags = tags; this.tags = tags;
this.updateStateColumnVisibility(); this.updateStateColumnVisibility();
}); }),
this.workflowRepo.getViewModelListObservable().subscribe(wfs => (this.workflows = wfs)); this.workflowRepo.getViewModelListObservable().subscribe(wfs => (this.workflows = wfs))
);
this.setFulltextFilter(); this.setFulltextFilter();
} }
@ -255,6 +267,7 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion, Motio
} }
this.tileCategories = Object.values(this.informationOfMotionsInTileCategories); this.tileCategories = Object.values(this.informationOfMotionsInTileCategories);
this.motionsVerboseName = this.motionRepo.getVerboseName(motions.length > 1);
}) })
); );
} }
@ -491,6 +504,7 @@ export class MotionListComponent extends ListViewBaseComponent<ViewMotion, Motio
*/ */
public onChangeView(value: string): void { public onChangeView(value: string): void {
this.selectedView = value; this.selectedView = value;
this.storedView = value;
this.storage.set('motionListView', value); this.storage.set('motionListView', value);
if (value === 'list') { if (value === 'list') {
this.initTable(); this.initTable();

View File

@ -57,6 +57,13 @@
border-color: mat-color($background, selected-button); border-color: mat-color($background, selected-button);
} }
.tile-text {
color: mat-color($foreground, text);
}
.tile-color {
background-color: mat-color($background, selected-button);
}
.main-nav-color { .main-nav-color {
color: mat-color($foreground, secondary-text); color: mat-color($foreground, secondary-text);
} }

View File

@ -32,7 +32,6 @@
@include os-sorting-tree-style($theme); @include os-sorting-tree-style($theme);
@include os-global-spinner-theme($theme); @include os-global-spinner-theme($theme);
@include os-tile-style($theme); @include os-tile-style($theme);
@include os-block-tile-style($theme);
/** More components are added here */ /** More components are added here */
} }