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",
"core-js": "^3.6.4",
"css-element-queries": "^1.2.3",
"exceljs": "3.8.2",
"exceljs": "1.15.0",
"file-saver": "^2.0.2",
"lz4js": "^0.2.0",
"material-icon-font": "git+https://github.com/petergng/materialIconFont.git",

View File

@ -145,12 +145,11 @@ export class HttpService {
if (isDetailResponse(e.error)) {
error += this.processDetailResponse(e.error);
} else {
error = Object.keys(e.error)
.map(key => {
const capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1);
return this.translate.instant(capitalizedKey) + ': ' + this.processDetailResponse(e.error[key]);
})
.join(', ');
const errorList = Object.keys(e.error).map(key => {
const capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1);
return `${this.translate.instant(capitalizedKey)}: ${this.processDetailResponse(e.error[key])}`;
});
error = errorList.join(', ');
}
} else if (e.status === 500) {
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) {
text = '';
} else {
const general_event_name = this.configService.instant<string>('general_event_name');
const general_event_description = this.configService.instant<string>('general_event_description');
const line1 = [
this.translate.instant(general_event_name),
this.translate.instant(general_event_description)
]
.filter(Boolean)
.join(' ');
const general_event_name = this.translate.instant(this.configService.instant<string>('general_event_name'));
const general_event_description = this.translate.instant(
this.configService.instant<string>('general_event_description')
);
const line1 = [general_event_name, general_event_description].filter(Boolean).join(' - ');
const line2 = [
this.configService.instant('general_event_location'),
this.configService.instant('general_event_date')

View File

@ -306,7 +306,8 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User, UserTi
} else if (numEmails === 1) {
msg = this.translate.instant('One email was send sucessfully.');
} 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) {

View File

@ -58,6 +58,13 @@ _('PDF footer logo (left)');
_('PDF footer logo (right)');
_('Web interface header 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
_('Enable numbering for agenda items');
@ -409,3 +416,18 @@ _('Motion change recommendation deleted');
// core misc strings
_('items per page');
_('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">
<p>
<mat-checkbox formControlName="agenda_create">
<span translate>Add to agenda</span>
<span>{{ 'Add to agenda' | translate }}</span>
</mat-checkbox>
</p>
</div>

View File

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

View File

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

View File

@ -9,9 +9,9 @@
[ngSwitch]="banner.type"
>
<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>
<a (click)="timeTravel.resumeTime()" translate>Exit</a>
<a (click)="timeTravel.resumeTime()">{{ 'Exit' | translate }}</a>
</ng-container>
<ng-container *ngSwitchDefault>
<a class="banner-link" [routerLink]="banner.link" [style.cursor]="banner.link ? 'pointer' : 'default'">

View File

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

View File

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

View File

@ -46,7 +46,7 @@ import { ViewportService } from 'app/core/ui-services/viewport.service';
* <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</span>
* </div>
* </os-head-bar>
* ```

View File

@ -2,8 +2,8 @@
<div>
<ng-container *ngIf="!isEditing">
<div *ngIf="legalNotice" class="legal-notice-text" [innerHtml]="legalNotice | trust: 'html'"></div>
<div *ngIf="!legalNotice" translate>
The event manager hasn't set up a legal notice yet.
<div *ngIf="!legalNotice">
{{ 'The event manager has not set up a legal notice yet.' | translate }}
</div>
</ng-container>
<ng-container *ngIf="isEditing">
@ -18,13 +18,17 @@
<a [attr.href]="versionInfo.openslides_url" target="_blank">
OpenSlides {{ versionInfo.openslides_version }}
</a>
(<span translate>License</span>: {{ versionInfo.openslides_license }})
<span>({{ 'License' | translate }}: {{ versionInfo.openslides_license }})</span>
<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">
<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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
<div cdkDropList [cdkDropListDisabled]="!enable" (cdkDropListDropped)="drop($event)">
<div class="line" *ngIf="!sortedItems.length">
<span translate>No data</span>
<span>{{ 'No data' | translate }}</span>
</div>
<div
[ngClass]="isSelectedRow(i) ? 'backgroundColorSelected line' : 'backgroundColorLight line'"
@ -23,7 +23,7 @@
</div>
<div class="line" *cdkDragPreview>
<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>

View File

@ -13,7 +13,7 @@
<button type="button" *ngIf="menuItem" mat-menu-item [routerLink]="listOfSpeakers.listOfSpeakersUrl">
<mat-icon>{{ icon }}</mat-icon>
<span translate>List of speakers</span>
<span>{{ 'List of speakers' | translate }}</span>
<span>&nbsp;</span>
<mat-basic-chip disableRipple class="lightblue" *ngIf="listOfSpeakers.waitingSpeakerAmount > 0">
<span>{{ listOfSpeakers.waitingSpeakerAmount }}</span>

View File

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

View File

@ -1,15 +1,20 @@
<h1 mat-dialog-title>
<span translate>Secret voting can not be guaranteed</span>
<span>{{ 'Secret voting can not be guaranteed' | translate }}</span>
</h1>
<div mat-dialog-content>
<span translate>
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.
<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.'
| translate
}}
</span>
</div>
<div mat-dialog-actions>
<button type="button" mat-button [mat-dialog-close]="null">
<span translate>I know the risk</span>
<span>{{ 'I know the risk' | translate }}</span>
</button>
</div>

View File

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

View File

@ -1,11 +1,8 @@
<os-head-bar
[nav]="false"
[editMode]="hasChanged"
(mainEvent)="onCancel()"
(saveEvent)="onSave()">
<os-head-bar [nav]="false" [editMode]="hasChanged" (mainEvent)="onCancel()" (saveEvent)="onSave()">
<!-- Title -->
<div class="title-slot"><h2 translate>Sort agenda</h2></div>
<div class="title-slot">
<h2>{{ 'Sort agenda' | translate }}</h2>
</div>
</os-head-bar>
<div class="custom-table-header sort-header">
<div class="button-menu left">
@ -13,7 +10,10 @@
<button mat-button (click)="onStateChange(false)">{{ 'Collapse all' | translate }}</button>
</div>
<div class="current-filters" *ngIf="hasActiveFilter">
<div><span translate>Active filters</span>:&nbsp;</div>
<div>
<span>{{ 'Active filters' | translate }}</span
>:&nbsp;
</div>
<div>
<button mat-button (click)="resetFilters()">
<mat-icon inline>cancel</mat-icon>
@ -22,7 +22,9 @@
</div>
</div>
<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">
<section class="sort-drawer-content">
<button mat-button (click)="visibilityFilter.toggle()">
@ -31,8 +33,13 @@
<span class="sort-grid">
<div class="hint">{{ 'Visibility' | translate }}</div>
<div>
<mat-checkbox *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
*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>
</div>
</span>
@ -42,8 +49,8 @@
</div>
<mat-card>
<div class="current-nodes">
{{ seenNodes[0] }} <span translate>of</span> {{ seenNodes[1] }}
<span translate>items</span>
{{ seenNodes[0] }} <span>{{ 'of' | translate }}</span> {{ seenNodes[1] }}
<span>{{ 'items' | translate }}</span>
</div>
<os-sorting-tree
#osSortedTree

View File

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

View File

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

View File

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

View File

@ -4,7 +4,9 @@
[multiSelectMode]="isMultiSelect"
>
<!-- Title -->
<div class="title-slot"><h2 translate>Elections</h2></div>
<div class="title-slot">
<h2>{{ 'Elections' | translate }}</h2>
</div>
<!-- Menu -->
<div class="menu-slot">
<button type="button" mat-icon-button [matMenuTriggerFor]="assignmentMenu">
@ -15,7 +17,7 @@
<!-- Multiselect info -->
<div class="central-info-slot">
<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>
</os-head-bar>
@ -90,28 +92,28 @@
<div *ngIf="!isMultiSelect">
<button mat-menu-item *osPerms="'assignment.can_manage'" (click)="toggleMultiSelect()">
<mat-icon>library_add</mat-icon>
<span translate>Multiselect</span>
<span>{{ 'Multiselect' | translate }}</span>
</button>
<button mat-menu-item (click)="downloadAssignmentButton()">
<mat-icon>archive</mat-icon>
<span translate>Export ...</span>
<span>{{ 'Export ...' | translate }}</span>
</button>
<mat-divider></mat-divider>
<!-- Settings -->
<button mat-menu-item *osPerms="'core.can_manage_config'" routerLink="/settings/elections">
<mat-icon>settings</mat-icon>
<span translate>Settings</span>
<span>{{ 'Settings' | translate }}</span>
</button>
</div>
<div *ngIf="isMultiSelect">
<button mat-menu-item (click)="selectAll()">
<mat-icon>done_all</mat-icon>
<span translate>Select all</span>
<span>{{ 'Select all' | translate }}</span>
</button>
<button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()">
<mat-icon>clear</mat-icon>
<span translate>Deselect all</span>
<span>{{ 'Deselect all' | translate }}</span>
</button>
<mat-divider></mat-divider>
<button
@ -132,7 +134,7 @@
(click)="deleteSelected()"
>
<mat-icon>delete</mat-icon>
<span translate>Delete</span>
<span>{{ 'Delete' | translate }}</span>
</button>
</div>
</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 { Title } from '@angular/platform-browser';
import { ActivatedRoute, Router } from '@angular/router';
@ -23,6 +23,7 @@ import { AssignmentPhases, ViewAssignment } from '../../models/view-assignment';
@Component({
selector: 'os-assignment-list',
templateUrl: './assignment-list.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./assignment-list.component.scss']
})
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>
<button *osPerms="'assignments.can_manage'" mat-menu-item (click)="openDialog(poll)">
<mat-icon>edit</mat-icon>
<span translate>Edit</span>
<span>{{ 'Edit' | translate }}</span>
</button>
<button
mat-menu-item
@ -119,11 +119,11 @@
(click)="pseudoanonymizePoll()"
>
<mat-icon>warning</mat-icon>
<span translate>Anonymize votes</span>
<span>{{ 'Anonymize votes' | translate }}</span>
</button>
<mat-divider></mat-divider>
<button *osPerms="'assignments.can_manage'" mat-menu-item (click)="deletePoll()">
<mat-icon color="warn">delete</mat-icon>
<span translate>Delete</span>
<span>{{ 'Delete' | translate }}</span>
</button>
</mat-menu>

View File

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

View File

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

View File

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

View File

@ -1,9 +1,9 @@
<os-head-bar>
<div class="title-slot">
<h2 translate>Error</h2>
<h2>{{ 'Error' | translate }}</h2>
</div>
</os-head-bar>
<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>

View File

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

View File

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

View File

@ -8,7 +8,7 @@
(cancelEditEvent)="isEditing = !isEditing"
>
<div class="title-slot">
<h2 translate>Home</h2>
<h2>{{ 'Home' | translate }}</h2>
</div>
</os-head-bar>
@ -30,7 +30,7 @@
required
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>
<editor formControlName="general_event_welcome_text" [init]="tinyMceSettings"></editor>
</form>

View File

@ -90,7 +90,7 @@
</ng-container>
</mat-accordion>
<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"
>&nbsp;({{ 'with filter' | translate }} "{{ searchCollection | translate }}")</span
>.

View File

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

View File

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

View File

@ -7,12 +7,12 @@
<ng-container [formGroupName]="i">
<mat-form-field>
<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-icon>arrow_forward</mat-icon>
<mat-form-field>
<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>
<button
mat-icon-button

View File

@ -1,6 +1,6 @@
<os-head-bar>
<!-- Title -->
<div class="title-slot" translate>History</div>
<div class="title-slot">{{ 'History' | translate }}</div>
<!-- Menu -->
<div class="menu-slot">
@ -27,7 +27,7 @@
<span class="spacer-left-20">
<button mat-button (click)="refresh()" *ngIf="currentModelId">
<mat-icon>refresh</mat-icon>
<span translate>Refresh</span>
<span>{{ 'Refresh' | translate }}</span>
</button>
</span>
</div>
@ -42,13 +42,13 @@
<mat-table [dataSource]="dataSource" matSort class="os-headed-listview-table">
<!-- Timestamp -->
<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>
</ng-container>
<!-- 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">
<div *ngIf="getElementInfo(history)">{{ getElementInfo(history) | translate }}</div>
<div
@ -63,13 +63,13 @@
<!-- 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>
</ng-container>
<!-- 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>
</ng-container>
@ -82,6 +82,6 @@
<mat-menu #historyMenu="matMenu">
<button mat-menu-item class="red-warning-text" (click)="clearHistory()">
<mat-icon>delete</mat-icon>
<span translate>Delete whole history</span>
<span>{{ 'Delete whole history' | translate }}</span>
</button>
</mat-menu>

View File

@ -1,5 +1,5 @@
<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>
</main>

View File

@ -1,5 +1,5 @@
<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>
</main>

View File

@ -1,16 +1,22 @@
<!-- The actual form -->
<header>
<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>
</header>
<main>
<router-outlet></router-outlet>
</main>
<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;
<a routerLink='/login/legalnotice' translate>Legal notice</a>
<a routerLink="/login/legalnotice">
{{ 'Legal notice' | translate }}
</a>
&middot;
<a routerLink='/login/privacypolicy' translate>Privacy policy</a>
<a routerLink="/login/privacypolicy">
{{ 'Privacy policy' | translate }}
</a>
</div>

View File

@ -1,6 +1,6 @@
<div class="form-wrapper">
<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>
<input
matInput
@ -10,8 +10,8 @@
formControlName="password"
type="password"
/>
<mat-error *ngIf="newPasswordForm.get('password').hasError('required')" translate>
A password is required
<mat-error *ngIf="newPasswordForm.get('password').hasError('required')">
{{ 'A password is required' | translate }}
</mat-error>
</mat-form-field>
<br />

View File

@ -1,6 +1,6 @@
<div class="form-wrapper">
<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>
<input
matInput
@ -10,8 +10,8 @@
type="email"
autocomplete="off"
/>
<mat-error *ngIf="resetPasswordForm.get('email').invalid" translate>
Please enter a valid email address!
<mat-error *ngIf="resetPasswordForm.get('email').invalid">
{{ 'Please enter a valid email address!' | translate }}
</mat-error>
</mat-form-field>
<br />

View File

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

View File

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

View File

@ -1,6 +1,8 @@
<os-head-bar prevUrl="../.." [nav]="false" [multiSelectMode]="isMultiSelect">
<!-- 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 -->
<div class="title-slot" *ngIf="parentMotion">
@ -20,7 +22,7 @@
<!-- Multiselect info -->
<div class="central-info-slot">
<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>
</os-head-bar>
@ -45,7 +47,7 @@
<span>{{ motion.identifier }}</span>
<span *ngIf="motion.diffLines && motion.diffLines.length">
<span *ngIf="motion.identifier">&nbsp;&middot;&nbsp;</span>
<span translate>Line</span>
<span>{{ 'Line' | translate }}</span>
<span>&nbsp;{{ motion.getChangeLines() }}</span>
</span>
</div>
@ -53,14 +55,14 @@
<!-- Submitter -->
<div class="submitters-line one-line">
<span *ngIf="motion.submitters.length">
<span translate>by</span>
<span>{{ 'by' | translate }}</span>
{{ motion.submitters }}
</span>
<span *ngIf="motion.submitters.length">
&middot;
</span>
<span translate>Sequential number</span>
<span>{{ 'Sequential number' | translate }}</span>
{{ motion.id }}
</div>
@ -115,26 +117,26 @@
<div *osPerms="'motions.can_manage'">
<button mat-menu-item (click)="toggleMultiSelect()">
<mat-icon>library_add</mat-icon>
<span translate>Multiselect</span>
<span>{{ 'Multiselect' | translate }}</span>
</button>
</div>
<button mat-menu-item (click)="openExportDialog()">
<mat-icon>archive</mat-icon>
<span translate>Export</span>
<span>{{ 'Export' | translate }}</span>
</button>
<button mat-menu-item (click)="exportAmendmentListPdf()">
<mat-icon>picture_as_pdf</mat-icon>
<span translate>Amendment list (PDF)</span>
<span>{{ 'Amendment list (PDF)' | translate }}</span>
</button>
</div>
<div *ngIf="isMultiSelect">
<button mat-menu-item (click)="selectAll()">
<mat-icon>done_all</mat-icon>
<span translate>Select all</span>
<span>{{ 'Select all' | translate }}</span>
</button>
<button mat-menu-item [disabled]="!selectedRows.length" (click)="deselectAll()">
<mat-icon>clear</mat-icon>
<span translate>Deselect all</span>
<span>{{ 'Deselect all' | translate }}</span>
</button>
<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()">
<!-- Title -->
<div class="title-slot">
<h2 translate>Call list</h2>
<h2>{{ 'Call list' | translate }}</h2>
</div>
<!-- Export menu -->
@ -14,15 +14,18 @@
<div class="custom-table-header flex-spaced">
<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>
</div>
<div class="current-filters" *ngIf="hasActiveFilter">
<div><span translate>Active filters</span>:&nbsp;</div>
<div>
<span>{{ 'Active filters' | translate }}</span
>:&nbsp;
</div>
<div>
<button mat-button (click)="resetFilters()">
<mat-icon inline>cancel</mat-icon>
<span translate>Clear all</span>
<span>{{ 'Clear all' | translate }}</span>
</button>
</div>
</div>
@ -34,9 +37,8 @@
[matBadge]="activeCatFilterCount > 0 ? activeCatFilterCount : null"
matBadgeColor="accent"
[matBadgeOverlap]="false"
translate
>
Categories
{{ 'Categories' | translate }}
</span>
</button>
</div>
@ -47,9 +49,8 @@
[matBadge]="activeTagFilterCount > 0 ? activeTagFilterCount : null"
matBadgeColor="accent"
[matBadgeOverlap]="false"
translate
>
Tags
{{ 'Tags' | translate }}
</span>
</button>
</div>
@ -103,18 +104,18 @@
<mat-menu #mainMenu="matMenu">
<button mat-menu-item (click)="sortMotionsByIdentifier()">
<mat-icon>sort</mat-icon>
<span translate>Sort by identifier</span>
<span>{{ 'Sort by identifier' | translate }}</span>
</button>
<mat-divider></mat-divider>
<button mat-menu-item (click)="pdfExportCallList()">
<mat-icon>picture_as_pdf</mat-icon>
<span translate>Export as PDF</span>
<span>{{ 'Export as PDF' | translate }}</span>
</button>
<button mat-menu-item (click)="csvExportCallList()">
<mat-icon>archive</mat-icon>
<span translate>Export as CSV</span>
<span>{{ 'Export as CSV' | translate }}</span>
</button>
</mat-menu>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -12,8 +12,8 @@
<ng-container class="meta-text-block-content">
<ng-container *ngIf="!isCommentEdited(section)">
<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>
No comment
<div class="no-content" *ngIf="!comments[section.id] || !comments[section.id].comment">
{{ 'No comment' | translate }}
</div>
</ng-container>
<form [formGroup]="commentForms[section.id]" *ngIf="isCommentEdited(section)">
@ -27,9 +27,9 @@
></editor>
</form>
<div *ngIf="saveHint">
<span translate>Touch the book icon to enter text</span>
<span>{{ 'Touch the book icon to enter text' | translate }}</span>
<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>
</ng-container>

View File

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

View File

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

View File

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

View File

@ -1,16 +1,20 @@
<os-head-bar prevUrl="../.." [nav]="false">
<!-- 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">
<button *ngIf="hasFile && newCount" mat-button (click)="doImport()">
<span class="upper" translate> Import</span>
<span class="upper">{{ 'Import' | translate }}</span>
</button>
</div>
</os-head-bar>
<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 />
<div class="code red-warning-text">
<span *ngFor="let header of this.expectedHeader; let last = last">
@ -19,18 +23,27 @@
</span>
</div>
<ul>
<li translate>
Identifier, reason, submitter, category, origin and motion block are optional and may be empty.
<li>
{{
'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 translate>Additional columns after the required ones may be present and won't affect the import.</li>
</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">
<mat-form-field>
<mat-label translate>Encoding of the file</mat-label>
<mat-label>{{ 'Encoding of the file' | translate }}</mat-label>
<mat-select
class="selection"
placeholder="translate.instant('Select encoding')"
placeholder="{{ 'Select encoding' | translate }}"
(selectionChange)="selectEncoding($event)"
[value]="encodings[0].value"
>
@ -40,7 +53,7 @@
</mat-select>
</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-option *ngFor="let option of columnSeparators" [value]="option.value">
{{ option.label | translate }}
@ -48,7 +61,7 @@
</mat-select>
</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-option *ngFor="let option of textSeparators" [value]="option.value">
{{ option.label | translate }}
@ -67,7 +80,7 @@
(change)="onSelectFile($event)"
/>
<button mat-button osAutofocus onclick="document.getElementById('motion-import-file-input').click()">
<span translate> Select file</span>
<span>{{ 'Select file' | translate }}</span>
</button>
</div>
</div>
@ -75,35 +88,35 @@
<!-- preview table -->
<mat-card *ngIf="hasFile" class="os-form-card import-table">
<h3 translate>Preview</h3>
<h3>{{ 'Preview' | translate }}</h3>
<div class="summary">
<!-- new entries -->
<div *ngIf="newCount">
&nbsp;
<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>
<!-- errors/duplicates -->
<div *ngIf="nonImportableCount" class="red-warning-text">
&nbsp;
<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>
<!-- have been imported -->
<div *ngIf="doneCount" class="green-text">
&nbsp;
<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 *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-option value="all" translate> Show all </mat-option>
<mat-option value="error" translate> Show errors only </mat-option>
<mat-option value="noerror" translate> Show correct entries </mat-option>
<mat-option value="all">{{ 'Show all' | translate }}</mat-option>
<mat-option value="error">{{ 'Show errors only' | translate }}</mat-option>
<mat-option value="noerror">{{ 'Show correct entries' | translate }}</mat-option>
</mat-select>
</div>
<div class="table-container">
@ -135,7 +148,7 @@
<!-- identifier column -->
<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-icon
color="warn"
@ -151,7 +164,7 @@
<!-- title column -->
<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-icon
color="warn"
@ -166,7 +179,7 @@
<!-- text column -->
<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-icon
color="warn"
@ -181,7 +194,7 @@
<!-- reason column -->
<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) }}">
{{ getShortPreview(entry.newEntry.reason) }}
</mat-cell>
@ -189,7 +202,7 @@
<!-- submitters column -->
<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">
<div *ngIf="entry.newEntry.csvSubmitters && entry.newEntry.csvSubmitters.length">
<mat-icon
@ -210,7 +223,7 @@
<!-- category column -->
<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">
<div *ngIf="entry.newEntry.csvCategory">
<mat-icon
@ -230,7 +243,7 @@
<!-- tag column -->
<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">
<div *ngIf="entry.newEntry.csvTags">
<mat-icon
@ -250,13 +263,13 @@
<!-- origin column -->
<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>
</ng-container>
<!-- motion block column -->
<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">
<div *ngIf="entry.newEntry.csvMotionblock">
<mat-icon

View File

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

View File

@ -90,7 +90,7 @@
<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)">
<mat-icon>edit</mat-icon>
<span translate>Edit</span>
<span>{{ 'Edit' | translate }}</span>
</button>
<button
mat-menu-item
@ -98,11 +98,11 @@
(click)="pseudoanonymizePoll()"
>
<mat-icon>warning</mat-icon>
<span translate>Anonymize votes</span>
<span>{{ 'Anonymize votes' | translate }}</span>
</button>
<mat-divider></mat-divider>
<button *osPerms="'motions.can_manage_polls'" mat-menu-item (click)="deletePoll()">
<mat-icon color="warn">delete</mat-icon>
<span translate>Delete</span>
<span>{{ 'Delete' | translate }}</span>
</button>
</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 { Title } from '@angular/platform-browser';
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',
templateUrl: './motion-poll-detail.component.html',
styleUrls: ['./motion-poll-detail.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
})
export class MotionPollDetailComponent extends BasePollDetailComponent<ViewMotionPoll, MotionPollService> {

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
<!-- Content -->
<div mat-dialog-content class="motion-export-dialog-wrapper">
<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 [value]="fileFormat.PDF">PDF</mat-button-toggle>
<mat-button-toggle [value]="fileFormat.CSV">CSV</mat-button-toggle>
@ -13,64 +13,84 @@
</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 [value]="lnMode.None"> <span translate>None</span> </mat-button-toggle>
<mat-button-toggle [value]="lnMode.Outside"> <span translate>Outside</span> </mat-button-toggle>
<mat-button-toggle [value]="lnMode.None">
<span>{{ 'None' | translate }}</span>
</mat-button-toggle>
<mat-button-toggle [value]="lnMode.Outside">
<span>{{ 'Outside' | translate }}</span>
</mat-button-toggle>
</mat-button-toggle-group>
</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 [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 [value]="crMode.Changed"> <span translate>Changed version</span> </mat-button-toggle>
<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 [value]="crMode.ModifiedFinal"> <span translate>Final version</span> </mat-button-toggle>
</mat-button-toggle-group>
</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 value="text"> <span translate>Text</span> </mat-button-toggle>
<mat-button-toggle value="reason"> <span translate>Reason</span> </mat-button-toggle>
<mat-button-toggle value="text">
<span>{{ 'Text' | translate }}</span>
</mat-button-toggle>
<mat-button-toggle value="reason">
<span>{{ 'Reason' | translate }}</span>
</mat-button-toggle>
</mat-button-toggle-group>
</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 *ngFor="let metaInfo of metaInfoExportOrder" [value]="metaInfo">
<span>{{ getLabelForMetadata(metaInfo) | translate }}</span>
</mat-button-toggle>
<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 value="polls" #votingResultButton>
<span translate>Voting result</span>
<span>{{ 'Voting result' | translate }}</span>
</mat-button-toggle>
</mat-button-toggle-group>
</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 value="toc"> <span translate>Table of contents</span> </mat-button-toggle>
<mat-button-toggle value="page"> <span translate>Page numbers</span> </mat-button-toggle>
<mat-button-toggle value="date"> <span translate>Current date</span> </mat-button-toggle>
<mat-button-toggle value="addBreaks"> <span translate>Enforce page breaks</span> </mat-button-toggle>
<mat-button-toggle value="toc">
<span>{{ 'Table of contents' | translate }}</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>
</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 [value]="PERSONAL_NOTE_ID">
<span translate>Personal note</span>
<span>{{ 'Personal note' | translate }}</span>
</mat-button-toggle>
<mat-button-toggle *ngFor="let comment of commentsToExport" [value]="comment.id">
<span>{{ comment.name }}</span>
@ -85,8 +105,10 @@
<!-- Action buttons -->
<div mat-dialog-actions>
<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 mat-button type="button" (click)="onCloseClick()"><span translate>Cancel</span></button>
</div>
</form>

View File

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

View File

@ -1,28 +1,40 @@
<os-head-bar [nav]="false">
<!-- 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">
<button *ngIf="hasFile && newCount" mat-button (click)="doImport()">
<span class="upper" translate>Import</span>
<span class="upper">{{ 'Import' | translate }}</span>
</button>
</div>
</os-head-bar>
<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 />
<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>
<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>
<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">
<mat-form-field>
<mat-label translate>Encoding of the file</mat-label>
<mat-label>{{ 'Encoding of the file' | translate }}</mat-label>
<mat-select
class="selection"
placeholder="translate.instant('Select encoding')"
(selectionChange)="selectEncoding($event)"
[value]="encodings[0].value"
>
@ -32,7 +44,7 @@
</mat-select>
</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-option *ngFor="let option of columnSeparators" [value]="option.value">
{{ option.label | translate }}
@ -40,7 +52,7 @@
</mat-select>
</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-option *ngFor="let option of textSeparators" [value]="option.value">
{{ option.label | translate }}
@ -58,42 +70,44 @@
(change)="onSelectFile($event)"
/>
<button mat-button osAutofocus onclick="document.getElementById('statute-import-file-input').click()">
<span translate> Select file</span>
<span>{{ 'Select file' | translate }}</span>
</button>
</div>
</mat-card>
<!-- preview table -->
<mat-card *ngIf="hasFile" class="os-form-card import-table">
<h3 translate>Preview</h3>
<h3>{{ 'Preview' | translate }}</h3>
<div class="summary">
<!-- new entries -->
<div *ngIf="newCount">
&nbsp;
<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>
<!-- errors/duplicates -->
<div *ngIf="nonImportableCount" class="red-warning-text">
&nbsp;
<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>
<!-- have been imported -->
<div *ngIf="doneCount" class="green-text">
&nbsp;
<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 *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-option value="all" translate> Show all </mat-option>
<mat-option value="error" translate> Show errors only </mat-option>
<mat-option value="noerror" translate> Show correct entries </mat-option>
<mat-option value="all">{{ 'Show all' | translate }}</mat-option>
<mat-option value="error">{{ 'Show errors only' | translate }}</mat-option>
<mat-option value="noerror">{{ 'Show correct entries' | translate }}</mat-option>
</mat-select>
</div>
<div class="table-container">
@ -125,7 +139,7 @@
<!-- title column -->
<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-icon
color="warn"
@ -140,7 +154,7 @@
<!-- text column -->
<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-icon
color="warn"

View File

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

View File

@ -17,7 +17,7 @@
{{ option.value | translate }}
</mat-option>
</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">
{{ 'Not suitable for formal secret voting!' | translate }}</mat-hint
>
@ -46,7 +46,7 @@
{{ option.value | translate }}
</mat-option>
</mat-select>
<mat-error translate>This field is required.</mat-error>
<mat-error>{{ 'This field is required.' | translate }}</mat-error>
</mat-form-field>
</ng-container>

View File

@ -1,5 +1,5 @@
<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-list-view-table

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,12 @@
<os-head-bar [hasMainButton]="true" [nav]="false" (mainEvent)="setEditMode(!editGroup)">
<!-- Title -->
<div class="title-slot">
<h2 translate>Groups</h2>
<h2>{{ 'Groups' | translate }}</h2>
</div>
</os-head-bar>
<div class="hint-text">
<span translate>All your changes are saved immediately.</span>
<span>{{ 'All your changes are saved immediately.' | translate }}</span>
</div>
<mat-accordion *ngFor="let app of appPermissions">
@ -20,7 +20,7 @@
<div class="scrollable-perm-matrix">
<table mat-table [dataSource]="getTableDataSource(app.permissions)">
<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">
{{ perm.display_name | translate }}
</mat-cell>
@ -68,7 +68,7 @@
formControlName="name"
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>
</form>
</div>
@ -80,13 +80,20 @@
color="primary"
(click)="saveGroup(groupForm.value)"
>
<span translate>Save</span>
<span>{{ 'Save' | translate }}</span>
</button>
<button type="button" mat-button (click)="cancelEditing()">
<span translate>Cancel</span>
<span>{{ 'Cancel' | translate }}</span>
</button>
<button *ngIf="selectedGroup" [disabled]="!canDeleteGroup(selectedGroup)" type="button" mat-button color="warn" (click)="deleteSelectedGroup()">
<span translate>Delete</span>
<button
*ngIf="selectedGroup"
[disabled]="!canDeleteGroup(selectedGroup)"
type="button"
mat-button
color="warn"
(click)="deleteSelectedGroup()"
>
<span>{{ 'Delete' | translate }}</span>
</button>
</div>
</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 -->
<div class="title-slot"><h2 translate>Change password</h2></div>
<div class="title-slot">
<h2>{{ 'Change password' | translate }}</h2>
</div>
</os-head-bar>
<mat-card class="os-card">
<div *ngIf="!this.canManage && !this.ownPage">
<!-- 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 *ngIf="this.canManage && !this.ownPage">
<!-- can Manage, but not own Page (a.k.a. Admin) -->
<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>
&nbsp;<span translate>You override the personally set password!</span>
&nbsp;<span>{{ 'You override the personally set password!' | translate }}</span>
</div>
<br>
<br />
<form [formGroup]="adminPasswordForm" (keydown)="onKeyDown($event)">
<mat-form-field>
<input
@ -29,7 +34,8 @@
matSuffix
mat-icon-button
matTooltip="{{ hidePassword ? ('Show password' | translate) : ('Hide password' | translate) }}"
(click)="hidePassword = !hidePassword">
(click)="hidePassword = !hidePassword"
>
{{ hidePassword ? 'visibility' : 'visibility_off' }}
</mat-icon>
<mat-icon
@ -37,16 +43,18 @@
matSuffix
mat-icon-button
matTooltip="{{ 'Generate password' | translate }}"
(click)="generatePassword()">
(click)="generatePassword()"
>
settings
</mat-icon>
</mat-form-field>
</form>
<br>
<br />
<div *ngIf="user">
<span translate>Initial password</span>: {{ user.default_password }}<br>
<span translate>Username</span>: {{ user.username }}
<span>{{ 'Initial password' | translate }}</span
>: {{ user.default_password }}<br />
<span>{{ 'Username' | translate }}</span
>: {{ user.username }}
</div>
</div>
@ -63,8 +71,8 @@
/>
<mat-icon mat-button matSuffix mat-icon-button (click)="hideOldPassword = !hideOldPassword">
{{ hideOldPassword ? 'visibility' : 'visibility_off' }}
</mat-icon>
</mat-form-field><br>
</mat-icon> </mat-form-field
><br />
<mat-form-field>
<input
[type]="hidePassword ? 'password' : 'text'"
@ -73,12 +81,10 @@
placeholder="{{ 'New password' | translate }}"
required
/>
<mat-icon
mat-button matSuffix mat-icon-button
(click)="hidePassword = !hidePassword">
<mat-icon mat-button matSuffix mat-icon-button (click)="hidePassword = !hidePassword">
{{ hidePassword ? 'visibility' : 'visibility_off' }}
</mat-icon>
</mat-form-field><br>
</mat-icon> </mat-form-field
><br />
<mat-form-field>
<input
[type]="hidePassword ? 'password' : 'text'"

View File

@ -1,13 +1,16 @@
<os-head-bar [hasMainButton]="false" [nav]="false">
<!-- Title -->
<div class="title-slot"><h2 translate>Presence</h2></div>
<div class="title-slot">
<h2>{{ 'Presence' | translate }}</h2>
</div>
</os-head-bar>
<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">
<input osAutofocus
<input
osAutofocus
matInput
[formControl]="userForm.get('number')"
placeholder="{{ 'Enter participant number' | translate }}"
@ -16,7 +19,8 @@
</mat-form-field>
<button mat-button (click)="changePresence()">{{ 'Change presence' | translate }}</button>
<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>
</mat-card>
<mat-card *ngIf="errorMsg" class="error">{{ errorMsg | translate }}</mat-card>

View File

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

View File

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

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