Merge pull request #5429 from tsiegleauq/main-page-cleanup

Cleanup main routing page and ngrid lists
This commit is contained in:
Emanuel Schütze 2020-07-02 22:04:53 +02:00 committed by GitHub
commit 55f1d02fcc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 290 additions and 340 deletions

View File

@ -1,70 +1,72 @@
<mat-drawer-container *ngIf="columns && columnSet">
<os-sort-filter-bar
*ngIf="showFilterBar"
[totalCount]="totalCount"
[filterCount]="countFilter"
[filterService]="filterService"
[sortService]="sortService"
[searchFieldInput]="inputValue"
(searchFieldChange)="searchFilter($event)"
>
</os-sort-filter-bar>
<mat-drawer-container class="list-view-frame" *ngIf="columns && columnSet">
<div class="list-view-table-wrapper">
<os-sort-filter-bar
class="sort-filter-bar"
*ngIf="showFilterBar"
[totalCount]="totalCount"
[filterCount]="countFilter"
[filterService]="filterService"
[sortService]="sortService"
[searchFieldInput]="inputValue"
(searchFieldChange)="searchFilter($event)"
>
</os-sort-filter-bar>
<!-- vScrollFixed="110" -->
<!-- vScrollAuto () -->
<pbl-ngrid
[ngClass]="cssClasses"
[attr.vScrollFixed]="vScrollFixed !== -1 ? vScrollFixed : false"
[attr.vScrollAuto]="vScrollFixed === -1"
[showHeader]="!showFilterBar || !fullScreen"
matCheckboxSelection="selection"
[dataSource]="dataSource"
[columns]="columnSet"
[hideColumns]="hiddenColumns"
(rowClick)="onSelectRow($event)"
[rowClassUpdate]="isElementProjected"
rowClassUpdateFreq="ngDoCheck"
>
<!-- "row" has the view model -->
<!-- "value" has the property, that was defined in the columnDefinition -->
<!-- "col" has a column reference -->
<pbl-ngrid
class="vscroll-list-view"
[attr.vScrollFixed]="vScrollFixed !== -1 ? vScrollFixed : false"
[attr.vScrollAuto]="vScrollFixed === -1"
[showHeader]="!showFilterBar || !fullScreen"
[showHeader]="false"
matCheckboxSelection="selection"
[dataSource]="dataSource"
[columns]="columnSet"
[hideColumns]="hiddenColumns"
(rowClick)="onSelectRow($event)"
[rowClassUpdate]="isElementProjected"
rowClassUpdateFreq="ngDoCheck"
>
<!-- "row" has the view model -->
<!-- "value" has the property, that was defined in the columnDefinition -->
<!-- "col" has a column reference -->
<!-- Projector column -->
<div *pblNgridCellDef="'projector'; row as viewModel" class="fill ngrid-lg">
<os-projector-button
*osPerms="'core.can_manage_projector'"
class="projector-button"
[object]="getProjectable(viewModel)"
(changeEvent)="viewUpdateEvent()"
></os-projector-button>
<!-- Projector indicator -->
<div class="projector-button" *osPerms="'core.can_manage_projector'; complement: true">
<mat-icon
color="accent"
*ngIf="projectorService.isProjected(getProjectable(viewModel))"
matTooltip="{{ 'Currently projected' | translate }}"
>
videocam
</mat-icon>
<!-- Projector column -->
<div *pblNgridCellDef="'projector'; row as viewModel" class="fill ngrid-lg">
<os-projector-button
*osPerms="'core.can_manage_projector'"
class="projector-button"
[object]="getProjectable(viewModel)"
(changeEvent)="viewUpdateEvent()"
></os-projector-button>
<!-- Projector indicator -->
<div class="projector-button" *osPerms="'core.can_manage_projector'; complement: true">
<mat-icon
color="accent"
*ngIf="projectorService.isProjected(getProjectable(viewModel))"
matTooltip="{{ 'Currently projected' | translate }}"
>
videocam
</mat-icon>
</div>
</div>
</div>
<!-- No Results -->
<div *pblNgridNoDataRef class="pbl-ngrid-no-data">
<span>{{ 'No data' | translate }}</span>
</div>
<!-- No Results -->
<div *pblNgridNoDataRef class="pbl-ngrid-no-data">
<span>{{ 'No data' | translate }}</span>
</div>
<!-- Slot transclusion for the individual cells -->
<div #contentWrapper>
<ng-content class="ngrid-lg" select=".cell-slot"></ng-content>
</div>
<!-- Slot transclusion for the individual cells -->
<div #contentWrapper>
<ng-content class="ngrid-lg" select=".cell-slot"></ng-content>
</div>
<!-- Speaker -->
<div *pblNgridCellDef="'speaker'; row as viewModel; rowContext as rowContext" class="fill">
<os-speaker-button
[object]="viewModel.contentObjectData ? viewModel.contentObjectData : viewModel"
[disabled]="multiSelect"
></os-speaker-button>
</div>
</pbl-ngrid>
<!-- Speaker -->
<div *pblNgridCellDef="'speaker'; row as viewModel; rowContext as rowContext" class="fill">
<os-speaker-button
[object]="viewModel.contentObjectData ? viewModel.contentObjectData : viewModel"
[disabled]="multiSelect"
></os-speaker-button>
</div>
</pbl-ngrid>
</div>
</mat-drawer-container>

