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

View File

@ -2,26 +2,45 @@
$pbl-height: var(--pbl-height); $pbl-height: var(--pbl-height);
.projector-button { .list-view-frame {
margin: auto; // remove the height of the top-bar
height: calc(100vh - 64px);
}
.list-view-table-wrapper {
display: flex; display: flex;
} flex-flow: column;
height: 100%;
.pbl-ngrid-row { .sort-filter-bar {
height: $pbl-height; flex: 0 1 auto;
} display: block;
}
// additional space if the jitsi integration is active .vscroll-list-view {
.pbl-ngrid-row:last-of-type { flex: 1 1 auto;
margin-bottom: 30px !important;
}
.pbl-ngrid-cell { .projector-button {
height: inherit; margin: auto;
} display: flex;
}
.multiselect { .pbl-ngrid-row {
.pbl-ngrid-cell { height: $pbl-height;
cursor: pointer; }
.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() @Input()
public fullScreen = true; 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 * Inform about changes in the dataSource
*/ */
@ -275,11 +250,6 @@ export class ListViewTableComponent<V extends BaseViewModel | BaseViewModelWithC
*/ */
public inputValue: string; public inputValue: string;
/**
* Private variable to hold all classes for the virtual-scrolling-list.
*/
private _cssClasses: CssClassDefinition = {};
/** /**
* Collect subsciptions * 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"> <ng-container *ngIf="!isEditing">
<div *ngIf="privacyPolicy" [innerHtml]="privacyPolicy | trust: 'html'"></div> <div *ngIf="privacyPolicy" [innerHtml]="privacyPolicy | trust: 'html'"></div>
<div *ngIf="!privacyPolicy"> <div *ngIf="!privacyPolicy">

View File

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

View File

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

View File

@ -54,7 +54,7 @@
</mat-card> </mat-card>
</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> <h2>{{ 'Statistics' | translate }}</h2>
<div> <div>
<h3>{{ 'Active users' | translate }}</h3> <h3>{{ 'Active users' | translate }}</h3>

View File

@ -12,7 +12,7 @@
</div> </div>
</os-head-bar> </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"> <ng-container *ngIf="!isEditing">
<div class="app-content"> <div class="app-content">
<h1>{{ startContent.general_event_welcome_title | translate }}</h1> <h1>{{ startContent.general_event_welcome_title | translate }}</h1>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,22 +1 @@
@import '~assets/styles/tables.scss'; @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-head-bar>
<os-list-view-table <os-list-view-table
class="block-list"
[vScrollFixed]="64" [vScrollFixed]="64"
[listObservableProvider]="repo" [listObservableProvider]="repo"
[showFilterBar]="true" [showFilterBar]="true"

View File

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

View File

@ -115,7 +115,7 @@
</mat-menu> </mat-menu>
</os-head-bar> </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 --> <!-- Title -->
<div class="title" *ngIf="motion && !editMotion"> <div class="title" *ngIf="motion && !editMotion">
<div class="title-line"> <div class="title-line">

View File

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

View File

@ -26,7 +26,12 @@
} }
.single-votes-table { .single-votes-table {
display: block;
height: 500px; height: 500px;
.list-view-frame {
height: 100%;
}
} }
.openslides-theme .pbl-ngrid-no-data { .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> </div>
</os-head-bar> </os-head-bar>
<cdk-virtual-scroll-viewport itemSize="50" [ngClass]="statuteParagraphs.length ? 'virtual-scroll-full-page' : ''"> <cdk-virtual-scroll-viewport class="statute-vscroll-wrapper" itemSize="50">
<mat-accordion class="os-card"> <mat-card>
<mat-expansion-panel *cdkVirtualFor="let statuteParagraph of statuteParagraphs" multiple="false"> <mat-accordion>
<mat-expansion-panel-header> <mat-expansion-panel *cdkVirtualFor="let statuteParagraph of statuteParagraphs" multiple="false">
<mat-panel-title> <mat-expansion-panel-header>
{{ statuteParagraph.title }} <mat-panel-title>
</mat-panel-title> {{ statuteParagraph.title }}
</mat-expansion-panel-header> </mat-panel-title>
<mat-card> </mat-expansion-panel-header>
<mat-card-title>{{ statuteParagraph.title }}</mat-card-title> <mat-card>
<mat-card-content> <mat-card-title>{{ statuteParagraph.title }}</mat-card-title>
<div [innerHTML]="statuteParagraph.text | trust: 'html'"></div> <mat-card-content>
</mat-card-content> <div [innerHTML]="statuteParagraph.text | trust: 'html'"></div>
</mat-card> </mat-card-content>
<mat-action-row> </mat-card>
<button mat-button mat-icon-button (click)="openDialog(statuteParagraph)"> <mat-action-row>
<mat-icon>edit</mat-icon> <button mat-button mat-icon-button (click)="openDialog(statuteParagraph)">
</button> <mat-icon>edit</mat-icon>
<button mat-button mat-icon-button (click)="onDeleteButton(statuteParagraph)"> </button>
<mat-icon>delete</mat-icon> <button mat-button mat-icon-button (click)="onDeleteButton(statuteParagraph)">
</button> <mat-icon>delete</mat-icon>
</mat-action-row> </button>
</mat-expansion-panel> </mat-action-row>
</mat-accordion> </mat-expansion-panel>
</mat-accordion>
</mat-card>
</cdk-virtual-scroll-viewport> </cdk-virtual-scroll-viewport>
<mat-card *ngIf="statuteParagraphs.length === 0"> <mat-card *ngIf="statuteParagraphs.length === 0">

View File

@ -1,16 +1,11 @@
.head-spacer { .statute-vscroll-wrapper {
width: 100%; height: calc(100vh - 64px);
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);
}
mat-card { .mat-card {
margin-bottom: 20px; margin-bottom: 20px;
mat-form-field { .mat-form-field {
width: 100%; 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"> <div class="vote-number">
<span>{{ votescast }} / {{ max }}</span> <span>{{ votescast }} / {{ max }}</span>
</div> </div>

View File

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

View File

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

View File

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

View File

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

View File

@ -309,11 +309,6 @@ b,
@extend %os-table; @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 */ /* hide scrollbars caused by hidden filter dialog outside of the viewport */
.mat-drawer-content { .mat-drawer-content {
overflow-x: hidden !important; overflow-x: hidden !important;
@ -447,6 +442,10 @@ button.mat-menu-item.selected {
margin-bottom: 40px !important; margin-bottom: 40px !important;
} }
.spacer-bottom-60 {
margin-bottom: 60px !important;
}
.spacer-left-10 { .spacer-left-10 {
margin-left: 10px; 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 */ /** css hacks https://codepen.io/edge0703/pen/iHJuA */
.innerTable { .innerTable {
display: inline-block; display: inline-block;
@ -519,12 +505,13 @@ button.mat-menu-item.selected {
width: -webkit-fill-available; width: -webkit-fill-available;
} }
.ngrid-hide-head { /**
// For some reason, hiding the table header adds an empty meta bar. * Compilcated ngrid hack: The meta row won't disappear (just like that)
.pbl-ngrid-container { * Select the first ever container pbl-ngrid-container div and hide
> div { */
height: 0; .pbl-ngrid-container {
} > div {
height: 0;
} }
} }