move listing component, add table header to remaining tables
This commit is contained in:
parent
a95362ba73
commit
62fa054697
@ -2,8 +2,7 @@ import { Component, Injector, OnInit } from '@angular/core';
|
||||
import { FileDownloadService } from '@upload-download/services/file-download.service';
|
||||
import { DownloadStatusWrapper } from '@upload-download/model/download-status.wrapper';
|
||||
import { DownloadControllerService } from '@redaction/red-ui-http';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { CircleButtonTypes, DefaultListingServices, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
|
||||
@ -13,7 +12,7 @@ import { LoadingService } from '@services/loading.service';
|
||||
styleUrls: ['./downloads-list-screen.component.scss'],
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DownloadsListScreenComponent extends BaseListingComponent<DownloadStatusWrapper> implements OnInit {
|
||||
export class DownloadsListScreenComponent extends ListingComponent<DownloadStatusWrapper> implements OnInit {
|
||||
readonly itemSize = 80;
|
||||
protected readonly _primaryKey = 'storageId';
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
|
||||
@ -8,13 +8,13 @@ import { Toaster } from '@services/toaster.service';
|
||||
import { DossierAttributesService } from '@shared/services/controller-wrappers/dossier-attributes.service';
|
||||
import { dossierAttributeTypesTranslations } from '../../translations/dossier-attribute-types-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { AutoUnsubscribeComponent } from '@iqser/common-ui';
|
||||
import { AutoUnsubscribe } from '@iqser/common-ui';
|
||||
|
||||
@Component({
|
||||
templateUrl: './add-edit-dossier-attribute-dialog.component.html',
|
||||
styleUrls: ['./add-edit-dossier-attribute-dialog.component.scss']
|
||||
})
|
||||
export class AddEditDossierAttributeDialogComponent extends AutoUnsubscribeComponent implements OnDestroy {
|
||||
export class AddEditDossierAttributeDialogComponent extends AutoUnsubscribe implements OnDestroy {
|
||||
dossierAttributeForm: FormGroup;
|
||||
dossierAttribute: DossierAttributeConfig;
|
||||
readonly translations = dossierAttributeTypesTranslations;
|
||||
|
||||
@ -1,13 +1,99 @@
|
||||
<div class="header-item">
|
||||
<iqser-round-checkbox
|
||||
(click)="toggleSelectAll()"
|
||||
[active]="entitiesService.areAllSelected$ | async"
|
||||
[indeterminate]="entitiesService.notAllSelected$ | async"
|
||||
></iqser-round-checkbox>
|
||||
<span class="all-caps-label">
|
||||
{{ 'file-attributes-csv-import.table-header.title' | translate: { length: (entitiesService.allLength$ | async) } }}
|
||||
</span>
|
||||
<redaction-table-header
|
||||
[bulkActions]="bulkActions"
|
||||
[selectionEnabled]="true"
|
||||
[hasEmptyColumn]="true"
|
||||
[tableColumnConfigs]="tableColumnConfigs"
|
||||
[tableHeaderLabel]="tableHeaderLabel"
|
||||
></redaction-table-header>
|
||||
|
||||
<redaction-empty-state
|
||||
*ngIf="entitiesService.noData$ | async"
|
||||
[text]="'file-attributes-csv-import.no-data.title' | translate"
|
||||
icon="red:attribute"
|
||||
></redaction-empty-state>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="50" redactionHasScrollbar>
|
||||
<div
|
||||
(mouseenter)="setHoveredColumn.emit(field.csvColumn)"
|
||||
(mouseleave)="setHoveredColumn.emit()"
|
||||
*cdkVirtualFor="let field of sortedDisplayedEntities$ | async; trackBy: trackByPrimaryKey"
|
||||
class="table-item"
|
||||
>
|
||||
<div (click)="toggleEntitySelected($event, field)" class="selection-column">
|
||||
<iqser-round-checkbox [active]="isSelected(field)"></iqser-round-checkbox>
|
||||
</div>
|
||||
<div [class.editing]="field.editingName" class="name">
|
||||
<div *ngIf="!field.editingName">
|
||||
{{ field.name }}
|
||||
</div>
|
||||
|
||||
<form (submit)="field.editingName = false; field.name = field.temporaryName" *ngIf="field.editingName">
|
||||
<div class="red-input-group w-200">
|
||||
<input [(ngModel)]="field.temporaryName" name="name" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="field.editingName = true"
|
||||
*ngIf="!field.editingName"
|
||||
[tooltip]="'file-attributes-csv-import.action.edit-name' | translate"
|
||||
class="edit-name-button"
|
||||
icon="red:edit"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
|
||||
<ng-container *ngIf="field.editingName">
|
||||
<iqser-circle-button
|
||||
(action)="field.editingName = false; field.name = field.temporaryName"
|
||||
[tooltip]="'file-attributes-csv-import.action.save-name' | translate"
|
||||
icon="red:check"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="field.editingName = false; field.temporaryName = field.name"
|
||||
[tooltip]="'file-attributes-csv-import.action.cancel-edit-name' | translate"
|
||||
icon="red:close"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div>
|
||||
<div class="red-input-group">
|
||||
<mat-form-field class="no-label">
|
||||
<mat-select [(ngModel)]="field.type">
|
||||
<mat-option *ngFor="let type of typeOptions" [value]="type">
|
||||
{{ translations[type] | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="center">
|
||||
<mat-slide-toggle [(ngModel)]="field.readonly" color="primary"></mat-slide-toggle>
|
||||
</div>
|
||||
|
||||
<div class="center">
|
||||
<iqser-round-checkbox (click)="togglePrimary(field)" [active]="field.primaryAttribute"></iqser-round-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="actions-container">
|
||||
<div class="action-buttons">
|
||||
<iqser-circle-button
|
||||
(action)="field.primaryAttribute = false; toggleFieldActive.emit(field)"
|
||||
[removeTooltip]="true"
|
||||
[tooltip]="'file-attributes-csv-import.action.remove' | translate"
|
||||
icon="red:trash"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
|
||||
<ng-template #bulkActions>
|
||||
<ng-container *ngIf="entitiesService.areSomeSelected$ | async">
|
||||
<iqser-circle-button
|
||||
[matMenuTriggerFor]="readOnlyMenu"
|
||||
@ -49,109 +135,4 @@
|
||||
</button>
|
||||
</mat-menu>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div class="table-header" redactionSyncWidth="table-item">
|
||||
<div class="select-oval-placeholder"></div>
|
||||
|
||||
<iqser-table-column-name [label]="'file-attributes-csv-import.table-col-names.name' | translate" class="name"></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name [label]="'file-attributes-csv-import.table-col-names.type' | translate"></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'file-attributes-csv-import.table-col-names.read-only' | translate"
|
||||
class="flex-center"
|
||||
leftIcon="red:read-only"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'file-attributes-csv-import.table-col-names.primary' | translate"
|
||||
[rightIconTooltip]="'file-attributes-csv-import.table-col-names.primary-info-tooltip' | translate"
|
||||
class="flex-center"
|
||||
rightIcon="red:status-info"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<div></div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<redaction-empty-state
|
||||
*ngIf="entitiesService.noData$ | async"
|
||||
[text]="'file-attributes-csv-import.no-data.title' | translate"
|
||||
icon="red:attribute"
|
||||
></redaction-empty-state>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="50" redactionHasScrollbar>
|
||||
<!-- Table lines -->
|
||||
<div
|
||||
(mouseenter)="setHoveredColumn.emit(field.csvColumn)"
|
||||
(mouseleave)="setHoveredColumn.emit()"
|
||||
*cdkVirtualFor="let field of sortedDisplayedEntities$ | async; trackBy: trackByPrimaryKey"
|
||||
class="table-item"
|
||||
>
|
||||
<div (click)="toggleEntitySelected($event, field)" class="selection-column">
|
||||
<iqser-round-checkbox [active]="isSelected(field)"></iqser-round-checkbox>
|
||||
</div>
|
||||
<div [class.editing]="field.editingName" class="name">
|
||||
<div *ngIf="!field.editingName">
|
||||
{{ field.name }}
|
||||
</div>
|
||||
<form (submit)="field.editingName = false; field.name = field.temporaryName" *ngIf="field.editingName">
|
||||
<div class="red-input-group w-200">
|
||||
<input [(ngModel)]="field.temporaryName" name="name" />
|
||||
</div>
|
||||
</form>
|
||||
<iqser-circle-button
|
||||
(action)="field.editingName = true"
|
||||
*ngIf="!field.editingName"
|
||||
[tooltip]="'file-attributes-csv-import.action.edit-name' | translate"
|
||||
class="edit-name-button"
|
||||
icon="red:edit"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
<ng-container *ngIf="field.editingName">
|
||||
<iqser-circle-button
|
||||
(action)="field.editingName = false; field.name = field.temporaryName"
|
||||
[tooltip]="'file-attributes-csv-import.action.save-name' | translate"
|
||||
icon="red:check"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="field.editingName = false; field.temporaryName = field.name"
|
||||
[tooltip]="'file-attributes-csv-import.action.cancel-edit-name' | translate"
|
||||
icon="red:close"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div>
|
||||
<div class="red-input-group">
|
||||
<mat-form-field class="no-label">
|
||||
<mat-select [(ngModel)]="field.type">
|
||||
<mat-option *ngFor="let type of typeOptions" [value]="type">
|
||||
{{ translations[type] | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<div class="center">
|
||||
<mat-slide-toggle [(ngModel)]="field.readonly" color="primary"></mat-slide-toggle>
|
||||
</div>
|
||||
<div class="center">
|
||||
<iqser-round-checkbox (click)="togglePrimary(field)" [active]="field.primaryAttribute"></iqser-round-checkbox>
|
||||
</div>
|
||||
<div class="actions-container">
|
||||
<div class="action-buttons">
|
||||
<iqser-circle-button
|
||||
(action)="field.primaryAttribute = false; toggleFieldActive.emit(field)"
|
||||
[removeTooltip]="true"
|
||||
[tooltip]="'file-attributes-csv-import.action.remove' | translate"
|
||||
icon="red:trash"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
</ng-template>
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
@import '../../../../../../assets/styles/variables';
|
||||
|
||||
iqser-table-column-name::ng-deep {
|
||||
> div {
|
||||
padding: 0 13px 0 10px !important;
|
||||
iqser-table-column-name::ng-deep > div {
|
||||
padding: 0 13px 0 10px !important;
|
||||
|
||||
&.name {
|
||||
padding-left: 22px !important;
|
||||
}
|
||||
&.name {
|
||||
padding-left: 22px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.header-item {
|
||||
redaction-table-header::ng-deep .header-item {
|
||||
padding: 0 24px 0 10px;
|
||||
box-shadow: none;
|
||||
border-top: 1px solid $separator;
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { Component, EventEmitter, Injector, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
import { Field } from '../file-attributes-csv-import-dialog.component';
|
||||
import { FileAttributeConfig } from '@redaction/red-ui-http';
|
||||
import { CircleButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, DefaultListingServices, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { fileAttributeTypesTranslations } from '../../../translations/file-attribute-types-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-active-fields-listing',
|
||||
@ -11,10 +11,29 @@ import { fileAttributeTypesTranslations } from '../../../translations/file-attri
|
||||
styleUrls: ['./active-fields-listing.component.scss'],
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class ActiveFieldsListingComponent extends BaseListingComponent<Field> implements OnChanges {
|
||||
export class ActiveFieldsListingComponent extends ListingComponent<Field> implements OnChanges {
|
||||
protected readonly _primaryKey = 'csvColumn';
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly translations = fileAttributeTypesTranslations;
|
||||
readonly tableHeaderLabel = _('file-attributes-csv-import.table-header.title');
|
||||
readonly tableColumnConfigs: TableColumnConfig<Field>[] = [
|
||||
{
|
||||
label: _('file-attributes-csv-import.table-col-names.name'),
|
||||
class: 'name'
|
||||
},
|
||||
{ label: _('file-attributes-csv-import.table-col-names.type') },
|
||||
{
|
||||
label: _('file-attributes-csv-import.table-col-names.read-only'),
|
||||
class: 'flex-center',
|
||||
leftIcon: 'red:read-only'
|
||||
},
|
||||
{
|
||||
label: _('file-attributes-csv-import.table-col-names.primary'),
|
||||
class: 'flex-center',
|
||||
rightIcon: 'red:status-info',
|
||||
rightIconTooltip: _('file-attributes-csv-import.table-col-names.primary-info-tooltip')
|
||||
}
|
||||
];
|
||||
readonly typeOptions = [
|
||||
FileAttributeConfig.TypeEnum.TEXT,
|
||||
FileAttributeConfig.TypeEnum.NUMBER,
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<div class="dialog-content">
|
||||
<div class="sub-header">
|
||||
<div class="left">
|
||||
<div class="info"><span translate="file-attributes-csv-import.file"> </span> {{ csvFile.name }}</div>
|
||||
<div class="info"><span translate="file-attributes-csv-import.file"> </span> {{ data.csv.name }}</div>
|
||||
<div class="large-label">
|
||||
{{ 'file-attributes-csv-import.total-rows' | translate: { rows: parseResult?.data?.length } }}
|
||||
</div>
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
import { Component, Inject, Injector } from '@angular/core';
|
||||
import { AbstractControl, FormBuilder, FormGroup, ValidatorFn, Validators } from '@angular/forms';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import * as Papa from 'papaparse';
|
||||
import { FileAttributeConfig, FileAttributesConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { Toaster } from '@services/toaster.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { DefaultListingServices, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
export interface Field {
|
||||
@ -27,15 +25,14 @@ export interface Field {
|
||||
styleUrls: ['./file-attributes-csv-import-dialog.component.scss'],
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class FileAttributesCsvImportDialogComponent extends BaseListingComponent<Field> {
|
||||
export class FileAttributesCsvImportDialogComponent extends ListingComponent<Field> {
|
||||
protected readonly _primaryKey = 'csvColumn';
|
||||
readonly tableColumnConfigs: TableColumnConfig<Field>[] = [];
|
||||
|
||||
csvFile: File;
|
||||
dossierTemplateId: string;
|
||||
parseResult: { data: any[]; errors: any[]; meta: any; fields: Field[] };
|
||||
hoveredColumn: string;
|
||||
activeFields: Field[] = [];
|
||||
baseConfigForm: FormGroup;
|
||||
readonly baseConfigForm: FormGroup;
|
||||
isSearchOpen = false;
|
||||
previewExpanded = true;
|
||||
filteredKeyOptions: Observable<string[]>;
|
||||
@ -44,23 +41,19 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
|
||||
initialParseConfig: { delimiter?: string; encoding?: string } = {};
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _fileAttributesControllerService: FileAttributesControllerService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _toaster: Toaster,
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
readonly dialogRef: MatDialogRef<FileAttributesCsvImportDialogComponent>,
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _fileAttributesControllerService: FileAttributesControllerService,
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
readonly data: {
|
||||
csv: File;
|
||||
dossierTemplateId: string;
|
||||
existingConfiguration: FileAttributesConfig;
|
||||
readonly csv: File;
|
||||
readonly dossierTemplateId: string;
|
||||
readonly existingConfiguration: FileAttributesConfig;
|
||||
}
|
||||
) {
|
||||
super(_injector);
|
||||
this.csvFile = data.csv;
|
||||
this.dossierTemplateId = data.dossierTemplateId;
|
||||
|
||||
this.baseConfigForm = this._formBuilder.group({
|
||||
filenameMappingColumnHeaderName: ['', [Validators.required, this._autocompleteStringValidator()]],
|
||||
@ -132,7 +125,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
|
||||
encoding: this.baseConfigForm.get('encoding').value
|
||||
};
|
||||
});
|
||||
reader.readAsText(this.csvFile, this.baseConfigForm.get('encoding').value);
|
||||
reader.readAsText(this.data.csv, this.baseConfigForm.get('encoding').value);
|
||||
}
|
||||
|
||||
getSample(csvColumn: string) {
|
||||
@ -199,7 +192,7 @@ export class FileAttributesCsvImportDialogComponent extends BaseListingComponent
|
||||
};
|
||||
|
||||
try {
|
||||
await this._fileAttributesControllerService.setFileAttributesConfig(fileAttributes, this.dossierTemplateId).toPromise();
|
||||
await this._fileAttributesControllerService.setFileAttributesConfig(fileAttributes, this.data.dossierTemplateId).toPromise();
|
||||
this._toaster.success(_('file-attributes-csv-import.save.success'), { params: { count: this.activeFields.length } });
|
||||
} catch (e) {
|
||||
this._toaster.error(_('file-attributes-csv-import.save.error'));
|
||||
|
||||
@ -4,7 +4,7 @@ import { AuditControllerService, AuditResponse, AuditSearchRequest } from '@reda
|
||||
import { Moment } from 'moment';
|
||||
import { applyIntervalConstraints } from '@utils/date-inputs-utils';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { AutoUnsubscribeComponent } from '@iqser/common-ui';
|
||||
import { AutoUnsubscribe } from '@iqser/common-ui';
|
||||
import { auditCategoriesTranslations } from '../../translations/audit-categories-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserService } from '@services/user.service';
|
||||
@ -16,7 +16,7 @@ const PAGE_SIZE = 50;
|
||||
templateUrl: './audit-screen.component.html',
|
||||
styleUrls: ['./audit-screen.component.scss']
|
||||
})
|
||||
export class AuditScreenComponent extends AutoUnsubscribeComponent implements OnDestroy {
|
||||
export class AuditScreenComponent extends AutoUnsubscribe implements OnDestroy {
|
||||
readonly ALL_CATEGORIES = 'allCategories';
|
||||
readonly ALL_USERS = _('audit-screen.all-users');
|
||||
readonly translations = auditCategoriesTranslations;
|
||||
|
||||
@ -20,30 +20,13 @@
|
||||
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
|
||||
|
||||
<div class="content-container">
|
||||
<div class="header-item">
|
||||
<span class="all-caps-label">
|
||||
{{ 'default-colors-screen.table-header.title' | translate: { length: entitiesService.allLength$ | async } }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="table-header" redactionSyncWidth="table-item">
|
||||
<iqser-table-column-name
|
||||
[label]="'default-colors-screen.table-col-names.key' | translate"
|
||||
[withSort]="true"
|
||||
column="key"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'default-colors-screen.table-col-names.color' | translate"
|
||||
class="flex-center"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<div></div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
<redaction-table-header
|
||||
[hasEmptyColumn]="true"
|
||||
[tableColumnConfigs]="tableColumnConfigs"
|
||||
[tableHeaderLabel]="tableHeaderLabel"
|
||||
></redaction-table-header>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<!-- Table lines -->
|
||||
<div *cdkVirtualFor="let color of sortedDisplayedEntities$ | async; trackBy: trackByPrimaryKey" class="table-item">
|
||||
<div>
|
||||
<div [translate]="translations[color.key]" class="table-item-title heading"></div>
|
||||
@ -57,7 +40,7 @@
|
||||
<div class="action-buttons">
|
||||
<iqser-circle-button
|
||||
(action)="openEditColorDialog($event, color)"
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
*ngIf="currentUser.isAdmin"
|
||||
[tooltip]="'default-colors-screen.action.edit' | translate"
|
||||
icon="red:edit"
|
||||
[type]="circleButtonTypes.dark"
|
||||
|
||||
@ -1,30 +1,26 @@
|
||||
.content-container {
|
||||
cdk-virtual-scroll-viewport {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: 2fr 1fr 2fr 11px;
|
||||
.content-container cdk-virtual-scroll-viewport {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: 2fr 1fr 2fr 11px;
|
||||
|
||||
.table-item {
|
||||
> div:not(.scrollbar-placeholder) {
|
||||
padding-left: 24px;
|
||||
}
|
||||
.table-item {
|
||||
> div:not(.scrollbar-placeholder) {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.color-wrapper {
|
||||
align-items: center;
|
||||
.color-wrapper {
|
||||
align-items: center;
|
||||
|
||||
.color-square {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
min-width: 16px;
|
||||
}
|
||||
.color-square {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
min-width: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.has-scrollbar:hover {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: 2fr 1fr 2fr;
|
||||
}
|
||||
}
|
||||
&.has-scrollbar:hover ::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: 2fr 1fr 2fr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,13 +2,18 @@ import { ChangeDetectionStrategy, Component, Injector, OnInit } from '@angular/c
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { Colors, DictionaryControllerService } from '@redaction/red-ui-http';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { CircleButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, DefaultListingServices, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { DefaultColorType } from '@models/default-color-key.model';
|
||||
import { defaultColorsTranslations } from '../../translations/default-colors-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserService } from '@services/user.service';
|
||||
|
||||
interface ListItem {
|
||||
readonly key: string;
|
||||
readonly value: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './default-colors-screen.component.html',
|
||||
@ -16,26 +21,31 @@ import { defaultColorsTranslations } from '../../translations/default-colors-tra
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DefaultColorsScreenComponent
|
||||
extends BaseListingComponent<{
|
||||
key: string;
|
||||
value: string;
|
||||
}>
|
||||
implements OnInit
|
||||
{
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly translations = defaultColorsTranslations;
|
||||
export class DefaultColorsScreenComponent extends ListingComponent<ListItem> implements OnInit {
|
||||
protected readonly _primaryKey = 'key';
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
readonly translations = defaultColorsTranslations;
|
||||
readonly tableHeaderLabel = _('default-colors-screen.table-header.title');
|
||||
readonly tableColumnConfigs: TableColumnConfig<ListItem>[] = [
|
||||
{
|
||||
label: _('default-colors-screen.table-col-names.key'),
|
||||
withSort: true,
|
||||
column: 'key'
|
||||
},
|
||||
{ label: _('default-colors-screen.table-col-names.color'), class: 'flex-center' }
|
||||
];
|
||||
|
||||
private _colorsObj: Colors;
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _activatedRoute: ActivatedRoute,
|
||||
private readonly _dictionaryControllerService: DictionaryControllerService,
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
readonly permissionsService: PermissionsService,
|
||||
protected readonly _injector: Injector
|
||||
private readonly _activatedRoute: ActivatedRoute,
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
private readonly _dictionaryControllerService: DictionaryControllerService
|
||||
) {
|
||||
super(_injector);
|
||||
_appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
|
||||
|
||||
@ -20,72 +20,19 @@
|
||||
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
|
||||
|
||||
<div class="content-container">
|
||||
<div class="header-item">
|
||||
<iqser-round-checkbox
|
||||
(click)="toggleSelectAll()"
|
||||
[active]="entitiesService.areAllSelected$ | async"
|
||||
[indeterminate]="entitiesService.notAllSelected$ | async"
|
||||
></iqser-round-checkbox>
|
||||
|
||||
<span class="all-caps-label">
|
||||
{{ 'dictionary-listing.table-header.title' | translate: { length: (entitiesService.displayedLength$ | async) } }}
|
||||
</span>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="openDeleteDictionariesDialog($event)"
|
||||
*ngIf="canBulkDelete$(permissionsService.isAdmin()) | async"
|
||||
[tooltip]="'dictionary-listing.bulk.delete' | translate"
|
||||
icon="red:trash"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-input-with-action
|
||||
[form]="searchService.searchForm"
|
||||
[placeholder]="'dictionary-listing.search' | translate"
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
<div class="actions">
|
||||
<iqser-icon-button
|
||||
(action)="openAddEditDictionaryDialog()"
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
[label]="'dictionary-listing.add-new' | translate"
|
||||
icon="red:plus"
|
||||
[type]="iconButtonTypes.primary"
|
||||
></iqser-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div [class.no-data]="entitiesService.noData$ | async" class="table-header" redactionSyncWidth="table-item">
|
||||
<div class="select-oval-placeholder"></div>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'dictionary-listing.table-col-names.type' | translate"
|
||||
[withSort]="true"
|
||||
column="label"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'dictionary-listing.table-col-names.order-of-importance' | translate"
|
||||
[withSort]="true"
|
||||
class="flex-center"
|
||||
column="rank"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'dictionary-listing.table-col-names.hint-redaction' | translate"
|
||||
class="flex-center"
|
||||
></iqser-table-column-name>
|
||||
<div></div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
<redaction-table-header
|
||||
[bulkActions]="bulkActions"
|
||||
[selectionEnabled]="true"
|
||||
[hasEmptyColumn]="true"
|
||||
[tableColumnConfigs]="tableColumnConfigs"
|
||||
[tableHeaderLabel]="tableHeaderLabel"
|
||||
></redaction-table-header>
|
||||
|
||||
<redaction-empty-state
|
||||
(action)="openAddEditDictionaryDialog()"
|
||||
*ngIf="entitiesService.noData$ | async"
|
||||
[buttonLabel]="'dictionary-listing.no-data.action' | translate"
|
||||
[showButton]="permissionsService.isAdmin()"
|
||||
[showButton]="currentUser.isAdmin"
|
||||
[text]="'dictionary-listing.no-data.title' | translate"
|
||||
icon="red:dictionary"
|
||||
></redaction-empty-state>
|
||||
@ -133,7 +80,7 @@
|
||||
</div>
|
||||
|
||||
<div class="actions-container">
|
||||
<div *ngIf="permissionsService.isAdmin()" class="action-buttons">
|
||||
<div *ngIf="currentUser.isAdmin" class="action-buttons">
|
||||
<iqser-circle-button
|
||||
(action)="openDeleteDictionariesDialog($event, [dict])"
|
||||
[tooltip]="'dictionary-listing.action.delete' | translate"
|
||||
@ -167,3 +114,30 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ng-template #bulkActions>
|
||||
<iqser-circle-button
|
||||
(action)="openDeleteDictionariesDialog($event)"
|
||||
*ngIf="currentUser.isAdmin && (entitiesService.areSomeSelected$ | async)"
|
||||
[tooltip]="'dictionary-listing.bulk.delete' | translate"
|
||||
icon="red:trash"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-input-with-action
|
||||
[form]="searchService.searchForm"
|
||||
[placeholder]="'dictionary-listing.search' | translate"
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
<div class="actions">
|
||||
<iqser-icon-button
|
||||
(action)="openAddEditDictionaryDialog()"
|
||||
*ngIf="currentUser.isAdmin"
|
||||
[label]="'dictionary-listing.add-new' | translate"
|
||||
icon="red:plus"
|
||||
[type]="iconButtonTypes.primary"
|
||||
></iqser-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
@ -1,67 +1,55 @@
|
||||
@import '../../../../../assets/styles/variables';
|
||||
@import '../../../../../assets/styles/red-mixins';
|
||||
|
||||
.header-item {
|
||||
padding: 0 16px 0 10px;
|
||||
redaction-table-header::ng-deep .header-item {
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.attributes-actions-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
.attributes-actions-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
|
||||
> *:not(:last-child) {
|
||||
margin-right: 16px;
|
||||
}
|
||||
> *:not(:last-child) {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
iqser-table-column-name::ng-deep {
|
||||
> div {
|
||||
padding-left: 10px !important;
|
||||
.content-container cdk-virtual-scroll-viewport {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: auto 2fr 1fr 1fr 1fr 11px;
|
||||
|
||||
.table-item > div:not(.scrollbar-placeholder) {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding-left: 10px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
&.center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.color-square {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
min-width: 16px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.dict-name {
|
||||
z-index: 1;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.stats-subtitle {
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-container {
|
||||
cdk-virtual-scroll-viewport {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: auto 2fr 1fr 1fr 1fr 11px;
|
||||
|
||||
.table-item {
|
||||
> div:not(.scrollbar-placeholder) {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding-left: 10px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
&.center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.color-square {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
min-width: 16px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.dict-name {
|
||||
z-index: 1;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.stats-subtitle {
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.has-scrollbar:hover {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: auto 2fr 1fr 1fr 1fr;
|
||||
}
|
||||
}
|
||||
&.has-scrollbar:hover ::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: auto 2fr 1fr 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,14 +4,14 @@ import { DictionaryControllerService } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { catchError, defaultIfEmpty, tap } from 'rxjs/operators';
|
||||
import { forkJoin, of } from 'rxjs';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { TypeValueWrapper } from '@models/file/type-value.wrapper';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { CircleButtonTypes, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, DefaultListingServices, IconButtonTypes, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserService } from '@services/user.service';
|
||||
|
||||
const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({
|
||||
value: dict.entries?.length ?? 0,
|
||||
@ -25,23 +25,41 @@ const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({
|
||||
styleUrls: ['./dictionary-listing-screen.component.scss'],
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DictionaryListingScreenComponent extends BaseListingComponent<TypeValueWrapper> implements OnInit {
|
||||
export class DictionaryListingScreenComponent extends ListingComponent<TypeValueWrapper> implements OnInit {
|
||||
protected readonly _primaryKey = 'label';
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
readonly tableHeaderLabel = _('dictionary-listing.table-header.title');
|
||||
readonly tableColumnConfigs: TableColumnConfig<TypeValueWrapper>[] = [
|
||||
{
|
||||
label: _('dictionary-listing.table-col-names.type'),
|
||||
withSort: true,
|
||||
column: 'label'
|
||||
},
|
||||
{
|
||||
label: _('dictionary-listing.table-col-names.order-of-importance'),
|
||||
withSort: true,
|
||||
column: 'rank',
|
||||
class: 'flex-center'
|
||||
},
|
||||
{
|
||||
label: _('dictionary-listing.table-col-names.hint-redaction'),
|
||||
class: 'flex-center'
|
||||
}
|
||||
];
|
||||
|
||||
chartData: DoughnutChartConfig[] = [];
|
||||
|
||||
protected readonly _primaryKey = 'label';
|
||||
|
||||
constructor(
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
private readonly _dictionaryControllerService: DictionaryControllerService,
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _activatedRoute: ActivatedRoute,
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
private readonly _translateService: TranslateService,
|
||||
readonly permissionsService: PermissionsService,
|
||||
protected readonly _injector: Injector
|
||||
private readonly _dictionaryControllerService: DictionaryControllerService
|
||||
) {
|
||||
super(_injector);
|
||||
_loadingService.start();
|
||||
|
||||
@ -3,7 +3,7 @@ import { DigitalSignature, DigitalSignatureControllerService } from '@redaction/
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Toaster } from '@services/toaster.service';
|
||||
import { lastIndexOfEnd } from '@utils/functions';
|
||||
import { AutoUnsubscribeComponent, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { AutoUnsubscribe, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserService } from '@services/user.service';
|
||||
@ -13,7 +13,7 @@ import { UserService } from '@services/user.service';
|
||||
templateUrl: './digital-signature-screen.component.html',
|
||||
styleUrls: ['./digital-signature-screen.component.scss']
|
||||
})
|
||||
export class DigitalSignatureScreenComponent extends AutoUnsubscribeComponent implements OnDestroy {
|
||||
export class DigitalSignatureScreenComponent extends AutoUnsubscribe implements OnDestroy {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
|
||||
|
||||
@ -20,72 +20,19 @@
|
||||
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
|
||||
|
||||
<div class="content-container">
|
||||
<div *ngIf="(entitiesService.noData$ | async) === false" class="header-item">
|
||||
<iqser-round-checkbox
|
||||
(click)="toggleSelectAll()"
|
||||
[active]="entitiesService.areAllSelected$ | async"
|
||||
[indeterminate]="entitiesService.notAllSelected$ | async"
|
||||
></iqser-round-checkbox>
|
||||
|
||||
<span class="all-caps-label">
|
||||
{{
|
||||
'dossier-attributes-listing.table-header.title' | translate: { length: (entitiesService.displayedLength$ | async) }
|
||||
}}
|
||||
</span>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="openConfirmDeleteAttributeDialog($event)"
|
||||
*ngIf="permissionsService.isAdmin() && entitiesService.areSomeSelected$ | async"
|
||||
[tooltip]="'dossier-attributes-listing.bulk.delete' | translate"
|
||||
icon="red:trash"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-input-with-action
|
||||
[form]="searchService.searchForm"
|
||||
[placeholder]="'dossier-attributes-listing.search' | translate"
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="openAddEditAttributeDialog($event)"
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
[label]="'dossier-attributes-listing.add-new' | translate"
|
||||
icon="red:plus"
|
||||
[type]="iconButtonTypes.primary"
|
||||
></iqser-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="(entitiesService.noData$ | async) === false" class="table-header" redactionSyncWidth="table-item">
|
||||
<div class="select-oval-placeholder"></div>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'dossier-attributes-listing.table-col-names.label' | translate"
|
||||
[withSort]="true"
|
||||
column="label"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'dossier-attributes-listing.table-col-names.placeholder' | translate"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'dossier-attributes-listing.table-col-names.type' | translate"
|
||||
[withSort]="true"
|
||||
column="type"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<div></div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
<redaction-table-header
|
||||
[bulkActions]="bulkActions"
|
||||
[selectionEnabled]="true"
|
||||
[hasEmptyColumn]="true"
|
||||
[tableColumnConfigs]="tableColumnConfigs"
|
||||
[tableHeaderLabel]="tableHeaderLabel"
|
||||
></redaction-table-header>
|
||||
|
||||
<redaction-empty-state
|
||||
(action)="openAddEditAttributeDialog($event)"
|
||||
*ngIf="entitiesService.noData$ | async"
|
||||
[buttonLabel]="'dossier-attributes-listing.no-data.action' | translate"
|
||||
[showButton]="permissionsService.isAdmin()"
|
||||
[showButton]="currentUser.isAdmin"
|
||||
[text]="'dossier-attributes-listing.no-data.title' | translate"
|
||||
icon="red:attribute"
|
||||
></redaction-empty-state>
|
||||
@ -116,7 +63,7 @@
|
||||
{{ translations[attribute.type] | translate }}
|
||||
</div>
|
||||
<div class="actions-container">
|
||||
<div *ngIf="permissionsService.isAdmin()" class="action-buttons">
|
||||
<div *ngIf="currentUser.isAdmin" class="action-buttons">
|
||||
<iqser-circle-button
|
||||
(action)="openAddEditAttributeDialog($event, attribute)"
|
||||
[tooltip]="'dossier-attributes-listing.action.edit' | translate"
|
||||
@ -138,3 +85,29 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ng-template #bulkActions>
|
||||
<iqser-circle-button
|
||||
(action)="openConfirmDeleteAttributeDialog($event)"
|
||||
*ngIf="currentUser.isAdmin && entitiesService.areSomeSelected$ | async"
|
||||
[tooltip]="'dossier-attributes-listing.bulk.delete' | translate"
|
||||
icon="red:trash"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-input-with-action
|
||||
[form]="searchService.searchForm"
|
||||
[placeholder]="'dossier-attributes-listing.search' | translate"
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="openAddEditAttributeDialog($event)"
|
||||
*ngIf="currentUser.isAdmin"
|
||||
[label]="'dossier-attributes-listing.add-new' | translate"
|
||||
icon="red:plus"
|
||||
[type]="iconButtonTypes.primary"
|
||||
></iqser-icon-button>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
@ -1,25 +1,40 @@
|
||||
import { Component, Injector, OnInit } from '@angular/core';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, DefaultListingServices, IconButtonTypes, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { DossierAttributeConfig } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { CircleButtonTypes, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { DossierAttributesService } from '@shared/services/controller-wrappers/dossier-attributes.service';
|
||||
import { dossierAttributeTypesTranslations } from '../../translations/dossier-attribute-types-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserService } from '@services/user.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossier-attributes-listing-screen.component.html',
|
||||
styleUrls: ['./dossier-attributes-listing-screen.component.scss'],
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DossierAttributesListingScreenComponent extends BaseListingComponent<DossierAttributeConfig> implements OnInit {
|
||||
export class DossierAttributesListingScreenComponent extends ListingComponent<DossierAttributeConfig> implements OnInit {
|
||||
protected readonly _primaryKey = 'label';
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
readonly translations = dossierAttributeTypesTranslations;
|
||||
protected readonly _primaryKey = 'label';
|
||||
readonly tableHeaderLabel = _('dossier-attributes-listing.table-header.title');
|
||||
readonly tableColumnConfigs: TableColumnConfig<DossierAttributeConfig>[] = [
|
||||
{
|
||||
label: _('dossier-attributes-listing.table-col-names.label'),
|
||||
withSort: true,
|
||||
column: 'label'
|
||||
},
|
||||
{ label: _('dossier-attributes-listing.table-col-names.placeholder') },
|
||||
{
|
||||
label: _('dossier-attributes-listing.table-col-names.type'),
|
||||
withSort: true,
|
||||
column: 'type'
|
||||
}
|
||||
];
|
||||
|
||||
constructor(
|
||||
protected readonly _injector: Injector,
|
||||
@ -28,7 +43,7 @@ export class DossierAttributesListingScreenComponent extends BaseListingComponen
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _dossierAttributesService: DossierAttributesService,
|
||||
readonly permissionsService: PermissionsService
|
||||
private readonly _userService: UserService
|
||||
) {
|
||||
super(_injector);
|
||||
_appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
|
||||
|
||||
@ -94,7 +94,7 @@
|
||||
<ng-template #bulkActions>
|
||||
<iqser-circle-button
|
||||
(action)="openBulkDeleteTemplatesDialog($event)"
|
||||
*ngIf="canBulkDelete$(currentUser.isAdmin) | async"
|
||||
*ngIf="currentUser.isAdmin && (entitiesService.areSomeSelected$ | async)"
|
||||
[tooltip]="'dossier-templates-listing.bulk.delete' | translate"
|
||||
[type]="circleButtonTypes.dark"
|
||||
icon="red:trash"
|
||||
|
||||
@ -5,8 +5,7 @@ import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { DossierTemplateModelWrapper } from '@models/file/dossier-template-model.wrapper';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { DossierTemplateControllerService } from '@redaction/red-ui-http';
|
||||
import { CircleButtonTypes, IconButtonTypes, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, DefaultListingServices, IconButtonTypes, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
@ -16,7 +15,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DossierTemplatesListingScreenComponent extends BaseListingComponent<DossierTemplateModelWrapper> implements OnInit {
|
||||
export class DossierTemplatesListingScreenComponent extends ListingComponent<DossierTemplateModelWrapper> implements OnInit {
|
||||
protected readonly _primaryKey = 'name';
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
|
||||
@ -20,89 +20,13 @@
|
||||
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
|
||||
|
||||
<div class="content-container">
|
||||
<div class="header-item">
|
||||
<iqser-round-checkbox
|
||||
(click)="toggleSelectAll()"
|
||||
[active]="entitiesService.areAllSelected$ | async"
|
||||
[indeterminate]="entitiesService.notAllSelected$ | async"
|
||||
></iqser-round-checkbox>
|
||||
|
||||
<span class="all-caps-label">
|
||||
{{ 'file-attributes-listing.table-header.title' | translate: { length: (entitiesService.displayedLength$ | async) } }}
|
||||
</span>
|
||||
|
||||
<iqser-circle-button
|
||||
(click)="openConfirmDeleteAttributeDialog($event)"
|
||||
*ngIf="canBulkDelete$(permissionsService.isAdmin()) | async"
|
||||
[tooltip]="'file-attributes-listing.bulk-actions.delete' | translate"
|
||||
icon="red:trash"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-input-with-action
|
||||
[form]="searchService.searchForm"
|
||||
[placeholder]="'file-attributes-listing.search' | translate"
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
<input #fileInput (change)="importCSV($event.target['files'])" accept=".csv" class="csv-input" type="file" />
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="fileInput.click()"
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
[tooltip]="'file-attributes-listing.upload-csv' | translate"
|
||||
icon="red:upload"
|
||||
tooltipPosition="above"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="openAddEditAttributeDialog($event)"
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
[label]="'file-attributes-listing.add-new' | translate"
|
||||
icon="red:plus"
|
||||
[type]="iconButtonTypes.primary"
|
||||
></iqser-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div [class.no-data]="entitiesService.noData$ | async" class="table-header" redactionSyncWidth="table-item">
|
||||
<div class="select-oval-placeholder"></div>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'file-attributes-listing.table-col-names.name' | translate"
|
||||
[withSort]="true"
|
||||
column="label"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'file-attributes-listing.table-col-names.type' | translate"
|
||||
[withSort]="true"
|
||||
column="type"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'file-attributes-listing.table-col-names.read-only' | translate"
|
||||
[withSort]="true"
|
||||
class="flex-center"
|
||||
column="editable"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'file-attributes-listing.table-col-names.csv-column' | translate"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'file-attributes-listing.table-col-names.primary' | translate"
|
||||
[rightIconTooltip]="'file-attributes-listing.table-col-names.primary-info-tooltip' | translate"
|
||||
class="flex-center"
|
||||
rightIcon="red:status-info"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<div></div>
|
||||
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
<redaction-table-header
|
||||
[bulkActions]="bulkActions"
|
||||
[selectionEnabled]="true"
|
||||
[hasEmptyColumn]="true"
|
||||
[tableColumnConfigs]="tableColumnConfigs"
|
||||
[tableHeaderLabel]="tableHeaderLabel"
|
||||
></redaction-table-header>
|
||||
|
||||
<redaction-empty-state
|
||||
*ngIf="entitiesService.noData$ | async"
|
||||
@ -116,7 +40,6 @@
|
||||
></redaction-empty-state>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<!-- Table lines -->
|
||||
<div *cdkVirtualFor="let attribute of sortedDisplayedEntities$ | async" class="table-item">
|
||||
<div (click)="toggleEntitySelected($event, attribute)" class="selection-column">
|
||||
<iqser-round-checkbox [active]="isSelected(attribute)"></iqser-round-checkbox>
|
||||
@ -143,7 +66,7 @@
|
||||
<iqser-round-checkbox *ngIf="attribute.primaryAttribute" [active]="true" [size]="18"></iqser-round-checkbox>
|
||||
</div>
|
||||
<div class="actions-container">
|
||||
<div *ngIf="permissionsService.isAdmin()" class="action-buttons">
|
||||
<div *ngIf="currentUser.isAdmin" class="action-buttons">
|
||||
<iqser-circle-button
|
||||
(action)="openAddEditAttributeDialog($event, attribute)"
|
||||
[tooltip]="'file-attributes-listing.action.edit' | translate"
|
||||
@ -166,3 +89,40 @@
|
||||
<div class="right-container"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ng-template #bulkActions>
|
||||
<iqser-circle-button
|
||||
(click)="openConfirmDeleteAttributeDialog($event)"
|
||||
*ngIf="currentUser.isAdmin && (entitiesService.areSomeSelected$ | async)"
|
||||
[tooltip]="'file-attributes-listing.bulk-actions.delete' | translate"
|
||||
icon="red:trash"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-input-with-action
|
||||
[form]="searchService.searchForm"
|
||||
[placeholder]="'file-attributes-listing.search' | translate"
|
||||
type="search"
|
||||
></redaction-input-with-action>
|
||||
|
||||
<input #fileInput (change)="importCSV($event.target['files'])" accept=".csv" class="csv-input" type="file" />
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="fileInput.click()"
|
||||
*ngIf="currentUser.isAdmin"
|
||||
[tooltip]="'file-attributes-listing.upload-csv' | translate"
|
||||
icon="red:upload"
|
||||
tooltipPosition="above"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="openAddEditAttributeDialog($event)"
|
||||
*ngIf="currentUser.isAdmin"
|
||||
[label]="'file-attributes-listing.add-new' | translate"
|
||||
icon="red:plus"
|
||||
[type]="iconButtonTypes.primary"
|
||||
></iqser-icon-button>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
@ -5,60 +5,48 @@
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.header-item {
|
||||
redaction-table-header::ng-deep .header-item {
|
||||
padding: 0 24px 0 10px;
|
||||
}
|
||||
|
||||
iqser-table-column-name::ng-deep {
|
||||
> div {
|
||||
padding-left: 10px !important;
|
||||
.content-container cdk-virtual-scroll-viewport {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: auto 2fr 1fr 1fr 1fr 1fr 1fr 11px;
|
||||
|
||||
.table-item {
|
||||
> div:not(.scrollbar-placeholder) {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
> div {
|
||||
&.center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&.label span {
|
||||
@include line-clamp(1);
|
||||
}
|
||||
|
||||
&.read-only mat-icon {
|
||||
width: 14px;
|
||||
height: 34px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.has-scrollbar:hover ::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: auto 2fr 1fr 1fr 1fr 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.content-container {
|
||||
.header-item {
|
||||
.attributes-actions-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
.attributes-actions-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
|
||||
> *:not(:last-child) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cdk-virtual-scroll-viewport {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: auto 2fr 1fr 1fr 1fr 1fr 1fr 11px;
|
||||
|
||||
.table-item {
|
||||
> div:not(.scrollbar-placeholder) {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
> div {
|
||||
&.center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&.label span {
|
||||
@include line-clamp(1);
|
||||
}
|
||||
|
||||
&.read-only mat-icon {
|
||||
width: 14px;
|
||||
height: 34px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.has-scrollbar:hover {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: auto 2fr 1fr 1fr 1fr 1fr 1fr;
|
||||
}
|
||||
}
|
||||
> *:not(:last-child) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import { ChangeDetectionStrategy, Component, ElementRef, Injector, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { FileAttributeConfig, FileAttributesConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { CircleButtonTypes, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, DefaultListingServices, IconButtonTypes, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { fileAttributeTypesTranslations } from '../../translations/file-attribute-types-translations';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
@Component({
|
||||
templateUrl: './file-attributes-listing-screen.component.html',
|
||||
@ -15,22 +15,50 @@ import { fileAttributeTypesTranslations } from '../../translations/file-attribut
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class FileAttributesListingScreenComponent extends BaseListingComponent<FileAttributeConfig> implements OnInit, OnDestroy {
|
||||
export class FileAttributesListingScreenComponent extends ListingComponent<FileAttributeConfig> implements OnInit, OnDestroy {
|
||||
protected readonly _primaryKey = 'label';
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
readonly translations = fileAttributeTypesTranslations;
|
||||
protected readonly _primaryKey = 'label';
|
||||
readonly tableHeaderLabel = _('file-attributes-listing.table-header.title');
|
||||
readonly tableColumnConfigs: TableColumnConfig<FileAttributeConfig>[] = [
|
||||
{
|
||||
label: _('file-attributes-listing.table-col-names.name'),
|
||||
withSort: true,
|
||||
column: 'label'
|
||||
},
|
||||
{
|
||||
label: _('file-attributes-listing.table-col-names.type'),
|
||||
withSort: true,
|
||||
column: 'type'
|
||||
},
|
||||
{
|
||||
label: _('file-attributes-listing.table-col-names.read-only'),
|
||||
withSort: true,
|
||||
column: 'editable',
|
||||
class: 'flex-center'
|
||||
},
|
||||
{ label: _('file-attributes-listing.table-col-names.csv-column') },
|
||||
{
|
||||
label: _('file-attributes-listing.table-col-names.primary'),
|
||||
class: 'flex-center',
|
||||
rightIcon: 'red:status-info',
|
||||
rightIconTooltip: _('file-attributes-listing.table-col-names.primary-info-tooltip')
|
||||
}
|
||||
];
|
||||
|
||||
private _existingConfiguration: FileAttributesConfig;
|
||||
@ViewChild('fileInput') private _fileInput: ElementRef;
|
||||
|
||||
constructor(
|
||||
readonly permissionsService: PermissionsService,
|
||||
private readonly _fileAttributesService: FileAttributesControllerService,
|
||||
private readonly _appStateService: AppStateService,
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _activatedRoute: ActivatedRoute,
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
protected readonly _injector: Injector
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
private readonly _fileAttributesService: FileAttributesControllerService
|
||||
) {
|
||||
super(_injector);
|
||||
_appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
|
||||
|
||||
@ -8,7 +8,7 @@ import {
|
||||
SMTPConfigurationModel
|
||||
} from '@redaction/red-ui-http';
|
||||
import { AppConfigService } from '@app-config/app-config.service';
|
||||
import { AutoUnsubscribeComponent, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { AutoUnsubscribe, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { Toaster } from '@services/toaster.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
@ -19,7 +19,7 @@ import { UserService } from '@services/user.service';
|
||||
templateUrl: './general-config-screen.component.html',
|
||||
styleUrls: ['./general-config-screen.component.scss']
|
||||
})
|
||||
export class GeneralConfigScreenComponent extends AutoUnsubscribeComponent implements OnInit, OnDestroy {
|
||||
export class GeneralConfigScreenComponent extends AutoUnsubscribe implements OnInit, OnDestroy {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
|
||||
|
||||
@ -4,8 +4,7 @@ import { Dossier } from '@redaction/red-ui-http';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
||||
import * as moment from 'moment';
|
||||
import { CircleButtonTypes, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, DefaultListingServices, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { DossiersService } from '../../../dossier/services/dossiers.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { ConfirmationDialogInput, TitleColors } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component';
|
||||
@ -25,7 +24,7 @@ interface DossierListItem extends Dossier {
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [...DefaultListingServices, DossiersService]
|
||||
})
|
||||
export class TrashScreenComponent extends BaseListingComponent<DossierListItem> implements OnInit {
|
||||
export class TrashScreenComponent extends ListingComponent<DossierListItem> implements OnInit {
|
||||
readonly itemSize = 80;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly tableHeaderLabel = _('trash.table-header.title');
|
||||
|
||||
@ -33,49 +33,13 @@
|
||||
|
||||
<div class="red-content-inner">
|
||||
<div [class.extended]="collapsedDetails" class="content-container">
|
||||
<div class="header-item">
|
||||
<iqser-round-checkbox
|
||||
(click)="toggleSelectAll()"
|
||||
[active]="entitiesService.areAllSelected$ | async"
|
||||
[indeterminate]="entitiesService.notAllSelected$ | async"
|
||||
></iqser-round-checkbox>
|
||||
|
||||
<span class="all-caps-label">
|
||||
{{ 'user-listing.table-header.title' | translate: { length: (entitiesService.displayedLength$ | async) } }}
|
||||
</span>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="bulkDelete()"
|
||||
*ngIf="entitiesService.areSomeSelected$ | async"
|
||||
[disabled]="(canDeleteSelected$ | async) === false"
|
||||
[tooltip]="
|
||||
(canDeleteSelected$ | async)
|
||||
? ('user-listing.bulk.delete' | translate)
|
||||
: ('user-listing.bulk.delete-disabled' | translate)
|
||||
"
|
||||
icon="red:trash"
|
||||
tooltipPosition="after"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
|
||||
<div class="table-header" redactionSyncWidth="table-item">
|
||||
<div class="select-oval-placeholder"></div>
|
||||
|
||||
<iqser-table-column-name [label]="'user-listing.table-col-names.name' | translate"></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name [label]="'user-listing.table-col-names.email' | translate"></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name
|
||||
[label]="'user-listing.table-col-names.active' | translate"
|
||||
class="flex-center"
|
||||
></iqser-table-column-name>
|
||||
|
||||
<iqser-table-column-name [label]="'user-listing.table-col-names.roles' | translate"></iqser-table-column-name>
|
||||
|
||||
<div></div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
<redaction-table-header
|
||||
[bulkActions]="bulkActions"
|
||||
[selectionEnabled]="true"
|
||||
[hasEmptyColumn]="true"
|
||||
[tableColumnConfigs]="tableColumnConfigs"
|
||||
[tableHeaderLabel]="tableHeaderLabel"
|
||||
></redaction-table-header>
|
||||
|
||||
<redaction-empty-state *ngIf="noMatch$ | async" [text]="'user-listing.no-match.title' | translate"></redaction-empty-state>
|
||||
|
||||
@ -129,3 +93,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ng-template #bulkActions>
|
||||
<iqser-circle-button
|
||||
(action)="bulkDelete()"
|
||||
*ngIf="entitiesService.areSomeSelected$ | async"
|
||||
[disabled]="(canDeleteSelected$ | async) === false"
|
||||
[tooltip]="
|
||||
(canDeleteSelected$ | async) ? ('user-listing.bulk.delete' | translate) : ('user-listing.bulk.delete-disabled' | translate)
|
||||
"
|
||||
icon="red:trash"
|
||||
tooltipPosition="after"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
</ng-template>
|
||||
|
||||
@ -7,24 +7,31 @@ import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/si
|
||||
import { TranslateChartService } from '@services/translate-chart.service';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { InitialsAvatarComponent } from '@shared/components/initials-avatar/initials-avatar.component';
|
||||
import { CircleButtonTypes, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, DefaultListingServices, IconButtonTypes, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { rolesTranslations } from '../../../../translations/roles-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
@Component({
|
||||
templateUrl: './user-listing-screen.component.html',
|
||||
styleUrls: ['./user-listing-screen.component.scss'],
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class UserListingScreenComponent extends BaseListingComponent<UserWrapper> implements OnInit {
|
||||
export class UserListingScreenComponent extends ListingComponent<UserWrapper> implements OnInit {
|
||||
protected readonly _primaryKey = 'id';
|
||||
readonly translations = rolesTranslations;
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly currentUser = this.userService.currentUser;
|
||||
readonly canDeleteSelected$ = this._canDeleteSelected$;
|
||||
readonly tableHeaderLabel = _('user-listing.table-header.title');
|
||||
readonly tableColumnConfigs: TableColumnConfig<UserWrapper>[] = [
|
||||
{ label: _('user-listing.table-col-names.name') },
|
||||
{ label: _('user-listing.table-col-names.email') },
|
||||
{ label: _('user-listing.table-col-names.active'), class: 'flex-center' },
|
||||
{ label: _('user-listing.table-col-names.roles') }
|
||||
];
|
||||
|
||||
collapsedDetails = false;
|
||||
chartData: DoughnutChartConfig[] = [];
|
||||
@ -43,7 +50,7 @@ export class UserListingScreenComponent extends BaseListingComponent<UserWrapper
|
||||
super(_injector);
|
||||
}
|
||||
|
||||
get _canDeleteSelected$(): Observable<boolean> {
|
||||
private get _canDeleteSelected$(): Observable<boolean> {
|
||||
const entities$ = this.entitiesService.selected$;
|
||||
return entities$.pipe(map(all => all.indexOf(this.currentUser) === -1));
|
||||
}
|
||||
|
||||
@ -16,8 +16,7 @@ import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { ButtonConfig } from '@shared/components/page-header/models/button-config.model';
|
||||
import { NestedFilter, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { DefaultListingServices, ListingComponent, NestedFilter, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { workloadTranslations } from '../../translations/workload-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { fileStatusTranslations } from '../../translations/file-status-translations';
|
||||
@ -38,7 +37,7 @@ const isLeavingScreen = event => event instanceof NavigationStart && event.url !
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DossierListingScreenComponent
|
||||
extends BaseListingComponent<DossierWrapper>
|
||||
extends ListingComponent<DossierWrapper>
|
||||
implements OnInit, AfterViewInit, OnDestroy, OnAttach, OnDetach
|
||||
{
|
||||
readonly itemSize = 85;
|
||||
|
||||
@ -21,8 +21,7 @@ import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
||||
import { ActionConfig } from '@shared/components/page-header/models/action-config.model';
|
||||
import { CircleButtonTypes, keyChecker, NestedFilter, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { CircleButtonTypes, DefaultListingServices, keyChecker, ListingComponent, NestedFilter, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { DossierAttributesService } from '@shared/services/controller-wrappers/dossier-attributes.service';
|
||||
import { DossierAttributeWithValue } from '@models/dossier-attributes.model';
|
||||
@ -39,10 +38,7 @@ import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
||||
styleUrls: ['./dossier-overview-screen.component.scss'],
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DossierOverviewScreenComponent
|
||||
extends BaseListingComponent<FileStatusWrapper>
|
||||
implements OnInit, OnDestroy, OnDetach, OnAttach
|
||||
{
|
||||
export class DossierOverviewScreenComponent extends ListingComponent<FileStatusWrapper> implements OnInit, OnDestroy, OnDetach, OnAttach {
|
||||
readonly itemSize = 80;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
|
||||
@ -33,7 +33,7 @@ import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
import { stampPDFPage } from '@utils/page-stamper';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AutoUnsubscribeComponent, CircleButtonTypes, NestedFilter, processFilters } from '@iqser/common-ui';
|
||||
import { AutoUnsubscribe, CircleButtonTypes, NestedFilter, processFilters } from '@iqser/common-ui';
|
||||
import { fileStatusTranslations } from '../../translations/file-status-translations';
|
||||
import { handleFilterDelta } from '@shared/components/filters/popup-filter/utils/filter-utils';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
@ -45,7 +45,7 @@ const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f'];
|
||||
templateUrl: './file-preview-screen.component.html',
|
||||
styleUrls: ['./file-preview-screen.component.scss']
|
||||
})
|
||||
export class FilePreviewScreenComponent extends AutoUnsubscribeComponent implements OnInit, OnDestroy, OnAttach, OnDetach {
|
||||
export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnInit, OnDestroy, OnAttach, OnDetach {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly translations = fileStatusTranslations;
|
||||
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import { Component, Injector, OnDestroy } from '@angular/core';
|
||||
import { BaseListingComponent, DefaultListingServices } from '@shared/base/base-listing.component';
|
||||
import { DefaultListingServices, keyChecker, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { MatchedDocument, SearchControllerService, SearchResult } from '@redaction/red-ui-http';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { debounceTime, map, skip, switchMap, tap } from 'rxjs/operators';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { keyChecker, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { LoadingService } from '@services/loading.service';
|
||||
@ -35,7 +34,7 @@ interface SearchInput {
|
||||
styleUrls: ['./search-screen.component.scss'],
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class SearchScreenComponent extends BaseListingComponent<ListItem> implements OnDestroy {
|
||||
export class SearchScreenComponent extends ListingComponent<ListItem> implements OnDestroy {
|
||||
readonly fileStatusTranslations = fileStatusTranslations;
|
||||
readonly searchPositions = SearchPositions;
|
||||
|
||||
|
||||
@ -1,90 +0,0 @@
|
||||
import { Directive, Injector, OnDestroy } from '@angular/core';
|
||||
import {
|
||||
AutoUnsubscribeComponent,
|
||||
Bind,
|
||||
EntitiesService,
|
||||
FilterService,
|
||||
KeysOf,
|
||||
SearchService,
|
||||
SortingOrders,
|
||||
SortingService,
|
||||
TableColumnConfig
|
||||
} from '@iqser/common-ui';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { distinctUntilChanged, map, switchMap } from 'rxjs/operators';
|
||||
|
||||
export const DefaultListingServices = [FilterService, SearchService, EntitiesService, SortingService] as const;
|
||||
|
||||
@Directive()
|
||||
export abstract class BaseListingComponent<T extends object> extends AutoUnsubscribeComponent implements OnDestroy {
|
||||
readonly filterService = this._injector.get(FilterService);
|
||||
readonly searchService = this._injector.get<SearchService<T>>(SearchService);
|
||||
readonly sortingService = this._injector.get<SortingService<T>>(SortingService);
|
||||
readonly entitiesService = this._injector.get<EntitiesService<T>>(EntitiesService);
|
||||
|
||||
readonly noMatch$ = this._noMatch$;
|
||||
readonly sortedDisplayedEntities$ = this._sortedDisplayedEntities$;
|
||||
|
||||
readonly tableColumnConfigs: TableColumnConfig<T>[];
|
||||
/**
|
||||
* Key used in the *trackBy* function with **ngFor* or **cdkVirtualFor*
|
||||
* and in the default sorting and as the search field
|
||||
* @protected
|
||||
*/
|
||||
protected readonly _primaryKey: KeysOf<T>;
|
||||
|
||||
protected constructor(protected readonly _injector: Injector) {
|
||||
super();
|
||||
setTimeout(() => this.setInitialConfig());
|
||||
}
|
||||
|
||||
get allEntities(): T[] {
|
||||
return this.entitiesService.all;
|
||||
}
|
||||
|
||||
private get _sortedDisplayedEntities$(): Observable<T[]> {
|
||||
const sort = entities => this.sortingService.defaultSort(entities);
|
||||
const sortedEntities = () => this.entitiesService.displayed$.pipe(map(sort));
|
||||
return this.sortingService.sortingOption$.pipe(switchMap(sortedEntities));
|
||||
}
|
||||
|
||||
private get _noMatch$(): Observable<boolean> {
|
||||
return combineLatest([this.entitiesService.allLength$, this.entitiesService.displayedLength$]).pipe(
|
||||
map(([hasEntities, hasDisplayedEntities]) => hasEntities && !hasDisplayedEntities),
|
||||
distinctUntilChanged()
|
||||
);
|
||||
}
|
||||
|
||||
setInitialConfig() {
|
||||
this.sortingService.setSortingOption({
|
||||
column: this._primaryKey,
|
||||
order: SortingOrders.asc
|
||||
});
|
||||
this.searchService.setSearchKey(this._primaryKey);
|
||||
}
|
||||
|
||||
canBulkDelete$(hasPermission = true): Observable<boolean> {
|
||||
return this.entitiesService.areSomeSelected$.pipe(
|
||||
map(areSomeEntitiesSelected => areSomeEntitiesSelected && hasPermission),
|
||||
distinctUntilChanged()
|
||||
);
|
||||
}
|
||||
|
||||
toggleSelectAll() {
|
||||
return this.entitiesService.selectAll();
|
||||
}
|
||||
|
||||
toggleEntitySelected(event: MouseEvent, entity: T) {
|
||||
event.stopPropagation();
|
||||
return this.entitiesService.select(entity);
|
||||
}
|
||||
|
||||
isSelected(entity: T): boolean {
|
||||
return this.entitiesService.isSelected(entity);
|
||||
}
|
||||
|
||||
@Bind()
|
||||
trackByPrimaryKey(index: number, item: T) {
|
||||
return item[this._primaryKey];
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,7 @@ import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { FileDownloadService } from '@upload-download/services/file-download.service';
|
||||
import { Toaster } from '@services/toaster.service';
|
||||
import { AutoUnsubscribeComponent, CircleButtonType, CircleButtonTypes } from '@iqser/common-ui';
|
||||
import { AutoUnsubscribe, CircleButtonType, CircleButtonTypes } from '@iqser/common-ui';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
@ -16,7 +16,7 @@ export type MenuState = 'OPEN' | 'CLOSED';
|
||||
styleUrls: ['./file-download-btn.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class FileDownloadBtnComponent extends AutoUnsubscribeComponent implements OnDestroy {
|
||||
export class FileDownloadBtnComponent extends AutoUnsubscribe implements OnDestroy {
|
||||
@Input() dossier: DossierWrapper;
|
||||
@Input() file: FileStatusWrapper | FileStatusWrapper[];
|
||||
@Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy } from '@angular/core';
|
||||
import { UserService, UserWrapper } from '@services/user.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AutoUnsubscribeComponent } from '@iqser/common-ui';
|
||||
import { AutoUnsubscribe } from '@iqser/common-ui';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-initials-avatar',
|
||||
@ -9,7 +9,7 @@ import { AutoUnsubscribeComponent } from '@iqser/common-ui';
|
||||
styleUrls: ['./initials-avatar.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class InitialsAvatarComponent extends AutoUnsubscribeComponent implements OnChanges, OnDestroy {
|
||||
export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChanges, OnDestroy {
|
||||
@Input() userId: string;
|
||||
@Input() color = 'lightgray';
|
||||
@Input() size: 'small' | 'large' = 'small';
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
<ng-container [ngTemplateOutlet]="bulkActions"></ng-container>
|
||||
|
||||
<redaction-quick-filters></redaction-quick-filters>
|
||||
<redaction-quick-filters *ngIf="hasQuickFilters$ | async"></redaction-quick-filters>
|
||||
|
||||
<!-- Custom content-->
|
||||
<ng-content></ng-content>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, TemplateRef } from '@angular/core';
|
||||
import { EntitiesService, Required, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { EntitiesService, FilterService, Required, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-table-header',
|
||||
@ -14,5 +15,7 @@ export class TableHeaderComponent<T extends object> {
|
||||
@Input() selectionEnabled = false;
|
||||
@Input() bulkActions: TemplateRef<any>;
|
||||
|
||||
constructor(readonly entitiesService: EntitiesService<T>) {}
|
||||
readonly hasQuickFilters$ = this.filterService.getGroup$('quickFilters').pipe(map(filters => !!filters));
|
||||
|
||||
constructor(readonly entitiesService: EntitiesService<T>, readonly filterService: FilterService) {}
|
||||
}
|
||||
|
||||
@ -25,8 +25,7 @@ export class SyncWidthDirective implements AfterViewInit, OnDestroy {
|
||||
@Debounce(10)
|
||||
matchWidth() {
|
||||
const headerItems = this._elementRef.nativeElement.children;
|
||||
const tableRows = document.getElementsByClassName(this.redactionSyncWidth);
|
||||
// const tableRows = this._elementRef.nativeElement.parentElement.getElementsByClassName(this.redactionSyncWidth);
|
||||
const tableRows = this._elementRef.nativeElement.parentElement.parentElement.getElementsByClassName(this.redactionSyncWidth);
|
||||
|
||||
if (!tableRows || !tableRows.length) {
|
||||
return;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user