View File

@ -2,26 +2,45 @@
$pbl-height: var(--pbl-height);
.projector-button {
margin: auto;
.list-view-frame {
// remove the height of the top-bar
height: calc(100vh - 64px);
}
.list-view-table-wrapper {
display: flex;
}
flex-flow: column;
height: 100%;
.pbl-ngrid-row {
height: $pbl-height;
}
.sort-filter-bar {
flex: 0 1 auto;
display: block;
}
// additional space if the jitsi integration is active
.pbl-ngrid-row:last-of-type {
margin-bottom: 30px !important;
}
.vscroll-list-view {
flex: 1 1 auto;
.pbl-ngrid-cell {
height: inherit;
}
.projector-button {
margin: auto;
display: flex;
}
.multiselect {
.pbl-ngrid-cell {
cursor: pointer;
.pbl-ngrid-row {
height: $pbl-height;
}
.pbl-ngrid-row:last-of-type {
margin-bottom: 60px !important;
}
.pbl-ngrid-cell {
height: inherit;
}
.multiselect {
.pbl-ngrid-cell {
cursor: pointer;
}
}
}
}

View File

@ -214,31 +214,6 @@ export class ListViewTableComponent<V extends BaseViewModel | BaseViewModelWithC
@Input()
public fullScreen = true;
/**
* Option to apply additional classes to the virtual-scrolling-list.
*/
@Input()
public set cssClasses(values: CssClassDefinition) {
this._cssClasses = values;
}
/**
* Returns the list of classes, that are applied to the virtual-scrolling-list.
* Already prepared for the `[ngClass]`-property.
*
* `Warning: The defaultClasses will overwrite custom classes with the same key.`
*
* @returns An object looking like `{ [key: string]: boolean }`.
*/
public get cssClasses(): CssClassDefinition {
const defaultClasses = {
'virtual-scroll-with-head-bar ngrid-hide-head': this.fullScreen && this.showFilterBar,
'virtual-scroll-full-page': this.fullScreen && !this.showFilterBar,
multiselect: this.multiSelect
};
return Object.assign(this._cssClasses, defaultClasses);
}
/**
* Inform about changes in the dataSource
*/
@ -275,11 +250,6 @@ export class ListViewTableComponent<V extends BaseViewModel | BaseViewModelWithC
*/
public inputValue: string;
/**
* Private variable to hold all classes for the virtual-scrolling-list.
*/
private _cssClasses: CssClassDefinition = {};
/**
* Collect subsciptions
*/

View File

@ -1,4 +1,4 @@
<mat-card [ngClass]="isEditing ? 'os-form-card' : 'os-card'">
<mat-card class="spacer-bottom-60" [ngClass]="isEditing ? 'os-form-card' : 'os-card'">
<ng-container *ngIf="!isEditing">
<div *ngIf="privacyPolicy" [innerHtml]="privacyPolicy | trust: 'html'"></div>
<div *ngIf="!privacyPolicy">

View File

@ -10,7 +10,7 @@
</div>
</os-head-bar>
<mat-card class="os-card">
<mat-card class="os-card spacer-bottom-60">
<ng-container [ngTemplateOutlet]="viewTemplate"></ng-container>
</mat-card>
@ -46,6 +46,7 @@
<div class="named-result-table" *ngIf="poll.type === 'named'">
<h3>{{ 'Single votes' | translate }}</h3>
<os-list-view-table
class="single-votes-table"
*ngIf="votesDataObservable"
[listObservable]="votesDataObservable"
[columns]="columnDefinitionSingleVotes"
@ -56,7 +57,6 @@
listStorageKey="assignment-poll-vote"
[showListOfSpeakers]="false"
[showMenu]="false"
[cssClasses]="{ 'single-votes-table': true }"
>
<!-- Header -->
<div *pblNgridHeaderCellDef="'user'; col as col">

View File

@ -13,6 +13,10 @@
display: block;
height: 500px;
.list-view-frame {
height: 100%;
}
.single-vote-result + .single-vote-result {
margin-top: 1em;
}

View File

@ -54,7 +54,7 @@
</mat-card>
</mat-card>
<mat-card class="os-card" *osPerms="'users.can_manage'">
<mat-card class="os-card spacer-bottom-60" *osPerms="'users.can_manage'">
<h2>{{ 'Statistics' | translate }}</h2>
<div>
<h3>{{ 'Active users' | translate }}</h3>

View File

@ -12,7 +12,7 @@
</div>
</os-head-bar>
<mat-card [ngClass]="isEditing ? 'os-form-card' : 'os-card'">
<mat-card class="spacer-bottom-60" [ngClass]="isEditing ? 'os-form-card' : 'os-card'">
<ng-container *ngIf="!isEditing">
<div class="app-content">
<h1>{{ startContent.general_event_welcome_title | translate }}</h1>

View File

@ -20,6 +20,7 @@
</tr>
</table>
<os-list-view-table
class="user-statistics-table--virtual-scroll "
[listObservable]="statisticsByStructureLevelObservable"
[columns]="columnDefinition"
[filterProps]="filterProps"
@ -27,7 +28,6 @@
[allowProjector]="false"
[fullScreen]="false"
[showListOfSpeakers]="false"
[cssClasses]="{ 'user-statistics-table--virtual-scroll': true }"
>
<!-- Header -->
<div *pblNgridHeaderCellDef="'*'; col as col">

View File

@ -17,9 +17,10 @@
}
.user-statistics-table--virtual-scroll {
display: block;
height: 500px;
.pbl-ngrid-header-cell:not(:first-child):before {
display: none;
.list-view-frame {
height: 100%;
}
}

View File

@ -22,7 +22,7 @@
<div class="spacer-top-20"></div>
<mat-card class="os-card" *ngIf="configGroup">
<mat-card class="os-card spacer-bottom-60" *ngIf="configGroup">
<div id="wrapper">
<ng-container *ngFor="let subgroup of configGroup.subgroups; trackBy: trackByIndex">
<h3 class="accent" *ngIf="configGroup.subgroups.length > 1">{{ subgroup.name | translate }}</h3>

View File

@ -11,73 +11,75 @@
</div>
</os-head-bar>
<div class="custom-table-header">
<div>
<span [formGroup]="modelSelectForm">
<mat-card class="os-card spacer-bottom-60">
<div class="history-table-header">
<div>
<span [formGroup]="modelSelectForm">
<mat-form-field>
<os-search-value-selector
formControlName="model"
[multiple]="false"
[includeNone]="false"
placeholder="{{ 'Motion' | translate }}"
[inputListValues]="collectionObserver"
></os-search-value-selector>
</mat-form-field>
</span>
<span class="spacer-left-20">
<button mat-button (click)="refresh()" *ngIf="currentModelId">
<mat-icon>refresh</mat-icon>
<span>{{ 'Refresh' | translate }}</span>
</button>
</span>
</div>
<div>
<mat-form-field>
<os-search-value-selector
formControlName="model"
[multiple]="false"
[includeNone]="false"
placeholder="{{ 'Motion' | translate }}"
[inputListValues]="collectionObserver"
></os-search-value-selector>
<input matInput (keyup)="applySearch($event.target.value)" placeholder="{{ 'Search' | translate }}" />
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
</span>
<span class="spacer-left-20">
<button mat-button (click)="refresh()" *ngIf="currentModelId">
<mat-icon>refresh</mat-icon>
<span>{{ 'Refresh' | translate }}</span>
</button>
</span>
</div>
</div>
<div>
<mat-form-field>
<input matInput (keyup)="applySearch($event.target.value)" placeholder="{{ 'Search' | translate }}" />
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
</div>
</div>
<mat-table [dataSource]="dataSource" matSort class="os-headed-listview-table">
<!-- Timestamp -->
<ng-container matColumnDef="time">
<mat-header-cell *matHeaderCellDef>{{ 'Timestamp' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let history">{{ getTimestamp(history) }}</mat-cell>
</ng-container>
<mat-table [dataSource]="dataSource" matSort class="os-headed-listview-table">
<!-- Timestamp -->
<ng-container matColumnDef="time">
<mat-header-cell *matHeaderCellDef>{{ 'Timestamp' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let history">{{ getTimestamp(history) }}</mat-cell>
</ng-container>
<!-- Element -->
<ng-container matColumnDef="element">
<mat-header-cell *matHeaderCellDef>{{ 'Element' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let history">
<div *ngIf="getElementInfo(history)">{{ getElementInfo(history) | translate }}</div>
<div
class="no-info"
matTooltip="{{ 'This element does not exist at this time.' | translate }}"
*ngIf="!getElementInfo(history)"
>
<span>{{ 'No information available' | translate }} ({{ history.element_id }})</span>
</div>
</mat-cell>
</ng-container>
<!-- Element -->
<ng-container matColumnDef="element">
<mat-header-cell *matHeaderCellDef>{{ 'Element' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let history">
<div *ngIf="getElementInfo(history)">{{ getElementInfo(history) | translate }}</div>
<div
class="no-info"
matTooltip="{{ 'This element does not exist at this time.' | translate }}"
*ngIf="!getElementInfo(history)"
>
<span>{{ 'No information available' | translate }} ({{ history.element_id }})</span>
</div>
</mat-cell>
</ng-container>
<!-- Info -->
<ng-container matColumnDef="info">
<mat-header-cell *matHeaderCellDef>{{ 'Comment' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let history">{{ parseInformation(history) }}</mat-cell>
</ng-container>
<!-- Info -->
<ng-container matColumnDef="info">
<mat-header-cell *matHeaderCellDef>{{ 'Comment' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let history">{{ parseInformation(history) }}</mat-cell>
</ng-container>
<!-- User -->
<ng-container matColumnDef="user">
<mat-header-cell *matHeaderCellDef>{{ 'Changed by' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let history">{{ getUserName(history) }}</mat-cell>
</ng-container>
<!-- User -->
<ng-container matColumnDef="user">
<mat-header-cell *matHeaderCellDef>{{ 'Changed by' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let history">{{ getUserName(history) }}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="getRowDef()"></mat-header-row>
<mat-row *matRowDef="let row; columns: getRowDef()" (click)="onClickRow(row)"></mat-row>
</mat-table>
<mat-header-row *matHeaderRowDef="getRowDef()"></mat-header-row>
<mat-row *matRowDef="let row; columns: getRowDef()" (click)="onClickRow(row)"></mat-row>
</mat-table>
<mat-paginator [pageSizeOptions]="pageSizes"></mat-paginator>
<mat-paginator [pageSizeOptions]="pageSizes"></mat-paginator>
</mat-card>
<mat-menu #historyMenu="matMenu">
<button mat-menu-item class="red-warning-text" (click)="clearHistory()">

View File

@ -1,13 +1,16 @@
.no-info {
font-style: italic;
color: slategray; // TODO: Colors per theme
}
.custom-table-header {
.history-table-header {
display: flex;
justify-content: space-between;
text-align: left;
}
& > div {
padding: 0 20px;
.os-headed-listview-table {
.mat-header-cell,
.mat-cell {
padding-left: 5px;
padding-right: 5px;
}
}

View File

@ -82,7 +82,7 @@
<!-- the actual file manager -->
<pbl-ngrid
class="virtual-scroll-with-head-bar ngrid-hide-head file-manager-table"
class="file-manager-table"
showHeader="false"
vScrollAuto
[dataSource]="dataSource"

View File

@ -51,6 +51,9 @@ $navbar-size: 64px;
}
.file-manager-table {
display: block;
height: calc(100vh - 130px);
.file-title {
font-weight: 500;
font-size: 16px;
@ -68,4 +71,8 @@ $navbar-size: 64px;
height: $size !important;
}
}
.pbl-ngrid-row:last-of-type {
margin-bottom: 60px !important;
}
}

View File

@ -1,22 +1 @@
@import '~assets/styles/tables.scss';
.os-headed-listview-table {
// Title
.mat-column-title {
flex: 9 0 0;
}
// Amount
.mat-column-amount {
flex: 1 0 60px;
}
// Menu
.mat-column-menu {
flex: 0 0 40px;
}
}
.mat-cell > div {
z-index: 1 !important;
}

View File

@ -6,7 +6,6 @@
</os-head-bar>
<os-list-view-table
class="block-list"
[vScrollFixed]="64"
[listObservableProvider]="repo"
[showFilterBar]="true"

View File

@ -1,13 +1,5 @@
@import '~assets/styles/tables.scss';
.block-list {
display: block;
.virtual-scroll-full-page {
height: calc(100vh - 150px);
}
}
.mat-dialog-container {
.mat-dialog-title {
margin: 0;

View File

@ -115,7 +115,7 @@
</mat-menu>
</os-head-bar>
<div class="content-container" (touchstart)="swipe($event, 'start')" (touchend)="swipe($event, 'end')">
<div class="content-container spacer-bottom-60" (touchstart)="swipe($event, 'start')" (touchend)="swipe($event, 'end')">
<!-- Title -->
<div class="title" *ngIf="motion && !editMotion">
<div class="title-line">

View File

@ -10,7 +10,7 @@
</div>
</os-head-bar>
<mat-card class="os-card">
<mat-card class="os-card spacer-bottom-60">
<ng-container [ngTemplateOutlet]="viewTemplate"></ng-container>
</mat-card>
@ -40,6 +40,7 @@
<h2>{{ 'Single votes' | translate }}</h2>
<os-list-view-table
*ngIf="votesDataObservable"
class="single-votes-table"
[listObservable]="votesDataObservable"
[columns]="columnDefinition"
[filterProps]="filterProps"
@ -47,7 +48,6 @@
[fullScreen]="true"
[vScrollFixed]="-1"
listStorageKey="motion-poll-vote"
[cssClasses]="{ 'single-votes-table': true }"
>
<!-- Header -->
<div *pblNgridHeaderCellDef="'*'; col as col">

View File

@ -26,7 +26,12 @@
}
.single-votes-table {
display: block;
height: 500px;
.list-view-frame {
height: 100%;
}
}
.openslides-theme .pbl-ngrid-no-data {

View File

@ -1,14 +0,0 @@
.os-headed-listview-table {
/** name */
.mat-column-name {
width: 100%;
flex: 1 0 200px;
padding-left: 10px;
}
/** delete */
.mat-column-delete {
flex: 0 0 190px;
justify-content: flex-end !important;
}
}

View File

@ -12,30 +12,32 @@
</div>
</os-head-bar>
<cdk-virtual-scroll-viewport itemSize="50" [ngClass]="statuteParagraphs.length ? 'virtual-scroll-full-page' : ''">
<mat-accordion class="os-card">
<mat-expansion-panel *cdkVirtualFor="let statuteParagraph of statuteParagraphs" multiple="false">
<mat-expansion-panel-header>
<mat-panel-title>
{{ statuteParagraph.title }}
</mat-panel-title>
</mat-expansion-panel-header>
<mat-card>
<mat-card-title>{{ statuteParagraph.title }}</mat-card-title>
<mat-card-content>
<div [innerHTML]="statuteParagraph.text | trust: 'html'"></div>
</mat-card-content>
</mat-card>
<mat-action-row>
<button mat-button mat-icon-button (click)="openDialog(statuteParagraph)">
<mat-icon>edit</mat-icon>
</button>
<button mat-button mat-icon-button (click)="onDeleteButton(statuteParagraph)">
<mat-icon>delete</mat-icon>
</button>
</mat-action-row>
</mat-expansion-panel>
</mat-accordion>
<cdk-virtual-scroll-viewport class="statute-vscroll-wrapper" itemSize="50">
<mat-card>
<mat-accordion>
<mat-expansion-panel *cdkVirtualFor="let statuteParagraph of statuteParagraphs" multiple="false">
<mat-expansion-panel-header>
<mat-panel-title>
{{ statuteParagraph.title }}
</mat-panel-title>
</mat-expansion-panel-header>
<mat-card>
<mat-card-title>{{ statuteParagraph.title }}</mat-card-title>
<mat-card-content>
<div [innerHTML]="statuteParagraph.text | trust: 'html'"></div>
</mat-card-content>
</mat-card>
<mat-action-row>
<button mat-button mat-icon-button (click)="openDialog(statuteParagraph)">
<mat-icon>edit</mat-icon>
</button>
<button mat-button mat-icon-button (click)="onDeleteButton(statuteParagraph)">
<mat-icon>delete</mat-icon>
</button>
</mat-action-row>
</mat-expansion-panel>
</mat-accordion>
</mat-card>
</cdk-virtual-scroll-viewport>
<mat-card *ngIf="statuteParagraphs.length === 0">

View File

@ -1,16 +1,11 @@
.head-spacer {
width: 100%;
height: 60px;
line-height: 60px;
text-align: right;
background: white; /* TODO: remove this and replace with theme */
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
}
.statute-vscroll-wrapper {
height: calc(100vh - 64px);
mat-card {
margin-bottom: 20px;
.mat-card {
margin-bottom: 20px;
mat-form-field {
width: 100%;
.mat-form-field {
width: 100%;
}
}
}

View File

@ -1,4 +1,6 @@
<div *ngIf="poll" class="poll-progress-wrapper">
out of poll
<div class="poll-progress-wrapper">
in the poll
<div class="vote-number">
<span>{{ votescast }} / {{ max }}</span>
</div>

View File

@ -95,9 +95,7 @@
</main>
</div>
<div class="toolbars">
<!-- test -->
<os-jitsi></os-jitsi>
<!-- <os-live-stream></os-live-stream> -->
</div>
</mat-sidenav-content>
</mat-sidenav-container>

View File

@ -122,12 +122,11 @@ mat-sidenav-container {
position: relative;
main {
position: absolute;
display: flex;
flex-direction: column;
width: 100%;
position: relative;
z-index: 50;
flex: 1;
> *:not(router-outlet) {
flex: 1;
display: block;

View File

@ -5,53 +5,54 @@
</div>
</os-head-bar>
<div class="hint-text">
<span>{{ 'All your changes are saved immediately.' | translate }}</span>
</div>
<mat-card class="spacer-bottom-60">
<div class="hint-text">
<span>{{ 'All your changes are saved immediately.' | translate }}</span>
</div>
<mat-accordion *ngFor="let app of appPermissions">
<mat-expansion-panel class="mat-elevation-z0" [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
{{ app.name | translate }}
</mat-panel-title>
</mat-expansion-panel-header>
<mat-accordion *ngFor="let app of appPermissions">
<mat-expansion-panel class="mat-elevation-z0" [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
{{ app.name | translate }}
</mat-panel-title>
</mat-expansion-panel-header>
<div class="scrollable-perm-matrix">
<table mat-table [dataSource]="getTableDataSource(app.permissions)">
<ng-container matColumnDef="perm" sticky>
<mat-header-cell *matHeaderCellDef>{{ 'Permissions' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let perm">
{{ perm.display_name | translate }}
</mat-cell>
</ng-container>
<div *ngFor="let group of groups; trackBy: trackByIndex">
<ng-container [matColumnDef]="group.name">
<mat-header-cell class="group-head-table-cell" *matHeaderCellDef (click)="selectGroup(group)">
<div class="inner-table">
{{ group.name | translate }}
</div>
</mat-header-cell>
<div class="scrollable-perm-matrix">
<table mat-table [dataSource]="getTableDataSource(app.permissions)">
<ng-container matColumnDef="perm" sticky>
<mat-header-cell *matHeaderCellDef>{{ 'Permissions' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let perm">
<div class="inner-table">
<mat-checkbox
*ngIf="group.id !== 2"
[checked]="group.hasPermission(perm.value)"
(change)="togglePerm(group, perm.value)"
></mat-checkbox>
<mat-checkbox *ngIf="group.id === 2" [checked]="true" [disabled]="true"></mat-checkbox>
</div>
{{ perm.display_name | translate }}
</mat-cell>
</ng-container>
</div>
<mat-header-row *matHeaderRowDef="headerRowDef"></mat-header-row>
<mat-row *matRowDef="let row; columns: headerRowDef"></mat-row>
</table>
</div>
</mat-expansion-panel>
</mat-accordion>
<div *ngFor="let group of groups; trackBy: trackByIndex">
<ng-container [matColumnDef]="group.name">
<mat-header-cell class="group-head-table-cell" *matHeaderCellDef (click)="selectGroup(group)">
<div class="inner-table">
{{ group.name | translate }}
</div>
</mat-header-cell>
<mat-cell *matCellDef="let perm">
<div class="inner-table">
<mat-checkbox
*ngIf="group.id !== 2"
[checked]="group.hasPermission(perm.value)"
(change)="togglePerm(group, perm.value)"
></mat-checkbox>
<mat-checkbox *ngIf="group.id === 2" [checked]="true" [disabled]="true"></mat-checkbox>
</div>
</mat-cell>
</ng-container>
</div>
<mat-header-row *matHeaderRowDef="headerRowDef"></mat-header-row>
<mat-row *matRowDef="let row; columns: headerRowDef"></mat-row>
</table>
</div>
</mat-expansion-panel>
</mat-accordion>
</mat-card>
<ng-template #groupEditDialog>
<h1 mat-dialog-title>

View File

@ -20,7 +20,7 @@ table {
}
.hint-text {
padding-top: 30px;
padding-top: 1em;
padding-left: 25px;
}

View File

@ -309,11 +309,6 @@ b,
@extend %os-table;
}
/* TODO: find a better way to get more vertical space in (empty/small) tables for maximize filter dialog */
.mat-paginator {
min-height: 800px;
}
/* hide scrollbars caused by hidden filter dialog outside of the viewport */
.mat-drawer-content {
overflow-x: hidden !important;
@ -447,6 +442,10 @@ button.mat-menu-item.selected {
margin-bottom: 40px !important;
}
.spacer-bottom-60 {
margin-bottom: 60px !important;
}
.spacer-left-10 {
margin-left: 10px;
}
@ -499,19 +498,6 @@ button.mat-menu-item.selected {
}
}
/**
* cdk-virtual-scroll-viewport requires a hight, otherwise it would always be 0
* Depending in mobile-mode and desktop mode we need to subtract different values
* from 100vh
*/
.virtual-scroll-full-page {
height: calc(100vh - 64px);
}
.virtual-scroll-with-head-bar {
height: calc(100vh - 129px);
}
/** css hacks https://codepen.io/edge0703/pen/iHJuA */
.innerTable {
display: inline-block;
@ -519,12 +505,13 @@ button.mat-menu-item.selected {
width: -webkit-fill-available;
}
.ngrid-hide-head {
// For some reason, hiding the table header adds an empty meta bar.
.pbl-ngrid-container {
> div {
height: 0;
}
/**
* Compilcated ngrid hack: The meta row won't disappear (just like that)
* Select the first ever container pbl-ngrid-container div and hide
*/
.pbl-ngrid-container {
> div {
height: 0;
}
}