Merge pull request #5297 from tsiegleauq/esr-cd

Fix malfunctions in Firefox ESR
This commit is contained in:
Sean 2020-04-06 23:34:32 +02:00 committed by GitHub
commit 04a7ce22fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
107 changed files with 1009 additions and 787 deletions

View File

@ -55,7 +55,7 @@
"chart.js": "^2.9.2", "chart.js": "^2.9.2",
"core-js": "^3.6.4", "core-js": "^3.6.4",
"css-element-queries": "^1.2.3", "css-element-queries": "^1.2.3",
"exceljs": "3.8.2", "exceljs": "1.15.0",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"lz4js": "^0.2.0", "lz4js": "^0.2.0",
"material-icon-font": "git+https://github.com/petergng/materialIconFont.git", "material-icon-font": "git+https://github.com/petergng/materialIconFont.git",

View File

@ -145,12 +145,11 @@ export class HttpService {
if (isDetailResponse(e.error)) { if (isDetailResponse(e.error)) {
error += this.processDetailResponse(e.error); error += this.processDetailResponse(e.error);
} else { } else {
error = Object.keys(e.error) const errorList = Object.keys(e.error).map(key => {
.map(key => {
const capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1); const capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1);
return this.translate.instant(capitalizedKey) + ': ' + this.processDetailResponse(e.error[key]); return `${this.translate.instant(capitalizedKey)}: ${this.processDetailResponse(e.error[key])}`;
}) });
.join(', '); error = errorList.join(', ');
} }
} else if (e.status === 500) { } else if (e.status === 500) {
error += this.translate.instant('A server error occured. Please contact your system administrator.'); error += this.translate.instant('A server error occured. Please contact your system administrator.');

View File

@ -256,14 +256,11 @@ export class PdfDocumentService {
if (logoHeaderLeftUrl && logoHeaderRightUrl) { if (logoHeaderLeftUrl && logoHeaderRightUrl) {
text = ''; text = '';
} else { } else {
const general_event_name = this.configService.instant<string>('general_event_name'); const general_event_name = this.translate.instant(this.configService.instant<string>('general_event_name'));
const general_event_description = this.configService.instant<string>('general_event_description'); const general_event_description = this.translate.instant(
const line1 = [ this.configService.instant<string>('general_event_description')
this.translate.instant(general_event_name), );
this.translate.instant(general_event_description) const line1 = [general_event_name, general_event_description].filter(Boolean).join(' - ');
]
.filter(Boolean)
.join(' ');
const line2 = [ const line2 = [
this.configService.instant('general_event_location'), this.configService.instant('general_event_location'),
this.configService.instant('general_event_date') this.configService.instant('general_event_date')

View File

@ -306,7 +306,8 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User, UserTi
} else if (numEmails === 1) { } else if (numEmails === 1) {
msg = this.translate.instant('One email was send sucessfully.'); msg = this.translate.instant('One email was send sucessfully.');
} else { } else {
msg = this.translate.instant('%num% emails were send sucessfully.').replace('%num%', numEmails); msg = this.translate.instant('%num% emails were send sucessfully.');
msg = msg.replace('%num%', numEmails);
} }
if (noEmailIds.length) { if (noEmailIds.length) {

View File

@ -58,6 +58,13 @@ _('PDF footer logo (left)');
_('PDF footer logo (right)'); _('PDF footer logo (right)');
_('Web interface header logo'); _('Web interface header logo');
_('PDF ballot paper logo'); _('PDF ballot paper logo');
_('Foreground color');
_('Background color');
_('Header background color');
_('Header font color');
_('Headline color');
_('Chyron background color');
_('Chyron font color');
// Agenda config strings // Agenda config strings
_('Enable numbering for agenda items'); _('Enable numbering for agenda items');
@ -409,3 +416,18 @@ _('Motion change recommendation deleted');
// core misc strings // core misc strings
_('items per page'); _('items per page');
_('Tag'); _('Tag');
// strings which are not extracted as translateable strings from client code
_('Foreground color');
_('Background color');
_('Header background color');
_('Header font color');
_('Headline color');
_('Chyron background color');
_('Chyron font color');
_('Show full text');
_('Hide more text');
_('Show password');
_('Hide password');
_('result');
_('results');

View File

@ -3,7 +3,7 @@
<div [formGroup]="form"> <div [formGroup]="form">
<p> <p>
<mat-checkbox formControlName="agenda_create"> <mat-checkbox formControlName="agenda_create">
<span translate>Add to agenda</span> <span>{{ 'Add to agenda' | translate }}</span>
</mat-checkbox> </mat-checkbox>
</p> </p>
</div> </div>

View File

@ -2,17 +2,17 @@
<table class="assignment-result-table"> <table class="assignment-result-table">
<tbody> <tbody>
<tr> <tr>
<th class="voting-option" translate>Candidates</th> <th class="voting-option">{{ 'Candidates' | translate }}</th>
<th class="result yes"> <th class="result yes">
<span *ngIf="!isMethodY" translate> <span *ngIf="!isMethodY">
Yes {{ 'Yes' | translate }}
</span> </span>
<span *ngIf="isMethodY" translate> <span *ngIf="isMethodY">
Votes {{ 'Votes' | translate }}
</span> </span>
</th> </th>
<th class="result no" translate *ngIf="!isMethodY">No</th> <th class="result no" *ngIf="!isMethodY">{{ 'No' | translate }}</th>
<th class="result abstain" translate *ngIf="isMethodYNA">Abstain</th> <th class="result abstain" *ngIf="isMethodYNA">{{ 'Abstain' | translate }}</th>
</tr> </tr>
<tr *ngFor="let row of tableData" [class]="row.class"> <tr *ngFor="let row of tableData" [class]="row.class">
<td class="voting-option"> <td class="voting-option">

View File

@ -16,7 +16,7 @@
<!-- upload file dialog --> <!-- upload file dialog -->
<ng-template #uploadDialog> <ng-template #uploadDialog>
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span translate>Upload files</span> <span>{{ 'Upload files' | translate }}</span>
</h1> </h1>
<os-media-upload-content <os-media-upload-content
(uploadSuccessEvent)="uploadSuccess($event)" (uploadSuccessEvent)="uploadSuccess($event)"

View File

@ -9,9 +9,9 @@
[ngSwitch]="banner.type" [ngSwitch]="banner.type"
> >
<ng-container *ngSwitchCase="'history'"> <ng-container *ngSwitchCase="'history'">
<span translate>You are using the history mode of OpenSlides. Changes will not be saved.</span> <span>{{ 'You are using the history mode of OpenSlides. Changes will not be saved.' | translate }}</span>
<span>({{ getHistoryTimestamp() }})</span> <span>({{ getHistoryTimestamp() }})</span>
<a (click)="timeTravel.resumeTime()" translate>Exit</a> <a (click)="timeTravel.resumeTime()">{{ 'Exit' | translate }}</a>
</ng-container> </ng-container>
<ng-container *ngSwitchDefault> <ng-container *ngSwitchDefault>
<a class="banner-link" [routerLink]="banner.link" [style.cursor]="banner.link ? 'pointer' : 'default'"> <a class="banner-link" [routerLink]="banner.link" [style.cursor]="banner.link ? 'pointer' : 'default'">

View File

@ -46,7 +46,7 @@
<!-- Cancel --> <!-- Cancel -->
<button mat-button (click)="closeDialog(false)"> <button mat-button (click)="closeDialog(false)">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</form> </form>

View File

@ -89,13 +89,14 @@ type StateMachine = { [state in State]?: { [event in StateEvent]?: SMAction } };
*ngIf="state === 'start'" *ngIf="state === 'start'"
mat-raised-button mat-raised-button
color="accent" color="accent"
translate
> >
Search player {{ 'Search player' | translate }}
</button> </button>
</div> </div>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions> <button mat-button mat-dialog-close translate>Close</button> </mat-dialog-actions> <mat-dialog-actions>
<button mat-button mat-dialog-close>{{ 'Close' | translate }}</button>
</mat-dialog-actions>
`, `,
styles: [ styles: [
` `

View File

@ -46,7 +46,7 @@ import { ViewportService } from 'app/core/ui-services/viewport.service';
* <button mat-icon-button (click)="toggleMultiSelect()"> * <button mat-icon-button (click)="toggleMultiSelect()">
* <mat-icon>arrow_back</mat-icon> * <mat-icon>arrow_back</mat-icon>
* </button> * </button>
* <span>{{ selectedRows.length }}&nbsp;</span><span translate>selected</span> * <span>{{ selectedRows.length }}&nbsp;</span><span>selected</span>
* </div> * </div>
* </os-head-bar> * </os-head-bar>
* ``` * ```

View File

@ -2,8 +2,8 @@
<div> <div>
<ng-container *ngIf="!isEditing"> <ng-container *ngIf="!isEditing">
<div *ngIf="legalNotice" class="legal-notice-text" [innerHtml]="legalNotice | trust: 'html'"></div> <div *ngIf="legalNotice" class="legal-notice-text" [innerHtml]="legalNotice | trust: 'html'"></div>
<div *ngIf="!legalNotice" translate> <div *ngIf="!legalNotice">
The event manager hasn't set up a legal notice yet. {{ 'The event manager has not set up a legal notice yet.' | translate }}
</div> </div>
</ng-container> </ng-container>
<ng-container *ngIf="isEditing"> <ng-container *ngIf="isEditing">
@ -18,13 +18,17 @@
<a [attr.href]="versionInfo.openslides_url" target="_blank"> <a [attr.href]="versionInfo.openslides_url" target="_blank">
OpenSlides {{ versionInfo.openslides_version }} OpenSlides {{ versionInfo.openslides_version }}
</a> </a>
(<span translate>License</span>: {{ versionInfo.openslides_license }}) <span>({{ 'License' | translate }}: {{ versionInfo.openslides_license }})</span>
<div *ngIf="versionInfo.plugins.length"> <div *ngIf="versionInfo.plugins.length">
<p><span translate>Installed plugins</span>:</p> <p>
<span>{{ 'Installed plugins' | translate }}:</span>
</p>
<div *ngFor="let plugin of versionInfo.plugins"> <div *ngFor="let plugin of versionInfo.plugins">
<a [attr.href]="plugin.url" target="_blank"> {{ plugin.verbose_name }} {{ plugin.version }} </a> <a [attr.href]="plugin.url" target="_blank"> {{ plugin.verbose_name }} {{ plugin.version }} </a>
<div *ngIf="plugin.license">(<span translate>License</span>: {{ plugin.license }})</div> <div *ngIf="plugin.license">
<span>({{ 'License' | translate }}: {{ plugin.license }})</span>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -38,7 +38,7 @@
<!-- No Results --> <!-- No Results -->
<div *pblNgridNoDataRef class="pbl-ngrid-no-data"> <div *pblNgridNoDataRef class="pbl-ngrid-no-data">
<span translate>No data</span> <span>{{ 'No data' | translate }}</span>
</div> </div>
<!-- Slot transclusion for the individual cells --> <!-- Slot transclusion for the individual cells -->

View File

@ -27,8 +27,9 @@
</div> </div>
<div> <div>
<span translate>Upload to:</span>&nbsp; <span> {{ 'Upload to:' | translate }}</span>
<i *ngIf="selectedDirectoryId === null" translate>Base folder</i> &nbsp;
<i *ngIf="selectedDirectoryId === null">{{ 'Base folder' | translate }}</i>
<i *ngIf="selectedDirectoryId !== null">{{ getDirectory(selectedDirectoryId).title }}</i> <i *ngIf="selectedDirectoryId !== null">{{ getDirectory(selectedDirectoryId).title }}</i>
</div> </div>
@ -36,7 +37,9 @@
<table mat-table [dataSource]="uploadList" class="mat-elevation-z8"> <table mat-table [dataSource]="uploadList" class="mat-elevation-z8">
<!-- Title --> <!-- Title -->
<ng-container matColumnDef="title" sticky> <ng-container matColumnDef="title" sticky>
<th mat-header-cell *matHeaderCellDef><span translate>Title</span></th> <th mat-header-cell *matHeaderCellDef>
<span>{{ 'Title' | translate }}</span>
</th>
<td mat-cell *matCellDef="let file"> <td mat-cell *matCellDef="let file">
<mat-form-field> <mat-form-field>
<input matInput [value]="file.title" (input)="onChangeTitle($event.target.value, file)" /> <input matInput [value]="file.title" (input)="onChangeTitle($event.target.value, file)" />
@ -46,13 +49,17 @@
<!-- Original file name --> <!-- Original file name -->
<ng-container matColumnDef="filename"> <ng-container matColumnDef="filename">
<th mat-header-cell *matHeaderCellDef><span translate>File name</span></th> <th mat-header-cell *matHeaderCellDef>
<span>{{ 'File name' | translate }}</span>
</th>
<td mat-cell *matCellDef="let file">{{ file.filename }}</td> <td mat-cell *matCellDef="let file">{{ file.filename }}</td>
</ng-container> </ng-container>
<!-- File information --> <!-- File information -->
<ng-container matColumnDef="information"> <ng-container matColumnDef="information">
<th mat-header-cell *matHeaderCellDef><span translate>File information</span></th> <th mat-header-cell *matHeaderCellDef>
<span>{{ 'File information' | translate }}</span>
</th>
<td mat-cell *matCellDef="let file"> <td mat-cell *matCellDef="let file">
<div class="file-info-cell"> <div class="file-info-cell">
<span> <span>
@ -69,7 +76,9 @@
<!-- Access groups --> <!-- Access groups -->
<ng-container matColumnDef="access_groups"> <ng-container matColumnDef="access_groups">
<th mat-header-cell *matHeaderCellDef><span translate>Access groups</span></th> <th mat-header-cell *matHeaderCellDef>
<span>{{ 'Access groups' | translate }}</span>
</th>
<td mat-cell *matCellDef="let file" [formGroup]="file.form"> <td mat-cell *matCellDef="let file" [formGroup]="file.form">
<mat-form-field> <mat-form-field>
<os-search-value-selector <os-search-value-selector
@ -84,7 +93,9 @@
<!-- Remove Button --> <!-- Remove Button -->
<ng-container matColumnDef="remove"> <ng-container matColumnDef="remove">
<th mat-header-cell *matHeaderCellDef><span translate>Remove</span></th> <th mat-header-cell *matHeaderCellDef>
<span>{{ 'Remove' | translate }}</span>
</th>
<td mat-cell *matCellDef="let file"> <td mat-cell *matCellDef="let file">
<button mat-icon-button color="warn" (click)="onRemoveButton(file)"> <button mat-icon-button color="warn" (click)="onRemoveButton(file)">
<mat-icon>close</mat-icon> <mat-icon>close</mat-icon>
@ -107,10 +118,10 @@
color="primary" color="primary"
[disabled]="uploadList.data.length === 0" [disabled]="uploadList.data.length === 0"
> >
<span translate> Upload </span> <span>{{ 'Upload' | translate }}</span>
</button> </button>
<button type="button" mat-raised-button (click)="onClearButton()" [disabled]="uploadList.data.length === 0"> <button type="button" mat-raised-button (click)="onClearButton()" [disabled]="uploadList.data.length === 0">
<span translate> Clear list </span> <span>{{ 'Clear list' | translate }}</span>
</button> </button>
</div> </div>

View File

@ -4,7 +4,7 @@
<tbody> <tbody>
<tr> <tr>
<th></th> <th></th>
<th colspan="2" translate>Votes</th> <th colspan="2">{{ 'Votes' | translate }}</th>
</tr> </tr>
<tr *ngFor="let row of getTableData()" [class]="row.votingOption"> <tr *ngFor="let row of getTableData()" [class]="row.votingOption">
<!-- YNA/Valid etc --> <!-- YNA/Valid etc -->

View File

@ -1,8 +1,8 @@
<mat-card [ngClass]="isEditing ? 'os-form-card' : 'os-card'"> <mat-card [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" translate> <div *ngIf="!privacyPolicy">
The event manager hasn't set up a privacy policy yet. {{ 'The event manager has not set up a privacy policy yet.' | translate }}
</div> </div>
</ng-container> </ng-container>
<ng-container *ngIf="isEditing"> <ng-container *ngIf="isEditing">

View File

@ -1,5 +1,5 @@
<h2 mat-dialog-title> <h2 mat-dialog-title>
<span translate>Project selection?</span> <span>{{ 'Project selection?' | translate }}</span>
</h2> </h2>
<div class="element-name" *ngIf="projectorElementBuildDescriptor"> <div class="element-name" *ngIf="projectorElementBuildDescriptor">
{{ projectorElementBuildDescriptor.getDialogTitle() }} {{ projectorElementBuildDescriptor.getDialogTitle() }}

View File

@ -1,7 +1,7 @@
<div class="custom-table-header flex-spaced"> <div class="custom-table-header flex-spaced">
<!-- Amount of filters --> <!-- Amount of filters -->
<div class="filter-count"> <div class="filter-count">
<span>{{ filterCount }}&nbsp;</span><span translate>of</span> <span>{{ filterCount }}&nbsp;</span><span>{{ 'of' | translate }}</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>
@ -30,10 +30,10 @@
<!-- Sort Button --> <!-- Sort Button -->
<button mat-button *ngIf="vp.isMobile && hasSorting" (click)="openSortDropDown()"> <button mat-button *ngIf="vp.isMobile && hasSorting" (click)="openSortDropDown()">
<span class="upper" translate>Sort</span> <span class="upper">{{ 'Sort' | translate }}</span>
</button> </button>
<button mat-button *ngIf="!vp.isMobile && hasSorting" [matMenuTriggerFor]="menu"> <button mat-button *ngIf="!vp.isMobile && hasSorting" [matMenuTriggerFor]="menu">
<span class="upper" translate>Sort</span> <span class="upper">{{ 'Sort' | translate }}</span>
</button> </button>
<!-- Search bar --> <!-- Search bar -->
@ -58,7 +58,7 @@
<button mat-button (click)="onClearAllButton($event)" *ngIf="filterAmount"> <button mat-button (click)="onClearAllButton($event)" *ngIf="filterAmount">
<os-icon-container icon="clear"> <os-icon-container icon="clear">
<span translate>Clear all filters</span> <span>{{ 'Clear all filters' | translate }}</span>
</os-icon-container> </os-icon-container>
</button> </button>
</div> </div>

View File

@ -1,6 +1,6 @@
<div cdkDropList [cdkDropListDisabled]="!enable" (cdkDropListDropped)="drop($event)"> <div cdkDropList [cdkDropListDisabled]="!enable" (cdkDropListDropped)="drop($event)">
<div class="line" *ngIf="!sortedItems.length"> <div class="line" *ngIf="!sortedItems.length">
<span translate>No data</span> <span>{{ 'No data' | translate }}</span>
</div> </div>
<div <div
[ngClass]="isSelectedRow(i) ? 'backgroundColorSelected line' : 'backgroundColorLight line'" [ngClass]="isSelectedRow(i) ? 'backgroundColorSelected line' : 'backgroundColorLight line'"
@ -23,7 +23,7 @@
</div> </div>
<div class="line" *cdkDragPreview> <div class="line" *cdkDragPreview>
<div class="spacer.left-10" *ngIf="multiSelectedIndex.length > 0"> <div class="spacer.left-10" *ngIf="multiSelectedIndex.length > 0">
{{ multiSelectedIndex.length }}&nbsp;<span translate>items selected</span> {{ multiSelectedIndex.length }}&nbsp;<span>{{ 'items selected' | translate }}</span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -13,7 +13,7 @@
<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>{{ 'List of speakers' | translate }}</span>
<span>&nbsp;</span> <span>&nbsp;</span>
<mat-basic-chip disableRipple class="lightblue" *ngIf="listOfSpeakers.waitingSpeakerAmount > 0"> <mat-basic-chip disableRipple class="lightblue" *ngIf="listOfSpeakers.waitingSpeakerAmount > 0">
<span>{{ listOfSpeakers.waitingSpeakerAmount }}</span> <span>{{ listOfSpeakers.waitingSpeakerAmount }}</span>

View File

@ -20,7 +20,7 @@
<mat-icon [color]="user.is_present ? 'primary' : ''" class="menu-icon"> <mat-icon [color]="user.is_present ? 'primary' : ''" class="menu-icon">
{{ user.is_present ? 'check_box' : 'check_box_outline_blank' }} {{ user.is_present ? 'check_box' : 'check_box_outline_blank' }}
</mat-icon> </mat-icon>
<span class="menu-text" translate>Present</span> <span class="menu-text">{{ 'Present' | translate }}</span>
</button> </button>
<!-- Show profile --> <!-- Show profile -->
<a <a
@ -30,7 +30,7 @@
mat-list-item mat-list-item
> >
<mat-icon class="menu-icon">person</mat-icon> <mat-icon class="menu-icon">person</mat-icon>
<span class="menu-text" translate>Show profile</span> <span class="menu-text">{{ 'Show profile' | translate }}</span>
</a> </a>
<!-- Change password --> <!-- Change password -->
<ng-container *ngIf="authType === 'default'"> <ng-container *ngIf="authType === 'default'">
@ -42,19 +42,19 @@
mat-list-item mat-list-item
> >
<mat-icon class="menu-icon">vpn_key</mat-icon> <mat-icon class="menu-icon">vpn_key</mat-icon>
<span class="menu-text" translate>Change password</span> <span class="menu-text">{{ 'Change password' | translate }}</span>
</a> </a>
</ng-container> </ng-container>
<ng-container *ngIf="authType === 'saml'"> <ng-container *ngIf="authType === 'saml'">
<a *osPerms="'users.can_change_password'" [href]="samlChangePasswordUrl" mat-list-item> <a *osPerms="'users.can_change_password'" [href]="samlChangePasswordUrl" mat-list-item>
<mat-icon class="menu-icon">vpn_key</mat-icon> <mat-icon class="menu-icon">vpn_key</mat-icon>
<span class="menu-text" translate>Change password</span> <span class="menu-text">{{ 'Change password' | translate }}</span>
</a> </a>
</ng-container> </ng-container>
<!-- logout --> <!-- logout -->
<a (click)="logout()" mat-list-item> <a (click)="logout()" mat-list-item>
<mat-icon class="menu-icon">exit_to_app</mat-icon> <mat-icon class="menu-icon">exit_to_app</mat-icon>
<span class="menu-text" translate>Logout</span> <span class="menu-text">{{ 'Logout' | translate }}</span>
</a> </a>
</div> </div>
</mat-nav-list> </mat-nav-list>
@ -62,7 +62,7 @@
<mat-nav-list *ngIf="!isLoggedIn"> <mat-nav-list *ngIf="!isLoggedIn">
<a routerLink="/login" mat-list-item> <a routerLink="/login" mat-list-item>
<mat-icon class="menu-icon">exit_to_app</mat-icon> <mat-icon class="menu-icon">exit_to_app</mat-icon>
<span class="menu-text" translate>Login</span> <span class="menu-text">{{ 'Login' | translate }}</span>
</a> </a>
</mat-nav-list> </mat-nav-list>

View File

@ -1,15 +1,20 @@
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span translate>Secret voting can not be guaranteed</span> <span>{{ 'Secret voting can not be guaranteed' | translate }}</span>
</h1> </h1>
<div mat-dialog-content> <div mat-dialog-content>
<span translate> <span>
During non-nominal voting OpenSlides does NOT store the individual user ID of the voter. This in no way means that a non-nominal vote is completely anonymous and secure. The votes cannot track their individual votes after the data has been submitted. The validity of the data cannot always be guaranteed. {{
'During non-nominal voting OpenSlides does NOT store the individual user ID of the voter. This in no way means
that a non-nominal vote is completely anonymous and secure. The votes cannot track their individual votes after
the data has been submitted. The validity of the data cannot always be guaranteed.'
| translate
}}
</span> </span>
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>I know the risk</span> <span>{{ 'I know the risk' | translate }}</span>
</button> </button>
</div> </div>

View File

@ -1,6 +1,8 @@
<os-head-bar [hasMainButton]="canManage" (mainEvent)="onPlusButton()" [multiSelectMode]="isMultiSelect"> <os-head-bar [hasMainButton]="canManage" (mainEvent)="onPlusButton()" [multiSelectMode]="isMultiSelect">
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Agenda</h2></div> <div class="title-slot">
<h2>{{ 'Agenda' | translate }}</h2>
</div>
<!-- Menu --> <!-- Menu -->
<div class="menu-slot"> <div class="menu-slot">
<button type="button" mat-icon-button [matMenuTriggerFor]="agendaMenu"><mat-icon>more_vert</mat-icon></button> <button type="button" mat-icon-button [matMenuTriggerFor]="agendaMenu"><mat-icon>more_vert</mat-icon></button>
@ -9,7 +11,7 @@
<!-- Multiselect info --> <!-- Multiselect info -->
<div class="central-info-slot"> <div class="central-info-slot">
<button mat-icon-button (click)="toggleMultiSelect()"><mat-icon>arrow_back</mat-icon></button> <button mat-icon-button (click)="toggleMultiSelect()"><mat-icon>arrow_back</mat-icon></button>
<span>{{ selectedRows.length }}&nbsp;</span><span translate>selected</span> <span>{{ selectedRows.length }}&nbsp;</span><span>{{ 'selected' | translate }}</span>
</div> </div>
</os-head-bar> </os-head-bar>
@ -79,17 +81,17 @@
<!-- Enable multi select --> <!-- Enable multi select -->
<button mat-menu-item (click)="toggleMultiSelect()"> <button mat-menu-item (click)="toggleMultiSelect()">
<mat-icon>library_add</mat-icon> <mat-icon>library_add</mat-icon>
<span translate>Multiselect</span> <span>{{ 'Multiselect' | translate }}</span>
</button> </button>
<!-- automatic numbering --> <!-- automatic numbering -->
<button mat-menu-item *ngIf="isNumberingAllowed" (click)="onAutoNumbering()"> <button mat-menu-item *ngIf="isNumberingAllowed" (click)="onAutoNumbering()">
<mat-icon>format_list_numbered</mat-icon> <mat-icon>format_list_numbered</mat-icon>
<span translate>Numbering</span> <span>{{ 'Numbering' | translate }}</span>
</button> </button>
<button mat-menu-item routerLink="sort-agenda"> <button mat-menu-item routerLink="sort-agenda">
<mat-icon>sort</mat-icon> <mat-icon>sort</mat-icon>
<span translate>Sort</span> <span>{{ 'Sort' | translate }}</span>
</button> </button>
</div> </div>
@ -99,28 +101,28 @@
<!-- Current list of speakers --> <!-- Current list of speakers -->
<button mat-menu-item *osPerms="'agenda.can_see_list_of_speakers'" routerLink="speakers"> <button mat-menu-item *osPerms="'agenda.can_see_list_of_speakers'" routerLink="speakers">
<mat-icon>mic</mat-icon> <mat-icon>mic</mat-icon>
<span translate>Current list of speakers</span> <span>{{ 'Current list of speakers' | translate }}</span>
</button> </button>
<!-- CSV export --> <!-- CSV export -->
<button mat-menu-item *osPerms="'agenda.can_manage'" (click)="csvExportItemList()"> <button mat-menu-item *osPerms="'agenda.can_manage'" (click)="csvExportItemList()">
<mat-icon>archive</mat-icon> <mat-icon>archive</mat-icon>
<span translate>Export as CSV</span> <span>{{ 'Export as CSV' | translate }}</span>
</button> </button>
<!-- PDF export --> <!-- PDF export -->
<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>Export as PDF</span> <span>{{ 'Export as PDF' | translate }}</span>
</button> </button>
<!-- Import --> <!-- Import -->
<button mat-menu-item *osPerms="'agenda.can_manage'" routerLink="import"> <button mat-menu-item *osPerms="'agenda.can_manage'" routerLink="import">
<mat-icon>cloud_upload</mat-icon> <mat-icon>cloud_upload</mat-icon>
<span translate>Import</span> <span>{{ 'Import' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<!-- Settings --> <!-- Settings -->
<button mat-menu-item *osPerms="'core.can_manage_config'" routerLink="/settings/agenda"> <button mat-menu-item *osPerms="'core.can_manage_config'" routerLink="/settings/agenda">
<mat-icon>settings</mat-icon> <mat-icon>settings</mat-icon>
<span translate>Settings</span> <span>{{ 'Settings' | translate }}</span>
</button> </button>
</div> </div>
@ -128,26 +130,26 @@
<!-- Select all --> <!-- Select all -->
<button mat-menu-item (click)="selectAll()"> <button mat-menu-item (click)="selectAll()">
<mat-icon>done_all</mat-icon> <mat-icon>done_all</mat-icon>
<span translate>Select all</span> <span>{{ 'Select all' | translate }}</span>
</button> </button>
<!-- Deselect all --> <!-- Deselect all -->
<button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()">
<mat-icon>clear</mat-icon> <mat-icon>clear</mat-icon>
<span translate>Deselect all</span> <span>{{ 'Deselect all' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<div *osPerms="'agenda.can_manage'"> <div *osPerms="'agenda.can_manage'">
<!-- Close selected --> <!-- Close selected -->
<button mat-menu-item [disabled]="!selectedRows.length" (click)="setClosedSelected(true)"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="setClosedSelected(true)">
<mat-icon>done</mat-icon> <mat-icon>done</mat-icon>
<span translate>Close</span> <span>{{ 'Close' | translate }}</span>
</button> </button>
<!-- Open selected --> <!-- Open selected -->
<button mat-menu-item [disabled]="!selectedRows.length" (click)="setClosedSelected(false)"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="setClosedSelected(false)">
<mat-icon>redo</mat-icon> <mat-icon>redo</mat-icon>
<span translate>Open</span> <span>{{ 'Open' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
@ -155,26 +157,26 @@
<!-- Set multiple to public --> <!-- Set multiple to public -->
<button mat-menu-item [disabled]="!selectedRows.length" (click)="setAgendaType(1)"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="setAgendaType(1)">
<mat-icon>public</mat-icon> <mat-icon>public</mat-icon>
<span translate>Set public</span> <span>{{ 'Set public' | translate }}</span>
</button> </button>
<!-- Set multiple to internal --> <!-- Set multiple to internal -->
<button mat-menu-item [disabled]="!selectedRows.length" (click)="setAgendaType(2)"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="setAgendaType(2)">
<mat-icon>visibility</mat-icon> <mat-icon>visibility</mat-icon>
<span translate>Set internal</span> <span>{{ 'Set internal' | translate }}</span>
</button> </button>
<!-- Set multiple to hidden --> <!-- Set multiple to hidden -->
<button mat-menu-item [disabled]="!selectedRows.length" (click)="setAgendaType(3)"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="setAgendaType(3)">
<mat-icon>visibility_off</mat-icon> <mat-icon>visibility_off</mat-icon>
<span translate>Set hidden</span> <span>{{ 'Set hidden' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<!-- Delete selected --> <!-- Delete selected -->
<button mat-menu-item [disabled]="!selectedRows.length" (click)="removeSelected()"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="removeSelected()">
<mat-icon>remove</mat-icon> <mat-icon>remove</mat-icon>
<span translate>Remove from agenda</span> <span>{{ 'Remove from agenda' | translate }}</span>
</button> </button>
</div> </div>
</div> </div>
@ -193,13 +195,13 @@
<!-- Done check --> <!-- Done check -->
<button mat-menu-item (click)="onDoneSingleButton(item)"> <button mat-menu-item (click)="onDoneSingleButton(item)">
<mat-icon color="accent"> {{ item.closed ? 'check_box' : 'check_box_outline_blank' }} </mat-icon> <mat-icon color="accent"> {{ item.closed ? 'check_box' : 'check_box_outline_blank' }} </mat-icon>
<span translate>Done</span> <span>{{ 'Done' | translate }}</span>
</button> </button>
<!-- Edit button --> <!-- Edit button -->
<button mat-menu-item (click)="openEditInfo(item, $event)"> <button mat-menu-item (click)="openEditInfo(item, $event)">
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
<span translate>Edit details</span> <span>{{ 'Edit details' | translate }}</span>
</button> </button>
<!-- Delete Button --> <!-- Delete Button -->
@ -209,7 +211,7 @@
*ngIf="item.contentObjectData.collection !== 'topics/topic'" *ngIf="item.contentObjectData.collection !== 'topics/topic'"
> >
<mat-icon>remove</mat-icon> <mat-icon>remove</mat-icon>
<span translate>Remove from agenda</span> <span>{{ 'Remove from agenda' | translate }}</span>
</button> </button>
<button <button
@ -219,7 +221,7 @@
*ngIf="item.contentObjectData.collection === 'topics/topic'" *ngIf="item.contentObjectData.collection === 'topics/topic'"
> >
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
@ -36,6 +36,7 @@ import { ViewListOfSpeakers } from '../../models/view-list-of-speakers';
@Component({ @Component({
selector: 'os-agenda-list', selector: 'os-agenda-list',
templateUrl: './agenda-list.component.html', templateUrl: './agenda-list.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./agenda-list.component.scss'] styleUrls: ['./agenda-list.component.scss']
}) })
export class AgendaListComponent extends BaseListViewComponent<ViewItem> implements OnInit { export class AgendaListComponent extends BaseListViewComponent<ViewItem> implements OnInit {

View File

@ -1,11 +1,8 @@
<os-head-bar <os-head-bar [nav]="false" [editMode]="hasChanged" (mainEvent)="onCancel()" (saveEvent)="onSave()">
[nav]="false"
[editMode]="hasChanged"
(mainEvent)="onCancel()"
(saveEvent)="onSave()">
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Sort agenda</h2></div> <div class="title-slot">
<h2>{{ 'Sort agenda' | translate }}</h2>
</div>
</os-head-bar> </os-head-bar>
<div class="custom-table-header sort-header"> <div class="custom-table-header sort-header">
<div class="button-menu left"> <div class="button-menu left">
@ -13,7 +10,10 @@
<button mat-button (click)="onStateChange(false)">{{ 'Collapse all' | translate }}</button> <button mat-button (click)="onStateChange(false)">{{ 'Collapse all' | translate }}</button>
</div> </div>
<div class="current-filters" *ngIf="hasActiveFilter"> <div class="current-filters" *ngIf="hasActiveFilter">
<div><span translate>Active filters</span>:&nbsp;</div> <div>
<span>{{ 'Active filters' | translate }}</span
>:&nbsp;
</div>
<div> <div>
<button mat-button (click)="resetFilters()"> <button mat-button (click)="resetFilters()">
<mat-icon inline>cancel</mat-icon> <mat-icon inline>cancel</mat-icon>
@ -22,7 +22,9 @@
</div> </div>
</div> </div>
<div class="button-menu right"> <div class="button-menu right">
<button mat-button (click)="visibilityFilter.opened ? visibilityFilter.close() : visibilityFilter.open()">Filter</button> <button mat-button (click)="visibilityFilter.opened ? visibilityFilter.close() : visibilityFilter.open()">
Filter
</button>
<mat-drawer #visibilityFilter mode="over" position="end"> <mat-drawer #visibilityFilter mode="over" position="end">
<section class="sort-drawer-content"> <section class="sort-drawer-content">
<button mat-button (click)="visibilityFilter.toggle()"> <button mat-button (click)="visibilityFilter.toggle()">
@ -31,8 +33,13 @@
<span class="sort-grid"> <span class="sort-grid">
<div class="hint">{{ 'Visibility' | translate }}</div> <div class="hint">{{ 'Visibility' | translate }}</div>
<div> <div>
<mat-checkbox *ngFor="let option of filterOptions" [(ngModel)]="option.state" (change)="onFilterChange(option.id)"> <mat-checkbox
<mat-icon matTooltip="{{ option.label | translate }}">{{ getIcon(option.label) }}</mat-icon> {{ option.label | translate }} *ngFor="let option of filterOptions"
[(ngModel)]="option.state"
(change)="onFilterChange(option.id)"
>
<mat-icon matTooltip="{{ option.label | translate }}">{{ getIcon(option.label) }}</mat-icon>
{{ option.label | translate }}
</mat-checkbox> </mat-checkbox>
</div> </div>
</span> </span>
@ -42,8 +49,8 @@
</div> </div>
<mat-card> <mat-card>
<div class="current-nodes"> <div class="current-nodes">
{{ seenNodes[0] }} <span translate>of</span> {{ seenNodes[1] }} {{ seenNodes[0] }} <span>{{ 'of' | translate }}</span> {{ seenNodes[1] }}
<span translate>items</span> <span>{{ 'items' | translate }}</span>
</div> </div>
<os-sorting-tree <os-sorting-tree
#osSortedTree #osSortedTree

View File

@ -13,9 +13,9 @@
<!-- Duration --> <!-- Duration -->
<mat-form-field> <mat-form-field>
<input type="string" matInput placeholder="{{ 'Duration' | translate }}" formControlName="durationText" /> <input type="string" matInput placeholder="{{ 'Duration' | translate }}" formControlName="durationText" />
<mat-error *ngIf="agendaInfoForm.invalid" <mat-error *ngIf="agendaInfoForm.invalid">
>Your input does not match the following structure 'hh:mm'...</mat-error {{ 'Your input does not match the following structure: "hh:mm"' | translate }}
> </mat-error>
</mat-form-field> </mat-form-field>
<!-- Item number (prefix) --> <!-- Item number (prefix) -->
@ -37,6 +37,10 @@
</form> </form>
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button mat-button (click)="saveItemInfo()" [disabled]="agendaInfoForm.invalid"><span translate>Save</span></button> <button mat-button (click)="saveItemInfo()" [disabled]="agendaInfoForm.invalid">
<button mat-button (click)="onCancelButton()"><span translate>Cancel</span></button> <span>{{ 'Save' | translate }}</span>
</button>
<button mat-button (click)="onCancelButton()">
<span>{{ 'Cancel' | translate }}</span>
</button>
</div> </div>

View File

@ -8,9 +8,9 @@
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2> <h2>
<span *ngIf="!isCurrentListOfSpeakers && !isSortMode" translate>List of speakers</span> <span *ngIf="!isCurrentListOfSpeakers && !isSortMode">{{ 'List of speakers' | translate }}</span>
<span *ngIf="isCurrentListOfSpeakers && !isSortMode" translate>Current list of speakers</span> <span *ngIf="isCurrentListOfSpeakers && !isSortMode">{{ 'Current list of speakers' | translate }}</span>
<span *ngIf="isSortMode" translate>Sort list of speakers</span> <span *ngIf="isSortMode">{{ 'Sort list of speakers' | translate }}</span>
</h2> </h2>
</div> </div>
<div class="menu-slot" *osPerms="['agenda.can_manage_list_of_speakers', 'core.can_manage_projector']"> <div class="menu-slot" *osPerms="['agenda.can_manage_list_of_speakers', 'core.can_manage_projector']">
@ -39,7 +39,7 @@
<!-- List of finished speakers --> <!-- List of finished speakers -->
<mat-expansion-panel *ngIf="finishedSpeakers && finishedSpeakers.length > 0" class="finished-list"> <mat-expansion-panel *ngIf="finishedSpeakers && finishedSpeakers.length > 0" class="finished-list">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title translate> Last speakers </mat-panel-title> <mat-panel-title>{{ 'Last speakers' | translate }}</mat-panel-title>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<mat-list> <mat-list>
<mat-list-item *ngFor="let speaker of finishedSpeakers; let number = index"> <mat-list-item *ngFor="let speaker of finishedSpeakers; let number = index">
@ -96,7 +96,7 @@
<ng-template let-speaker> <ng-template let-speaker>
<span *osPerms="'agenda.can_manage_list_of_speakers'"> <span *osPerms="'agenda.can_manage_list_of_speakers'">
<span *ngIf="hasSpokenCount(speaker)" class="red-warning-text speaker-warning"> <span *ngIf="hasSpokenCount(speaker)" class="red-warning-text speaker-warning">
{{ hasSpokenCount(speaker) + 1 }}. <span translate>contribution</span> {{ hasSpokenCount(speaker) + 1 }}. <span>{{ 'contribution' | translate }}</span>
</span> </span>
<span *ngIf="speaker.gender">({{ speaker.gender | translate }})</span> <span *ngIf="speaker.gender">({{ speaker.gender | translate }})</span>
</span> </span>
@ -154,11 +154,11 @@
*ngIf="!isOpInList() && canAddSelf" *ngIf="!isOpInList() && canAddSelf"
> >
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
<span translate>Add me</span> <span>{{ 'Add me' | translate }}</span>
</button> </button>
<button mat-stroked-button (click)="onDeleteButton()" *ngIf="isOpInList()"> <button mat-stroked-button (click)="onDeleteButton()" *ngIf="isOpInList()">
<mat-icon>remove</mat-icon> <mat-icon>remove</mat-icon>
<span translate>Remove me</span> <span>{{ 'Remove me' | translate }}</span>
</button> </button>
</div> </div>
</div> </div>
@ -167,7 +167,7 @@
<mat-menu #speakerMenu="matMenu"> <mat-menu #speakerMenu="matMenu">
<button mat-menu-item (click)="isSortMode = true"> <button mat-menu-item (click)="isSortMode = true">
<mat-icon>sort</mat-icon> <mat-icon>sort</mat-icon>
<span translate>Sort</span> <span>{{ 'Sort' | translate }}</span>
</button> </button>
<os-projector-button <os-projector-button
@ -193,18 +193,18 @@
<button mat-menu-item *ngIf="isListOfSpeakersClosed" (click)="openSpeakerList()"> <button mat-menu-item *ngIf="isListOfSpeakersClosed" (click)="openSpeakerList()">
<mat-icon>lock_open</mat-icon> <mat-icon>lock_open</mat-icon>
<span translate>Open list of speakers</span> <span>{{ 'Open list of speakers' | translate }}</span>
</button> </button>
<button mat-menu-item *ngIf="!isListOfSpeakersClosed" (click)="closeSpeakerList()"> <button mat-menu-item *ngIf="!isListOfSpeakersClosed" (click)="closeSpeakerList()">
<mat-icon>lock</mat-icon> <mat-icon>lock</mat-icon>
<span translate>Close list of speakers</span> <span>{{ 'Close list of speakers' | translate }}</span>
</button> </button>
<mat-divider *ngIf="!isListOfSpeakersEmpty"></mat-divider> <mat-divider *ngIf="!isListOfSpeakersEmpty"></mat-divider>
<button mat-menu-item (click)="clearSpeakerList()" *ngIf="!isListOfSpeakersEmpty" class="red-warning-text"> <button mat-menu-item (click)="clearSpeakerList()" *ngIf="!isListOfSpeakersEmpty" class="red-warning-text">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Remove all speakers</span> <span>{{ 'Remove all speakers' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>

View File

@ -9,8 +9,8 @@
> >
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 *ngIf="!newAssignment" translate>Election</h2> <h2 *ngIf="!newAssignment">{{ 'Election' | translate }}</h2>
<h2 *ngIf="newAssignment" translate>New election</h2> <h2 *ngIf="newAssignment">{{ 'New election' | translate }}</h2>
</div> </div>
<!-- Menu --> <!-- Menu -->
@ -25,7 +25,7 @@
<!-- 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>{{ 'PDF' | translate }}</span>
</button> </button>
<!-- List of speakers --> <!-- List of speakers -->
<os-speaker-button [object]="assignment" [menuItem]="true"></os-speaker-button> <os-speaker-button [object]="assignment" [menuItem]="true"></os-speaker-button>
@ -37,11 +37,11 @@
<div *osPerms="'agenda.can_manage'"> <div *osPerms="'agenda.can_manage'">
<button mat-menu-item (click)="addToAgenda()" *ngIf="assignment && !assignment.item"> <button mat-menu-item (click)="addToAgenda()" *ngIf="assignment && !assignment.item">
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
<span translate>Add to agenda</span> <span>{{ 'Add to agenda' | translate }}</span>
</button> </button>
<button mat-menu-item (click)="removeFromAgenda()" *ngIf="assignment && assignment.item"> <button mat-menu-item (click)="removeFromAgenda()" *ngIf="assignment && assignment.item">
<mat-icon>remove</mat-icon> <mat-icon>remove</mat-icon>
<span translate>Remove from agenda</span> <span>{{ 'Remove from agenda' | translate }}</span>
</button> </button>
</div> </div>
@ -51,7 +51,7 @@
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button mat-menu-item class="red-warning-text" (click)="onDeleteAssignmentButton()"> <button mat-menu-item class="red-warning-text" (click)="onDeleteAssignmentButton()">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</mat-menu> </mat-menu>
@ -76,7 +76,7 @@
<div class="new-ballot-button" *ngIf="assignment && hasPerms('createPoll')"> <div class="new-ballot-button" *ngIf="assignment && hasPerms('createPoll')">
<button mat-stroked-button (click)="openDialog()"> <button mat-stroked-button (click)="openDialog()">
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
<span translate>New ballot</span> <span>{{ 'New ballot' | translate }}</span>
</button> </button>
</div> </div>
@ -98,11 +98,11 @@
</div> </div>
<div class="meta-info-grid"> <div class="meta-info-grid">
<div class="number-of-elected"> <div class="number-of-elected">
<h4 translate>Number of persons to be elected</h4> <h4>{{ 'Number of persons to be elected' | translate }}</h4>
<span>{{ assignment.assignment.open_posts }}</span> <span>{{ assignment.assignment.open_posts }}</span>
</div> </div>
<div class="current-phase"> <div class="current-phase">
<h4 translate>Phase</h4> <h4>{{ 'Phase' | translate }}</h4>
<mat-basic-chip <mat-basic-chip
*ngIf="hasPerms('manage')" *ngIf="hasPerms('manage')"
[matMenuTriggerFor]="phaseMenu" [matMenuTriggerFor]="phaseMenu"
@ -123,7 +123,7 @@
</div> </div>
<div *ngIf="assignment.attachments.length"> <div *ngIf="assignment.attachments.length">
<h4 translate>Election documents</h4> <h4>{{ 'Election documents' | translate }}</h4>
<mat-list dense class="election-document-list"> <mat-list dense class="election-document-list">
<mat-list-item *ngFor="let file of assignment.attachments"> <mat-list-item *ngFor="let file of assignment.attachments">
<a [routerLink]="file.url" target="_blank">{{ file.getTitle() }}</a> <a [routerLink]="file.url" target="_blank">{{ file.getTitle() }}</a>
@ -136,7 +136,7 @@
<ng-template #candidatesTemplate> <ng-template #candidatesTemplate>
<mat-card class="os-card" *ngIf="assignment && !assignment.isFinished"> <mat-card class="os-card" *ngIf="assignment && !assignment.isFinished">
<ng-container> <ng-container>
<h3 translate>Candidates</h3> <h3>{{ 'Candidates' | translate }}</h3>
<div> <div>
<div <div
class="candidates-list" class="candidates-list"
@ -196,11 +196,11 @@
<div> <div>
<button mat-button color="accent" (click)="addSelf()" *ngIf="!isSelfCandidate"> <button mat-button color="accent" (click)="addSelf()" *ngIf="!isSelfCandidate">
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
<span translate>Add me</span> <span>{{ 'Add me' | translate }}</span>
</button> </button>
<button mat-button color="accent" (click)="removeSelf()" *ngIf="isSelfCandidate"> <button mat-button color="accent" (click)="removeSelf()" *ngIf="isSelfCandidate">
<mat-icon>remove</mat-icon> <mat-icon>remove</mat-icon>
<span translate>Remove me</span> <span>{{ 'Remove me' | translate }}</span>
</button> </button>
</div> </div>
</div> </div>
@ -291,7 +291,7 @@
<!-- Number candidates --> <!-- Number candidates -->
<div> <div>
<mat-checkbox formControlName="number_poll_candidates"> <mat-checkbox formControlName="number_poll_candidates">
<span translate>Number candidates</span> <span>{{ 'Number candidates' | translate }}</span>
</mat-checkbox> </mat-checkbox>
</div> </div>
</form> </form>

View File

@ -4,7 +4,9 @@
[multiSelectMode]="isMultiSelect" [multiSelectMode]="isMultiSelect"
> >
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Elections</h2></div> <div class="title-slot">
<h2>{{ 'Elections' | translate }}</h2>
</div>
<!-- Menu --> <!-- Menu -->
<div class="menu-slot"> <div class="menu-slot">
<button type="button" mat-icon-button [matMenuTriggerFor]="assignmentMenu"> <button type="button" mat-icon-button [matMenuTriggerFor]="assignmentMenu">
@ -15,7 +17,7 @@
<!-- Multiselect info --> <!-- Multiselect info -->
<div class="central-info-slot"> <div class="central-info-slot">
<button mat-icon-button (click)="toggleMultiSelect()"><mat-icon>arrow_back</mat-icon></button> <button mat-icon-button (click)="toggleMultiSelect()"><mat-icon>arrow_back</mat-icon></button>
<span>{{ selectedRows.length }}&nbsp;</span><span translate>selected</span> <span>{{ selectedRows.length }}&nbsp;</span><span>{{ 'selected' | translate }}</span>
</div> </div>
</os-head-bar> </os-head-bar>
@ -90,28 +92,28 @@
<div *ngIf="!isMultiSelect"> <div *ngIf="!isMultiSelect">
<button mat-menu-item *osPerms="'assignment.can_manage'" (click)="toggleMultiSelect()"> <button mat-menu-item *osPerms="'assignment.can_manage'" (click)="toggleMultiSelect()">
<mat-icon>library_add</mat-icon> <mat-icon>library_add</mat-icon>
<span translate>Multiselect</span> <span>{{ 'Multiselect' | translate }}</span>
</button> </button>
<button mat-menu-item (click)="downloadAssignmentButton()"> <button mat-menu-item (click)="downloadAssignmentButton()">
<mat-icon>archive</mat-icon> <mat-icon>archive</mat-icon>
<span translate>Export ...</span> <span>{{ 'Export ...' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<!-- Settings --> <!-- Settings -->
<button mat-menu-item *osPerms="'core.can_manage_config'" routerLink="/settings/elections"> <button mat-menu-item *osPerms="'core.can_manage_config'" routerLink="/settings/elections">
<mat-icon>settings</mat-icon> <mat-icon>settings</mat-icon>
<span translate>Settings</span> <span>{{ 'Settings' | translate }}</span>
</button> </button>
</div> </div>
<div *ngIf="isMultiSelect"> <div *ngIf="isMultiSelect">
<button mat-menu-item (click)="selectAll()"> <button mat-menu-item (click)="selectAll()">
<mat-icon>done_all</mat-icon> <mat-icon>done_all</mat-icon>
<span translate>Select all</span> <span>{{ 'Select all' | translate }}</span>
</button> </button>
<button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()">
<mat-icon>clear</mat-icon> <mat-icon>clear</mat-icon>
<span translate>Deselect all</span> <span>{{ 'Deselect all' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button <button
@ -132,7 +134,7 @@
(click)="deleteSelected()" (click)="deleteSelected()"
> >
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</mat-menu> </mat-menu>

View File

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
@ -23,6 +23,7 @@ import { AssignmentPhases, ViewAssignment } from '../../models/view-assignment';
@Component({ @Component({
selector: 'os-assignment-list', selector: 'os-assignment-list',
templateUrl: './assignment-list.component.html', templateUrl: './assignment-list.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./assignment-list.component.scss'] styleUrls: ['./assignment-list.component.scss']
}) })
export class AssignmentListComponent extends BaseListViewComponent<ViewAssignment> implements OnInit { export class AssignmentListComponent extends BaseListViewComponent<ViewAssignment> implements OnInit {

View File

@ -111,7 +111,7 @@
<os-projector-button [menuItem]="true" [object]="poll" *osPerms="'core.can_manage_projector'"></os-projector-button> <os-projector-button [menuItem]="true" [object]="poll" *osPerms="'core.can_manage_projector'"></os-projector-button>
<button *osPerms="'assignments.can_manage'" mat-menu-item (click)="openDialog(poll)"> <button *osPerms="'assignments.can_manage'" mat-menu-item (click)="openDialog(poll)">
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
<span translate>Edit</span> <span>{{ 'Edit' | translate }}</span>
</button> </button>
<button <button
mat-menu-item mat-menu-item
@ -119,11 +119,11 @@
(click)="pseudoanonymizePoll()" (click)="pseudoanonymizePoll()"
> >
<mat-icon>warning</mat-icon> <mat-icon>warning</mat-icon>
<span translate>Anonymize votes</span> <span>{{ 'Anonymize votes' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button *osPerms="'assignments.can_manage'" mat-menu-item (click)="deletePoll()"> <button *osPerms="'assignments.can_manage'" mat-menu-item (click)="deletePoll()">
<mat-icon color="warn">delete</mat-icon> <mat-icon color="warn">delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>

View File

@ -68,11 +68,9 @@
<!-- Publish Check --> <!-- Publish Check -->
<div class="spacer-top-20"> <div class="spacer-top-20">
<mat-checkbox [(ngModel)]="publishImmediately" (change)="publishStateChanged($event.checked)"> <mat-checkbox [(ngModel)]="publishImmediately" (change)="publishStateChanged($event.checked)">
<span translate>Publish immediately</span> <span>{{ 'Publish immediately' | translate }}</span>
</mat-checkbox> </mat-checkbox>
<mat-error *ngIf="!dialogVoteForm.valid" translate> <mat-error *ngIf="!dialogVoteForm.valid"> {{ 'Error in form field.' | translate }}</mat-error>
Error in form field.
</mat-error>
</div> </div>
</ng-container> </ng-container>
@ -85,11 +83,11 @@
*ngIf="pollForm && dialogVoteForm && pollForm.contentForm" *ngIf="pollForm && dialogVoteForm && pollForm.contentForm"
[disabled]="pollForm.contentForm.invalid || dialogVoteForm.invalid" [disabled]="pollForm.contentForm.invalid || dialogVoteForm.invalid"
> >
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<!-- Cancel Button --> <!-- Cancel Button -->
<button mat-button [mat-dialog-close]="false"> <button mat-button [mat-dialog-close]="false">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>

View File

@ -103,7 +103,7 @@
<div *osPerms="'assignments.can_manage'"> <div *osPerms="'assignments.can_manage'">
<button mat-menu-item (click)="openDialog()"> <button mat-menu-item (click)="openDialog()">
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
<span translate>Edit</span> <span>{{ 'Edit' | translate }}</span>
</button> </button>
</div> </div>
<div *osPerms="'core.can_manage_projector'"> <div *osPerms="'core.can_manage_projector'">
@ -112,17 +112,17 @@
<div *osPerms="'assignments.can_manage'"> <div *osPerms="'assignments.can_manage'">
<button mat-menu-item (click)="printBallot()"> <button mat-menu-item (click)="printBallot()">
<mat-icon>picture_as_pdf</mat-icon> <mat-icon>picture_as_pdf</mat-icon>
<span translate>Ballot papers</span> <span>{{ 'Ballot papers' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<!-- Reset Button --> <!-- Reset Button -->
<button mat-menu-item (click)="resetState()"> <button mat-menu-item (click)="resetState()">
<mat-icon color="warn">replay</mat-icon> <mat-icon color="warn">replay</mat-icon>
<span translate>Reset state</span> <span>{{ 'Reset state' | translate }}</span>
</button> </button>
<button mat-menu-item class="red-warning-text" (click)="onDeletePoll()"> <button mat-menu-item class="red-warning-text" (click)="onDeletePoll()">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</mat-menu> </mat-menu>

View File

@ -1,22 +1,24 @@
<mat-card class="os-card" *osPerms="'users.can_manage'"> <mat-card class="os-card" *osPerms="'users.can_manage'">
<button type="button" mat-button (click)="countUsers()" *ngIf="!this.token"> <button type="button" mat-button (click)="countUsers()" *ngIf="!this.token">
<span translate>Count active users</span> <span>{{ 'Count active users' | translate }}</span>
</button> </button>
<button type="button" mat-button (click)="stopCounting()" *ngIf="this.token"> <button type="button" mat-button (click)="stopCounting()" *ngIf="this.token">
<span translate>Stop counting</span> <span>{{ 'Stop counting' | translate }}</span>
</button> </button>
<div *ngIf="stats"> <div *ngIf="stats">
<p> <p>
{{ userIds().length }} <span translate>active users</span> ({{ stats.activeUserHandles }} {{ userIds().length }} <span>{{ 'active users' | translate }}</span> ({{ stats.activeUserHandles }}
<span translate>connections</span>) <span>{{ 'connections' | translate }}</span
>)
</p> </p>
<h3 translate>Groups</h3> <h3>{{ 'Groups' | translate }}</h3>
<ul> <ul>
<li *ngFor="let groupId of groupIds()"> <li *ngFor="let groupId of groupIds()">
<strong>{{ stats.groups[groupId].name }}</strong> <strong>{{ stats.groups[groupId].name }}</strong>
<span> : {{ userInGroupIds(groupId).length }} </span> <span> : {{ userInGroupIds(groupId).length }} </span>
<span translate>active users</span> <span>{{ 'active users' | translate }}</span>
(<span>{{ stats.groups[groupId].userHandleCount }}</span> <span translate>connections</span>) (<span>{{ stats.groups[groupId].userHandleCount }}</span> <span>{{ 'connections' | translate }}</span
>)
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -1,9 +1,9 @@
<os-head-bar> <os-head-bar>
<div class="title-slot"> <div class="title-slot">
<h2 translate>Error</h2> <h2>{{ 'Error' | translate }}</h2>
</div> </div>
</os-head-bar> </os-head-bar>
<mat-card class="os-card"> <mat-card class="os-card">
<h1 translate>You do not have the required permission to see that page!</h1> <h1>{{ 'You do not have the required permission to see that page!' | translate }}</h1>
</mat-card> </mat-card>

View File

@ -10,7 +10,7 @@
(saveEvent)="saveChanges()" (saveEvent)="saveChanges()"
> >
<div class="title-slot"> <div class="title-slot">
<h2 translate>Legal notice</h2> <h2>{{ 'Legal notice' | translate }}</h2>
</div> </div>
</os-head-bar> </os-head-bar>
@ -23,13 +23,13 @@
<mat-card class="os-card"> <mat-card class="os-card">
<div> <div>
<button type="button" mat-button (click)="resetCache()"> <button type="button" mat-button (click)="resetCache()">
<span translate>Reset cache</span> <span>{{ 'Reset cache' | translate }}</span>
</button> </button>
</div> </div>
<div> <div>
<button type="button" mat-button (click)="checkForUpdate()"> <button type="button" mat-button (click)="checkForUpdate()">
<span translate>Check for updates</span> <span>{{ 'Check for updates' | translate }}</span>
</button> </button>
</div> </div>
</mat-card> </mat-card>

View File

@ -10,7 +10,7 @@
(saveEvent)="saveChanges()" (saveEvent)="saveChanges()"
> >
<div class="title-slot"> <div class="title-slot">
<h2 translate>Privacy Policy</h2> <h2>{{ 'Privacy Policy' | translate }}</h2>
</div> </div>
</os-head-bar> </os-head-bar>

View File

@ -8,7 +8,7 @@
(cancelEditEvent)="isEditing = !isEditing" (cancelEditEvent)="isEditing = !isEditing"
> >
<div class="title-slot"> <div class="title-slot">
<h2 translate>Home</h2> <h2>{{ 'Home' | translate }}</h2>
</div> </div>
</os-head-bar> </os-head-bar>
@ -30,7 +30,7 @@
required required
placeholder="{{ 'Front page title' | translate }}" placeholder="{{ 'Front page title' | translate }}"
/> />
<mat-error translate>The title is required</mat-error> <mat-error>{{ 'The title is required' | translate }}</mat-error>
</mat-form-field> </mat-form-field>
<editor formControlName="general_event_welcome_text" [init]="tinyMceSettings"></editor> <editor formControlName="general_event_welcome_text" [init]="tinyMceSettings"></editor>
</form> </form>

View File

@ -90,7 +90,7 @@
</ng-container> </ng-container>
</mat-accordion> </mat-accordion>
<div class="no-results" *ngIf="!selectedModel && searchString.length > 0"> <div class="no-results" *ngIf="!selectedModel && searchString.length > 0">
<span translate>No search result found</span> <span>{{ 'No search result found' | translate }}</span>
<span *ngIf="searchCollection" <span *ngIf="searchCollection"
>&nbsp;({{ 'with filter' | translate }} "{{ searchCollection | translate }}")</span >&nbsp;({{ 'with filter' | translate }} "{{ searchCollection | translate }}")</span
>. >.

View File

@ -40,6 +40,6 @@
<mat-menu #settingsMenu="matMenu"> <mat-menu #settingsMenu="matMenu">
<button mat-menu-item (click)="resetAll()"> <button mat-menu-item (click)="resetAll()">
<mat-icon>undo</mat-icon> <mat-icon>undo</mat-icon>
<span translate>Reset to factory defaults</span> <span>{{ 'Reset to factory defaults' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>

View File

@ -1,7 +1,7 @@
<os-head-bar [isSearchEnabled]="false"> <os-head-bar [isSearchEnabled]="false">
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 translate>Settings</h2> <h2>{{ 'Settings' | translate }}</h2>
</div> </div>
<!-- Menu --> <!-- Menu -->
<div class="menu-slot"> <div class="menu-slot">
@ -45,6 +45,6 @@
<mat-menu #settingsMenu="matMenu"> <mat-menu #settingsMenu="matMenu">
<button mat-menu-item (click)="resetAll()"> <button mat-menu-item (click)="resetAll()">
<mat-icon>undo</mat-icon> <mat-icon>undo</mat-icon>
<span translate>Reset to factory defaults</span> <span>{{ 'Reset to factory defaults' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>

View File

@ -7,12 +7,12 @@
<ng-container [formGroupName]="i"> <ng-container [formGroupName]="i">
<mat-form-field> <mat-form-field>
<input formControlName="original" matInput placeholder="{{ 'Original' | translate }}" /> <input formControlName="original" matInput placeholder="{{ 'Original' | translate }}" />
<mat-error translate>You have to fill this field.</mat-error> <mat-error>{{ 'You have to fill this field.' | translate }}</mat-error>
</mat-form-field> </mat-form-field>
<mat-icon>arrow_forward</mat-icon> <mat-icon>arrow_forward</mat-icon>
<mat-form-field> <mat-form-field>
<input formControlName="translation" matInput placeholder="{{ 'Translation' | translate }}" /> <input formControlName="translation" matInput placeholder="{{ 'Translation' | translate }}" />
<mat-error translate>You have to fill this field.</mat-error> <mat-error>{{ 'You have to fill this field.' | translate }}</mat-error>
</mat-form-field> </mat-form-field>
<button <button
mat-icon-button mat-icon-button

View File

@ -1,6 +1,6 @@
<os-head-bar> <os-head-bar>
<!-- Title --> <!-- Title -->
<div class="title-slot" translate>History</div> <div class="title-slot">{{ 'History' | translate }}</div>
<!-- Menu --> <!-- Menu -->
<div class="menu-slot"> <div class="menu-slot">
@ -27,7 +27,7 @@
<span class="spacer-left-20"> <span class="spacer-left-20">
<button mat-button (click)="refresh()" *ngIf="currentModelId"> <button mat-button (click)="refresh()" *ngIf="currentModelId">
<mat-icon>refresh</mat-icon> <mat-icon>refresh</mat-icon>
<span translate>Refresh</span> <span>{{ 'Refresh' | translate }}</span>
</button> </button>
</span> </span>
</div> </div>
@ -42,13 +42,13 @@
<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 translate>Timestamp</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 translate>Element</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
@ -63,13 +63,13 @@
<!-- Info --> <!-- Info -->
<ng-container matColumnDef="info"> <ng-container matColumnDef="info">
<mat-header-cell *matHeaderCellDef translate>Comment</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 translate>Changed by</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>
@ -82,6 +82,6 @@
<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()">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete whole history</span> <span>{{ 'Delete whole history' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>

View File

@ -1,5 +1,5 @@
<main> <main>
<h1 class="center spacer-top-20" translate>Legal notice</h1> <h1 class="center spacer-top-20">{{ 'Legal notice' | translate }}</h1>
<os-legal-notice-content></os-legal-notice-content> <os-legal-notice-content></os-legal-notice-content>
</main> </main>

View File

@ -1,5 +1,5 @@
<main> <main>
<h1 class="center spacer-top-20" translate>Privacy Policy</h1> <h1 class="center spacer-top-20">{{ 'Privacy Policy' | translate }}</h1>
<os-privacy-policy-content></os-privacy-policy-content> <os-privacy-policy-content></os-privacy-policy-content>
</main> </main>

View File

@ -1,16 +1,22 @@
<!-- The actual form --> <!-- The actual form -->
<header> <header>
<mat-toolbar class="login-logo-bar" color="primary"> <mat-toolbar class="login-logo-bar" color="primary">
<a routerLink="/login"><img src="assets/img/openslides-logo-dark.svg" alt="OpenSlides-logo"></a> <a routerLink="/login"><img src="assets/img/openslides-logo-dark.svg" alt="OpenSlides-logo" /></a>
</mat-toolbar> </mat-toolbar>
</header> </header>
<main> <main>
<router-outlet></router-outlet> <router-outlet></router-outlet>
</main> </main>
<div class="footer"> <div class="footer">
<a href='https://openslides.com' target='_bank'>© Copyright by OpenSlides</a> <a href="https://openslides.com" target="_bank">© Copyright by OpenSlides</a>
&middot; &middot;
<a routerLink='/login/legalnotice' translate>Legal notice</a> <a routerLink="/login/legalnotice">
{{ 'Legal notice' | translate }}
</a>
&middot; &middot;
<a routerLink='/login/privacypolicy' translate>Privacy policy</a> <a routerLink="/login/privacypolicy">
{{ 'Privacy policy' | translate }}
</a>
</div> </div>

View File

@ -1,6 +1,6 @@
<div class="form-wrapper"> <div class="form-wrapper">
<form [formGroup]="newPasswordForm" (ngSubmit)="submitNewPassword()" autocomplete="off"> <form [formGroup]="newPasswordForm" (ngSubmit)="submitNewPassword()" autocomplete="off">
<h3 translate>Please enter your new password</h3> <h3>{{ 'Please enter your new password' | translate }}</h3>
<mat-form-field> <mat-form-field>
<input <input
matInput matInput
@ -10,8 +10,8 @@
formControlName="password" formControlName="password"
type="password" type="password"
/> />
<mat-error *ngIf="newPasswordForm.get('password').hasError('required')" translate> <mat-error *ngIf="newPasswordForm.get('password').hasError('required')">
A password is required {{ 'A password is required' | translate }}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<br /> <br />

View File

@ -1,6 +1,6 @@
<div class="form-wrapper"> <div class="form-wrapper">
<form [formGroup]="resetPasswordForm" (ngSubmit)="resetPassword()" autocomplete="off"> <form [formGroup]="resetPasswordForm" (ngSubmit)="resetPassword()" autocomplete="off">
<h3 translate>Enter your email to send the password reset link</h3> <h3>{{ 'Enter your email to send the password reset link' | translate }}</h3>
<mat-form-field> <mat-form-field>
<input <input
matInput matInput
@ -10,8 +10,8 @@
type="email" type="email"
autocomplete="off" autocomplete="off"
/> />
<mat-error *ngIf="resetPasswordForm.get('email').invalid" translate> <mat-error *ngIf="resetPasswordForm.get('email').invalid">
Please enter a valid email address! {{ 'Please enter a valid email address!' | translate }}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<br /> <br />

View File

@ -1,6 +1,8 @@
<os-head-bar [nav]="false" [goBack]="true"> <os-head-bar [nav]="false" [goBack]="true">
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Upload files</h2></div> <div class="title-slot">
<h2>{{ 'Upload files' | translate }}</h2>
</div>
<!-- Menu --> <!-- Menu -->
<div class="menu-slot"> <div class="menu-slot">
@ -23,6 +25,6 @@
<!-- Select upload strategy --> <!-- Select upload strategy -->
<button mat-menu-item (click)="setUploadStrategy(!parallel)"> <button mat-menu-item (click)="setUploadStrategy(!parallel)">
<mat-icon color="accent">{{ parallel ? 'check_box' : 'check_box_outline_blank' }}</mat-icon> <mat-icon color="accent">{{ parallel ? 'check_box' : 'check_box_outline_blank' }}</mat-icon>
<span translate>Parallel upload</span> <span>{{ 'Parallel upload' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>

View File

@ -1,7 +1,7 @@
<os-head-bar [hasMainButton]="canEdit" [multiSelectMode]="isMultiSelect" (mainEvent)="onMainEvent()"> <os-head-bar [hasMainButton]="canEdit" [multiSelectMode]="isMultiSelect" (mainEvent)="onMainEvent()">
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 translate>Files</h2> <h2>{{ 'Files' | translate }}</h2>
</div> </div>
<!-- Menu --> <!-- Menu -->
@ -17,7 +17,7 @@
<!-- Multiselect info --> <!-- Multiselect info -->
<div *ngIf="isMultiSelect" class="central-info-slot"> <div *ngIf="isMultiSelect" class="central-info-slot">
<button mat-icon-button (click)="toggleMultiSelect()"><mat-icon>arrow_back</mat-icon></button> <button mat-icon-button (click)="toggleMultiSelect()"><mat-icon>arrow_back</mat-icon></button>
<span>{{ selectedRows.length }}&nbsp;</span><span translate>selected</span> <span>{{ selectedRows.length }}&nbsp;</span><span>{{ 'selected' | translate }}</span>
</div> </div>
</os-head-bar> </os-head-bar>
@ -93,7 +93,12 @@
> >
<!-- Icon column --> <!-- Icon column -->
<div *pblNgridCellDef="'icon'; row as mediafile" class="fill clickable"> <div *pblNgridCellDef="'icon'; row as mediafile" class="fill clickable">
<a class="detail-link" target="_blank" [routerLink]="mediafile.url" *ngIf="!mediafile.is_directory && !isMultiSelect"> <a
class="detail-link"
target="_blank"
[routerLink]="mediafile.url"
*ngIf="!mediafile.is_directory && !isMultiSelect"
>
</a> </a>
<a class="detail-link" (click)="changeDirectory(mediafile.id)" *ngIf="mediafile.is_directory && !isMultiSelect"> <a class="detail-link" (click)="changeDirectory(mediafile.id)" *ngIf="mediafile.is_directory && !isMultiSelect">
</a> </a>
@ -102,7 +107,12 @@
<!-- Title column --> <!-- Title column -->
<div *pblNgridCellDef="'title'; row as mediafile" class="fill clickable"> <div *pblNgridCellDef="'title'; row as mediafile" class="fill clickable">
<a class="detail-link" target="_blank" [routerLink]="mediafile.url" *ngIf="!mediafile.is_directory && !isMultiSelect"> <a
class="detail-link"
target="_blank"
[routerLink]="mediafile.url"
*ngIf="!mediafile.is_directory && !isMultiSelect"
>
</a> </a>
<a class="detail-link" (click)="changeDirectory(mediafile.id)" *ngIf="mediafile.is_directory && !isMultiSelect"> <a class="detail-link" (click)="changeDirectory(mediafile.id)" *ngIf="mediafile.is_directory && !isMultiSelect">
</a> </a>
@ -155,7 +165,7 @@
<!-- No Results --> <!-- No Results -->
<div *pblNgridNoDataRef class="pbl-ngrid-no-data"> <div *pblNgridNoDataRef class="pbl-ngrid-no-data">
<span translate>No data</span> <span>{{ 'No data' | translate }}</span>
</div> </div>
</pbl-ngrid> </pbl-ngrid>
@ -203,15 +213,15 @@
<div *ngIf="canEdit"> <div *ngIf="canEdit">
<button mat-menu-item (click)="onEditFile(mediafile)"> <button mat-menu-item (click)="onEditFile(mediafile)">
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
<span translate>Edit</span> <span>{{ 'Edit' | translate }}</span>
</button> </button>
<button mat-menu-item (click)="move(moveDialog, [mediafile])"> <button mat-menu-item (click)="move(moveDialog, [mediafile])">
<mat-icon>near_me</mat-icon> <mat-icon>near_me</mat-icon>
<span translate>Move</span> <span>{{ 'Move' | translate }}</span>
</button> </button>
<button mat-menu-item class="red-warning-text" (click)="onDelete(mediafile)"> <button mat-menu-item class="red-warning-text" (click)="onDelete(mediafile)">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>
@ -222,22 +232,22 @@
<div *ngIf="!isMultiSelect"> <div *ngIf="!isMultiSelect">
<button mat-menu-item *osPerms="'mediafiles.can_manage'" (click)="toggleMultiSelect()"> <button mat-menu-item *osPerms="'mediafiles.can_manage'" (click)="toggleMultiSelect()">
<mat-icon>library_add</mat-icon> <mat-icon>library_add</mat-icon>
<span translate>Multiselect</span> <span>{{ 'Multiselect' | translate }}</span>
</button> </button>
</div> </div>
<div *ngIf="isMultiSelect"> <div *ngIf="isMultiSelect">
<button mat-menu-item [disabled]="!selectedRows.length" (click)="move(moveDialog, selectedRows)"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="move(moveDialog, selectedRows)">
<mat-icon>near_me</mat-icon> <mat-icon>near_me</mat-icon>
<span translate>Move</span> <span>{{ 'Move' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button mat-menu-item (click)="selectAll()"> <button mat-menu-item (click)="selectAll()">
<mat-icon>done_all</mat-icon> <mat-icon>done_all</mat-icon>
<span translate>Select all</span> <span>{{ 'Select all' | translate }}</span>
</button> </button>
<button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()">
<mat-icon>clear</mat-icon> <mat-icon>clear</mat-icon>
<span translate>Deselect all</span> <span>{{ 'Deselect all' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button <button
@ -247,7 +257,7 @@
(click)="deleteSelected()" (click)="deleteSelected()"
> >
<mat-icon color="warn">delete</mat-icon> <mat-icon color="warn">delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</mat-menu> </mat-menu>
@ -266,7 +276,7 @@
formControlName="title" formControlName="title"
placeholder="{{ 'New file name' | translate }}" placeholder="{{ 'New file name' | translate }}"
/> />
<mat-error *ngIf="fileEditForm.invalid" translate>Required</mat-error> <mat-error *ngIf="fileEditForm.invalid">{{ 'Required' | translate }}</mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
@ -287,10 +297,10 @@
color="primary" color="primary"
(click)="onSaveEditedFile(fileEditForm.value)" (click)="onSaveEditedFile(fileEditForm.value)"
> >
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>
@ -300,7 +310,7 @@
<h1 mat-dialog-title>{{ 'New directory' | translate }}</h1> <h1 mat-dialog-title>{{ 'New directory' | translate }}</h1>
<div class="os-form-card-mobile" mat-dialog-content> <div class="os-form-card-mobile" mat-dialog-content>
<form class="edit-file-form" [formGroup]="newDirectoryForm"> <form class="edit-file-form" [formGroup]="newDirectoryForm">
<p translate>Please enter a name for the new directory:</p> <p>{{ 'Please enter a name for the new directory:' | translate }}</p>
<mat-form-field> <mat-form-field>
<input matInput osAutofocus formControlName="title" placeholder="{{ 'Title' | translate }}" required /> <input matInput osAutofocus formControlName="title" placeholder="{{ 'Title' | translate }}" required />
</mat-form-field> </mat-form-field>
@ -317,10 +327,10 @@
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button type="submit" mat-button [disabled]="!newDirectoryForm.valid" color="primary" [mat-dialog-close]="true"> <button type="submit" mat-button [disabled]="!newDirectoryForm.valid" color="primary" [mat-dialog-close]="true">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>
@ -328,10 +338,10 @@
<!-- Move dialog --> <!-- Move dialog -->
<ng-template #moveDialog> <ng-template #moveDialog>
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span translate>Move into directory</span> <span>{{ 'Move into directory' | translate }}</span>
</h1> </h1>
<div class="os-form-card-mobile" [formGroup]="moveForm" mat-dialog-content> <div class="os-form-card-mobile" [formGroup]="moveForm" mat-dialog-content>
<p translate>Please select the directory:</p> <p>{{ 'Please select the directory:' | translate }}</p>
<mat-form-field> <mat-form-field>
<os-search-value-selector <os-search-value-selector
formControlName="directory_id" formControlName="directory_id"
@ -344,10 +354,10 @@
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button type="submit" mat-button color="primary" [mat-dialog-close]="true"> <button type="submit" mat-button color="primary" [mat-dialog-close]="true">
<span translate>Move</span> <span>{{ 'Move' | translate }}</span>
</button> </button>
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -1,6 +1,8 @@
<os-head-bar prevUrl="../.." [nav]="false" [multiSelectMode]="isMultiSelect"> <os-head-bar prevUrl="../.." [nav]="false" [multiSelectMode]="isMultiSelect">
<!-- Title --> <!-- Title -->
<div class="title-slot" *ngIf="!parentMotion"><h2 translate>Amendments</h2></div> <div class="title-slot" *ngIf="!parentMotion">
<h2>{{ 'Amendments' | translate }}</h2>
</div>
<!-- TODO would require translations with parameters --> <!-- TODO would require translations with parameters -->
<div class="title-slot" *ngIf="parentMotion"> <div class="title-slot" *ngIf="parentMotion">
@ -20,7 +22,7 @@
<!-- Multiselect info --> <!-- Multiselect info -->
<div class="central-info-slot"> <div class="central-info-slot">
<button mat-icon-button (click)="toggleMultiSelect()"><mat-icon>arrow_back</mat-icon></button> <button mat-icon-button (click)="toggleMultiSelect()"><mat-icon>arrow_back</mat-icon></button>
<span>{{ selectedRows.length }}&nbsp;</span><span translate>selected</span> <span>{{ selectedRows.length }}&nbsp;</span><span>{{ 'selected' | translate }}</span>
</div> </div>
</os-head-bar> </os-head-bar>
@ -45,7 +47,7 @@
<span>{{ motion.identifier }}</span> <span>{{ motion.identifier }}</span>
<span *ngIf="motion.diffLines && motion.diffLines.length"> <span *ngIf="motion.diffLines && motion.diffLines.length">
<span *ngIf="motion.identifier">&nbsp;&middot;&nbsp;</span> <span *ngIf="motion.identifier">&nbsp;&middot;&nbsp;</span>
<span translate>Line</span> <span>{{ 'Line' | translate }}</span>
<span>&nbsp;{{ motion.getChangeLines() }}</span> <span>&nbsp;{{ motion.getChangeLines() }}</span>
</span> </span>
</div> </div>
@ -53,14 +55,14 @@
<!-- Submitter --> <!-- Submitter -->
<div class="submitters-line one-line"> <div class="submitters-line one-line">
<span *ngIf="motion.submitters.length"> <span *ngIf="motion.submitters.length">
<span translate>by</span> <span>{{ 'by' | translate }}</span>
{{ motion.submitters }} {{ motion.submitters }}
</span> </span>
<span *ngIf="motion.submitters.length"> <span *ngIf="motion.submitters.length">
&middot; &middot;
</span> </span>
<span translate>Sequential number</span> <span>{{ 'Sequential number' | translate }}</span>
{{ motion.id }} {{ motion.id }}
</div> </div>
@ -115,26 +117,26 @@
<div *osPerms="'motions.can_manage'"> <div *osPerms="'motions.can_manage'">
<button mat-menu-item (click)="toggleMultiSelect()"> <button mat-menu-item (click)="toggleMultiSelect()">
<mat-icon>library_add</mat-icon> <mat-icon>library_add</mat-icon>
<span translate>Multiselect</span> <span>{{ 'Multiselect' | translate }}</span>
</button> </button>
</div> </div>
<button mat-menu-item (click)="openExportDialog()"> <button mat-menu-item (click)="openExportDialog()">
<mat-icon>archive</mat-icon> <mat-icon>archive</mat-icon>
<span translate>Export</span> <span>{{ 'Export' | translate }}</span>
</button> </button>
<button mat-menu-item (click)="exportAmendmentListPdf()"> <button mat-menu-item (click)="exportAmendmentListPdf()">
<mat-icon>picture_as_pdf</mat-icon> <mat-icon>picture_as_pdf</mat-icon>
<span translate>Amendment list (PDF)</span> <span>{{ 'Amendment list (PDF)' | translate }}</span>
</button> </button>
</div> </div>
<div *ngIf="isMultiSelect"> <div *ngIf="isMultiSelect">
<button mat-menu-item (click)="selectAll()"> <button mat-menu-item (click)="selectAll()">
<mat-icon>done_all</mat-icon> <mat-icon>done_all</mat-icon>
<span translate>Select all</span> <span>{{ 'Select all' | translate }}</span>
</button> </button>
<button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()">
<mat-icon>clear</mat-icon> <mat-icon>clear</mat-icon>
<span translate>Deselect all</span> <span>{{ 'Deselect all' | translate }}</span>
</button> </button>
<ng-container *osPerms="'motions.can_manage'; or: 'motions.can_manage_metadata'"> <ng-container *osPerms="'motions.can_manage'; or: 'motions.can_manage_metadata'">

View File

@ -1,7 +1,7 @@
<os-head-bar prevUrl="../.." [nav]="false" [editMode]="hasChanged" (mainEvent)="onCancel()" (saveEvent)="onSave()"> <os-head-bar prevUrl="../.." [nav]="false" [editMode]="hasChanged" (mainEvent)="onCancel()" (saveEvent)="onSave()">
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 translate>Call list</h2> <h2>{{ 'Call list' | translate }}</h2>
</div> </div>
<!-- Export menu --> <!-- Export menu -->
@ -14,15 +14,18 @@
<div class="custom-table-header flex-spaced"> <div class="custom-table-header flex-spaced">
<div class="filter-count"> <div class="filter-count">
<span> {{ seenNodes[0] }}&nbsp;</span><span translate>of</span> <span> {{ seenNodes[0] }}&nbsp;</span><span>{{ 'of' | translate }}</span>
<span>&nbsp;{{ seenNodes[1] }}</span> <span>&nbsp;{{ seenNodes[1] }}</span>
</div> </div>
<div class="current-filters" *ngIf="hasActiveFilter"> <div class="current-filters" *ngIf="hasActiveFilter">
<div><span translate>Active filters</span>:&nbsp;</div> <div>
<span>{{ 'Active filters' | translate }}</span
>:&nbsp;
</div>
<div> <div>
<button mat-button (click)="resetFilters()"> <button mat-button (click)="resetFilters()">
<mat-icon inline>cancel</mat-icon> <mat-icon inline>cancel</mat-icon>
<span translate>Clear all</span> <span>{{ 'Clear all' | translate }}</span>
</button> </button>
</div> </div>
</div> </div>
@ -34,9 +37,8 @@
[matBadge]="activeCatFilterCount > 0 ? activeCatFilterCount : null" [matBadge]="activeCatFilterCount > 0 ? activeCatFilterCount : null"
matBadgeColor="accent" matBadgeColor="accent"
[matBadgeOverlap]="false" [matBadgeOverlap]="false"
translate
> >
Categories {{ 'Categories' | translate }}
</span> </span>
</button> </button>
</div> </div>
@ -47,9 +49,8 @@
[matBadge]="activeTagFilterCount > 0 ? activeTagFilterCount : null" [matBadge]="activeTagFilterCount > 0 ? activeTagFilterCount : null"
matBadgeColor="accent" matBadgeColor="accent"
[matBadgeOverlap]="false" [matBadgeOverlap]="false"
translate
> >
Tags {{ 'Tags' | translate }}
</span> </span>
</button> </button>
</div> </div>
@ -103,18 +104,18 @@
<mat-menu #mainMenu="matMenu"> <mat-menu #mainMenu="matMenu">
<button mat-menu-item (click)="sortMotionsByIdentifier()"> <button mat-menu-item (click)="sortMotionsByIdentifier()">
<mat-icon>sort</mat-icon> <mat-icon>sort</mat-icon>
<span translate>Sort by identifier</span> <span>{{ 'Sort by identifier' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button mat-menu-item (click)="pdfExportCallList()"> <button mat-menu-item (click)="pdfExportCallList()">
<mat-icon>picture_as_pdf</mat-icon> <mat-icon>picture_as_pdf</mat-icon>
<span translate>Export as PDF</span> <span>{{ 'Export as PDF' | translate }}</span>
</button> </button>
<button mat-menu-item (click)="csvExportCallList()"> <button mat-menu-item (click)="csvExportCallList()">
<mat-icon>archive</mat-icon> <mat-icon>archive</mat-icon>
<span translate>Export as CSV</span> <span>{{ 'Export as CSV' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>

View File

@ -1,11 +1,7 @@
<os-head-bar <os-head-bar [editMode]="hasChanged" (saveEvent)="onSave()" (mainEvent)="onCancel()" [nav]="false">
[editMode]="hasChanged"
(saveEvent)="onSave()"
(mainEvent)="onCancel()"
[nav]="false">
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 translate>Sort categories</h2> <h2>{{ 'Sort categories' | translate }}</h2>
</div> </div>
</os-head-bar> </os-head-bar>
@ -15,7 +11,8 @@
parentKey="parent_id" parentKey="parent_id"
weightKey="weight" weightKey="weight"
(hasChanged)="receiveChanges($event)" (hasChanged)="receiveChanges($event)"
[model]="categoriesObservable"> [model]="categoriesObservable"
>
<ng-template #innerNode let-item="item"> <ng-template #innerNode let-item="item">
{{ item.getTitle() }} {{ item.getTitle() }}
</ng-template> </ng-template>

View File

@ -25,7 +25,9 @@
<table class="os-headed-listview-table" mat-table [dataSource]="dataSources[category.id]"> <table class="os-headed-listview-table" mat-table [dataSource]="dataSources[category.id]">
<!-- title column --> <!-- title column -->
<ng-container matColumnDef="title"> <ng-container matColumnDef="title">
<mat-header-cell *matHeaderCellDef> <span translate>Motion</span> </mat-header-cell> <mat-header-cell *matHeaderCellDef>
<span>{{ 'Motion' | translate }}</span>
</mat-header-cell>
<mat-cell *matCellDef="let motion"> <mat-cell *matCellDef="let motion">
{{ motion.getTitle() }} {{ motion.getTitle() }}
</mat-cell> </mat-cell>
@ -33,7 +35,9 @@
<!-- state column --> <!-- state column -->
<ng-container matColumnDef="state"> <ng-container matColumnDef="state">
<mat-header-cell *matHeaderCellDef> <span translate>State</span> </mat-header-cell> <mat-header-cell *matHeaderCellDef>
<span>{{ 'State' | translate }}</span>
</mat-header-cell>
<mat-cell class="chip-container" *matCellDef="let motion"> <mat-cell class="chip-container" *matCellDef="let motion">
<mat-basic-chip disableRipple [ngClass]="motion.stateCssColor"> <mat-basic-chip disableRipple [ngClass]="motion.stateCssColor">
{{ getStateLabel(motion) }} {{ getStateLabel(motion) }}
@ -43,7 +47,9 @@
<!-- Recommendation column --> <!-- Recommendation column -->
<ng-container matColumnDef="recommendation"> <ng-container matColumnDef="recommendation">
<mat-header-cell *matHeaderCellDef> <span translate>Recommendation</span> </mat-header-cell> <mat-header-cell *matHeaderCellDef>
<span>{{ 'Recommendation' | translate }}</span>
</mat-header-cell>
<mat-cell class="chip-container" *matCellDef="let motion"> <mat-cell class="chip-container" *matCellDef="let motion">
<mat-basic-chip *ngIf="motion.recommendation" disableRipple class="bluegrey"> <mat-basic-chip *ngIf="motion.recommendation" disableRipple class="bluegrey">
{{ getRecommendationLabel(motion) }} {{ getRecommendationLabel(motion) }}
@ -69,20 +75,20 @@
<mat-menu #categoryMenu="matMenu"> <mat-menu #categoryMenu="matMenu">
<button mat-menu-item (click)="toggleEditMode()"> <button mat-menu-item (click)="toggleEditMode()">
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
<span translate>Edit</span> <span>{{ 'Edit' | translate }}</span>
</button> </button>
<button mat-menu-item [routerLink]="'./sort'"> <button mat-menu-item [routerLink]="'./sort'">
<mat-icon>sort</mat-icon> <mat-icon>sort</mat-icon>
<span translate>Sort motions</span> <span>{{ 'Sort motions' | translate }}</span>
</button> </button>
<button mat-menu-item (click)="numberMotions()"> <button mat-menu-item (click)="numberMotions()">
<mat-icon>format_list_numbered</mat-icon> <mat-icon>format_list_numbered</mat-icon>
<span translate>Number motions</span> <span>{{ 'Number motions' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button mat-menu-item class="red-warning-text" (click)="onDeleteButton()"> <button mat-menu-item class="red-warning-text" (click)="onDeleteButton()">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>
@ -102,10 +108,10 @@
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button type="submit" mat-button [disabled]="!editForm.valid" color="primary" (click)="save()"> <button type="submit" mat-button [disabled]="!editForm.valid" color="primary" (click)="save()">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -1,7 +1,7 @@
<os-head-bar prevUrl="../.." [nav]="false" [hasMainButton]="canEdit" (mainEvent)="onPlusButton()"> <os-head-bar prevUrl="../.." [nav]="false" [hasMainButton]="canEdit" (mainEvent)="onPlusButton()">
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 translate>Categories</h2> <h2>{{ 'Categories' | translate }}</h2>
</div> </div>
<!-- Menu --> <!-- Menu -->
@ -38,14 +38,14 @@
<mat-menu #categoryMenu="matMenu"> <mat-menu #categoryMenu="matMenu">
<button mat-menu-item [routerLink]="'./sort'"> <button mat-menu-item [routerLink]="'./sort'">
<mat-icon>sort</mat-icon> <mat-icon>sort</mat-icon>
<span translate>Sort categories</span> <span>{{ 'Sort categories' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>
<!-- Template for new motion block dialog --> <!-- Template for new motion block dialog -->
<ng-template #newCategoryDialog> <ng-template #newCategoryDialog>
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span translate>New category</span> <span>{{ 'New category' | translate }}</span>
</h1> </h1>
<div class="os-form-card-mobile" mat-dialog-content> <div class="os-form-card-mobile" mat-dialog-content>
<form [formGroup]="createForm" (keydown)="onKeyDown($event)"> <form [formGroup]="createForm" (keydown)="onKeyDown($event)">
@ -60,8 +60,8 @@
<p> <p>
<mat-form-field> <mat-form-field>
<input formControlName="name" matInput placeholder="{{ 'Name' | translate }}" required /> <input formControlName="name" matInput placeholder="{{ 'Name' | translate }}" required />
<mat-error *ngIf="!createForm.controls.name.valid" translate> <mat-error *ngIf="!createForm.controls.name.valid">
A name is required {{ 'A name is required' | translate }}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
</p> </p>
@ -69,10 +69,10 @@
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button mat-button [disabled]="!createForm.valid" [mat-dialog-close]="true"> <button mat-button [disabled]="!createForm.valid" [mat-dialog-close]="true">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button mat-button [mat-dialog-close]="false"> <button mat-button [mat-dialog-close]="false">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -8,8 +8,10 @@
<mat-card class="os-form-card"> <mat-card class="os-form-card">
<div *ngIf="isMultiSelect"> <div *ngIf="isMultiSelect">
<span>{{ sortSelector.multiSelectedIndex.length }}&nbsp;</span> <span>{{ sortSelector.multiSelectedIndex.length }}&nbsp;</span>
<span translate>selected</span> <span>{{ 'selected' | translate }}</span>
<button mat-button (click)="moveToPosition()"><span translate>move ...</span></button> <button mat-button (click)="moveToPosition()">
<span>{{ 'move ...' | translate }}</span>
</button>
</div> </div>
<os-sorting-list (sortEvent)="onListUpdate($event)" [input]="motionObservable" #sorter> <os-sorting-list (sortEvent)="onListUpdate($event)" [input]="motionObservable" #sorter>
<ng-template let-motion> <ng-template let-motion>

View File

@ -37,7 +37,7 @@
[disabled]="isFollowingProhibited()" [disabled]="isFollowingProhibited()"
> >
<os-icon-container icon="done_all"> <os-icon-container icon="done_all">
<span translate>Follow recommendations for all motions</span> <span>{{ 'Follow recommendations for all motions' | translate }}</span>
</os-icon-container> </os-icon-container>
</button> </button>
</div> </div>
@ -85,7 +85,7 @@
<!-- Submitters --> <!-- Submitters -->
<div class="submitters-line ellipsis-overflow"> <div class="submitters-line ellipsis-overflow">
<span *ngIf="motion.submitters.length"> <span *ngIf="motion.submitters.length">
<span translate>by</span> <span>{{ 'by' | translate }}</span>
{{ motion.submitters }} {{ motion.submitters }}
</span> </span>
@ -93,7 +93,7 @@
<span *ngIf="motion.submitters.length"> <span *ngIf="motion.submitters.length">
&middot; &middot;
</span> </span>
<span translate>Sequential number</span> <span>{{ 'Sequential number' | translate }}</span>
{{ motion.id }} {{ motion.id }}
</span> </span>
</div> </div>
@ -148,7 +148,7 @@
<os-speaker-button [object]="motion" [menuItem]="true"></os-speaker-button> <os-speaker-button [object]="motion" [menuItem]="true"></os-speaker-button>
<button mat-menu-item class="red-warning-text" (click)="onRemoveMotionButton(motion)"> <button mat-menu-item class="red-warning-text" (click)="onRemoveMotionButton(motion)">
<mat-icon>close</mat-icon> <mat-icon>close</mat-icon>
<span translate>Remove from motion block</span> <span>{{ 'Remove from motion block' | translate }}</span>
</button> </button>
</ng-template> </ng-template>
</mat-menu> </mat-menu>
@ -163,7 +163,7 @@
[disabled]="isFollowingProhibited()" [disabled]="isFollowingProhibited()"
> >
<mat-icon>done_all</mat-icon> <mat-icon>done_all</mat-icon>
<span translate>Follow recommendations for all motions</span> <span>{{ 'Follow recommendations for all motions' | translate }}</span>
</button> </button>
</div> </div>
@ -174,24 +174,24 @@
<div *osPerms="'agenda.can_manage'"> <div *osPerms="'agenda.can_manage'">
<button mat-menu-item (click)="addToAgenda()" *ngIf="block && !block.item"> <button mat-menu-item (click)="addToAgenda()" *ngIf="block && !block.item">
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
<span translate>Add to agenda</span> <span>{{ 'Add to agenda' | translate }}</span>
</button> </button>
<button mat-menu-item (click)="removeFromAgenda()" *ngIf="block && block.item"> <button mat-menu-item (click)="removeFromAgenda()" *ngIf="block && block.item">
<mat-icon>remove</mat-icon> <mat-icon>remove</mat-icon>
<span translate>Remove from agenda</span> <span>{{ 'Remove from agenda' | translate }}</span>
</button> </button>
</div> </div>
<div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']"> <div *osPerms="['motions.can_manage', 'motions.can_manage_metadata']">
<button mat-menu-item (click)="toggleEditMode()"> <button mat-menu-item (click)="toggleEditMode()">
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
<span translate>Edit</span> <span>{{ 'Edit' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button mat-menu-item class="red-warning-text" (click)="onDeleteBlockButton()"> <button mat-menu-item class="red-warning-text" (click)="onDeleteBlockButton()">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</mat-menu> </mat-menu>
@ -210,10 +210,10 @@
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button type="submit" mat-button [disabled]="!blockEditForm.valid" color="primary" (click)="saveBlock()"> <button type="submit" mat-button [disabled]="!blockEditForm.valid" color="primary" (click)="saveBlock()">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -1,6 +1,8 @@
<os-head-bar prevUrl="../.." [nav]="false" [hasMainButton]="canEdit" (mainEvent)="onPlusButton()"> <os-head-bar prevUrl="../.." [nav]="false" [hasMainButton]="canEdit" (mainEvent)="onPlusButton()">
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Motion blocks</h2></div> <div class="title-slot">
<h2>{{ 'Motion blocks' | translate }}</h2>
</div>
</os-head-bar> </os-head-bar>
<os-list-view-table <os-list-view-table
@ -28,7 +30,7 @@
[noWrap]="true" [noWrap]="true"
[icon]="block.isFinished ? 'check' : block.internal ? 'lock' : null" [icon]="block.isFinished ? 'check' : block.internal ? 'lock' : null"
size="large" size="large"
[iconTooltip]="block.isFinished ? 'Finished' : block.internal ? 'Internal' : '' | translate" [iconTooltip]="block.isFinished ? 'Finished' : block.internal ? 'Internal' : ('' | translate)"
> >
<os-icon-container <os-icon-container
[noWrap]="true" [noWrap]="true"
@ -75,21 +77,23 @@
<!-- Template for new motion block dialog --> <!-- Template for new motion block dialog -->
<ng-template #newMotionBlockDialog> <ng-template #newMotionBlockDialog>
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span translate>New motion block</span> <span>{{ 'New motion block' | translate }}</span>
</h1> </h1>
<form [formGroup]="createBlockForm" (keydown)="onKeyDown($event)"> <form [formGroup]="createBlockForm" (keydown)="onKeyDown($event)">
<div mat-dialog-content> <div mat-dialog-content>
<!-- Title --> <!-- Title -->
<mat-form-field> <mat-form-field>
<input formControlName="title" matInput placeholder="{{ 'Title' | translate }}" required /> <input formControlName="title" matInput placeholder="{{ 'Title' | translate }}" required />
<mat-error *ngIf="createBlockForm.get('title').hasError('required')" translate> <mat-error *ngIf="createBlockForm.get('title').hasError('required')">
A title is required {{ 'A title is required' | translate }}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<!-- Internal --> <!-- Internal -->
<p> <p>
<mat-checkbox formControlName="internal"><span translate>Internal</span></mat-checkbox> <mat-checkbox formControlName="internal"
><span>{{ 'Internal' | translate }}</span></mat-checkbox
>
</p> </p>
<os-agenda-content-object-form [form]="createBlockForm"></os-agenda-content-object-form> <os-agenda-content-object-form [form]="createBlockForm"></os-agenda-content-object-form>
@ -97,8 +101,10 @@
</form> </form>
<div mat-dialog-actions> <div mat-dialog-actions>
<button mat-button [disabled]="!createBlockForm.valid" [mat-dialog-close]="true"> <button mat-button [disabled]="!createBlockForm.valid" [mat-dialog-close]="true">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button>
<button mat-button [mat-dialog-close]="false">
<span>{{ 'Cancel' | translate }}</span>
</button> </button>
<button mat-button [mat-dialog-close]="false"><span translate>Cancel</span></button>
</div> </div>
</ng-template> </ng-template>

View File

@ -1,7 +1,7 @@
<os-head-bar prevUrl="../.." [nav]="false" [hasMainButton]="true" (mainEvent)="openDialog()"> <os-head-bar prevUrl="../.." [nav]="false" [hasMainButton]="true" (mainEvent)="openDialog()">
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 translate>Comment fields</h2> <h2>{{ 'Comment fields' | translate }}</h2>
</div> </div>
<!-- Menu --> <!-- Menu -->
@ -40,18 +40,18 @@
</div> </div>
</mat-panel-title> </mat-panel-title>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<h3 translate>Name</h3> <h3>{{ 'Name' | translate }}</h3>
<div class="spacer-left">{{ section.name }}</div> <div class="spacer-left">{{ section.name }}</div>
<h3 translate>Groups with read permissions</h3> <h3>{{ 'Groups with read permissions' | translate }}</h3>
<ul *ngFor="let group of section.read_groups"> <ul *ngFor="let group of section.read_groups">
<li>{{ group.getTitle() }}</li> <li>{{ group.getTitle() }}</li>
</ul> </ul>
<div class="spacer-left" *ngIf="section.read_groups.length === 0" translate>No groups selected</div> <div class="spacer-left" *ngIf="section.read_groups.length === 0">{{ 'No groups selected' | translate }}</div>
<h3 translate>Groups with write permissions</h3> <h3>{{ 'Groups with write permissions' | translate }}</h3>
<ul *ngFor="let group of section.write_groups"> <ul *ngFor="let group of section.write_groups">
<li>{{ group.getTitle() }}</li> <li>{{ group.getTitle() }}</li>
</ul> </ul>
<div class="spacer-left" *ngIf="section.write_groups.length === 0" translate>No groups selected</div> <div class="spacer-left" *ngIf="section.write_groups.length === 0">{{ 'No groups selected' | translate }}</div>
<mat-action-row> <mat-action-row>
<button mat-button (click)="openDialog(section)" mat-icon-button> <button mat-button (click)="openDialog(section)" mat-icon-button>
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
@ -66,15 +66,15 @@
<mat-menu #commentListMenu="matMenu"> <mat-menu #commentListMenu="matMenu">
<button mat-menu-item routerLink="sort"> <button mat-menu-item routerLink="sort">
<mat-icon>sort</mat-icon> <mat-icon>sort</mat-icon>
<span translate>Sort</span> <span>{{ 'Sort' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>
<!-- Template for motion comment dialog --> <!-- Template for motion comment dialog -->
<ng-template #motionCommentDialog> <ng-template #motionCommentDialog>
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span *ngIf="currentComment" translate>Edit comment field</span> <span *ngIf="currentComment">{{ 'Edit comment field' | translate }}</span>
<span *ngIf="!currentComment" translate>New comment field</span> <span *ngIf="!currentComment">{{ 'New comment field' | translate }}</span>
</h1> </h1>
<div class="os-form-card-mobile" mat-dialog-content> <div class="os-form-card-mobile" mat-dialog-content>
<form [formGroup]="commentFieldForm" (keydown)="onKeyDown($event)"> <form [formGroup]="commentFieldForm" (keydown)="onKeyDown($event)">
@ -82,7 +82,7 @@
<mat-form-field> <mat-form-field>
<input formControlName="name" matInput placeholder="{{ 'Name' | translate }}" required /> <input formControlName="name" matInput placeholder="{{ 'Name' | translate }}" required />
<mat-error *ngIf="!commentFieldForm.controls.name.valid"> <mat-error *ngIf="!commentFieldForm.controls.name.valid">
<span translate>Required</span> <span>{{ 'Required' | translate }}</span>
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
</p> </p>
@ -110,10 +110,10 @@
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button [disabled]="commentFieldForm.invalid" mat-button [mat-dialog-close]="true"> <button [disabled]="commentFieldForm.invalid" mat-button [mat-dialog-close]="true">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button mat-button [mat-dialog-close]="false"> <button mat-button [mat-dialog-close]="false">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -1,13 +1,12 @@
<os-head-bar [nav]="false"> <os-head-bar [nav]="false">
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 translate>Sort comments</h2> <h2>{{ 'Sort comments' | translate }}</h2>
</div> </div>
</os-head-bar> </os-head-bar>
<!-- Content --> <!-- Content -->
<mat-card class="os-form-card"> <mat-card class="os-form-card">
<!-- The sorting component --> <!-- The sorting component -->
<os-sorting-list (sortEvent)="onSortingChange($event)" [live]="true" [input]="comments" #sorter> <os-sorting-list (sortEvent)="onSortingChange($event)" [live]="true" [input]="comments" #sorter> </os-sorting-list>
</os-sorting-list>
</mat-card> </mat-card>

View File

@ -7,7 +7,9 @@
(cancelEditEvent)="cancelCreation()" (cancelEditEvent)="cancelCreation()"
> >
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>New amendment</h2></div> <div class="title-slot">
<h2>{{ 'New amendment' | translate }}</h2>
</div>
<!-- Next-button --> <!-- Next-button -->
<div class="extra-controls-slot"> <div class="extra-controls-slot">
@ -17,12 +19,12 @@
[disabled]="contentForm.value.selectedParagraphs.length === 0" [disabled]="contentForm.value.selectedParagraphs.length === 0"
(click)="matStepper.next()" (click)="matStepper.next()"
> >
<span class="upper" translate>Next</span> <span class="upper">{{ 'Next' | translate }}</span>
</button> </button>
</div> </div>
<div *ngIf="matStepper.selectedIndex === 1"> <div *ngIf="matStepper.selectedIndex === 1">
<button type="button" mat-button (click)="matStepper.previous()"> <button type="button" mat-button (click)="matStepper.previous()">
<span class="upper" translate>Previous</span> <span class="upper">{{ 'Previous' | translate }}</span>
</button> </button>
</div> </div>
</div> </div>
@ -59,7 +61,9 @@
<mat-step> <mat-step>
<ng-template matStepLabel>{{ 'Change paragraph' | translate }}</ng-template> <ng-template matStepLabel>{{ 'Change paragraph' | translate }}</ng-template>
<h3><span translate>Amendment text</span></h3> <h3>
<span>{{ 'Amendment text' | translate }}</span>
</h3>
<!-- Text --> <!-- Text -->
<section *ngFor="let paragraph of contentForm.value.selectedParagraphs"> <section *ngFor="let paragraph of contentForm.value.selectedParagraphs">
@ -84,7 +88,8 @@
: '' : ''
" "
> >
<span translate>Reason</span>&nbsp;<span *ngIf="reasonRequired">*</span> <span>{{ 'Reason' | translate }}</span
>&nbsp;<span *ngIf="reasonRequired">*</span>
</h3> </h3>
<editor formControlName="reason" [init]="tinyMceSettings" required></editor> <editor formControlName="reason" [init]="tinyMceSettings" required></editor>
@ -95,9 +100,8 @@
(contentForm.get('reason').dirty || contentForm.get('reason').touched) (contentForm.get('reason').dirty || contentForm.get('reason').touched)
" "
class="red-warning-text" class="red-warning-text"
translate
> >
This field is required. {{ 'This field is required.' | translate }}
</div> </div>
</mat-step> </mat-step>
</mat-horizontal-stepper> </mat-horizontal-stepper>

View File

@ -1,5 +1,5 @@
<h4> <h4>
<span translate>Submitters</span> <span>{{ 'Submitters' | translate }}</span>
<button <button
class="small-button" class="small-button"
type="button" type="button"
@ -45,7 +45,11 @@
</form> </form>
<p> <p>
<button type="button" mat-button (click)="onSave()"><span translate>Save</span></button> <button type="button" mat-button (click)="onSave()">
<button type="button" mat-button (click)="onCancel()"><span translate>Cancel</span></button> <span>{{ 'Save' | translate }}</span>
</button>
<button type="button" mat-button (click)="onCancel()">
<span>{{ 'Cancel' | translate }}</span>
</button>
</p> </p>
</div> </div>

View File

@ -1,4 +1,4 @@
<h1 mat-dialog-title translate>New change recommendation</h1> <h1 mat-dialog-title>{{ 'New change recommendation' | translate }}</h1>
<div mat-dialog-content> <div mat-dialog-content>
<form class="motion-content" [formGroup]="contentForm" (ngSubmit)="saveChangeRecommendation()"> <form class="motion-content" [formGroup]="contentForm" (ngSubmit)="saveChangeRecommendation()">
<mat-radio-group #rGroup formControlName="diffType"> <mat-radio-group #rGroup formControlName="diffType">
@ -9,11 +9,11 @@
<!-- The HTML Editor --> <!-- The HTML Editor -->
<h4 *ngIf="lineRange.to == lineRange.from + 1"> <h4 *ngIf="lineRange.to == lineRange.from + 1">
<span translate>Changed version in line</span> {{ lineRange.from }}: <span>{{ 'Changed version in line' | translate }}</span> {{ lineRange.from }}:
</h4> </h4>
<h4 *ngIf="lineRange.to != lineRange.from + 1"> <h4 *ngIf="lineRange.to != lineRange.from + 1">
<span translate>Changed version in line</span> {{ lineRange.from }} <span translate>to</span> <span>{{ 'Changed version in line' | translate }}</span> {{ lineRange.from }}
{{ lineRange.to - 1 }}: <span>{{ 'to' | translate }}</span> {{ lineRange.to - 1 }}:
</h4> </h4>
<div> <div>
<editor formControlName="text" [init]="tinyMceSettings"></editor> <editor formControlName="text" [init]="tinyMceSettings"></editor>
@ -25,9 +25,9 @@
<div mat-dialog-actions> <div mat-dialog-actions>
<!-- The mat-dialog-close directive optionally accepts a value as a result for the dialog. --> <!-- The mat-dialog-close directive optionally accepts a value as a result for the dialog. -->
<button mat-button (click)="saveChangeRecommendation()"> <button mat-button (click)="saveChangeRecommendation()">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button mat-button mat-dialog-close> <button mat-button mat-dialog-close>
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>

View File

@ -12,8 +12,8 @@
<ng-container class="meta-text-block-content"> <ng-container class="meta-text-block-content">
<ng-container *ngIf="!isCommentEdited(section)"> <ng-container *ngIf="!isCommentEdited(section)">
<div *ngIf="comments[section.id]" [innerHTML]="comments[section.id].comment | trust: 'html'"></div> <div *ngIf="comments[section.id]" [innerHTML]="comments[section.id].comment | trust: 'html'"></div>
<div class="no-content" *ngIf="!comments[section.id] || !comments[section.id].comment" translate> <div class="no-content" *ngIf="!comments[section.id] || !comments[section.id].comment">
No comment {{ 'No comment' | translate }}
</div> </div>
</ng-container> </ng-container>
<form [formGroup]="commentForms[section.id]" *ngIf="isCommentEdited(section)"> <form [formGroup]="commentForms[section.id]" *ngIf="isCommentEdited(section)">
@ -27,9 +27,9 @@
></editor> ></editor>
</form> </form>
<div *ngIf="saveHint"> <div *ngIf="saveHint">
<span translate>Touch the book icon to enter text</span> <span>{{ 'Touch the book icon to enter text' | translate }}</span>
<br /> <br />
<span class="red-warning-text" translate>Do not forget to save your changes!</span> <span class="red-warning-text">{{ 'Do not forget to save your changes!' | translate }}</span>
</div> </div>
</ng-container> </ng-container>

View File

@ -26,7 +26,9 @@
--> -->
</span> </span>
<span class="status"> <span class="status">
<ng-container *ngIf="change.isRejected()"> <span translate>Rejected</span></ng-container> <ng-container *ngIf="change.isRejected()">
<span>{{ 'Rejected' | translate }}</span></ng-container
>
<ng-container *ngIf="change.isAccepted() && isAmendment(change)"> <ng-container *ngIf="change.isAccepted() && isAmendment(change)">
{{ change.stateName | translate }}</ng-container {{ change.stateName | translate }}</ng-container
> >
@ -150,7 +152,7 @@
(click)="setAcceptanceValue(change, 'accepted')" (click)="setAcceptanceValue(change, 'accepted')"
> >
<mat-icon>thumb_up</mat-icon> <mat-icon>thumb_up</mat-icon>
<span translate>Accept</span> <span>{{ 'Accept' | translate }}</span>
<mat-icon class="active-indicator">{{ change.isAccepted() ? 'done' : '' }}</mat-icon> <mat-icon class="active-indicator">{{ change.isAccepted() ? 'done' : '' }}</mat-icon>
</button> </button>
<button <button
@ -160,16 +162,16 @@
(click)="setAcceptanceValue(change, 'rejected')" (click)="setAcceptanceValue(change, 'rejected')"
> >
<mat-icon>thumb_down</mat-icon> <mat-icon>thumb_down</mat-icon>
<span translate>Reject</span> <span>{{ 'Reject' | translate }}</span>
<mat-icon class="active-indicator">{{ change.isRejected() ? 'done' : '' }}</mat-icon> <mat-icon class="active-indicator">{{ change.isRejected() ? 'done' : '' }}</mat-icon>
</button> </button>
<button type="button" mat-menu-item (click)="setInternal(change, !change.internal)"> <button type="button" mat-menu-item (click)="setInternal(change, !change.internal)">
<mat-icon>{{ change.internal ? 'check_box_outline_blank' : 'check_box' }}</mat-icon> <mat-icon>{{ change.internal ? 'check_box_outline_blank' : 'check_box' }}</mat-icon>
<span translate>Public</span> <span>{{ 'Public' | translate }}</span>
</button> </button>
<button type="button" mat-menu-item (click)="deleteChangeRecommendation(change, $event)"> <button type="button" mat-menu-item (click)="deleteChangeRecommendation(change, $event)">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
<button <button
type="button" type="button"
@ -178,7 +180,7 @@
*ngIf="!change.isTitleChange()" *ngIf="!change.isTitleChange()"
> >
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
<span translate>Edit</span> <span>{{ 'Edit' | translate }}</span>
</button> </button>
<button <button
type="button" type="button"
@ -187,7 +189,7 @@
*ngIf="change.isTitleChange()" *ngIf="change.isTitleChange()"
> >
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
<span translate>Edit</span> <span>{{ 'Edit' | translate }}</span>
</button> </button>
</ng-template> </ng-template>
</mat-menu> </mat-menu>

View File

@ -12,13 +12,13 @@
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 *ngIf="motion && !newMotion"> <h2 *ngIf="motion && !newMotion">
<span translate>Motion</span> <span>{{ 'Motion' | translate }}</span>
<!-- Whitespace between "Motion" and identifier --> <!-- Whitespace between "Motion" and identifier -->
<span>&nbsp;</span> <span *ngIf="!editMotion">{{ motion.identifier }}</span> <span>&nbsp;</span> <span *ngIf="!editMotion">{{ motion.identifier }}</span>
<span *ngIf="editMotion">{{ contentForm.get('identifier').value }}</span> <span *ngIf="editMotion">{{ contentForm.get('identifier').value }}</span>
</h2> </h2>
<h2 *ngIf="newMotion && !amendmentEdit" translate>New motion</h2> <h2 *ngIf="newMotion && !amendmentEdit">{{ 'New motion' | translate }}</h2>
<h2 *ngIf="amendmentEdit" translate>New amendment</h2> <h2 *ngIf="amendmentEdit">{{ 'New amendment' | translate }}</h2>
</div> </div>
<!-- Back and forth buttons --> <!-- Back and forth buttons -->
@ -62,7 +62,7 @@
<!-- 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>{{ 'PDF' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<!-- Project --> <!-- Project -->
@ -75,11 +75,11 @@
<div *osPerms="'agenda.can_manage'"> <div *osPerms="'agenda.can_manage'">
<button mat-menu-item (click)="addToAgenda()" *ngIf="motion && !motion.item"> <button mat-menu-item (click)="addToAgenda()" *ngIf="motion && !motion.item">
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
<span translate>Add to agenda</span> <span>{{ 'Add to agenda' | translate }}</span>
</button> </button>
<button mat-menu-item (click)="removeFromAgenda()" *ngIf="motion && motion.item"> <button mat-menu-item (click)="removeFromAgenda()" *ngIf="motion && motion.item">
<mat-icon>remove</mat-icon> <mat-icon>remove</mat-icon>
<span translate>Remove from agenda</span> <span>{{ 'Remove from agenda' | translate }}</span>
</button> </button>
</div> </div>
<button <button
@ -89,15 +89,15 @@
[queryParams]="{ element: motion.elementId }" [queryParams]="{ element: motion.elementId }"
> >
<mat-icon>history</mat-icon> <mat-icon>history</mat-icon>
<span translate> <span>
History {{ 'History' | translate }}
</span> </span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<!-- Edit--> <!-- Edit-->
<button mat-menu-item (click)="setEditMode(true)" *ngIf="perms.isAllowed('update', motion)"> <button mat-menu-item (click)="setEditMode(true)" *ngIf="perms.isAllowed('update', motion)">
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
<span translate>Edit</span> <span>{{ 'Edit' | translate }}</span>
</button> </button>
<!-- Delete --> <!-- Delete -->
<button <button
@ -107,7 +107,7 @@
*ngIf="perms.isAllowed('manage')" *ngIf="perms.isAllowed('manage')"
> >
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</mat-menu> </mat-menu>
@ -145,14 +145,15 @@
<!-- Sequential number --> <!-- Sequential number -->
<span class="main-nav-color title-font"> <span class="main-nav-color title-font">
<span *ngIf="showSequential"> <span translate>Sequential number</span>&nbsp;{{ motion.id }} </span> <span *ngIf="showSequential">
<span>{{ 'Sequential number' | translate }}</span
>&nbsp;{{ motion.id }}
</span>
<span *ngIf="showSequential && motion.parent_id">&#xb7;&nbsp;</span> <span *ngIf="showSequential && motion.parent_id">&#xb7;&nbsp;</span>
<span *ngIf="motion.parent_id"> <span *ngIf="motion.parent_id">
<span> <span>
<span translate>Amendment to</span>&nbsp;<a <span>{{ 'Amendment to' | translate }}</span
[routerLink]="motion.parent.getDetailStateURL()" >&nbsp;<a [routerLink]="motion.parent.getDetailStateURL()" [state]="{ back: 'true' }">
[state]="{ back: 'true' }"
>
{{ motion.parent.identifier || motion.parent.title }} {{ motion.parent.identifier || motion.parent.title }}
</a> </a>
</span> </span>
@ -208,7 +209,7 @@
<!-- do Support --> <!-- do Support -->
<div *ngIf="minSupporters && !editMotion"> <div *ngIf="minSupporters && !editMotion">
<h4 *ngIf="perms.isAllowed('support', motion) || motion.hasSupporters()" translate>Supporters</h4> <h4 *ngIf="perms.isAllowed('support', motion) || motion.hasSupporters()">{{ 'Supporters' | translate }}</h4>
<!-- support button --> <!-- support button -->
<button <button
@ -321,13 +322,13 @@
(click)="onFollowRecButton()" (click)="onFollowRecButton()"
class="spacer-top-10" class="spacer-top-10"
> >
<span translate>Follow recommendation</span> <span>{{ 'Follow recommendation' | translate }}</span>
</button> </button>
</div> </div>
<!-- recommendation referencing motions --> <!-- recommendation referencing motions -->
<div *ngIf="!editMotion && recommendationReferencingMotions.length > 0 && showReferringMotions"> <div *ngIf="!editMotion && recommendationReferencingMotions.length > 0 && showReferringMotions">
<h4 translate>Referring motions</h4> <h4>{{ 'Referring motions' | translate }}</h4>
<span *ngFor="let motion of recommendationReferencingMotions; let last = last"> <span *ngFor="let motion of recommendationReferencingMotions; let last = last">
<a [routerLink]="motion.getDetailStateURL()" class="nowrap">{{ motion.identifierOrTitle }}</a> <a [routerLink]="motion.getDetailStateURL()" class="nowrap">{{ motion.identifierOrTitle }}</a>
<span *ngIf="!last"> · </span> <span *ngIf="!last"> · </span>
@ -337,7 +338,7 @@
<!-- Category --> <!-- Category -->
<!-- Disabled during "new motion" since changing has no effect --> <!-- Disabled during "new motion" since changing has no effect -->
<div *ngIf="!editMotion && categoryObserver.value.length"> <div *ngIf="!editMotion && categoryObserver.value.length">
<h4 *ngIf="perms.isAllowed('change_metadata', motion) || motion.category" translate>Category</h4> <h4 *ngIf="perms.isAllowed('change_metadata', motion) || motion.category">{{ 'Category' | translate }}</h4>
<mat-menu #categoryMenu="matMenu"> <mat-menu #categoryMenu="matMenu">
<button <button
mat-menu-item mat-menu-item
@ -382,7 +383,7 @@
<!-- Tags --> <!-- Tags -->
<!-- Disabled during "new motion" since changing has no effect --> <!-- Disabled during "new motion" since changing has no effect -->
<div *ngIf="!editMotion && tagObserver.value.length > 0"> <div *ngIf="!editMotion && tagObserver.value.length > 0">
<h4 *ngIf="perms.isAllowed('change_metadata', motion) || motion.hasTags()" translate>Tags</h4> <h4 *ngIf="perms.isAllowed('change_metadata', motion) || motion.hasTags()">{{ 'Tags' | translate }}</h4>
<!-- For privileged users --> <!-- For privileged users -->
<div *ngIf="perms.isAllowed('change_metadata', motion)"> <div *ngIf="perms.isAllowed('change_metadata', motion)">
@ -422,7 +423,9 @@
<!-- Block --> <!-- Block -->
<div *ngIf="!editMotion && blockObserver.value.length > 0"> <div *ngIf="!editMotion && blockObserver.value.length > 0">
<h4 *ngIf="perms.isAllowed('change_metadata', motion) || motion.motion_block" translate>Motion block</h4> <h4 *ngIf="perms.isAllowed('change_metadata', motion) || motion.motion_block">
{{ 'Motion block' | translate }}
</h4>
<mat-menu #blockMenu="matMenu"> <mat-menu #blockMenu="matMenu">
<button mat-menu-item *ngFor="let block of blockObserver.value" (click)="setBlock(block.id)"> <button mat-menu-item *ngFor="let block of blockObserver.value" (click)="setBlock(block.id)">
<mat-icon *ngIf="motion.motion_block_id === block.id">check</mat-icon> <mat-icon *ngIf="motion.motion_block_id === block.id">check</mat-icon>
@ -448,17 +451,17 @@
<!-- Origin - display only --> <!-- Origin - display only -->
<div *ngIf="!editMotion && motion.origin"> <div *ngIf="!editMotion && motion.origin">
<h4 translate>Origin</h4> <h4>{{ 'Origin' | translate }}</h4>
{{ motion.origin }} {{ motion.origin }}
</div> </div>
<!-- Ammendments --> <!-- Ammendments -->
<div *ngIf="!editMotion && amendments && amendments.length > 0"> <div *ngIf="!editMotion && amendments && amendments.length > 0">
<h4 translate>Amendments</h4> <h4>{{ 'Amendments' | translate }}</h4>
<a [routerLink]="['/motions/amendments', motion.id]" [state]="{ back: 'true' }"> <a [routerLink]="['/motions/amendments', motion.id]" [state]="{ back: 'true' }">
{{ amendments.length }} {{ amendments.length }}
<span *ngIf="amendments.length === 1" translate>Amendment</span> <span *ngIf="amendments.length === 1">{{ 'Amendment' | translate }}</span>
<span *ngIf="amendments.length > 1" translate>Amendments</span> <span *ngIf="amendments.length > 1">{{ 'Amendments' | translate }}</span>
</a> </a>
</div> </div>
@ -473,7 +476,7 @@
*ngIf="perms.isAllowed('createpoll', motion)" *ngIf="perms.isAllowed('createpoll', motion)"
> >
<mat-icon class="main-nav-color">add</mat-icon> <mat-icon class="main-nav-color">add</mat-icon>
<span translate>New vote</span> <span>{{ 'New vote' | translate }}</span>
</button> </button>
</div> </div>
</div> </div>
@ -496,7 +499,7 @@
[ngModelOptions]="{ standalone: true }" [ngModelOptions]="{ standalone: true }"
[errorStateMatcher]="highlightedLineMatcher" [errorStateMatcher]="highlightedLineMatcher"
/> />
<mat-error *ngIf="highlightedLineTyping > 10" translate>Invalid line number</mat-error> <mat-error *ngIf="highlightedLineTyping > 10">{{ 'Invalid line number' | translate }}</mat-error>
<button <button
type="submit" type="submit"
mat-button mat-button
@ -515,8 +518,11 @@
<button type="button" mat-button [matMenuTriggerFor]="lineNumberingMenu"> <button type="button" mat-button [matMenuTriggerFor]="lineNumberingMenu">
<mat-icon>format_list_numbered</mat-icon> <mat-icon>format_list_numbered</mat-icon>
&nbsp;<span translate>Line numbering</span> &nbsp;<span>{{ 'Line numbering' | translate }}</span>
<span *ngIf="lnMode === LineNumberingMode.None"> &nbsp;(<span translate>none</span>) </span> <span *ngIf="lnMode === LineNumberingMode.None">
&nbsp;(<span>{{ 'none' | translate }}</span
>)
</span>
</button> </button>
<button <button
type="button" type="button"
@ -695,9 +701,8 @@
contentForm.get('modified_final_version').touched) contentForm.get('modified_final_version').touched)
" "
class="red-warning-text" class="red-warning-text"
translate
> >
This field is required. {{ 'This field is required.' | translate }}
</div> </div>
</div> </div>
</ng-container> </ng-container>
@ -718,9 +723,8 @@
(contentForm.get('text').dirty || contentForm.get('text').touched) (contentForm.get('text').dirty || contentForm.get('text').touched)
" "
class="red-warning-text" class="red-warning-text"
translate
> >
This field is required. {{ 'This field is required.' | translate }}
</div> </div>
</ng-container> </ng-container>
@ -743,9 +747,8 @@
contentForm.get('text_' + paragraph.paragraphNo).touched) contentForm.get('text_' + paragraph.paragraphNo).touched)
" "
class="red-warning-text" class="red-warning-text"
translate
> >
This field is required. {{ 'This field is required.' | translate }}
</div> </div>
</section> </section>
</ng-container> </ng-container>
@ -766,7 +769,8 @@
: '' : ''
" "
> >
<span translate>Reason</span>&nbsp;<span *ngIf="reasonRequired && editMotion">*</span> <span>{{ 'Reason' | translate }}</span
>&nbsp;<span *ngIf="reasonRequired && editMotion">*</span>
</h3> </h3>
<div class="motion-text" *ngIf="!editMotion" [innerHtml]="motion.reason | trust: 'html'"></div> <div class="motion-text" *ngIf="!editMotion" [innerHtml]="motion.reason | trust: 'html'"></div>
@ -784,9 +788,8 @@
(contentForm.get('reason').dirty || contentForm.get('reason').touched) (contentForm.get('reason').dirty || contentForm.get('reason').touched)
" "
class="red-warning-text" class="red-warning-text"
translate
> >
This field is required. {{ 'This field is required.' | translate }}
</div> </div>
</div> </div>
@ -869,7 +872,7 @@
<!-- If the array exists, we do not have an error --> <!-- If the array exists, we do not have an error -->
<div *ngIf="motion.diffLines"> <div *ngIf="motion.diffLines">
<div class="alert alert-info" *ngIf="motion.diffLines.length === 0"> <div class="alert alert-info" *ngIf="motion.diffLines.length === 0">
<span translate>No changes at the text.</span> <span>{{ 'No changes at the text.' | translate }}</span>
</div> </div>
<div <div
*ngFor="let paragraph of getAmendmentParagraphs(showAmendmentContext)" *ngFor="let paragraph of getAmendmentParagraphs(showAmendmentContext)"
@ -900,9 +903,9 @@
</div> </div>
</div> </div>
<div *ngIf="!motion.diffLines"> <div *ngIf="!motion.diffLines">
<span class="red-warning-text" translate> <span class="red-warning-text">{{
There is an error with this amendment. Please edit it manually. 'There is an error with this amendment. Please edit it manually.' | translate
</span> }}</span>
</div> </div>
</section> </section>
@ -913,7 +916,7 @@
*ngIf="motion && motion.isParagraphBasedAmendment()" *ngIf="motion && motion.isParagraphBasedAmendment()"
class="show-entire-text-check" class="show-entire-text-check"
> >
<span translate>Show entire motion text</span> <span>{{ 'Show entire motion text' | translate }}</span>
</mat-checkbox> </mat-checkbox>
</div> </div>
</ng-template> </ng-template>
@ -923,32 +926,29 @@
<div *ngIf="motion"> <div *ngIf="motion">
<button <button
mat-menu-item mat-menu-item
translate
(click)="setLineNumberingMode(LineNumberingMode.None)" (click)="setLineNumberingMode(LineNumberingMode.None)"
[ngClass]="{ selected: lnMode === LineNumberingMode.None }" [ngClass]="{ selected: lnMode === LineNumberingMode.None }"
> >
none {{ 'none' | translate }}
</button> </button>
<button <button
mat-menu-item mat-menu-item
translate
(click)="setLineNumberingMode(LineNumberingMode.Inside)" (click)="setLineNumberingMode(LineNumberingMode.Inside)"
[ngClass]="{ selected: lnMode === LineNumberingMode.Inside }" [ngClass]="{ selected: lnMode === LineNumberingMode.Inside }"
> >
inline {{ 'inline' | translate }}
</button> </button>
<button <button
mat-menu-item mat-menu-item
translate
(click)="setLineNumberingMode(LineNumberingMode.Outside)" (click)="setLineNumberingMode(LineNumberingMode.Outside)"
[ngClass]="{ selected: lnMode === LineNumberingMode.Outside }" [ngClass]="{ selected: lnMode === LineNumberingMode.Outside }"
> >
outside {{ 'outside' | translate }}
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button mat-menu-item *ngIf="!highlightedLineOpened" (click)="highlightedLineOpened = true"> <button mat-menu-item *ngIf="!highlightedLineOpened" (click)="highlightedLineOpened = true">
<mat-icon>redo</mat-icon> <mat-icon>redo</mat-icon>
<span translate>Go to line</span> <span>{{ 'Go to line' | translate }}</span>
</button> </button>
</div> </div>
</mat-menu> </mat-menu>
@ -957,46 +957,41 @@
<mat-menu #changeRecoMenu="matMenu"> <mat-menu #changeRecoMenu="matMenu">
<button <button
mat-menu-item mat-menu-item
translate
(click)="setChangeRecoMode(ChangeRecoMode.Original)" (click)="setChangeRecoMode(ChangeRecoMode.Original)"
[ngClass]="{ selected: crMode === ChangeRecoMode.Original }" [ngClass]="{ selected: crMode === ChangeRecoMode.Original }"
> >
Original version {{ 'Original version' | translate }}
</button> </button>
<button <button
mat-menu-item mat-menu-item
translate
(click)="setChangeRecoMode(ChangeRecoMode.Changed)" (click)="setChangeRecoMode(ChangeRecoMode.Changed)"
[ngClass]="{ selected: crMode === ChangeRecoMode.Changed }" [ngClass]="{ selected: crMode === ChangeRecoMode.Changed }"
*ngIf="allChangingObjects && allChangingObjects.length" *ngIf="allChangingObjects && allChangingObjects.length"
> >
Changed version {{ 'Changed version' | translate }}
</button> </button>
<button <button
mat-menu-item mat-menu-item
translate
(click)="setChangeRecoMode(ChangeRecoMode.Diff)" (click)="setChangeRecoMode(ChangeRecoMode.Diff)"
[ngClass]="{ selected: crMode === ChangeRecoMode.Diff }" [ngClass]="{ selected: crMode === ChangeRecoMode.Diff }"
*ngIf="allChangingObjects && allChangingObjects.length" *ngIf="allChangingObjects && allChangingObjects.length"
> >
Diff version {{ 'Diff version' | translate }}
</button> </button>
<button <button
mat-menu-item mat-menu-item
translate
(click)="setChangeRecoMode(ChangeRecoMode.Final)" (click)="setChangeRecoMode(ChangeRecoMode.Final)"
[ngClass]="{ selected: crMode === ChangeRecoMode.Final }" [ngClass]="{ selected: crMode === ChangeRecoMode.Final }"
*ngIf="allChangingObjects && allChangingObjects.length" *ngIf="allChangingObjects && allChangingObjects.length"
> >
Final version {{ 'Final version' | translate }}
</button> </button>
<button <button
mat-menu-item mat-menu-item
translate
*ngIf="motion && motion.modified_final_version" *ngIf="motion && motion.modified_final_version"
(click)="setChangeRecoMode(ChangeRecoMode.ModifiedFinal)" (click)="setChangeRecoMode(ChangeRecoMode.ModifiedFinal)"
[ngClass]="{ selected: crMode === ChangeRecoMode.ModifiedFinal }" [ngClass]="{ selected: crMode === ChangeRecoMode.ModifiedFinal }"
> >
Final print template {{ 'Final print template' | translate }}
</button> </button>
</mat-menu> </mat-menu>

View File

@ -1,4 +1,4 @@
<h1 mat-dialog-title translate>New change recommendation</h1> <h1 mat-dialog-title>{{ 'New change recommendation' | translate }}</h1>
<mat-dialog-content> <mat-dialog-content>
<form class="motion-content" [formGroup]="contentForm" (ngSubmit)="saveChangeRecommendation()"> <form class="motion-content" [formGroup]="contentForm" (ngSubmit)="saveChangeRecommendation()">
<mat-form-field> <mat-form-field>
@ -11,9 +11,9 @@
<mat-dialog-actions> <mat-dialog-actions>
<!-- The mat-dialog-close directive optionally accepts a value as a result for the dialog. --> <!-- The mat-dialog-close directive optionally accepts a value as a result for the dialog. -->
<button mat-button (click)="saveChangeRecommendation()"> <button mat-button (click)="saveChangeRecommendation()">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button mat-button mat-dialog-close> <button mat-button mat-dialog-close>
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</mat-dialog-actions> </mat-dialog-actions>

View File

@ -1,7 +1,7 @@
<os-meta-text-block showActionRow="true" icon="speaker_notes" [disableExpandControl]="true"> <os-meta-text-block showActionRow="true" icon="speaker_notes" [disableExpandControl]="true">
<!-- Title row --> <!-- Title row -->
<ng-container class="meta-text-block-title"> <ng-container class="meta-text-block-title">
<span translate>Personal note</span> <span>{{ 'Personal note' | translate }}</span>
</ng-container> </ng-container>
<!-- Actions --> <!-- Actions -->
@ -40,8 +40,8 @@
<ng-container class="meta-text-block-content"> <ng-container class="meta-text-block-content">
<ng-container *ngIf="!isEditMode"> <ng-container *ngIf="!isEditMode">
<div *ngIf="motion && motion.personalNote" [innerHTML]="personalNoteText | trust: 'html'"></div> <div *ngIf="motion && motion.personalNote" [innerHTML]="personalNoteText | trust: 'html'"></div>
<div class="no-content" *ngIf="!motion || !motion.hasNotes" translate> <div class="no-content" *ngIf="!motion || !motion.hasNotes">
No personal note {{ 'No personal note' | translate }}
</div> </div>
</ng-container> </ng-container>
<form [formGroup]="personalNoteForm" *ngIf="isEditMode"> <form [formGroup]="personalNoteForm" *ngIf="isEditMode">
@ -54,9 +54,9 @@
></editor> ></editor>
</form> </form>
<div *ngIf="saveHint"> <div *ngIf="saveHint">
<span translate>Touch the book icon to enter text</span> <span>{{ 'Touch the book icon to enter text' | translate }}</span>
<br /> <br />
<span class="red-warning-text" translate>Do not forget to save your changes!</span> <span class="red-warning-text">{{ 'Do not forget to save your changes!' | translate }}</span>
</div> </div>
</ng-container> </ng-container>
</os-meta-text-block> </os-meta-text-block>

View File

@ -1,16 +1,20 @@
<os-head-bar prevUrl="../.." [nav]="false"> <os-head-bar prevUrl="../.." [nav]="false">
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Import motions</h2></div> <div class="title-slot">
<h2>{{ 'Import motions' | translate }}</h2>
</div>
<div class="menu-slot"> <div class="menu-slot">
<button *ngIf="hasFile && newCount" mat-button (click)="doImport()"> <button *ngIf="hasFile && newCount" mat-button (click)="doImport()">
<span class="upper" translate> Import</span> <span class="upper">{{ 'Import' | translate }}</span>
</button> </button>
</div> </div>
</os-head-bar> </os-head-bar>
<mat-card class="os-form-card import-table"> <mat-card class="os-form-card import-table">
<span translate>Required comma or semicolon separated values with these column header names in the first row:</span> <span>{{
'Required comma or semicolon separated values with these column header names in the first row:' | translate
}}</span>
<br /> <br />
<div class="code red-warning-text"> <div class="code red-warning-text">
<span *ngFor="let header of this.expectedHeader; let last = last"> <span *ngFor="let header of this.expectedHeader; let last = last">
@ -19,18 +23,27 @@
</span> </span>
</div> </div>
<ul> <ul>
<li translate> <li>
Identifier, reason, submitter, category, origin and motion block are optional and may be empty. {{
'Identifier, reason, submitter, category, origin and motion block are optional and may be empty.'
| translate
}}
</li>
<li>
{{
'Additional columns after the required ones may be present and will not affect the import.' | translate
}}
</li> </li>
<li translate>Additional columns after the required ones may be present and won't affect the import.</li>
</ul> </ul>
<button mat-button color="accent" (click)="downloadCsvExample()" translate>Download CSV example file</button> <button mat-button color="accent" (click)="downloadCsvExample()">
{{ 'Download CSV example file' | translate }}
</button>
<div class="wrapper"> <div class="wrapper">
<mat-form-field> <mat-form-field>
<mat-label translate>Encoding of the file</mat-label> <mat-label>{{ 'Encoding of the file' | translate }}</mat-label>
<mat-select <mat-select
class="selection" class="selection"
placeholder="translate.instant('Select encoding')" placeholder="{{ 'Select encoding' | translate }}"
(selectionChange)="selectEncoding($event)" (selectionChange)="selectEncoding($event)"
[value]="encodings[0].value" [value]="encodings[0].value"
> >
@ -40,7 +53,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<mat-label translate>Column separator</mat-label> <mat-label>{{ 'Column separator' | translate }}</mat-label>
<mat-select class="selection" (selectionChange)="selectColSep($event)" value=""> <mat-select class="selection" (selectionChange)="selectColSep($event)" value="">
<mat-option *ngFor="let option of columnSeparators" [value]="option.value"> <mat-option *ngFor="let option of columnSeparators" [value]="option.value">
{{ option.label | translate }} {{ option.label | translate }}
@ -48,7 +61,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<mat-label translate>Text separator</mat-label> <mat-label>{{ 'Text separator' | translate }}</mat-label>
<mat-select class="selection" (selectionChange)="selectTextSep($event)" value='"'> <mat-select class="selection" (selectionChange)="selectTextSep($event)" value='"'>
<mat-option *ngFor="let option of textSeparators" [value]="option.value"> <mat-option *ngFor="let option of textSeparators" [value]="option.value">
{{ option.label | translate }} {{ option.label | translate }}
@ -67,7 +80,7 @@
(change)="onSelectFile($event)" (change)="onSelectFile($event)"
/> />
<button mat-button osAutofocus onclick="document.getElementById('motion-import-file-input').click()"> <button mat-button osAutofocus onclick="document.getElementById('motion-import-file-input').click()">
<span translate> Select file</span> <span>{{ 'Select file' | translate }}</span>
</button> </button>
</div> </div>
</div> </div>
@ -75,35 +88,35 @@
<!-- preview table --> <!-- preview table -->
<mat-card *ngIf="hasFile" class="os-form-card import-table"> <mat-card *ngIf="hasFile" class="os-form-card import-table">
<h3 translate>Preview</h3> <h3>{{ 'Preview' | translate }}</h3>
<div class="summary"> <div class="summary">
<!-- new entries --> <!-- new entries -->
<div *ngIf="newCount"> <div *ngIf="newCount">
&nbsp; &nbsp;
<mat-icon inline>playlist_add</mat-icon> <mat-icon inline>playlist_add</mat-icon>
<span>&nbsp;{{ newCount }}&nbsp;</span> <span translate>Motion(s) will be imported.</span> <span>&nbsp;{{ newCount }}&nbsp;</span> <span>{{ 'Motion(s) will be imported.' | translate }}</span>
</div> </div>
<!-- errors/duplicates --> <!-- errors/duplicates -->
<div *ngIf="nonImportableCount" class="red-warning-text"> <div *ngIf="nonImportableCount" class="red-warning-text">
&nbsp; &nbsp;
<mat-icon inline>warning</mat-icon> <mat-icon inline>warning</mat-icon>
<span>&nbsp;{{ nonImportableCount }}&nbsp;</span> <span translate>entries will be ommitted.</span> <span>&nbsp;{{ nonImportableCount }}&nbsp;</span> <span>{{ 'entries will be ommitted.' | translate }}</span>
</div> </div>
<!-- have been imported --> <!-- have been imported -->
<div *ngIf="doneCount" class="green-text"> <div *ngIf="doneCount" class="green-text">
&nbsp; &nbsp;
<mat-icon inline>done</mat-icon> <mat-icon inline>done</mat-icon>
<span>&nbsp;{{ doneCount }}&nbsp;</span> <span translate>Motions have been imported.</span> <span>&nbsp;{{ doneCount }}&nbsp;</span> <span>{{ 'Motions have been imported.' | translate }}</span>
</div> </div>
</div> </div>
<div *ngIf="newCount"> <div *ngIf="newCount">
<span translate>After verifiy the preview click on 'import' please (see top right).</span> <span>{{ 'After verifiy the preview click on "import" please (see top right).' | translate }}</span>
</div> </div>
<div> <div>
<mat-select *ngIf="nonImportableCount" class="filter-imports" [(value)]="shown" (selectionChange)="setFilter()"> <mat-select *ngIf="nonImportableCount" class="filter-imports" [(value)]="shown" (selectionChange)="setFilter()">
<mat-option value="all" translate> Show all </mat-option> <mat-option value="all">{{ 'Show all' | translate }}</mat-option>
<mat-option value="error" translate> Show errors only </mat-option> <mat-option value="error">{{ 'Show errors only' | translate }}</mat-option>
<mat-option value="noerror" translate> Show correct entries </mat-option> <mat-option value="noerror">{{ 'Show correct entries' | translate }}</mat-option>
</mat-select> </mat-select>
</div> </div>
<div class="table-container"> <div class="table-container">
@ -135,7 +148,7 @@
<!-- identifier column --> <!-- identifier column -->
<ng-container matColumnDef="identifier"> <ng-container matColumnDef="identifier">
<mat-header-cell *matHeaderCellDef translate>Identifier</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Identifier' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<mat-icon <mat-icon
color="warn" color="warn"
@ -151,7 +164,7 @@
<!-- title column --> <!-- title column -->
<ng-container matColumnDef="title"> <ng-container matColumnDef="title">
<mat-header-cell *matHeaderCellDef translate>Title</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Title' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<mat-icon <mat-icon
color="warn" color="warn"
@ -166,7 +179,7 @@
<!-- text column --> <!-- text column -->
<ng-container matColumnDef="text"> <ng-container matColumnDef="text">
<mat-header-cell *matHeaderCellDef translate>Motion text</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Motion text' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry" matTooltip="{{ getLongPreview(entry.newEntry.text) }}"> <mat-cell *matCellDef="let entry" matTooltip="{{ getLongPreview(entry.newEntry.text) }}">
<mat-icon <mat-icon
color="warn" color="warn"
@ -181,7 +194,7 @@
<!-- reason column --> <!-- reason column -->
<ng-container matColumnDef="reason"> <ng-container matColumnDef="reason">
<mat-header-cell *matHeaderCellDef translate>Reason</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Reason' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry" matTooltip="{{ getLongPreview(entry.newEntry.reason) }}"> <mat-cell *matCellDef="let entry" matTooltip="{{ getLongPreview(entry.newEntry.reason) }}">
{{ getShortPreview(entry.newEntry.reason) }} {{ getShortPreview(entry.newEntry.reason) }}
</mat-cell> </mat-cell>
@ -189,7 +202,7 @@
<!-- submitters column --> <!-- submitters column -->
<ng-container matColumnDef="submitters"> <ng-container matColumnDef="submitters">
<mat-header-cell *matHeaderCellDef translate>Submitters</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Submitters' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<div *ngIf="entry.newEntry.csvSubmitters && entry.newEntry.csvSubmitters.length"> <div *ngIf="entry.newEntry.csvSubmitters && entry.newEntry.csvSubmitters.length">
<mat-icon <mat-icon
@ -210,7 +223,7 @@
<!-- category column --> <!-- category column -->
<ng-container matColumnDef="category"> <ng-container matColumnDef="category">
<mat-header-cell *matHeaderCellDef translate>Category</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Category' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<div *ngIf="entry.newEntry.csvCategory"> <div *ngIf="entry.newEntry.csvCategory">
<mat-icon <mat-icon
@ -230,7 +243,7 @@
<!-- tag column --> <!-- tag column -->
<ng-container matColumnDef="tags"> <ng-container matColumnDef="tags">
<mat-header-cell *matHeaderCellDef translate>Tags</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Tags' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<div *ngIf="entry.newEntry.csvTags"> <div *ngIf="entry.newEntry.csvTags">
<mat-icon <mat-icon
@ -250,13 +263,13 @@
<!-- origin column --> <!-- origin column -->
<ng-container matColumnDef="origin"> <ng-container matColumnDef="origin">
<mat-header-cell *matHeaderCellDef translate>Origin</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Origin' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry">{{ entry.newEntry.origin }}</mat-cell> <mat-cell *matCellDef="let entry">{{ entry.newEntry.origin }}</mat-cell>
</ng-container> </ng-container>
<!-- motion block column --> <!-- motion block column -->
<ng-container matColumnDef="motion_block"> <ng-container matColumnDef="motion_block">
<mat-header-cell *matHeaderCellDef translate>Motion block</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Motion block' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<div *ngIf="entry.newEntry.csvMotionblock"> <div *ngIf="entry.newEntry.csvMotionblock">
<mat-icon <mat-icon

View File

@ -1,6 +1,8 @@
<os-head-bar [hasMainButton]="perms.isAllowed('create')" (mainEvent)="onPlusButton()" [multiSelectMode]="isMultiSelect"> <os-head-bar [hasMainButton]="perms.isAllowed('create')" (mainEvent)="onPlusButton()" [multiSelectMode]="isMultiSelect">
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Motions</h2></div> <div class="title-slot">
<h2>{{ 'Motions' | translate }}</h2>
</div>
<!-- Menu --> <!-- Menu -->
<div class="menu-slot"> <div class="menu-slot">
@ -12,7 +14,7 @@
<!-- Multiselect info --> <!-- Multiselect info -->
<div class="central-info-slot"> <div class="central-info-slot">
<button mat-icon-button (click)="toggleMultiSelect()"><mat-icon>arrow_back</mat-icon></button> <button mat-icon-button (click)="toggleMultiSelect()"><mat-icon>arrow_back</mat-icon></button>
<span>{{ selectedRows.length }}&nbsp;</span><span translate>selected</span> <span>{{ selectedRows.length }}&nbsp;</span><span>{{ 'selected' | translate }}</span>
</div> </div>
<div class="extra-controls-slot"> <div class="extra-controls-slot">
@ -89,7 +91,7 @@
<!-- Submitters --> <!-- Submitters -->
<div class="submitters-line ellipsis-overflow"> <div class="submitters-line ellipsis-overflow">
<span *ngIf="motion.submitters.length"> <span *ngIf="motion.submitters.length">
<span translate>by</span> <span>{{ 'by' | translate }}</span>
{{ motion.submitters }} {{ motion.submitters }}
</span> </span>
@ -97,7 +99,7 @@
<span *ngIf="motion.submitters.length"> <span *ngIf="motion.submitters.length">
&middot; &middot;
</span> </span>
<span translate>Sequential number</span> <span>{{ 'Sequential number' | translate }}</span>
{{ motion.id }} {{ motion.id }}
</span> </span>
</div> </div>
@ -228,7 +230,7 @@
<div *ngIf="perms.isAllowed('change_metadata') && selectedView === 'list'"> <div *ngIf="perms.isAllowed('change_metadata') && selectedView === 'list'">
<button mat-menu-item (click)="toggleMultiSelect()"> <button mat-menu-item (click)="toggleMultiSelect()">
<mat-icon>library_add</mat-icon> <mat-icon>library_add</mat-icon>
<span translate>Multiselect</span> <span>{{ 'Multiselect' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
</div> </div>
@ -239,7 +241,7 @@
<!-- color_lens --> <!-- color_lens -->
<!-- format_paint --> <!-- format_paint -->
<mat-icon>color_lens</mat-icon> <mat-icon>color_lens</mat-icon>
<span translate>Amendments</span> <span>{{ 'Amendments' | translate }}</span>
</button> </button>
</div> </div>
@ -247,7 +249,7 @@
<div *ngIf="perms.isAllowed('manage') || categories.length"> <div *ngIf="perms.isAllowed('manage') || categories.length">
<button mat-menu-item routerLink="category"> <button mat-menu-item routerLink="category">
<mat-icon>category</mat-icon> <mat-icon>category</mat-icon>
<span translate>Categories</span> <span>{{ 'Categories' | translate }}</span>
</button> </button>
</div> </div>
@ -255,7 +257,7 @@
<div *ngIf="perms.isAllowed('manage') || motionBlocks.length"> <div *ngIf="perms.isAllowed('manage') || motionBlocks.length">
<button mat-menu-item routerLink="blocks"> <button mat-menu-item routerLink="blocks">
<mat-icon>widgets</mat-icon> <mat-icon>widgets</mat-icon>
<span translate>Motion blocks</span> <span>{{ 'Motion blocks' | translate }}</span>
</button> </button>
</div> </div>
@ -267,31 +269,31 @@
<!-- Call list --> <!-- Call list -->
<button mat-menu-item routerLink="call-list"> <button mat-menu-item routerLink="call-list">
<mat-icon>sort</mat-icon> <mat-icon>sort</mat-icon>
<span translate>Call list</span> <span>{{ 'Call list' | translate }}</span>
</button> </button>
<!-- Statutes --> <!-- Statutes -->
<button mat-menu-item routerLink="statute-paragraphs" *ngIf="statutesEnabled"> <button mat-menu-item routerLink="statute-paragraphs" *ngIf="statutesEnabled">
<mat-icon>account_balance</mat-icon> <mat-icon>account_balance</mat-icon>
<span translate>Statute</span> <span>{{ 'Statute' | translate }}</span>
</button> </button>
<!-- Comments --> <!-- Comments -->
<button mat-menu-item routerLink="comment-section"> <button mat-menu-item routerLink="comment-section">
<mat-icon>speaker_notes</mat-icon> <mat-icon>speaker_notes</mat-icon>
<span translate>Comment fields</span> <span>{{ 'Comment fields' | translate }}</span>
</button> </button>
<!-- Workflows --> <!-- Workflows -->
<button mat-menu-item routerLink="workflow"> <button mat-menu-item routerLink="workflow">
<mat-icon>build</mat-icon> <mat-icon>build</mat-icon>
<span translate>Workflows</span> <span>{{ 'Workflows' | translate }}</span>
</button> </button>
<!-- Tags --> <!-- Tags -->
<button mat-menu-item routerLink="/tags" *osPerms="'core.can_manage_tags'"> <button mat-menu-item routerLink="/tags" *osPerms="'core.can_manage_tags'">
<mat-icon>local_offer</mat-icon> <mat-icon>local_offer</mat-icon>
<span translate>Tags</span> <span>{{ 'Tags' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
@ -300,14 +302,14 @@
<!-- Export --> <!-- Export -->
<button mat-menu-item *ngIf="selectedView === 'list'" (click)="openExportDialog()"> <button mat-menu-item *ngIf="selectedView === 'list'" (click)="openExportDialog()">
<mat-icon>archive</mat-icon> <mat-icon>archive</mat-icon>
<span translate>Export</span> <span>{{ 'Export' | translate }}</span>
</button> </button>
<!-- Import --> <!-- Import -->
<div *ngIf="perms.isAllowed('manage')"> <div *ngIf="perms.isAllowed('manage')">
<button mat-menu-item routerLink="import"> <button mat-menu-item routerLink="import">
<mat-icon>cloud_upload</mat-icon> <mat-icon>cloud_upload</mat-icon>
<span translate>Import</span> <span>{{ 'Import' | translate }}</span>
</button> </button>
</div> </div>
@ -316,17 +318,17 @@
<!-- Settings --> <!-- Settings -->
<button mat-menu-item *osPerms="'core.can_manage_config'" routerLink="/settings/motions"> <button mat-menu-item *osPerms="'core.can_manage_config'" routerLink="/settings/motions">
<mat-icon>settings</mat-icon> <mat-icon>settings</mat-icon>
<span translate>Settings</span> <span>{{ 'Settings' | translate }}</span>
</button> </button>
</div> </div>
<div *ngIf="isMultiSelect"> <div *ngIf="isMultiSelect">
<button mat-menu-item (click)="selectAll()"> <button mat-menu-item (click)="selectAll()">
<mat-icon>done_all</mat-icon> <mat-icon>done_all</mat-icon>
<span translate>Select all</span> <span>{{ 'Select all' | translate }}</span>
</button> </button>
<button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()"> <button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()">
<mat-icon>clear</mat-icon> <mat-icon>clear</mat-icon>
<span translate>Deselect all</span> <span>{{ 'Deselect all' | translate }}</span>
</button> </button>
<ng-container *ngIf="perms.isAllowed('change_metadata')"> <ng-container *ngIf="perms.isAllowed('change_metadata')">
<mat-divider></mat-divider> <mat-divider></mat-divider>
@ -337,7 +339,7 @@
(click)="multiselectWrapper(multiselectService.moveToItem(selectedRows))" (click)="multiselectWrapper(multiselectService.moveToItem(selectedRows))"
> >
<mat-icon>sort</mat-icon> <mat-icon>sort</mat-icon>
<span translate>Move to agenda item</span> <span>{{ 'Move to agenda item' | translate }}</span>
</button> </button>
<button <button
mat-menu-item mat-menu-item
@ -345,7 +347,7 @@
(click)="multiselectWrapper(multiselectService.bulkMoveItems(selectedRows))" (click)="multiselectWrapper(multiselectService.bulkMoveItems(selectedRows))"
> >
<mat-icon>format_indent_increase</mat-icon> <mat-icon>format_indent_increase</mat-icon>
<span translate>Move in call list</span> <span>{{ 'Move in call list' | translate }}</span>
</button> </button>
</os-motion-multiselect-actions> </os-motion-multiselect-actions>
</ng-container> </ng-container>
@ -406,10 +408,10 @@
<div mat-dialog-actions> <div mat-dialog-actions>
<button type="submit" mat-button color="primary" [mat-dialog-close]="infoDialog"> <button type="submit" mat-button color="primary" [mat-dialog-close]="infoDialog">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -1,4 +1,4 @@
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { ChangeDetectionStrategy, Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
@ -89,7 +89,8 @@ interface InfoDialog {
@Component({ @Component({
selector: 'os-motion-list', selector: 'os-motion-list',
templateUrl: './motion-list.component.html', templateUrl: './motion-list.component.html',
styleUrls: ['./motion-list.component.scss'] styleUrls: ['./motion-list.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class MotionListComponent extends BaseListViewComponent<ViewMotion> implements OnInit { export class MotionListComponent extends BaseListViewComponent<ViewMotion> implements OnInit {
/** /**

View File

@ -90,7 +90,7 @@
<os-projector-button [menuItem]="true" [object]="poll" *osPerms="'core.can_manage_projector'"></os-projector-button> <os-projector-button [menuItem]="true" [object]="poll" *osPerms="'core.can_manage_projector'"></os-projector-button>
<button *osPerms="'motions.can_manage_polls'" mat-menu-item (click)="openDialog(poll)"> <button *osPerms="'motions.can_manage_polls'" mat-menu-item (click)="openDialog(poll)">
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
<span translate>Edit</span> <span>{{ 'Edit' | translate }}</span>
</button> </button>
<button <button
mat-menu-item mat-menu-item
@ -98,11 +98,11 @@
(click)="pseudoanonymizePoll()" (click)="pseudoanonymizePoll()"
> >
<mat-icon>warning</mat-icon> <mat-icon>warning</mat-icon>
<span translate>Anonymize votes</span> <span>{{ 'Anonymize votes' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button *osPerms="'motions.can_manage_polls'" mat-menu-item (click)="deletePoll()"> <button *osPerms="'motions.can_manage_polls'" mat-menu-item (click)="deletePoll()">
<mat-icon color="warn">delete</mat-icon> <mat-icon color="warn">delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>

View File

@ -1,4 +1,4 @@
import { Component, ViewEncapsulation } from '@angular/core'; import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
@ -21,6 +21,7 @@ import { BasePollDetailComponent } from 'app/site/polls/components/base-poll-det
selector: 'os-motion-poll-detail', selector: 'os-motion-poll-detail',
templateUrl: './motion-poll-detail.component.html', templateUrl: './motion-poll-detail.component.html',
styleUrls: ['./motion-poll-detail.component.scss'], styleUrls: ['./motion-poll-detail.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class MotionPollDetailComponent extends BasePollDetailComponent<ViewMotionPoll, MotionPollService> { export class MotionPollDetailComponent extends BasePollDetailComponent<ViewMotionPoll, MotionPollService> {

View File

@ -49,18 +49,16 @@
<!-- Publish immediately button. Only show for new polls --> <!-- Publish immediately button. Only show for new polls -->
<div *ngIf="!pollData.isPublished"> <div *ngIf="!pollData.isPublished">
<mat-checkbox [(ngModel)]="publishImmediately" (change)="publishStateChanged($event.checked)"> <mat-checkbox [(ngModel)]="publishImmediately" (change)="publishStateChanged($event.checked)">
<span translate>Publish immediately</span> <span>{{ 'Publish immediately' | translate }}</span>
</mat-checkbox> </mat-checkbox>
<mat-error *ngIf="!dialogVoteForm.valid" translate> <mat-error *ngIf="!dialogVoteForm.valid"> {{ 'Error in form field.' | translate }}</mat-error>
Error in form field.
</mat-error>
</div> </div>
</ng-container> </ng-container>
<div mat-dialog-actions> <div mat-dialog-actions>
<button mat-button (click)="submitPoll()" [disabled]="pollForm.contentForm.invalid || dialogVoteForm.invalid"> <button mat-button (click)="submitPoll()" [disabled]="pollForm.contentForm.invalid || dialogVoteForm.invalid">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button mat-button [mat-dialog-close]="false"> <button mat-button [mat-dialog-close]="false">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>

View File

@ -109,25 +109,25 @@
<mat-menu #pollDetailMenu="matMenu"> <mat-menu #pollDetailMenu="matMenu">
<button *osPerms="'motions.can_manage_polls'" mat-menu-item (click)="openDialog()"> <button *osPerms="'motions.can_manage_polls'" mat-menu-item (click)="openDialog()">
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
<span translate>Edit</span> <span>{{ 'Edit' | translate }}</span>
</button> </button>
<os-projector-button [menuItem]="true" [object]="poll" *osPerms="'core.can_manage_projector'"></os-projector-button> <os-projector-button [menuItem]="true" [object]="poll" *osPerms="'core.can_manage_projector'"></os-projector-button>
<button mat-menu-item (click)="downloadPdf()"> <button mat-menu-item (click)="downloadPdf()">
<mat-icon>picture_as_pdf</mat-icon> <mat-icon>picture_as_pdf</mat-icon>
<span translate>Ballot papers</span> <span>{{ 'Ballot papers' | translate }}</span>
</button> </button>
<div *osPerms="'motions.can_manage_polls'"> <div *osPerms="'motions.can_manage_polls'">
<mat-divider></mat-divider> <mat-divider></mat-divider>
<!-- Reset Button --> <!-- Reset Button -->
<button mat-menu-item (click)="resetState()"> <button mat-menu-item (click)="resetState()">
<mat-icon color="warn">replay</mat-icon> <mat-icon color="warn">replay</mat-icon>
<span translate>Reset state</span> <span>{{ 'Reset state' | translate }}</span>
</button> </button>
<!-- Delete button --> <!-- Delete button -->
<button mat-menu-item (click)="deletePoll()"> <button mat-menu-item (click)="deletePoll()">
<mat-icon color="warn">delete</mat-icon> <mat-icon color="warn">delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</mat-menu> </mat-menu>

View File

@ -18,7 +18,8 @@
<div *ngIf="workflow"> <div *ngIf="workflow">
<div class="title-line"> <div class="title-line">
<strong> <strong>
<span translate>First state</span>: <span>{{ 'First state' | translate }}</span
>:
<span>{{ workflow.first_state.name | translate }}</span> <span>{{ workflow.first_state.name | translate }}</span>
</strong> </strong>
</div> </div>
@ -26,7 +27,7 @@
<div class="scrollable-matrix"> <div class="scrollable-matrix">
<table mat-table [dataSource]="getTableDataSource()"> <table mat-table [dataSource]="getTableDataSource()">
<ng-container matColumnDef="perm" sticky> <ng-container matColumnDef="perm" sticky>
<th mat-header-cell class="group-head-table-cell" *matHeaderCellDef translate>Permissions</th> <th mat-header-cell class="group-head-table-cell" *matHeaderCellDef>{{ 'Permissions' | translate }}</th>
<td mat-cell *matCellDef="let perm"> <td mat-cell *matCellDef="let perm">
<div class="permission-name"> <div class="permission-name">
{{ perm.name | translate }} {{ perm.name | translate }}
@ -144,10 +145,10 @@
color="primary" color="primary"
[mat-dialog-close]="{ action: 'update', value: dialogData.value }" [mat-dialog-close]="{ action: 'update', value: dialogData.value }"
> >
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
<button <button
type="button" type="button"
@ -156,7 +157,7 @@
*ngIf="dialogData.deletable" *ngIf="dialogData.deletable"
[mat-dialog-close]="{ action: 'delete' }" [mat-dialog-close]="{ action: 'delete' }"
> >
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -1,6 +1,8 @@
<os-head-bar prevUrl="../.." [nav]="false" [hasMainButton]="true" (mainEvent)="onNewButton(newWorkflowDialog)"> <os-head-bar prevUrl="../.." [nav]="false" [hasMainButton]="true" (mainEvent)="onNewButton(newWorkflowDialog)">
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Workflows</h2></div> <div class="title-slot">
<h2>{{ 'Workflows' | translate }}</h2>
</div>
</os-head-bar> </os-head-bar>
<os-list-view-table <os-list-view-table
@ -30,10 +32,10 @@
<!-- New workflow dialog --> <!-- New workflow dialog -->
<ng-template #newWorkflowDialog> <ng-template #newWorkflowDialog>
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span translate>New workflow</span> <span>{{ 'New workflow' | translate }}</span>
</h1> </h1>
<div mat-dialog-content> <div mat-dialog-content>
<p translate>Please enter a name for the new workflow:</p> <p>{{ 'Please enter a name for the new workflow:' | translate }}</p>
<mat-form-field> <mat-form-field>
<input matInput osAutofocus [(ngModel)]="newWorkflowTitle" required /> <input matInput osAutofocus [(ngModel)]="newWorkflowTitle" required />
</mat-form-field> </mat-form-field>
@ -46,10 +48,10 @@
[disabled]="newWorkflowTitle === ''" [disabled]="newWorkflowTitle === ''"
[mat-dialog-close]="newWorkflowTitle" [mat-dialog-close]="newWorkflowTitle"
> >
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -4,7 +4,7 @@
<!-- Content --> <!-- Content -->
<div mat-dialog-content class="motion-export-dialog-wrapper"> <div mat-dialog-content class="motion-export-dialog-wrapper">
<div> <div>
<p class="toggle-group-head" translate>Format</p> <p class="toggle-group-head">{{ 'Format' | translate }}</p>
<mat-button-toggle-group class="smaller-buttons" formControlName="format"> <mat-button-toggle-group class="smaller-buttons" formControlName="format">
<mat-button-toggle [value]="fileFormat.PDF">PDF</mat-button-toggle> <mat-button-toggle [value]="fileFormat.PDF">PDF</mat-button-toggle>
<mat-button-toggle [value]="fileFormat.CSV">CSV</mat-button-toggle> <mat-button-toggle [value]="fileFormat.CSV">CSV</mat-button-toggle>
@ -13,64 +13,84 @@
</div> </div>
<div> <div>
<p class="toggle-group-head" translate>Line numbering</p> <p class="toggle-group-head">{{ 'Line numbering' | translate }}</p>
<mat-button-toggle-group class="smaller-buttons" formControlName="lnMode"> <mat-button-toggle-group class="smaller-buttons" formControlName="lnMode">
<mat-button-toggle [value]="lnMode.None"> <span translate>None</span> </mat-button-toggle> <mat-button-toggle [value]="lnMode.None">
<mat-button-toggle [value]="lnMode.Outside"> <span translate>Outside</span> </mat-button-toggle> <span>{{ 'None' | translate }}</span>
</mat-button-toggle>
<mat-button-toggle [value]="lnMode.Outside">
<span>{{ 'Outside' | translate }}</span>
</mat-button-toggle>
</mat-button-toggle-group> </mat-button-toggle-group>
</div> </div>
<div> <div>
<p class="toggle-group-head" translate>Change recommendations</p> <p class="toggle-group-head">{{ 'Change recommendations' | translate }}</p>
<mat-button-toggle-group class="smaller-buttons" formControlName="crMode"> <mat-button-toggle-group class="smaller-buttons" formControlName="crMode">
<mat-button-toggle [value]="crMode.Original"> <mat-button-toggle [value]="crMode.Original">
<span translate>Original version</span> <span>{{ 'Original version' | translate }}</span>
</mat-button-toggle>
<mat-button-toggle [value]="crMode.Changed">
<span>{{ 'Changed version' | translate }}</span>
</mat-button-toggle> </mat-button-toggle>
<mat-button-toggle [value]="crMode.Changed"> <span translate>Changed version</span> </mat-button-toggle>
<mat-button-toggle [value]="crMode.Diff" #diffVersionButton> <mat-button-toggle [value]="crMode.Diff" #diffVersionButton>
<span translate>Diff version</span> <span>{{ 'Diff version' | translate }}</span>
</mat-button-toggle>
<mat-button-toggle [value]="crMode.ModifiedFinal">
<span>{{ 'Final version' | translate }}</span>
</mat-button-toggle> </mat-button-toggle>
<mat-button-toggle [value]="crMode.ModifiedFinal"> <span translate>Final version</span> </mat-button-toggle>
</mat-button-toggle-group> </mat-button-toggle-group>
</div> </div>
<div> <div>
<p class="toggle-group-head" translate>Content</p> <p class="toggle-group-head">{{ 'Content' | translate }}</p>
<mat-button-toggle-group class="smaller-buttons" multiple formControlName="content"> <mat-button-toggle-group class="smaller-buttons" multiple formControlName="content">
<mat-button-toggle value="text"> <span translate>Text</span> </mat-button-toggle> <mat-button-toggle value="text">
<mat-button-toggle value="reason"> <span translate>Reason</span> </mat-button-toggle> <span>{{ 'Text' | translate }}</span>
</mat-button-toggle>
<mat-button-toggle value="reason">
<span>{{ 'Reason' | translate }}</span>
</mat-button-toggle>
</mat-button-toggle-group> </mat-button-toggle-group>
</div> </div>
<div> <div>
<p class="toggle-group-head" translate>Meta information</p> <p class="toggle-group-head">{{ 'Meta information' | translate }}</p>
<mat-button-toggle-group class="smaller-buttons" multiple formControlName="metaInfo"> <mat-button-toggle-group class="smaller-buttons" multiple formControlName="metaInfo">
<mat-button-toggle *ngFor="let metaInfo of metaInfoExportOrder" [value]="metaInfo"> <mat-button-toggle *ngFor="let metaInfo of metaInfoExportOrder" [value]="metaInfo">
<span>{{ getLabelForMetadata(metaInfo) | translate }}</span> <span>{{ getLabelForMetadata(metaInfo) | translate }}</span>
</mat-button-toggle> </mat-button-toggle>
<mat-button-toggle *osPerms="'agenda.can_see_list_of_speakers'" value="speakers" #speakersButton> <mat-button-toggle *osPerms="'agenda.can_see_list_of_speakers'" value="speakers" #speakersButton>
<span translate>Speakers</span> <span>{{ 'Speakers' | translate }}</span>
</mat-button-toggle> </mat-button-toggle>
<mat-button-toggle value="polls" #votingResultButton> <mat-button-toggle value="polls" #votingResultButton>
<span translate>Voting result</span> <span>{{ 'Voting result' | translate }}</span>
</mat-button-toggle> </mat-button-toggle>
</mat-button-toggle-group> </mat-button-toggle-group>
</div> </div>
<div> <div>
<p class="toggle-group-head" translate>PDF options</p> <p class="toggle-group-head">{{ 'PDF options' | translate }}</p>
<mat-button-toggle-group class="smaller-buttons" multiple formControlName="pdfOptions"> <mat-button-toggle-group class="smaller-buttons" multiple formControlName="pdfOptions">
<mat-button-toggle value="toc"> <span translate>Table of contents</span> </mat-button-toggle> <mat-button-toggle value="toc">
<mat-button-toggle value="page"> <span translate>Page numbers</span> </mat-button-toggle> <span>{{ 'Table of contents' | translate }}</span>
<mat-button-toggle value="date"> <span translate>Current date</span> </mat-button-toggle> </mat-button-toggle>
<mat-button-toggle value="addBreaks"> <span translate>Enforce page breaks</span> </mat-button-toggle> <mat-button-toggle value="page">
<span>{{ 'Page numbers' | translate }}</span>
</mat-button-toggle>
<mat-button-toggle value="date">
<span>{{ 'Current date' | translate }}</span>
</mat-button-toggle>
<mat-button-toggle value="addBreaks">
<span>{{ 'Enforce page breaks' | translate }}</span>
</mat-button-toggle>
</mat-button-toggle-group> </mat-button-toggle-group>
</div> </div>
<div> <div>
<p class="toggle-group-head" translate>Comments</p> <p class="toggle-group-head">{{ 'Comments' | translate }}</p>
<mat-button-toggle-group class="smaller-buttons" multiple formControlName="comments"> <mat-button-toggle-group class="smaller-buttons" multiple formControlName="comments">
<mat-button-toggle [value]="PERSONAL_NOTE_ID"> <mat-button-toggle [value]="PERSONAL_NOTE_ID">
<span translate>Personal note</span> <span>{{ 'Personal note' | translate }}</span>
</mat-button-toggle> </mat-button-toggle>
<mat-button-toggle *ngFor="let comment of commentsToExport" [value]="comment.id"> <mat-button-toggle *ngFor="let comment of commentsToExport" [value]="comment.id">
<span>{{ comment.name }}</span> <span>{{ comment.name }}</span>
@ -85,8 +105,10 @@
<!-- Action buttons --> <!-- Action buttons -->
<div mat-dialog-actions> <div mat-dialog-actions>
<button mat-button type="button" color="primary" [mat-dialog-close]="exportForm.value"> <button mat-button type="button" color="primary" [mat-dialog-close]="exportForm.value">
<span translate>Export</span> <span>{{ 'Export' | translate }}</span>
</button>
<button mat-button type="button" (click)="onCloseClick()">
<span>{{ 'Cancel' | translate }}</span>
</button> </button>
<button mat-button type="button" (click)="onCloseClick()"><span translate>Cancel</span></button>
</div> </div>
</form> </form>

View File

@ -4,7 +4,7 @@
(click)="action.emit(multiselectService.bulkSetFavorite(selectedMotions))" (click)="action.emit(multiselectService.bulkSetFavorite(selectedMotions))"
> >
<mat-icon>star</mat-icon> <mat-icon>star</mat-icon>
<span translate>Set favorite</span> <span>{{ 'Set favorite' | translate }}</span>
</button> </button>
<button <button
mat-menu-item mat-menu-item
@ -12,7 +12,7 @@
(click)="action.emit(multiselectService.setStateOfMultiple(selectedMotions))" (click)="action.emit(multiselectService.setStateOfMultiple(selectedMotions))"
> >
<mat-icon>label</mat-icon> <mat-icon>label</mat-icon>
<span translate>Set status</span> <span>{{ 'Set status' | translate }}</span>
</button> </button>
<button <button
*ngIf="recommendationEnabled" *ngIf="recommendationEnabled"
@ -22,7 +22,7 @@
> >
<mat-icon>report</mat-icon> <mat-icon>report</mat-icon>
<!-- TODO: better icon --> <!-- TODO: better icon -->
<span translate>Set recommendation</span> <span>{{ 'Set recommendation' | translate }}</span>
</button> </button>
<button <button
mat-menu-item mat-menu-item
@ -32,7 +32,7 @@
> >
<mat-icon>category</mat-icon> <mat-icon>category</mat-icon>
<!-- TODO: icon --> <!-- TODO: icon -->
<span translate>Set category</span> <span>{{ 'Set category' | translate }}</span>
</button> </button>
<button <button
mat-menu-item mat-menu-item
@ -42,7 +42,7 @@
> >
<mat-icon>widgets</mat-icon> <mat-icon>widgets</mat-icon>
<!-- TODO: icon --> <!-- TODO: icon -->
<span translate>Set motion block</span> <span>{{ 'Set motion block' | translate }}</span>
</button> </button>
<button <button
@ -52,7 +52,7 @@
> >
<mat-icon>person_add</mat-icon> <mat-icon>person_add</mat-icon>
<!-- TODO: icon --> <!-- TODO: icon -->
<span translate>Add/remove submitters</span> <span>{{ 'Add/remove submitters' | translate }}</span>
</button> </button>
<button <button
mat-menu-item mat-menu-item
@ -62,7 +62,7 @@
> >
<mat-icon>bookmarks</mat-icon> <mat-icon>bookmarks</mat-icon>
<!-- TODO: icon --> <!-- TODO: icon -->
<span translate>Add/remove tags</span> <span>{{ 'Add/remove tags' | translate }}</span>
</button> </button>
<ng-content></ng-content> <ng-content></ng-content>
@ -70,7 +70,7 @@
<ng-container *osPerms="'motions.can_manage'"> <ng-container *osPerms="'motions.can_manage'">
<button mat-menu-item [disabled]="!selectedMotions.length" (click)="openExportDialog()"> <button mat-menu-item [disabled]="!selectedMotions.length" (click)="openExportDialog()">
<mat-icon>archive</mat-icon> <mat-icon>archive</mat-icon>
<span translate>Export selected motions</span> <span>{{ 'Export selected motions' | translate }}</span>
</button> </button>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button <button
@ -80,6 +80,6 @@
(click)="action.emit(multiselectService.delete(selectedMotions))" (click)="action.emit(multiselectService.delete(selectedMotions))"
> >
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</ng-container> </ng-container>

View File

@ -1,28 +1,40 @@
<os-head-bar [nav]="false"> <os-head-bar [nav]="false">
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Import statute</h2></div> <div class="title-slot">
<h2>{{ 'Import statute' | translate }}</h2>
</div>
<div class="menu-slot"> <div class="menu-slot">
<button *ngIf="hasFile && newCount" mat-button (click)="doImport()"> <button *ngIf="hasFile && newCount" mat-button (click)="doImport()">
<span class="upper" translate>Import</span> <span class="upper">{{ 'Import' | translate }}</span>
</button> </button>
</div> </div>
</os-head-bar> </os-head-bar>
<mat-card class="os-form-card import-table"> <mat-card class="os-form-card import-table">
<span translate>Required comma or semicolon separated values with these column header names in the first row:</span> <span>{{
'Required comma or semicolon separated values with these column header names in the first row:' | translate
}}</span>
<br /> <br />
<div class="code red-warning-text"><span translate>Title</span>, <span translate>Text</span></div> <div class="code red-warning-text">
<span>{{ 'Title' | translate }}</span
>, <span>{{ 'Text' | translate }}</span>
</div>
<ul> <ul>
<li translate>Additional columns after the required ones may be present and won't affect the import.</li> <li>
{{
'Additional columns after the required ones may be present and will not affect the import.' | translate
}}
</li>
</ul> </ul>
<button mat-button color="accent" (click)="downloadCsvExample()" translate>Download CSV example file</button> <button mat-button color="accent" (click)="downloadCsvExample()">
{{ 'Download CSV example file' | translate }}
</button>
<div class="wrapper"> <div class="wrapper">
<mat-form-field> <mat-form-field>
<mat-label translate>Encoding of the file</mat-label> <mat-label>{{ 'Encoding of the file' | translate }}</mat-label>
<mat-select <mat-select
class="selection" class="selection"
placeholder="translate.instant('Select encoding')"
(selectionChange)="selectEncoding($event)" (selectionChange)="selectEncoding($event)"
[value]="encodings[0].value" [value]="encodings[0].value"
> >
@ -32,7 +44,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<mat-label translate>Column separator</mat-label> <mat-label>{{ 'Column separator' | translate }}</mat-label>
<mat-select class="selection" (selectionChange)="selectColSep($event)" value=""> <mat-select class="selection" (selectionChange)="selectColSep($event)" value="">
<mat-option *ngFor="let option of columnSeparators" [value]="option.value"> <mat-option *ngFor="let option of columnSeparators" [value]="option.value">
{{ option.label | translate }} {{ option.label | translate }}
@ -40,7 +52,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<mat-label translate>Text separator</mat-label> <mat-label>{{ 'Text separator' | translate }}</mat-label>
<mat-select class="selection" (selectionChange)="selectTextSep($event)" value='"'> <mat-select class="selection" (selectionChange)="selectTextSep($event)" value='"'>
<mat-option *ngFor="let option of textSeparators" [value]="option.value"> <mat-option *ngFor="let option of textSeparators" [value]="option.value">
{{ option.label | translate }} {{ option.label | translate }}
@ -58,42 +70,44 @@
(change)="onSelectFile($event)" (change)="onSelectFile($event)"
/> />
<button mat-button osAutofocus onclick="document.getElementById('statute-import-file-input').click()"> <button mat-button osAutofocus onclick="document.getElementById('statute-import-file-input').click()">
<span translate> Select file</span> <span>{{ 'Select file' | translate }}</span>
</button> </button>
</div> </div>
</mat-card> </mat-card>
<!-- preview table --> <!-- preview table -->
<mat-card *ngIf="hasFile" class="os-form-card import-table"> <mat-card *ngIf="hasFile" class="os-form-card import-table">
<h3 translate>Preview</h3> <h3>{{ 'Preview' | translate }}</h3>
<div class="summary"> <div class="summary">
<!-- new entries --> <!-- new entries -->
<div *ngIf="newCount"> <div *ngIf="newCount">
&nbsp; &nbsp;
<mat-icon inline>playlist_add</mat-icon> <mat-icon inline>playlist_add</mat-icon>
<span>&nbsp;{{ newCount }}&nbsp;</span> <span translate>statute paragraphs(s) will be imported.</span> <span>&nbsp;{{ newCount }}&nbsp;</span>
<span>{{ 'statute paragraphs(s) will be imported.' | translate }}</span>
</div> </div>
<!-- errors/duplicates --> <!-- errors/duplicates -->
<div *ngIf="nonImportableCount" class="red-warning-text"> <div *ngIf="nonImportableCount" class="red-warning-text">
&nbsp; &nbsp;
<mat-icon inline>warning</mat-icon> <mat-icon inline>warning</mat-icon>
<span>&nbsp;{{ nonImportableCount }}&nbsp;</span> <span translate>entries will be ommitted.</span> <span>&nbsp;{{ nonImportableCount }}&nbsp;</span> <span>{{ 'entries will be ommitted.' | translate }}</span>
</div> </div>
<!-- have been imported --> <!-- have been imported -->
<div *ngIf="doneCount" class="green-text"> <div *ngIf="doneCount" class="green-text">
&nbsp; &nbsp;
<mat-icon inline>done</mat-icon> <mat-icon inline>done</mat-icon>
<span>&nbsp;{{ doneCount }}&nbsp;</span> <span translate>statute paragraphs have been imported.</span> <span>&nbsp;{{ doneCount }}&nbsp;</span>
<span>{{ 'statute paragraphs have been imported.' | translate }}</span>
</div> </div>
</div> </div>
<div *ngIf="newCount"> <div *ngIf="newCount">
<span translate>After verifiy the preview click on 'import' please (see top right).</span> <span>{{ 'After verifiy the preview click on "import" please (see top right).' | translate }}</span>
</div> </div>
<div> <div>
<mat-select *ngIf="nonImportableCount" class="filter-imports" [(value)]="shown" (selectionChange)="setFilter()"> <mat-select *ngIf="nonImportableCount" class="filter-imports" [(value)]="shown" (selectionChange)="setFilter()">
<mat-option value="all" translate> Show all </mat-option> <mat-option value="all">{{ 'Show all' | translate }}</mat-option>
<mat-option value="error" translate> Show errors only </mat-option> <mat-option value="error">{{ 'Show errors only' | translate }}</mat-option>
<mat-option value="noerror" translate> Show correct entries </mat-option> <mat-option value="noerror">{{ 'Show correct entries' | translate }}</mat-option>
</mat-select> </mat-select>
</div> </div>
<div class="table-container"> <div class="table-container">
@ -125,7 +139,7 @@
<!-- title column --> <!-- title column -->
<ng-container matColumnDef="title"> <ng-container matColumnDef="title">
<mat-header-cell *matHeaderCellDef translate>Title</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Title' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<mat-icon <mat-icon
color="warn" color="warn"
@ -140,7 +154,7 @@
<!-- text column --> <!-- text column -->
<ng-container matColumnDef="text"> <ng-container matColumnDef="text">
<mat-header-cell *matHeaderCellDef translate>Text</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Text' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry" matTooltip="{{ getLongPreview(entry.newEntry.text) }}"> <mat-cell *matCellDef="let entry" matTooltip="{{ getLongPreview(entry.newEntry.text) }}">
<mat-icon <mat-icon
color="warn" color="warn"

View File

@ -1,7 +1,7 @@
<os-head-bar prevUrl="../.." [nav]="false" [hasMainButton]="true" (mainEvent)="openDialog()"> <os-head-bar prevUrl="../.." [nav]="false" [hasMainButton]="true" (mainEvent)="openDialog()">
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 translate>Statute</h2> <h2>{{ 'Statute' | translate }}</h2>
</div> </div>
<!-- Use the menu slot for an add button --> <!-- Use the menu slot for an add button -->
@ -14,10 +14,7 @@
<cdk-virtual-scroll-viewport itemSize="50" [ngClass]="statuteParagraphs.length ? 'virtual-scroll-full-page' : ''"> <cdk-virtual-scroll-viewport itemSize="50" [ngClass]="statuteParagraphs.length ? 'virtual-scroll-full-page' : ''">
<mat-accordion class="os-card"> <mat-accordion class="os-card">
<mat-expansion-panel <mat-expansion-panel *cdkVirtualFor="let statuteParagraph of statuteParagraphs" multiple="false">
*cdkVirtualFor="let statuteParagraph of statuteParagraphs"
multiple="false"
>
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title> <mat-panel-title>
{{ statuteParagraph.title }} {{ statuteParagraph.title }}
@ -43,26 +40,26 @@
<mat-card *ngIf="statuteParagraphs.length === 0"> <mat-card *ngIf="statuteParagraphs.length === 0">
<mat-card-content> <mat-card-content>
<div class="no-content" translate>No statute paragraphs</div> <div class="no-content">{{ 'No statute paragraphs' | translate }}</div>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
<mat-menu #commentMenu="matMenu"> <mat-menu #commentMenu="matMenu">
<button mat-menu-item (click)="onCsvExport()"> <button mat-menu-item (click)="onCsvExport()">
<mat-icon>archive</mat-icon> <mat-icon>archive</mat-icon>
<span translate>Export as CSV</span> <span>{{ 'Export as CSV' | translate }}</span>
</button> </button>
<button mat-menu-item *osPerms="'motions.can_manage'" routerLink="import"> <button mat-menu-item *osPerms="'motions.can_manage'" routerLink="import">
<mat-icon>cloud_upload</mat-icon> <mat-icon>cloud_upload</mat-icon>
<span translate>Import</span> <span>{{ 'Import' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>
<!-- Template for statute paragraph dialog --> <!-- Template for statute paragraph dialog -->
<ng-template #statuteParagraphDialog> <ng-template #statuteParagraphDialog>
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span *ngIf="currentStatuteParagraph" translate>Edit statute paragraph</span> <span *ngIf="currentStatuteParagraph">{{ 'Edit statute paragraph' | translate }}</span>
<span *ngIf="!currentStatuteParagraph" translate>New statute paragraph</span> <span *ngIf="!currentStatuteParagraph">{{ 'New statute paragraph' | translate }}</span>
</h1> </h1>
<div class="os-form-card-mobile" mat-dialog-content> <div class="os-form-card-mobile" mat-dialog-content>
<form [formGroup]="statuteParagraphForm" (keydown)="onKeyDown($event)"> <form [formGroup]="statuteParagraphForm" (keydown)="onKeyDown($event)">
@ -70,23 +67,23 @@
<mat-form-field> <mat-form-field>
<input formControlName="title" matInput placeholder="{{ 'Title' | translate }}" required /> <input formControlName="title" matInput placeholder="{{ 'Title' | translate }}" required />
<mat-hint *ngIf="!statuteParagraphForm.controls.title.valid"> <mat-hint *ngIf="!statuteParagraphForm.controls.title.valid">
<span translate>Required</span> <span>{{ 'Required' | translate }}</span>
</mat-hint> </mat-hint>
</mat-form-field> </mat-form-field>
</p> </p>
<span> <span>
<!-- The HTML Editor --> <!-- The HTML Editor -->
<h4 translate>Statute paragraph</h4> <h4>{{ 'Statute paragraph' | translate }}</h4>
<editor formControlName="text" [init]="tinyMceSettings"></editor> <editor formControlName="text" [init]="tinyMceSettings"></editor>
</span> </span>
</form> </form>
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button mat-button [mat-dialog-close]="true" [disabled]="!statuteParagraphForm.valid"> <button mat-button [mat-dialog-close]="true" [disabled]="!statuteParagraphForm.valid">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button mat-button [mat-dialog-close]="false"> <button mat-button [mat-dialog-close]="false">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -17,7 +17,7 @@
{{ option.value | translate }} {{ option.value | translate }}
</mat-option> </mat-option>
</mat-select> </mat-select>
<mat-error translate>This field is required.</mat-error> <mat-error>{{ 'This field is required.' | translate }}</mat-error>
<mat-hint (click)="openVotingWarning()" *ngIf="showNonNominalWarning"> <mat-hint (click)="openVotingWarning()" *ngIf="showNonNominalWarning">
{{ 'Not suitable for formal secret voting!' | translate }}</mat-hint {{ 'Not suitable for formal secret voting!' | translate }}</mat-hint
> >
@ -46,7 +46,7 @@
{{ option.value | translate }} {{ option.value | translate }}
</mat-option> </mat-option>
</mat-select> </mat-select>
<mat-error translate>This field is required.</mat-error> <mat-error>{{ 'This field is required.' | translate }}</mat-error>
</mat-form-field> </mat-form-field>
</ng-container> </ng-container>

View File

@ -1,5 +1,5 @@
<os-head-bar> <os-head-bar>
<div class="title-slot" translate>List of electronic votes</div> <div class="title-slot">{{ 'List of electronic votes' | translate }}</div>
</os-head-bar> </os-head-bar>
<os-list-view-table <os-list-view-table

View File

@ -3,6 +3,6 @@
<span>{{ poll.votescast }} / {{ max }}</span> <span>{{ poll.votescast }} / {{ max }}</span>
</div> </div>
<span translate>Received votes</span> <span>{{ 'Received votes' | translate }}</span>
<mat-progress-bar class="voting-progress-bar" [value]="valueInPercent"></mat-progress-bar> <mat-progress-bar class="voting-progress-bar" [value]="valueInPercent"></mat-progress-bar>
</div> </div>

View File

@ -1,5 +1,5 @@
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span translate>Countdown</span> <span>{{ 'Countdown' | translate }}</span>
</h1> </h1>
<form [formGroup]="countdownForm"> <form [formGroup]="countdownForm">
@ -34,12 +34,12 @@
[mat-dialog-close]="countdownForm.value" [mat-dialog-close]="countdownForm.value"
[disabled]="!countdownForm.valid" [disabled]="!countdownForm.valid"
> >
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<!-- Cancel Countdown button --> <!-- Cancel Countdown button -->
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</form> </form>

View File

@ -1,5 +1,5 @@
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span translate>Message</span> <span>{{ 'Message' | translate }}</span>
</h1> </h1>
<form [formGroup]="messageForm"> <form [formGroup]="messageForm">
@ -16,12 +16,12 @@
[mat-dialog-close]="messageForm.value" [mat-dialog-close]="messageForm.value"
[disabled]="!messageForm.valid" [disabled]="!messageForm.valid"
> >
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<!-- Cancel Countdown button --> <!-- Cancel Countdown button -->
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</form> </form>

View File

@ -1,6 +1,6 @@
<mat-expansion-panel *ngIf="elements.length"> <mat-expansion-panel *ngIf="elements.length">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<span translate>Media file</span> <span>{{ 'Media file' | translate }}</span>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<div *ngFor="let element of elements"> <div *ngFor="let element of elements">
<i>{{ getMediafile(element).getTitle() }}</i> <i>{{ getMediafile(element).getTitle() }}</i>
@ -11,18 +11,23 @@
<button type="button" *ngIf="!!element.fullscreen" mat-icon-button (click)="fullscreen(element)"> <button type="button" *ngIf="!!element.fullscreen" mat-icon-button (click)="fullscreen(element)">
<mat-icon>check_box</mat-icon> <mat-icon>check_box</mat-icon>
</button> </button>
<span translate>fullscreen</span> <span>{{ 'fullscreen' | translate }}</span>
</div> </div>
<div *ngIf="getMediafile(element).isPdf()"> <div *ngIf="getMediafile(element).isPdf()">
<button type="button" mat-icon-button (click)="pdfBackward(element)" [disabled]="getPage(element) <= 1"> <button type="button" mat-icon-button (click)="pdfBackward(element)" [disabled]="getPage(element) <= 1">
<mat-icon>arrow_back</mat-icon> <mat-icon>arrow_back</mat-icon>
</button> </button>
<button type="button" mat-icon-button (click)="pdfForward(element)" [disabled]="getPage(element) >= getMediafile(element).pages"> <button
type="button"
mat-icon-button
(click)="pdfForward(element)"
[disabled]="getPage(element) >= getMediafile(element).pages"
>
<mat-icon>arrow_forward</mat-icon> <mat-icon>arrow_forward</mat-icon>
</button> </button>
<!-- TODO: Use form for page number; use pdfSetPage then. --> <!-- TODO: Use form for page number; use pdfSetPage then. -->
<span translate>Page</span> {{ getPage(element) }}/{{ getMediafile(element).pages }} <span>{{ 'Page' | translate }}</span> {{ getPage(element) }}/{{ getMediafile(element).pages }}
<br> <br />
<button type="button" mat-icon-button (click)="zoom(element, 'in')"> <button type="button" mat-icon-button (click)="zoom(element, 'in')">
<mat-icon>zoom_in</mat-icon> <mat-icon>zoom_in</mat-icon>
</button> </button>

View File

@ -33,7 +33,7 @@
<!-- delete --> <!-- delete -->
<button mat-menu-item class="red-warning-text" (click)="onDeleteProjectorButton()"> <button mat-menu-item class="red-warning-text" (click)="onDeleteProjectorButton()">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</mat-menu> </mat-menu>
</os-head-bar> </os-head-bar>
@ -143,7 +143,7 @@
[disabled]="projector?.elements_history.length === 0" [disabled]="projector?.elements_history.length === 0"
> >
<mat-icon>arrow_back</mat-icon> <mat-icon>arrow_back</mat-icon>
<span translate>Previous</span> <span>{{ 'Previous' | translate }}</span>
</button> </button>
<button <button
type="button" type="button"
@ -151,7 +151,7 @@
(click)="projectNextSlide()" (click)="projectNextSlide()"
[disabled]="projector?.elements_preview.length === 0" [disabled]="projector?.elements_preview.length === 0"
> >
<span translate>Next</span> <span>{{ 'Next' | translate }}</span>
<mat-icon>arrow_forward</mat-icon> <mat-icon>arrow_forward</mat-icon>
</button> </button>
<hr /> <hr />
@ -186,7 +186,7 @@
<!-- Queue --> <!-- Queue -->
<mat-expansion-panel *ngIf="projector.elements_preview.length" [expanded]="true" class="queue"> <mat-expansion-panel *ngIf="projector.elements_preview.length" [expanded]="true" class="queue">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<span translate>Queue</span> <span>{{ 'Queue' | translate }}</span>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<div <div
cdkDropList cdkDropList
@ -232,7 +232,7 @@
<!-- countdowns --> <!-- countdowns -->
<mat-expansion-panel> <mat-expansion-panel>
<mat-expansion-panel-header> <mat-expansion-panel-header>
<span translate>Countdowns</span> <span>{{ 'Countdowns' | translate }}</span>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<mat-list> <mat-list>
<mat-list-item *ngFor="let countdown of countdowns" class="larger-mat-list-item"> <mat-list-item *ngFor="let countdown of countdowns" class="larger-mat-list-item">
@ -247,7 +247,7 @@
<mat-action-row> <mat-action-row>
<button type="button" mat-button (click)="openCountdownDialog()"> <button type="button" mat-button (click)="openCountdownDialog()">
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
<span translate>Add countdown</span> <span>{{ 'Add countdown' | translate }}</span>
</button> </button>
</mat-action-row> </mat-action-row>
</mat-expansion-panel> </mat-expansion-panel>
@ -255,7 +255,7 @@
<!-- messages --> <!-- messages -->
<mat-expansion-panel> <mat-expansion-panel>
<mat-expansion-panel-header> <mat-expansion-panel-header>
<span translate>Messages</span> <span>{{ 'Messages' | translate }}</span>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<mat-list> <mat-list>
<mat-list-item *ngFor="let message of messages" class="larger-mat-list-item"> <mat-list-item *ngFor="let message of messages" class="larger-mat-list-item">
@ -271,7 +271,7 @@
<mat-action-row> <mat-action-row>
<button type="button" mat-button (click)="openMessagesDialog()"> <button type="button" mat-button (click)="openMessagesDialog()">
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
<span translate>Add message</span> <span>{{ 'Add message' | translate }}</span>
</button> </button>
</mat-action-row> </mat-action-row>
</mat-expansion-panel> </mat-expansion-panel>
@ -279,7 +279,7 @@
<!-- Current list of speakers --> <!-- Current list of speakers -->
<mat-expansion-panel> <mat-expansion-panel>
<mat-expansion-panel-header> <mat-expansion-panel-header>
<span translate>Current list of speakers</span> <span>{{ 'Current list of speakers' | translate }}</span>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<!-- Slide--> <!-- Slide-->
@ -293,7 +293,7 @@
> >
<mat-icon>videocam</mat-icon> <mat-icon>videocam</mat-icon>
</button> </button>
<span class="spacer-left-10" translate>Slide</span> <span class="spacer-left-10">{{ 'Slide' | translate }}</span>
</mat-list-item> </mat-list-item>
</mat-list> </mat-list>
@ -308,7 +308,7 @@
> >
<mat-icon>videocam</mat-icon> <mat-icon>videocam</mat-icon>
</button> </button>
<span class="spacer-left-10" translate>Overlay</span> <span class="spacer-left-10">{{ 'Overlay' | translate }}</span>
</mat-list-item> </mat-list-item>
</mat-list> </mat-list>
@ -323,14 +323,14 @@
> >
<mat-icon>videocam</mat-icon> <mat-icon>videocam</mat-icon>
</button> </button>
<span class="spacer-left-10" translate>Chyron</span> <span class="spacer-left-10">{{ 'Chyron' | translate }}</span>
</mat-list-item> </mat-list-item>
</mat-list> </mat-list>
</mat-expansion-panel> </mat-expansion-panel>
<mat-expansion-panel *ngIf="projector.elements_history.length"> <mat-expansion-panel *ngIf="projector.elements_history.length">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<span translate>Previous slides</span> <span>{{ 'Previous slides' | translate }}</span>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<ol> <ol>
<li *ngFor="let elements of projector.elements_history"> <li *ngFor="let elements of projector.elements_history">

View File

@ -1,5 +1,5 @@
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span translate>Edit projector</span> <span>{{ 'Edit projector' | translate }}</span>
</h1> </h1>
<div class="settings-grid"> <div class="settings-grid">
@ -9,11 +9,11 @@
<mat-form-field> <mat-form-field>
<input formControlName="name" matInput placeholder="{{ 'Name' | translate }}" required /> <input formControlName="name" matInput placeholder="{{ 'Name' | translate }}" required />
<mat-hint *ngIf="!updateForm.controls.name.valid"> <mat-hint *ngIf="!updateForm.controls.name.valid">
<span translate>Required</span> <span>{{ 'Required' | translate }}</span>
</mat-hint> </mat-hint>
</mat-form-field> </mat-form-field>
<h3 translate>Resolution and size</h3> <h3>{{ 'Resolution and size' | translate }}</h3>
<!-- Aspect ratio field --> <!-- Aspect ratio field -->
<div> <div>
<mat-radio-group formControlName="aspectRatio" name="aspectRatio"> <mat-radio-group formControlName="aspectRatio" name="aspectRatio">
@ -72,28 +72,28 @@
<div> <div>
<div> <div>
<mat-checkbox formControlName="show_header_footer"> <mat-checkbox formControlName="show_header_footer">
<span translate>Show header and footer</span> <span>{{ 'Show header and footer' | translate }}</span>
</mat-checkbox> </mat-checkbox>
</div> </div>
<div> <div>
<mat-checkbox formControlName="show_title"> <mat-checkbox formControlName="show_title">
<span translate>Show title</span> <span>{{ 'Show title' | translate }}</span>
</mat-checkbox> </mat-checkbox>
</div> </div>
<div> <div>
<mat-checkbox formControlName="show_logo"> <mat-checkbox formControlName="show_logo">
<span translate>Show logo</span> <span>{{ 'Show logo' | translate }}</span>
</mat-checkbox> </mat-checkbox>
</div> </div>
<div> <div>
<mat-checkbox formControlName="clock"> <mat-checkbox formControlName="clock">
<span translate>Show clock</span> <span>{{ 'Show clock' | translate }}</span>
</mat-checkbox> </mat-checkbox>
</div> </div>
</div> </div>
<!-- projection defaults --> <!-- projection defaults -->
<h3 translate>Projection defaults</h3> <h3>{{ 'Projection defaults' | translate }}</h3>
<mat-select <mat-select
formControlName="projectiondefaults_id" formControlName="projectiondefaults_id"
placeholder="{{ 'Projection defaults' | translate }}" placeholder="{{ 'Projection defaults' | translate }}"
@ -130,43 +130,49 @@
<ng-template <ng-template
[ngTemplateOutlet]="colorFormField" [ngTemplateOutlet]="colorFormField"
[ngTemplateOutletContext]="{ title: 'Foreground color' | translate, form: 'color' }" [ngTemplateOutletContext]="{ title: 'Foreground color', form: 'color' }"
> >
</ng-template> </ng-template>
<ng-template <ng-template
[ngTemplateOutlet]="colorFormField" [ngTemplateOutlet]="colorFormField"
[ngTemplateOutletContext]="{ title: 'Background color' | translate, form: 'background_color' }" [ngTemplateOutletContext]="{ title: 'Background color', form: 'background_color' }"
> >
</ng-template> </ng-template>
<ng-template <ng-template
[ngTemplateOutlet]="colorFormField" [ngTemplateOutlet]="colorFormField"
[ngTemplateOutletContext]="{ title: 'Header background color' | translate, form: 'header_background_color' }" [ngTemplateOutletContext]="{
title: 'Header background color',
form: 'header_background_color'
}"
> >
</ng-template> </ng-template>
<ng-template <ng-template
[ngTemplateOutlet]="colorFormField" [ngTemplateOutlet]="colorFormField"
[ngTemplateOutletContext]="{ title: 'Header font color' | translate, form: 'header_font_color' }" [ngTemplateOutletContext]="{ title: 'Header font color', form: 'header_font_color' }"
> >
</ng-template> </ng-template>
<ng-template <ng-template
[ngTemplateOutlet]="colorFormField" [ngTemplateOutlet]="colorFormField"
[ngTemplateOutletContext]="{ title: 'Headline color' | translate, form: 'header_h1_color' }" [ngTemplateOutletContext]="{ title: 'Headline color', form: 'header_h1_color' }"
> >
</ng-template> </ng-template>
<ng-template <ng-template
[ngTemplateOutlet]="colorFormField" [ngTemplateOutlet]="colorFormField"
[ngTemplateOutletContext]="{ title: 'Chyron background color' | translate, form: 'chyron_background_color' }" [ngTemplateOutletContext]="{
title: 'Chyron background color',
form: 'chyron_background_color'
}"
> >
</ng-template> </ng-template>
<ng-template <ng-template
[ngTemplateOutlet]="colorFormField" [ngTemplateOutlet]="colorFormField"
[ngTemplateOutletContext]="{ title: 'Chyron font color' | translate, form: 'chyron_font_color' }" [ngTemplateOutletContext]="{ title: 'Chyron font color', form: 'chyron_font_color' }"
> >
</ng-template> </ng-template>
</div> </div>
@ -176,18 +182,18 @@
<div mat-dialog-actions> <div mat-dialog-actions>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button type="submit" mat-button color="primary"> <button type="submit" mat-button color="primary">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
<button type="button" mat-button (click)="applyChanges()"> <button type="button" mat-button (click)="applyChanges()">
<span translate>Apply</span> <span>{{ 'Apply' | translate }}</span>
</button> </button>
</div> </div>
</form> </form>
<div> <div>
<h3 translate>Preview</h3> <h3>{{ 'Preview' | translate }}</h3>
<div class="preview-container"> <div class="preview-container">
<os-projector #preview *ngIf="previewProjector" [projector]="previewProjector"></os-projector> <os-projector #preview *ngIf="previewProjector" [projector]="previewProjector"></os-projector>
</div> </div>

View File

@ -1,14 +1,14 @@
<os-head-bar [nav]="true" [hasMainButton]="canManage" (mainEvent)="createNewProjector(projectorDialog)"> <os-head-bar [nav]="true" [hasMainButton]="canManage" (mainEvent)="createNewProjector(projectorDialog)">
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 translate>Projectors</h2> <h2>{{ 'Projectors' | translate }}</h2>
</div> </div>
</os-head-bar> </os-head-bar>
<!-- Create projector dialog --> <!-- Create projector dialog -->
<ng-template #projectorDialog> <ng-template #projectorDialog>
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span translate>New Projector</span> <span>{{ 'New Projector' | translate }}</span>
</h1> </h1>
<form [formGroup]="createForm"> <form [formGroup]="createForm">
@ -16,17 +16,17 @@
<mat-form-field> <mat-form-field>
<input formControlName="name" matInput placeholder="{{ 'Name' | translate }}" required /> <input formControlName="name" matInput placeholder="{{ 'Name' | translate }}" required />
<mat-hint *ngIf="!createForm.controls.name.valid"> <mat-hint *ngIf="!createForm.controls.name.valid">
<span translate>Required</span> <span>{{ 'Required' | translate }}</span>
</mat-hint> </mat-hint>
</mat-form-field> </mat-form-field>
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button type="submit" mat-button [disabled]="!createForm.valid" color="primary" [mat-dialog-close]="true"> <button type="submit" mat-button [disabled]="!createForm.valid" color="primary" [mat-dialog-close]="true">
<span translate>Create</span> <span>{{ 'Create' | translate }}</span>
</button> </button>
<button type="button" mat-button [mat-dialog-close]="null"> <button type="button" mat-button [mat-dialog-close]="null">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</form> </form>

View File

@ -48,7 +48,7 @@
(click)="mobileAutoCloseNav()" (click)="mobileAutoCloseNav()"
> >
<mat-icon>info</mat-icon> <mat-icon>info</mat-icon>
<span translate>Legal notice</span> <span>{{ 'Legal notice' | translate }}</span>
</a> </a>
<a <a
[@navItemAnim] [@navItemAnim]
@ -58,7 +58,7 @@
(click)="mobileAutoCloseNav()" (click)="mobileAutoCloseNav()"
> >
<mat-icon>security</mat-icon> <mat-icon>security</mat-icon>
<span translate>Privacy policy</span> <span>{{ 'Privacy policy' | translate }}</span>
</a> </a>
<a <a
[@navItemAnim] [@navItemAnim]

View File

@ -1,5 +1,7 @@
<os-head-bar [hasMainButton]="true" [nav]="true" (mainEvent)="openTagDialog()" [multiSelectMode]="isMultiSelect"> <os-head-bar [hasMainButton]="true" [nav]="true" (mainEvent)="openTagDialog()" [multiSelectMode]="isMultiSelect">
<div class="title-slot"><h2 translate>Tags</h2></div> <div class="title-slot">
<h2>{{ 'Tags' | translate }}</h2>
</div>
</os-head-bar> </os-head-bar>
<os-list-view-table <os-list-view-table
@ -35,8 +37,8 @@
<!-- Template for dialog for quick editing --> <!-- Template for dialog for quick editing -->
<ng-template #tagDialog> <ng-template #tagDialog>
<h1 mat-dialog-title> <h1 mat-dialog-title>
<span *ngIf="currentTag" translate>Edit tag</span> <span *ngIf="currentTag">{{ 'Edit tag' | translate }}</span>
<span *ngIf="!currentTag" translate>New tag</span> <span *ngIf="!currentTag">{{ 'New tag' | translate }}</span>
</h1> </h1>
<div class="os-form-card-mobile" mat-dialog-content> <div class="os-form-card-mobile" mat-dialog-content>
<form [formGroup]="tagForm" (keydown)="onKeyDown($event)"> <form [formGroup]="tagForm" (keydown)="onKeyDown($event)">
@ -48,10 +50,10 @@
<div mat-dialog-actions> <div mat-dialog-actions>
<button type="submit" mat-button [mat-dialog-close]="true" color="primary"> <button type="submit" mat-button [mat-dialog-close]="true" color="primary">
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button type="button" mat-button [mat-dialog-close]="false"> <button type="button" mat-button [mat-dialog-close]="false">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -11,9 +11,9 @@
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2> <h2>
<span *ngIf="newTopic" translate>New topic</span> <span *ngIf="newTopic">{{ 'New topic' | translate }}</span>
<span *ngIf="editTopic && !newTopic" translate>Edit topic</span> <span *ngIf="editTopic && !newTopic">{{ 'Edit topic' | translate }}</span>
<span *ngIf="!newTopic && !editTopic" translate>Topic</span> <span *ngIf="!newTopic && !editTopic">{{ 'Topic' | translate }}</span>
</h2> </h2>
</div> </div>
@ -38,7 +38,8 @@
<div *ngIf="topic.hasAttachments() && !editTopic"> <div *ngIf="topic.hasAttachments() && !editTopic">
<h3> <h3>
<span translate>Attachments</span>: <span>{{ 'Attachments' | translate }}</span
>:
<mat-list dense> <mat-list dense>
<mat-list-item *ngFor="let file of topic.attachments"> <mat-list-item *ngFor="let file of topic.attachments">
<a [routerLink]="file.url" target="_blank">{{ file.getTitle() }}</a> <a [routerLink]="file.url" target="_blank">{{ file.getTitle() }}</a>
@ -58,13 +59,13 @@
formControlName="title" formControlName="title"
placeholder="{{ 'Title' | translate }}" placeholder="{{ 'Title' | translate }}"
/> />
<mat-error *ngIf="topicForm.invalid" translate>A name is required</mat-error> <mat-error *ngIf="topicForm.invalid">{{ 'A name is required' | translate }}</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>
<!-- The editor --> <!-- The editor -->
<div class="spacer-bottom-20"> <div class="spacer-bottom-20">
<h4 translate>Text</h4> <h4>{{ 'Text' | translate }}</h4>
<editor formControlName="text" [init]="tinyMceSettings"></editor> <editor formControlName="text" [init]="tinyMceSettings"></editor>
</div> </div>
@ -108,7 +109,7 @@
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button *osPerms="'agenda.can_manage'" mat-menu-item class="red-warning-text" (click)="onDeleteButton()"> <button *osPerms="'agenda.can_manage'" mat-menu-item class="red-warning-text" (click)="onDeleteButton()">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</mat-menu> </mat-menu>

View File

@ -1,10 +1,12 @@
<os-head-bar [nav]="false"> <os-head-bar [nav]="false">
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Import topics</h2></div> <div class="title-slot">
<h2>{{ 'Import topics' | translate }}</h2>
</div>
<div class="menu-slot"> <div class="menu-slot">
<button *ngIf="hasFile && newCount" mat-button (click)="doImport()"> <button *ngIf="hasFile && newCount" mat-button (click)="doImport()">
<span class="upper" translate> Import</span> <span class="upper">{{ 'Import' | translate }}</span>
</button> </button>
</div> </div>
</os-head-bar> </os-head-bar>
@ -15,8 +17,8 @@
<mat-tab label="{{ 'Text import' | translate }}"> <mat-tab label="{{ 'Text import' | translate }}">
<div [formGroup]="textAreaForm"> <div [formGroup]="textAreaForm">
<div> <div>
<span translate> Paste/write your topics in this textbox.</span> <span>{{ 'Paste/write your topics in this textbox.' | translate }}</span>
<span translate> Keep each item in a single line. </span> <span>{{ 'Keep each item in a single line.' | translate }}</span>
</div> </div>
<mat-form-field> <mat-form-field>
<textarea <textarea
@ -31,36 +33,45 @@
</mat-form-field> </mat-form-field>
</div> </div>
<div> <div>
<button mat-button color="accent" (click)="parseTextArea()"><span translate>Preview</span></button> <button mat-button color="accent" (click)="parseTextArea()">
<span>{{ 'Preview' | translate }}</span>
</button>
</div> </div>
</mat-tab> </mat-tab>
<!-- CSV import tab --> <!-- CSV import tab -->
<mat-tab label="{{ 'CSV import' | translate }}"> <mat-tab label="{{ 'CSV import' | translate }}">
<span translate <span>{{
>Required comma or semicolon separated values with these column header names in the first row:</span 'Required comma or semicolon separated values with these column header names in the first row:'
> | translate
}}</span>
<br /> <br />
<div class="code red-warning-text"> <div class="code red-warning-text">
<span translate>Title</span>,&nbsp; <span translate>Text</span>,&nbsp; <span>{{ 'Title' | translate }}</span
<span translate>Duration</span>,&nbsp; <span translate>Comment</span>,&nbsp; >,&nbsp; <span>{{ 'Text' | translate }}</span
<span translate>Internal item</span> >,&nbsp; <span>{{ 'Duration' | translate }}</span
>,&nbsp; <span>{{ 'Comment' | translate }}</span
>,&nbsp;
<span>{{ 'Internal item' | translate }}</span>
</div> </div>
<ul> <ul>
<li translate>Title is required. All other fields are optional and may be empty.</li> <li>{{ 'Title is required. All other fields are optional and may be empty.' | translate }}</li>
<li translate> <li>
Additional columns after the required ones may be present and won't affect the import. {{
'Additional columns after the required ones may be present and will not affect the import.'
| translate
}}
</li> </li>
</ul> </ul>
<button mat-button color="accent" (click)="downloadCsvExample()" translate> <button mat-button color="accent" (click)="downloadCsvExample()">
Download CSV example file {{ 'Download CSV example file' | translate }}
</button> </button>
<div class="wrapper"> <div class="wrapper">
<mat-form-field> <mat-form-field>
<mat-label translate>Encoding of the file</mat-label> <mat-label>{{ 'Encoding of the file' | translate }}</mat-label>
<mat-select <mat-select
class="selection" class="selection"
placeholder="translate.instant('Select encoding')" placeholder="{{ 'Select encoding' | translate }}"
(selectionChange)="selectEncoding($event)" (selectionChange)="selectEncoding($event)"
[value]="encodings[0].value" [value]="encodings[0].value"
> >
@ -70,7 +81,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<mat-label translate>Column separator</mat-label> <mat-label>{{ 'Column separator' | translate }}</mat-label>
<mat-select class="selection" (selectionChange)="selectColSep($event)" value=""> <mat-select class="selection" (selectionChange)="selectColSep($event)" value="">
<mat-option *ngFor="let option of columnSeparators" [value]="option.value"> <mat-option *ngFor="let option of columnSeparators" [value]="option.value">
{{ option.label | translate }} {{ option.label | translate }}
@ -78,7 +89,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<mat-label translate>Text separator</mat-label> <mat-label>{{ 'Text separator' | translate }}</mat-label>
<mat-select class="selection" (selectionChange)="selectTextSep($event)" value='"'> <mat-select class="selection" (selectionChange)="selectTextSep($event)" value='"'>
<mat-option *ngFor="let option of textSeparators" [value]="option.value"> <mat-option *ngFor="let option of textSeparators" [value]="option.value">
{{ option.label | translate }} {{ option.label | translate }}
@ -97,7 +108,7 @@
(change)="onSelectFile($event)" (change)="onSelectFile($event)"
/> />
<button mat-button onclick="document.getElementById('agenda-import-file-input').click()"> <button mat-button onclick="document.getElementById('agenda-import-file-input').click()">
<span translate>Select file</span> <span>{{ 'Select file' | translate }}</span>
</button> </button>
</div> </div>
</div> </div>
@ -107,35 +118,35 @@
<!-- preview table --> <!-- preview table -->
<mat-card *ngIf="hasFile" class="os-form-card import-table"> <mat-card *ngIf="hasFile" class="os-form-card import-table">
<h3 translate>Preview</h3> <h3>{{ 'Preview' | translate }}</h3>
<div class="summary"> <div class="summary">
<!-- new entries --> <!-- new entries -->
<div *ngIf="newCount"> <div *ngIf="newCount">
&nbsp; &nbsp;
<mat-icon inline>playlist_add</mat-icon> <mat-icon inline>playlist_add</mat-icon>
<span>&nbsp;{{ newCount }}&nbsp;</span> <span translate>Topics(s) will be imported.</span> <span>&nbsp;{{ newCount }}&nbsp;</span> <span>{{ 'Topics(s) will be imported.' | translate }}</span>
</div> </div>
<!-- errors/duplicates --> <!-- errors/duplicates -->
<div *ngIf="nonImportableCount" class="red-warning-text"> <div *ngIf="nonImportableCount" class="red-warning-text">
&nbsp; &nbsp;
<mat-icon inline>warning</mat-icon> <mat-icon inline>warning</mat-icon>
<span>&nbsp;{{ nonImportableCount }}&nbsp;</span> <span translate>entries will be ommitted.</span> <span>&nbsp;{{ nonImportableCount }}&nbsp;</span> <span>{{ 'entries will be ommitted.' | translate }}</span>
</div> </div>
<!-- have been imported --> <!-- have been imported -->
<div *ngIf="doneCount" class="green-text"> <div *ngIf="doneCount" class="green-text">
&nbsp; &nbsp;
<mat-icon inline>done</mat-icon> <mat-icon inline>done</mat-icon>
<span>&nbsp;{{ doneCount }}&nbsp;</span> <span translate>Topics have been imported.</span> <span>&nbsp;{{ doneCount }}&nbsp;</span> <span>{{ 'Topics have been imported.' | translate }}</span>
</div> </div>
</div> </div>
<div *ngIf="newCount"> <div *ngIf="newCount">
<span translate>After verifiy the preview click on 'import' please (see top right).</span> <span>{{ 'After verifiy the preview click on "import" please (see top right).' | translate }}</span>
</div> </div>
<div> <div>
<mat-select *ngIf="nonImportableCount" class="filter-imports" [(value)]="shown" (selectionChange)="setFilter()"> <mat-select *ngIf="nonImportableCount" class="filter-imports" [(value)]="shown" (selectionChange)="setFilter()">
<mat-option value="all" translate>Show all</mat-option> <mat-option value="all">{{ 'Show all' | translate }}</mat-option>
<mat-option value="error" translate>Show errors only</mat-option> <mat-option value="error">{{ 'Show errors only' | translate }}</mat-option>
<mat-option value="noerror" translate>Show correct entries only</mat-option> <mat-option value="noerror">{{ 'Show correct entries only' | translate }}</mat-option>
</mat-select> </mat-select>
</div> </div>
<div class="table-container"> <div class="table-container">
@ -167,7 +178,7 @@
<!-- title column --> <!-- title column -->
<ng-container matColumnDef="title"> <ng-container matColumnDef="title">
<mat-header-cell *matHeaderCellDef translate>Title</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Title' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<mat-icon <mat-icon
color="warn" color="warn"
@ -190,7 +201,7 @@
</ng-container> </ng-container>
<ng-container matColumnDef="text"> <ng-container matColumnDef="text">
<mat-header-cell *matHeaderCellDef translate>Text</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Text' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry" matTooltip="{{ getLongPreview(entry.newEntry.text) }}"> <mat-cell *matCellDef="let entry" matTooltip="{{ getLongPreview(entry.newEntry.text) }}">
{{ getShortPreview(entry.newEntry.text) }} {{ getShortPreview(entry.newEntry.text) }}
</mat-cell> </mat-cell>
@ -198,20 +209,22 @@
<!-- duration column --> <!-- duration column -->
<ng-container matColumnDef="agenda_duration"> <ng-container matColumnDef="agenda_duration">
<mat-header-cell *matHeaderCellDef translate>Duration</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Duration' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> {{ getDuration(entry.newEntry.agenda_duration) }} </mat-cell> <mat-cell *matCellDef="let entry"> {{ getDuration(entry.newEntry.agenda_duration) }} </mat-cell>
</ng-container> </ng-container>
<!-- comment column--> <!-- comment column-->
<ng-container matColumnDef="agenda_comment"> <ng-container matColumnDef="agenda_comment">
<mat-header-cell *matHeaderCellDef translate>Comment</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Comment' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> {{ entry.newEntry.agenda_comment }} </mat-cell> <mat-cell *matCellDef="let entry"> {{ entry.newEntry.agenda_comment }} </mat-cell>
</ng-container> </ng-container>
<!-- type column --> <!-- type column -->
<ng-container matColumnDef="agenda_type"> <ng-container matColumnDef="agenda_type">
<mat-header-cell *matHeaderCellDef translate>Type</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Type' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> {{ getTypeString(entry.newEntry.agenda_type) | translate }} </mat-cell> <mat-cell *matCellDef="let entry">
{{ getTypeString(entry.newEntry.agenda_type) | translate }}
</mat-cell>
</ng-container> </ng-container>
<mat-header-row *matHeaderRowDef="getColumnDefinition()"></mat-header-row> <mat-header-row *matHeaderRowDef="getColumnDefinition()"></mat-header-row>

View File

@ -1,12 +1,12 @@
<os-head-bar [hasMainButton]="true" [nav]="false" (mainEvent)="setEditMode(!editGroup)"> <os-head-bar [hasMainButton]="true" [nav]="false" (mainEvent)="setEditMode(!editGroup)">
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2 translate>Groups</h2> <h2>{{ 'Groups' | translate }}</h2>
</div> </div>
</os-head-bar> </os-head-bar>
<div class="hint-text"> <div class="hint-text">
<span translate>All your changes are saved immediately.</span> <span>{{ 'All your changes are saved immediately.' | translate }}</span>
</div> </div>
<mat-accordion *ngFor="let app of appPermissions"> <mat-accordion *ngFor="let app of appPermissions">
@ -20,7 +20,7 @@
<div class="scrollable-perm-matrix"> <div class="scrollable-perm-matrix">
<table mat-table [dataSource]="getTableDataSource(app.permissions)"> <table mat-table [dataSource]="getTableDataSource(app.permissions)">
<ng-container matColumnDef="perm" sticky> <ng-container matColumnDef="perm" sticky>
<mat-header-cell *matHeaderCellDef translate>Permissions</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Permissions' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let perm"> <mat-cell *matCellDef="let perm">
{{ perm.display_name | translate }} {{ perm.display_name | translate }}
</mat-cell> </mat-cell>
@ -68,7 +68,7 @@
formControlName="name" formControlName="name"
placeholder="{{ 'New group name' | translate }}" placeholder="{{ 'New group name' | translate }}"
/> />
<mat-error *ngIf="!groupForm.valid" translate>Required</mat-error> <mat-error *ngIf="!groupForm.valid">{{ 'Required' | translate }}</mat-error>
</mat-form-field> </mat-form-field>
</form> </form>
</div> </div>
@ -80,13 +80,20 @@
color="primary" color="primary"
(click)="saveGroup(groupForm.value)" (click)="saveGroup(groupForm.value)"
> >
<span translate>Save</span> <span>{{ 'Save' | translate }}</span>
</button> </button>
<button type="button" mat-button (click)="cancelEditing()"> <button type="button" mat-button (click)="cancelEditing()">
<span translate>Cancel</span> <span>{{ 'Cancel' | translate }}</span>
</button> </button>
<button *ngIf="selectedGroup" [disabled]="!canDeleteGroup(selectedGroup)" type="button" mat-button color="warn" (click)="deleteSelectedGroup()"> <button
<span translate>Delete</span> *ngIf="selectedGroup"
[disabled]="!canDeleteGroup(selectedGroup)"
type="button"
mat-button
color="warn"
(click)="deleteSelectedGroup()"
>
<span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</ng-template> </ng-template>

View File

@ -1,20 +1,25 @@
<os-head-bar (mainEvent)="goBack()" [hasMainButton]="true" [nav]="false" [editMode]="true" (saveEvent)="save()">a <os-head-bar (mainEvent)="goBack()" [hasMainButton]="true" [nav]="false" [editMode]="true" (saveEvent)="save()"
>a
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Change password</h2></div> <div class="title-slot">
<h2>{{ 'Change password' | translate }}</h2>
</div>
</os-head-bar> </os-head-bar>
<mat-card class="os-card"> <mat-card class="os-card">
<div *ngIf="!this.canManage && !this.ownPage"> <div *ngIf="!this.canManage && !this.ownPage">
<!-- no Admin, cannot Manage (a.k.a Attack Prevention) --> <!-- no Admin, cannot Manage (a.k.a Attack Prevention) -->
<span translate>You are not supposed to be here...</span> <span>{{ 'You are not supposed to be here...' | translate }}</span>
</div> </div>
<div *ngIf="this.canManage && !this.ownPage"> <div *ngIf="this.canManage && !this.ownPage">
<!-- can Manage, but not own Page (a.k.a. Admin) --> <!-- can Manage, but not own Page (a.k.a. Admin) -->
<div *ngIf="user"> <div *ngIf="user">
<h1><span translate>Change password for</span> {{ user.full_name }}</h1> <h1>
<span>{{ 'Change password for' | translate }}</span> {{ user.full_name }}
</h1>
<mat-icon>warning</mat-icon> <mat-icon>warning</mat-icon>
&nbsp;<span translate>You override the personally set password!</span> &nbsp;<span>{{ 'You override the personally set password!' | translate }}</span>
</div> </div>
<br> <br />
<form [formGroup]="adminPasswordForm" (keydown)="onKeyDown($event)"> <form [formGroup]="adminPasswordForm" (keydown)="onKeyDown($event)">
<mat-form-field> <mat-form-field>
<input <input
@ -29,7 +34,8 @@
matSuffix matSuffix
mat-icon-button mat-icon-button
matTooltip="{{ hidePassword ? ('Show password' | translate) : ('Hide password' | translate) }}" matTooltip="{{ hidePassword ? ('Show password' | translate) : ('Hide password' | translate) }}"
(click)="hidePassword = !hidePassword"> (click)="hidePassword = !hidePassword"
>
{{ hidePassword ? 'visibility' : 'visibility_off' }} {{ hidePassword ? 'visibility' : 'visibility_off' }}
</mat-icon> </mat-icon>
<mat-icon <mat-icon
@ -37,16 +43,18 @@
matSuffix matSuffix
mat-icon-button mat-icon-button
matTooltip="{{ 'Generate password' | translate }}" matTooltip="{{ 'Generate password' | translate }}"
(click)="generatePassword()"> (click)="generatePassword()"
>
settings settings
</mat-icon> </mat-icon>
</mat-form-field> </mat-form-field>
</form> </form>
<br> <br />
<div *ngIf="user"> <div *ngIf="user">
<span translate>Initial password</span>: {{ user.default_password }}<br> <span>{{ 'Initial password' | translate }}</span
<span translate>Username</span>: {{ user.username }} >: {{ user.default_password }}<br />
<span>{{ 'Username' | translate }}</span
>: {{ user.username }}
</div> </div>
</div> </div>
@ -63,8 +71,8 @@
/> />
<mat-icon mat-button matSuffix mat-icon-button (click)="hideOldPassword = !hideOldPassword"> <mat-icon mat-button matSuffix mat-icon-button (click)="hideOldPassword = !hideOldPassword">
{{ hideOldPassword ? 'visibility' : 'visibility_off' }} {{ hideOldPassword ? 'visibility' : 'visibility_off' }}
</mat-icon> </mat-icon> </mat-form-field
</mat-form-field><br> ><br />
<mat-form-field> <mat-form-field>
<input <input
[type]="hidePassword ? 'password' : 'text'" [type]="hidePassword ? 'password' : 'text'"
@ -73,12 +81,10 @@
placeholder="{{ 'New password' | translate }}" placeholder="{{ 'New password' | translate }}"
required required
/> />
<mat-icon <mat-icon mat-button matSuffix mat-icon-button (click)="hidePassword = !hidePassword">
mat-button matSuffix mat-icon-button
(click)="hidePassword = !hidePassword">
{{ hidePassword ? 'visibility' : 'visibility_off' }} {{ hidePassword ? 'visibility' : 'visibility_off' }}
</mat-icon> </mat-icon> </mat-form-field
</mat-form-field><br> ><br />
<mat-form-field> <mat-form-field>
<input <input
[type]="hidePassword ? 'password' : 'text'" [type]="hidePassword ? 'password' : 'text'"

View File

@ -1,13 +1,16 @@
<os-head-bar [hasMainButton]="false" [nav]="false"> <os-head-bar [hasMainButton]="false" [nav]="false">
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Presence</h2></div> <div class="title-slot">
<h2>{{ 'Presence' | translate }}</h2>
</div>
</os-head-bar> </os-head-bar>
<mat-card *ngIf="permission"> <mat-card *ngIf="permission">
<p translate>Check in or check out participants based on their participant numbers:</p> <p>{{ 'Check in or check out participants based on their participant numbers:' | translate }}</p>
<mat-form-field [formGroup]="userForm"> <mat-form-field [formGroup]="userForm">
<input osAutofocus <input
osAutofocus
matInput matInput
[formControl]="userForm.get('number')" [formControl]="userForm.get('number')"
placeholder="{{ 'Enter participant number' | translate }}" placeholder="{{ 'Enter participant number' | translate }}"
@ -16,7 +19,8 @@
</mat-form-field> </mat-form-field>
<button mat-button (click)="changePresence()">{{ 'Change presence' | translate }}</button> <button mat-button (click)="changePresence()">{{ 'Change presence' | translate }}</button>
<mat-card *ngIf="lastChangedUser" [ngClass]="lastChangedUser.is_present ? 'success' : 'warning'"> <mat-card *ngIf="lastChangedUser" [ngClass]="lastChangedUser.is_present ? 'success' : 'warning'">
<span>{{ lastChangedUser.full_name }}&nbsp;</span> <span translate>is now</span>: <span>{{ lastChangedUser.full_name }}&nbsp;</span> <span>{{ 'is now' | translate }}</span
>:
<span>&nbsp;{{ lastChangedUser.is_present ? ('present' | translate) : ('absent' | translate) }}</span> <span>&nbsp;{{ lastChangedUser.is_present ? ('present' | translate) : ('absent' | translate) }}</span>
</mat-card> </mat-card>
<mat-card *ngIf="errorMsg" class="error">{{ errorMsg | translate }}</mat-card> <mat-card *ngIf="errorMsg" class="error">{{ errorMsg | translate }}</mat-card>

View File

@ -11,7 +11,7 @@
<!-- Title --> <!-- Title -->
<div class="title-slot"> <div class="title-slot">
<h2> <h2>
<span *ngIf="newUser" translate>New participant</span> <span *ngIf="newUser">{{ 'New participant' | translate }}</span>
<span *ngIf="!newUser && user">{{ user.full_name }}</span> <span *ngIf="!newUser && user">{{ user.full_name }}</span>
</h2> </h2>
</div> </div>
@ -31,24 +31,24 @@
<mat-menu #userExtraMenu="matMenu"> <mat-menu #userExtraMenu="matMenu">
<button mat-menu-item *ngIf="isAllowed('changePassword')" (click)="changePassword()"> <button mat-menu-item *ngIf="isAllowed('changePassword')" (click)="changePassword()">
<mat-icon>security</mat-icon> <mat-icon>security</mat-icon>
<span translate>Change password</span> <span>{{ 'Change password' | translate }}</span>
</button> </button>
<!-- invitation email --> <!-- invitation email -->
<button mat-menu-item *ngIf="isAllowed('manage') && user && user.email" (click)="sendInvitationEmail()"> <button mat-menu-item *ngIf="isAllowed('manage') && user && user.email" (click)="sendInvitationEmail()">
<mat-icon>mail</mat-icon> <mat-icon>mail</mat-icon>
<span translate>Send invitation email</span> <span>{{ 'Send invitation email' | translate }}</span>
</button> </button>
<!-- PDF --> <!-- PDF -->
<button mat-menu-item *ngIf="isAllowed('manage')" (click)="onDownloadPdf()"> <button mat-menu-item *ngIf="isAllowed('manage')" (click)="onDownloadPdf()">
<mat-icon>picture_as_pdf</mat-icon> <mat-icon>picture_as_pdf</mat-icon>
<span translate>PDF</span> <span>{{ 'PDF' | translate }}</span>
</button> </button>
<!-- delete button --> <!-- delete button -->
<div *ngIf="isAllowed('delete')"> <div *ngIf="isAllowed('delete')">
<mat-divider></mat-divider> <mat-divider></mat-divider>
<button mat-menu-item class="red-warning-text" (click)="deleteUserButton()"> <button mat-menu-item class="red-warning-text" (click)="deleteUserButton()">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
<span translate>Delete</span> <span>{{ 'Delete' | translate }}</span>
</button> </button>
</div> </div>
</mat-menu> </mat-menu>
@ -95,8 +95,8 @@
name="email" name="email"
formControlName="email" formControlName="email"
/> />
<mat-error *ngIf="personalInfoForm.get('email').hasError('email')" translate> <mat-error *ngIf="personalInfoForm.get('email').hasError('email')">
Please enter a valid email address {{ 'Please enter a valid email address' | translate }}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
@ -168,7 +168,7 @@
<!-- About me --> <!-- About me -->
<div *ngIf="isAllowed('seePersonal')" class="spacer-bottom-20"> <div *ngIf="isAllowed('seePersonal')" class="spacer-bottom-20">
<!-- The HTML Editor --> <!-- The HTML Editor -->
<h4 translate>About me</h4> <h4>{{ 'About me' | translate }}</h4>
<editor formControlName="about_me" [init]="tinyMceSettings"></editor> <editor formControlName="about_me" [init]="tinyMceSettings"></editor>
</div> </div>
@ -183,7 +183,7 @@
<!-- Comment --> <!-- Comment -->
<mat-form-field> <mat-form-field>
<input matInput placeholder="{{ 'Comment' | translate }}" formControlName="comment" /> <input matInput placeholder="{{ 'Comment' | translate }}" formControlName="comment" />
<mat-hint translate>Only for internal notes.</mat-hint> <mat-hint>{{ 'Only for internal notes.' | translate }}</mat-hint>
</mat-form-field> </mat-form-field>
</div> </div>
@ -193,7 +193,7 @@
formControlName="is_present" formControlName="is_present"
matTooltip="{{ 'Designates whether this user is in the room.' | translate }}" matTooltip="{{ 'Designates whether this user is in the room.' | translate }}"
> >
<span translate>Is present</span> <span>{{ 'Is present' | translate }}</span>
</mat-checkbox> </mat-checkbox>
<!-- Active? --> <!-- Active? -->
@ -205,7 +205,7 @@
| translate | translate
}}" }}"
> >
<span translate>Is active</span> <span>{{ 'Is active' | translate }}</span>
</mat-checkbox> </mat-checkbox>
<!-- Commitee? --> <!-- Commitee? -->
@ -213,7 +213,7 @@
formControlName="is_committee" formControlName="is_committee"
matTooltip="{{ 'Designates whether this user should be treated as a committee.' | translate }}" matTooltip="{{ 'Designates whether this user should be treated as a committee.' | translate }}"
> >
<span translate>Is a committee</span> <span>{{ 'Is a committee' | translate }}</span>
</mat-checkbox> </mat-checkbox>
</div> </div>
</form> </form>
@ -223,7 +223,7 @@
<ng-container *ngIf="user"> <ng-container *ngIf="user">
<!-- User name --> <!-- User name -->
<div *ngIf="isAllowed('seeName')"> <div *ngIf="isAllowed('seeName')">
<h4 translate>Name</h4> <h4>{{ 'Name' | translate }}</h4>
<span class="state-icons"> <span class="state-icons">
<span>{{ user.short_name }}</span> <span>{{ user.short_name }}</span>
<mat-icon *ngIf="user.is_present" matTooltip="{{ 'Is present' | translate }}">check_box</mat-icon> <mat-icon *ngIf="user.is_present" matTooltip="{{ 'Is present' | translate }}">check_box</mat-icon>
@ -239,45 +239,45 @@
<div *ngIf="isAllowed('seePersonal')"> <div *ngIf="isAllowed('seePersonal')">
<!-- Mail --> <!-- Mail -->
<div *ngIf="user.email"> <div *ngIf="user.email">
<h4 translate>Email</h4> <h4>{{ 'Email' | translate }}</h4>
<span>{{ user.email }}</span> <span>{{ user.email }}</span>
</div> </div>
<!-- Gender --> <!-- Gender -->
<div *ngIf="user.gender"> <div *ngIf="user.gender">
<h4 translate>Gender</h4> <h4>{{ 'Gender' | translate }}</h4>
<span>{{ user.gender | translate }}</span> <span>{{ user.gender | translate }}</span>
</div> </div>
</div> </div>
<!-- Structure Level --> <!-- Structure Level -->
<div *ngIf="user.structure_level"> <div *ngIf="user.structure_level">
<h4 translate>Structure level</h4> <h4>{{ 'Structure level' | translate }}</h4>
<span>{{ user.structure_level }}</span> <span>{{ user.structure_level }}</span>
</div> </div>
<!-- Participant number --> <!-- Participant number -->
<div *ngIf="user.number"> <div *ngIf="user.number">
<h4 translate>Participant number</h4> <h4>{{ 'Participant number' | translate }}</h4>
<span>{{ user.number }}</span> <span>{{ user.number }}</span>
</div> </div>
<!-- Groups --> <!-- Groups -->
<div *ngIf="user.groups && user.groups.length > 0"> <div *ngIf="user.groups && user.groups.length > 0">
<h4 translate>Groups</h4> <h4>{{ 'Groups' | translate }}</h4>
<span *ngFor="let group of user.groups; let last = last"> <span *ngFor="let group of user.groups; let last = last">
{{ group.getTitle() | translate }}<span *ngIf="!last">,&nbsp;</span> {{ group.getTitle() | translate }}<span *ngIf="!last">,&nbsp;</span>
</span> </span>
</div> </div>
<div *ngIf="!user.groups || user.groups.length === 0"> <div *ngIf="!user.groups || user.groups.length === 0">
<h4 translate>Groups</h4> <h4>{{ 'Groups' | translate }}</h4>
<span translate>Default group</span> <span>{{ 'Default group' | translate }}</span>
</div> </div>
<div *ngIf="isAllowed('manage')"> <div *ngIf="isAllowed('manage')">
<!-- Initial Password --> <!-- Initial Password -->
<div *ngIf="user.default_password"> <div *ngIf="user.default_password">
<h4 translate>Initial password</h4> <h4>{{ 'Initial password' | translate }}</h4>
<span>{{ user.default_password }}</span> <span>{{ user.default_password }}</span>
</div> </div>
</div> </div>
@ -285,13 +285,13 @@
<div *ngIf="isAllowed('seePersonal')"> <div *ngIf="isAllowed('seePersonal')">
<!-- About me --> <!-- About me -->
<div *ngIf="user.about_me"> <div *ngIf="user.about_me">
<h4 translate>About me</h4> <h4>{{ 'About me' | translate }}</h4>
<div [innerHTML]="user.about_me | trust: 'html'"></div> <div [innerHTML]="user.about_me | trust: 'html'"></div>
</div> </div>
<!-- Username --> <!-- Username -->
<div *ngIf="user.username"> <div *ngIf="user.username">
<h4 translate>Username</h4> <h4>{{ 'Username' | translate }}</h4>
<span>{{ user.username }}</span> <span>{{ user.username }}</span>
</div> </div>
</div> </div>
@ -299,14 +299,14 @@
<div *ngIf="isAllowed('seeExtra')"> <div *ngIf="isAllowed('seeExtra')">
<!-- Comment --> <!-- Comment -->
<div *ngIf="user.comment"> <div *ngIf="user.comment">
<h4 translate>Comment</h4> <h4>{{ 'Comment' | translate }}</h4>
<span>{{ user.comment }}</span> <span>{{ user.comment }}</span>
</div> </div>
</div> </div>
<div *ngIf="isAllowed('seePersonal') && user.isLastEmailSend"> <div *ngIf="isAllowed('seePersonal') && user.isLastEmailSend">
<div> <div>
<h4 translate>Last email sent</h4> <h4>{{ 'Last email sent' | translate }}</h4>
<span>{{ getEmailSentTime() }}</span> <span>{{ getEmailSentTime() }}</span>
</div> </div>
</div> </div>

View File

@ -1,10 +1,12 @@
<os-head-bar [nav]="false"> <os-head-bar [nav]="false">
<!-- Title --> <!-- Title -->
<div class="title-slot"><h2 translate>Import participants</h2></div> <div class="title-slot">
<h2>{{ 'Import participants' | translate }}</h2>
</div>
<div class="menu-slot"> <div class="menu-slot">
<button *ngIf="hasFile && newCount" mat-button (click)="doImport()"> <button *ngIf="hasFile && newCount" mat-button (click)="doImport()">
<span class="upper" translate> Import</span> <span class="upper">{{ 'Import' | translate }}</span>
</button> </button>
</div> </div>
</os-head-bar> </os-head-bar>
@ -12,12 +14,13 @@
<mat-tab-group (selectedTabChange)="onTabChange()"> <mat-tab-group (selectedTabChange)="onTabChange()">
<!-- textarea import tab --> <!-- textarea import tab -->
<mat-tab label="{{ 'Text import' | translate }}"> <mat-tab label="{{ 'Text import' | translate }}">
<br> <br />
<div [formGroup]="textAreaForm"> <div [formGroup]="textAreaForm">
<div> <div>
<span translate> Copy and paste your participant names in this textbox.</span> <span>{{ 'Copy and paste your participant names in this textbox.' | translate }}</span>
<span translate> Keep each person in a single line. </span><br /> <span>{{ 'Keep each person in a single line.' | translate }}</span
<span translate> Comma separated names will be read as 'Surname, given name(s)'. </span> ><br />
<span>{{ 'Comma separated names will be read as "Surname, given name(s)".' | translate }}</span>
</div> </div>
<mat-form-field> <mat-form-field>
<textarea <textarea
@ -32,39 +35,59 @@
</mat-form-field> </mat-form-field>
</div> </div>
<div> <div>
<button mat-button color="accent" (click)="parseTextArea()"><span translate>Preview</span></button> <button mat-button color="accent" (click)="parseTextArea()">
<span>{{ 'Preview' | translate }}</span>
</button>
</div> </div>
</mat-tab> </mat-tab>
<!-- CSV import tab --> <!-- CSV import tab -->
<mat-tab label="{{ 'CSV import' | translate }}"> <mat-tab label="{{ 'CSV import' | translate }}">
<br> <br />
<span translate <span>
>Required comma or semicolon separated values with these column header names in the first row:</span {{
><br /> 'Required comma or semicolon separated values with these column header names in the first row:'
| translate
}}
</span>
<br />
<div class="code red-warning-text"> <div class="code red-warning-text">
<span translate>Title</span>, <span translate>Given name</span>, <span translate>Surname</span>, <span>{{ 'Title' | translate }}</span
<span translate>Structure level</span>, <span translate>Participant number</span>, >, <span>{{ 'Given name' | translate }}</span
<span translate>Groups</span>, <span translate>Comment</span>, <span translate>Is active</span>, >, <span>{{ 'Surname' | translate }}</span
<span translate>Is present</span>, <span translate>Is committee</span>, <span translate>Initial password</span>, >, <span>{{ 'Structure level' | translate }}</span
<span translate>Email</span>, <span translate>Username</span>, <span translate>Gender</span> >, <span>{{ 'Participant number' | translate }}</span
>, <span>{{ 'Groups' | translate }}</span
>, <span>{{ 'Comment' | translate }}</span
>, <span>{{ 'Is active' | translate }}</span
>, <span>{{ 'Is present' | translate }}</span
>, <span>{{ 'Is committee' | translate }}</span
>, <span>{{ 'Initial password' | translate }}</span
>, <span>{{ 'Email' | translate }}</span
>, <span>{{ 'Username' | translate }}</span
>, <span>{{ 'Gender' | translate }}</span>
</div> </div>
<ul> <ul>
<li translate> <li>
One of given name, surname and username has to be filled in. All other fields are optional and may be empty. {{
'One of given name, surname and username has to be filled in. All other fields are optional and may be empty.'
| translate
}}
</li> </li>
<li translate> <li>
Additional columns after the required ones may be present and won't affect the import. {{
'Additional columns after the required ones may be present and will not affect the import.'
| translate
}}
</li> </li>
</ul> </ul>
<button mat-button color="accent" (click)="downloadCsvExample()" translate> <button mat-button color="accent" (click)="downloadCsvExample()">
Download CSV example file {{ 'Download CSV example file' | translate }}
</button> </button>
<div class="wrapper"> <div class="wrapper">
<mat-form-field> <mat-form-field>
<mat-label translate>Encoding of the file</mat-label> <mat-label>{{ 'Encoding of the file' | translate }}</mat-label>
<mat-select <mat-select
class="selection" class="selection"
placeholder="translate.instant('Select encoding')"
(selectionChange)="selectEncoding($event)" (selectionChange)="selectEncoding($event)"
[value]="encodings[0].value" [value]="encodings[0].value"
> >
@ -74,7 +97,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<mat-label translate>Column separator</mat-label> <mat-label>{{ 'Column separator' | translate }}</mat-label>
<mat-select class="selection" (selectionChange)="selectColSep($event)" value=""> <mat-select class="selection" (selectionChange)="selectColSep($event)" value="">
<mat-option *ngFor="let option of columnSeparators" [value]="option.value"> <mat-option *ngFor="let option of columnSeparators" [value]="option.value">
{{ option.label | translate }} {{ option.label | translate }}
@ -82,7 +105,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<mat-label translate>Text separator</mat-label> <mat-label>{{ 'Text separator' | translate }}</mat-label>
<mat-select class="selection" (selectionChange)="selectTextSep($event)" value='"'> <mat-select class="selection" (selectionChange)="selectTextSep($event)" value='"'>
<mat-option *ngFor="let option of textSeparators" [value]="option.value"> <mat-option *ngFor="let option of textSeparators" [value]="option.value">
{{ option.label | translate }} {{ option.label | translate }}
@ -105,7 +128,7 @@
color="accent" color="accent"
onclick="document.getElementById('user-import-file-input').click()" onclick="document.getElementById('user-import-file-input').click()"
> >
<span translate> Select file</span> <span>{{ 'Select file' | translate }}</span>
</button> </button>
</div> </div>
</div> </div>
@ -115,34 +138,34 @@
<!-- preview table --> <!-- preview table -->
<mat-card *ngIf="hasFile" class="os-form-card import-table"> <mat-card *ngIf="hasFile" class="os-form-card import-table">
<h3 translate>Preview</h3> <h3>{{ 'Preview' | translate }}</h3>
<div class="summary"> <div class="summary">
<!-- new entries --> <!-- new entries -->
<div *ngIf="newCount"> <div *ngIf="newCount">
&nbsp; &nbsp;
<mat-icon inline>playlist_add</mat-icon> <mat-icon inline>playlist_add</mat-icon>
<span>&nbsp;{{ newCount }}&nbsp;</span> <span translate>Participant(s) will be imported.</span> <span>&nbsp;{{ newCount }}&nbsp;</span> <span>{{ 'Participant(s) will be imported.' | translate }}</span>
</div> </div>
<!-- errors/duplicates --> <!-- errors/duplicates -->
<div *ngIf="nonImportableCount" class="red-warning-text"> <div *ngIf="nonImportableCount" class="red-warning-text">
&nbsp; &nbsp;
<mat-icon inline>warning</mat-icon> <mat-icon inline>warning</mat-icon>
<span>&nbsp;{{ nonImportableCount }}&nbsp;</span> <span translate>entries will be ommitted.</span> <span>&nbsp;{{ nonImportableCount }}&nbsp;</span> <span>{{ 'entries will be ommitted.' | translate }}</span>
</div> </div>
<!-- have been imported --> <!-- have been imported -->
<div *ngIf="doneCount" class="green-text"> <div *ngIf="doneCount" class="green-text">
&nbsp; &nbsp;
<mat-icon inline>done</mat-icon> <mat-icon inline>done</mat-icon>
<span>&nbsp;{{ doneCount }}&nbsp;</span> <span translate>Participants have been imported.</span> <span>&nbsp;{{ doneCount }}&nbsp;</span> <span>{{ 'Participants have been imported.' | translate }}</span>
</div> </div>
</div> </div>
<div *ngIf="newCount"> <div *ngIf="newCount">
<span translate>After verifiy the preview click on 'import' please (see top right).</span> <span>{{ 'After verifiy the preview click on "import" please (see top right).' | translate }}</span>
</div> </div>
<mat-select *ngIf="nonImportableCount" class="filter-imports" [(value)]="shown" (selectionChange)="setFilter()"> <mat-select *ngIf="nonImportableCount" class="filter-imports" [(value)]="shown" (selectionChange)="setFilter()">
<mat-option value="all" translate>Show all</mat-option> <mat-option value="all">{{ 'Show all' | translate }}</mat-option>
<mat-option value="error" translate>Show errors only</mat-option> <mat-option value="error">{{ 'Show errors only' | translate }}</mat-option>
<mat-option value="noerror" translate>Show correct entries only</mat-option> <mat-option value="noerror">{{ 'Show correct entries only' | translate }}</mat-option>
</mat-select> </mat-select>
<div class="table-container"> <div class="table-container">
<table mat-table [dataSource]="dataSource" matSort> <table mat-table [dataSource]="dataSource" matSort>
@ -180,7 +203,7 @@
<!-- Title column --> <!-- Title column -->
<ng-container matColumnDef="title"> <ng-container matColumnDef="title">
<mat-header-cell *matHeaderCellDef translate>Title</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Title' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<span *ngIf="nameErrors(entry)"> <span *ngIf="nameErrors(entry)">
<mat-icon color="warn" inline matTooltip="{{ nameErrors(entry) | translate }}"> <mat-icon color="warn" inline matTooltip="{{ nameErrors(entry) | translate }}">
@ -194,7 +217,7 @@
<!-- title column --> <!-- title column -->
<ng-container matColumnDef="first_name"> <ng-container matColumnDef="first_name">
<mat-header-cell *matHeaderCellDef translate>Given name</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Given name' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<span *ngIf="nameErrors(entry)"> <span *ngIf="nameErrors(entry)">
<mat-icon color="warn" inline matTooltip="{{ nameErrors(entry) | translate }}"> <mat-icon color="warn" inline matTooltip="{{ nameErrors(entry) | translate }}">
@ -207,7 +230,7 @@
</ng-container> </ng-container>
<ng-container matColumnDef="last_name"> <ng-container matColumnDef="last_name">
<mat-header-cell *matHeaderCellDef translate>Surname</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Surname' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<span *ngIf="nameErrors(entry)"> <span *ngIf="nameErrors(entry)">
<mat-icon color="warn" inline matTooltip="{{ nameErrors(entry) | translate }}"> <mat-icon color="warn" inline matTooltip="{{ nameErrors(entry) | translate }}">
@ -220,18 +243,18 @@
</ng-container> </ng-container>
<ng-container matColumnDef="structure_level"> <ng-container matColumnDef="structure_level">
<mat-header-cell *matHeaderCellDef translate>Structure level</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Structure level' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> {{ entry.newEntry.structure_level }} </mat-cell> <mat-cell *matCellDef="let entry"> {{ entry.newEntry.structure_level }} </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="number"> <ng-container matColumnDef="number">
<mat-header-cell *matHeaderCellDef translate>Participant number</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Participant number' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> {{ entry.newEntry.number }} </mat-cell> <mat-cell *matCellDef="let entry"> {{ entry.newEntry.number }} </mat-cell>
</ng-container> </ng-container>
<!-- groups column --> <!-- groups column -->
<ng-container matColumnDef="groups_id"> <ng-container matColumnDef="groups_id">
<mat-header-cell *matHeaderCellDef translate>Groups</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Groups' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<div *ngIf="entry.newEntry.csvGroups.length"> <div *ngIf="entry.newEntry.csvGroups.length">
<span *ngIf="hasError(entry, 'Groups')"> <span *ngIf="hasError(entry, 'Groups')">
@ -249,42 +272,42 @@
</ng-container> </ng-container>
<ng-container matColumnDef="comment"> <ng-container matColumnDef="comment">
<mat-header-cell *matHeaderCellDef translate>Comment</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Comment' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> {{ entry.newEntry.comment }} </mat-cell> <mat-cell *matCellDef="let entry"> {{ entry.newEntry.comment }} </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="is_active"> <ng-container matColumnDef="is_active">
<mat-header-cell *matHeaderCellDef translate>Is active</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Is active' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<mat-checkbox disabled [checked]="entry.newEntry.is_active"> </mat-checkbox> <mat-checkbox disabled [checked]="entry.newEntry.is_active"> </mat-checkbox>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="is_present"> <ng-container matColumnDef="is_present">
<mat-header-cell *matHeaderCellDef translate>Is present</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Is present' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<mat-checkbox disabled [checked]="entry.newEntry.is_present"> </mat-checkbox> <mat-checkbox disabled [checked]="entry.newEntry.is_present"> </mat-checkbox>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="is_committee"> <ng-container matColumnDef="is_committee">
<mat-header-cell *matHeaderCellDef translate>Is committee</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Is committee' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> <mat-cell *matCellDef="let entry">
<mat-checkbox disabled [checked]="entry.newEntry.is_committee"> </mat-checkbox> <mat-checkbox disabled [checked]="entry.newEntry.is_committee"> </mat-checkbox>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="default_password"> <ng-container matColumnDef="default_password">
<mat-header-cell *matHeaderCellDef translate>Initial password</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Initial password' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> {{ entry.newEntry.default_password }} </mat-cell> <mat-cell *matCellDef="let entry"> {{ entry.newEntry.default_password }} </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="email"> <ng-container matColumnDef="email">
<mat-header-cell *matHeaderCellDef translate>Email</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Email' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> {{ entry.newEntry.email }} </mat-cell> <mat-cell *matCellDef="let entry"> {{ entry.newEntry.email }} </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="username"> <ng-container matColumnDef="username">
<mat-header-cell *matHeaderCellDef translate>Username</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Username' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> {{ entry.newEntry.username }} </mat-cell> <mat-cell *matCellDef="let entry"> {{ entry.newEntry.username }} </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="gender"> <ng-container matColumnDef="gender">
<mat-header-cell *matHeaderCellDef translate>Gender</mat-header-cell> <mat-header-cell *matHeaderCellDef>{{ 'Gender' | translate }}</mat-header-cell>
<mat-cell *matCellDef="let entry"> {{ entry.newEntry.gender }} </mat-cell> <mat-cell *matCellDef="let entry"> {{ entry.newEntry.gender }} </mat-cell>
</ng-container> </ng-container>

Some files were not shown because too many files have changed in this diff Show More