RED-1817: fixed access permissions to settings screens
This commit is contained in:
parent
d30e74e14c
commit
1c81469e6b
@ -111,14 +111,19 @@ const routes = [
|
|||||||
{ path: '', redirectTo: 'dictionaries', pathMatch: 'full' }
|
{ path: '', redirectTo: 'dictionaries', pathMatch: 'full' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
data: {
|
||||||
|
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
|
||||||
|
requiredRoles: ['RED_MANAGER', 'RED_ADMIN']
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'users',
|
path: 'users',
|
||||||
component: UserListingScreenComponent,
|
component: UserListingScreenComponent,
|
||||||
canActivate: [CompositeRouteGuard],
|
canActivate: [CompositeRouteGuard],
|
||||||
data: {
|
data: {
|
||||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
|
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
|
||||||
|
requiredRoles: ['RED_USER_ADMIN']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -126,7 +131,8 @@ const routes = [
|
|||||||
component: LicenseInformationScreenComponent,
|
component: LicenseInformationScreenComponent,
|
||||||
canActivate: [CompositeRouteGuard],
|
canActivate: [CompositeRouteGuard],
|
||||||
data: {
|
data: {
|
||||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
|
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
|
||||||
|
requiredRoles: ['RED_ADMIN']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -134,7 +140,8 @@ const routes = [
|
|||||||
component: DigitalSignatureScreenComponent,
|
component: DigitalSignatureScreenComponent,
|
||||||
canActivate: [CompositeRouteGuard],
|
canActivate: [CompositeRouteGuard],
|
||||||
data: {
|
data: {
|
||||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
|
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
|
||||||
|
requiredRoles: ['RED_ADMIN']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -142,7 +149,8 @@ const routes = [
|
|||||||
component: AuditScreenComponent,
|
component: AuditScreenComponent,
|
||||||
canActivate: [CompositeRouteGuard],
|
canActivate: [CompositeRouteGuard],
|
||||||
data: {
|
data: {
|
||||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
|
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
|
||||||
|
requiredRoles: ['RED_ADMIN']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -150,7 +158,8 @@ const routes = [
|
|||||||
component: SmtpConfigScreenComponent,
|
component: SmtpConfigScreenComponent,
|
||||||
canActivate: [CompositeRouteGuard],
|
canActivate: [CompositeRouteGuard],
|
||||||
data: {
|
data: {
|
||||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
|
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
|
||||||
|
requiredRoles: ['RED_ADMIN']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,7 +4,8 @@
|
|||||||
*ngIf="
|
*ngIf="
|
||||||
(!item.onlyAdmin || permissionsService.isAdmin()) &&
|
(!item.onlyAdmin || permissionsService.isAdmin()) &&
|
||||||
(!item.onlyDevMode || userPreferenceService.areDevFeaturesEnabled) &&
|
(!item.onlyDevMode || userPreferenceService.areDevFeaturesEnabled) &&
|
||||||
(!item.userManagerOnly || permissionsService.canManageUsers())
|
(!item.userManagerOnly || permissionsService.canManageUsers()) &&
|
||||||
|
(!item.onlyManager || permissionsService.isManager())
|
||||||
"
|
"
|
||||||
[routerLinkActiveOptions]="{ exact: false }"
|
[routerLinkActiveOptions]="{ exact: false }"
|
||||||
[routerLink]="prefix + item.screen"
|
[routerLink]="prefix + item.screen"
|
||||||
|
|||||||
@ -16,12 +16,13 @@ export class AdminSideNavComponent {
|
|||||||
screen: string;
|
screen: string;
|
||||||
onlyDevMode?: boolean;
|
onlyDevMode?: boolean;
|
||||||
onlyAdmin?: boolean;
|
onlyAdmin?: boolean;
|
||||||
|
onlyManager?: boolean;
|
||||||
userManagerOnly?: boolean;
|
userManagerOnly?: boolean;
|
||||||
label?: string;
|
label?: string;
|
||||||
}[];
|
}[];
|
||||||
} = {
|
} = {
|
||||||
settings: [
|
settings: [
|
||||||
{ screen: 'dossier-templates', onlyAdmin: true },
|
{ screen: 'dossier-templates', onlyManager: true },
|
||||||
{ screen: 'digital-signature', onlyAdmin: true },
|
{ screen: 'digital-signature', onlyAdmin: true },
|
||||||
{ screen: 'license-info', label: 'license-information', onlyAdmin: true },
|
{ screen: 'license-info', label: 'license-information', onlyAdmin: true },
|
||||||
{ screen: 'audit', onlyAdmin: true },
|
{ screen: 'audit', onlyAdmin: true },
|
||||||
@ -33,9 +34,9 @@ export class AdminSideNavComponent {
|
|||||||
{ screen: 'rules', onlyDevMode: true, label: 'rule-editor' },
|
{ screen: 'rules', onlyDevMode: true, label: 'rule-editor' },
|
||||||
{ screen: 'default-colors' },
|
{ screen: 'default-colors' },
|
||||||
{ screen: 'watermark' },
|
{ screen: 'watermark' },
|
||||||
{ screen: 'file-attributes', onlyAdmin: true },
|
{ screen: 'file-attributes' },
|
||||||
{ screen: 'dossier-attributes', onlyAdmin: true },
|
{ screen: 'dossier-attributes' },
|
||||||
{ screen: 'reports', onlyAdmin: true, onlyDevMode: true }
|
{ screen: 'reports', onlyDevMode: true }
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -7,10 +7,7 @@
|
|||||||
></redaction-round-checkbox>
|
></redaction-round-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<span class="all-caps-label">
|
<span class="all-caps-label">
|
||||||
{{
|
{{ 'file-attributes-csv-import.table-header.title' | translate: { length: allEntities.length } }}
|
||||||
'file-attributes-csv-import.table-header.title'
|
|
||||||
| translate: { length: allEntities.length }
|
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<ng-container *ngIf="areSomeEntitiesSelected$ | async">
|
<ng-container *ngIf="areSomeEntitiesSelected$ | async">
|
||||||
@ -49,11 +46,7 @@
|
|||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
<mat-menu #typeMenu="matMenu" class="padding-bottom-8">
|
<mat-menu #typeMenu="matMenu" class="padding-bottom-8">
|
||||||
<button
|
<button (click)="setAttributeForSelection('type', type)" *ngFor="let type of typeOptions" mat-menu-item>
|
||||||
(click)="setAttributeForSelection('type', type)"
|
|
||||||
*ngFor="let type of typeOptions"
|
|
||||||
mat-menu-item
|
|
||||||
>
|
|
||||||
{{ 'file-attribute-types.' + type | translate }}
|
{{ 'file-attribute-types.' + type | translate }}
|
||||||
</button>
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
@ -63,14 +56,9 @@
|
|||||||
<div class="table-header" redactionSyncWidth="table-item">
|
<div class="table-header" redactionSyncWidth="table-item">
|
||||||
<div class="select-oval-placeholder"></div>
|
<div class="select-oval-placeholder"></div>
|
||||||
|
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name class="name" label="file-attributes-csv-import.table-col-names.name"></redaction-table-col-name>
|
||||||
class="name"
|
|
||||||
label="file-attributes-csv-import.table-col-names.name"
|
|
||||||
></redaction-table-col-name>
|
|
||||||
|
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name label="file-attributes-csv-import.table-col-names.type"></redaction-table-col-name>
|
||||||
label="file-attributes-csv-import.table-col-names.type"
|
|
||||||
></redaction-table-col-name>
|
|
||||||
|
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name
|
||||||
class="flex-center"
|
class="flex-center"
|
||||||
@ -89,11 +77,7 @@
|
|||||||
<div class="scrollbar-placeholder"></div>
|
<div class="scrollbar-placeholder"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state *ngIf="noData" icon="red:attribute" screen="file-attributes-csv-import"></redaction-empty-state>
|
||||||
*ngIf="(allEntities$ | async)?.length === 0"
|
|
||||||
icon="red:attribute"
|
|
||||||
screen="file-attributes-csv-import"
|
|
||||||
></redaction-empty-state>
|
|
||||||
|
|
||||||
<cdk-virtual-scroll-viewport [itemSize]="50" redactionHasScrollbar>
|
<cdk-virtual-scroll-viewport [itemSize]="50" redactionHasScrollbar>
|
||||||
<!-- Table lines -->
|
<!-- Table lines -->
|
||||||
@ -110,10 +94,7 @@
|
|||||||
<div *ngIf="!field.editingName">
|
<div *ngIf="!field.editingName">
|
||||||
{{ field.name }}
|
{{ field.name }}
|
||||||
</div>
|
</div>
|
||||||
<form
|
<form (submit)="field.editingName = false; field.name = field.temporaryName" *ngIf="field.editingName">
|
||||||
(submit)="field.editingName = false; field.name = field.temporaryName"
|
|
||||||
*ngIf="field.editingName"
|
|
||||||
>
|
|
||||||
<div class="red-input-group w-200">
|
<div class="red-input-group w-200">
|
||||||
<input [(ngModel)]="field.temporaryName" name="name" />
|
<input [(ngModel)]="field.temporaryName" name="name" />
|
||||||
</div>
|
</div>
|
||||||
@ -156,10 +137,7 @@
|
|||||||
<mat-slide-toggle [(ngModel)]="field.readonly" color="primary"></mat-slide-toggle>
|
<mat-slide-toggle [(ngModel)]="field.readonly" color="primary"></mat-slide-toggle>
|
||||||
</div>
|
</div>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<redaction-round-checkbox
|
<redaction-round-checkbox (click)="togglePrimary(field)" [active]="field.primaryAttribute"></redaction-round-checkbox>
|
||||||
(click)="togglePrimary(field)"
|
|
||||||
[active]="field.primaryAttribute"
|
|
||||||
></redaction-round-checkbox>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="actions-container">
|
<div class="actions-container">
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(action)="openConfirmDeleteAttributeDialog($event)"
|
(action)="openConfirmDeleteAttributeDialog($event)"
|
||||||
*ngIf="areSomeEntitiesSelected$ | async"
|
*ngIf="permissionsService.isAdmin() && areSomeEntitiesSelected$ | async"
|
||||||
icon="red:trash"
|
icon="red:trash"
|
||||||
tooltip="dossier-attributes-listing.bulk.delete"
|
tooltip="dossier-attributes-listing.bulk.delete"
|
||||||
type="dark-bg"
|
type="dark-bg"
|
||||||
@ -50,6 +50,7 @@
|
|||||||
|
|
||||||
<redaction-icon-button
|
<redaction-icon-button
|
||||||
(action)="openAddEditAttributeDialog($event)"
|
(action)="openAddEditAttributeDialog($event)"
|
||||||
|
*ngIf="permissionsService.isAdmin()"
|
||||||
icon="red:plus"
|
icon="red:plus"
|
||||||
text="dossier-attributes-listing.add-new"
|
text="dossier-attributes-listing.add-new"
|
||||||
type="primary"
|
type="primary"
|
||||||
@ -81,17 +82,13 @@
|
|||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state
|
||||||
(action)="openAddEditAttributeDialog($event)"
|
(action)="openAddEditAttributeDialog($event)"
|
||||||
*ngIf="(allEntities$ | async)?.length === 0"
|
*ngIf="noData"
|
||||||
[showButton]="true"
|
[showButton]="permissionsService.isAdmin()"
|
||||||
icon="red:attribute"
|
icon="red:attribute"
|
||||||
screen="dossier-attributes-listing"
|
screen="dossier-attributes-listing"
|
||||||
></redaction-empty-state>
|
></redaction-empty-state>
|
||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state *ngIf="noMatch" screen="dossier-attributes-listing" type="no-match"></redaction-empty-state>
|
||||||
*ngIf="(allEntities$ | async)?.length && (displayedEntities$ | async)?.length === 0"
|
|
||||||
screen="dossier-attributes-listing"
|
|
||||||
type="no-match"
|
|
||||||
></redaction-empty-state>
|
|
||||||
|
|
||||||
<cdk-virtual-scroll-viewport [itemSize]="50" redactionHasScrollbar>
|
<cdk-virtual-scroll-viewport [itemSize]="50" redactionHasScrollbar>
|
||||||
<div
|
<div
|
||||||
@ -114,7 +111,7 @@
|
|||||||
{{ 'dossier-attribute-types.' + attribute.type | translate }}
|
{{ 'dossier-attribute-types.' + attribute.type | translate }}
|
||||||
</div>
|
</div>
|
||||||
<div class="actions-container">
|
<div class="actions-container">
|
||||||
<div class="action-buttons">
|
<div *ngIf="permissionsService.isAdmin()" class="action-buttons">
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(action)="openAddEditAttributeDialog($event, attribute)"
|
(action)="openAddEditAttributeDialog($event, attribute)"
|
||||||
icon="red:edit"
|
icon="red:edit"
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { ScreenNames, SortingService } from '../../../../services/sorting.servic
|
|||||||
import { FilterService } from '../../../shared/services/filter.service';
|
import { FilterService } from '../../../shared/services/filter.service';
|
||||||
import { SearchService } from '../../../shared/services/search.service';
|
import { SearchService } from '../../../shared/services/search.service';
|
||||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||||
|
import { PermissionsService } from '@services/permissions.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './dossier-attributes-listing-screen.component.html',
|
templateUrl: './dossier-attributes-listing-screen.component.html',
|
||||||
@ -22,7 +23,8 @@ export class DossierAttributesListingScreenComponent extends BaseListingComponen
|
|||||||
private readonly _activatedRoute: ActivatedRoute,
|
private readonly _activatedRoute: ActivatedRoute,
|
||||||
private readonly _dialogService: AdminDialogService,
|
private readonly _dialogService: AdminDialogService,
|
||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _dossierAttributesService: DossierAttributesControllerService
|
private readonly _dossierAttributesService: DossierAttributesControllerService,
|
||||||
|
readonly permissionsService: PermissionsService
|
||||||
) {
|
) {
|
||||||
super(_injector);
|
super(_injector);
|
||||||
this._searchService.setSearchKey('label');
|
this._searchService.setSearchKey('label');
|
||||||
|
|||||||
@ -23,17 +23,12 @@
|
|||||||
<redaction-round-checkbox
|
<redaction-round-checkbox
|
||||||
(click)="toggleSelectAll()"
|
(click)="toggleSelectAll()"
|
||||||
[active]="areAllEntitiesSelected"
|
[active]="areAllEntitiesSelected"
|
||||||
[indeterminate]="
|
[indeterminate]="(areSomeEntitiesSelected$ | async) && !areAllEntitiesSelected"
|
||||||
(areSomeEntitiesSelected$ | async) && !areAllEntitiesSelected
|
|
||||||
"
|
|
||||||
></redaction-round-checkbox>
|
></redaction-round-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="all-caps-label">
|
<span class="all-caps-label">
|
||||||
{{
|
{{ 'dossier-templates-listing.table-header.title' | translate: { length: (displayedEntities$ | async).length } }}
|
||||||
'dossier-templates-listing.table-header.title'
|
|
||||||
| translate: { length: (displayedEntities$ | async).length }
|
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<ng-container *ngIf="areSomeEntitiesSelected$ | async">
|
<ng-container *ngIf="areSomeEntitiesSelected$ | async">
|
||||||
@ -55,10 +50,7 @@
|
|||||||
|
|
||||||
<redaction-icon-button
|
<redaction-icon-button
|
||||||
(action)="openAddDossierTemplateDialog()"
|
(action)="openAddDossierTemplateDialog()"
|
||||||
*ngIf="
|
*ngIf="permissionsService.isAdmin() && userPreferenceService.areDevFeaturesEnabled"
|
||||||
permissionsService.isAdmin() &&
|
|
||||||
userPreferenceService.areDevFeaturesEnabled
|
|
||||||
"
|
|
||||||
icon="red:plus"
|
icon="red:plus"
|
||||||
text="dossier-templates-listing.add-new"
|
text="dossier-templates-listing.add-new"
|
||||||
type="primary"
|
type="primary"
|
||||||
@ -66,11 +58,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div [class.no-data]="noData" class="table-header" redactionSyncWidth="table-item">
|
||||||
[class.no-data]="(allEntities$ | async)?.length === 0"
|
|
||||||
class="table-header"
|
|
||||||
redactionSyncWidth="table-item"
|
|
||||||
>
|
|
||||||
<div class="select-oval-placeholder"></div>
|
<div class="select-oval-placeholder"></div>
|
||||||
|
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name
|
||||||
@ -101,37 +89,20 @@
|
|||||||
<div class="scrollbar-placeholder"></div>
|
<div class="scrollbar-placeholder"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state *ngIf="noData" icon="red:template" screen="dossier-templates-listing"></redaction-empty-state>
|
||||||
*ngIf="(allEntities$ | async)?.length === 0"
|
|
||||||
icon="red:template"
|
|
||||||
screen="dossier-templates-listing"
|
|
||||||
></redaction-empty-state>
|
|
||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state *ngIf="noMatch" screen="dossier-templates-listing" type="no-match"></redaction-empty-state>
|
||||||
*ngIf="
|
|
||||||
(allEntities$ | async)?.length && (displayedEntities$ | async).length === 0
|
|
||||||
"
|
|
||||||
screen="dossier-templates-listing"
|
|
||||||
type="no-match"
|
|
||||||
></redaction-empty-state>
|
|
||||||
|
|
||||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||||
<div
|
<div
|
||||||
*cdkVirtualFor="
|
*cdkVirtualFor="
|
||||||
let dossierTemplate of displayedEntities$
|
let dossierTemplate of displayedEntities$ | async | sortBy: sortingOption.order:sortingOption.column
|
||||||
| async
|
|
||||||
| sortBy: sortingOption.order:sortingOption.column
|
|
||||||
"
|
"
|
||||||
[routerLink]="[dossierTemplate.dossierTemplateId, 'dictionaries']"
|
[routerLink]="[dossierTemplate.dossierTemplateId, 'dictionaries']"
|
||||||
class="table-item pointer"
|
class="table-item pointer"
|
||||||
>
|
>
|
||||||
<div
|
<div (click)="toggleEntitySelected($event, dossierTemplate)" class="selection-column">
|
||||||
(click)="toggleEntitySelected($event, dossierTemplate)"
|
<redaction-round-checkbox [active]="isSelected(dossierTemplate)"></redaction-round-checkbox>
|
||||||
class="selection-column"
|
|
||||||
>
|
|
||||||
<redaction-round-checkbox
|
|
||||||
[active]="isSelected(dossierTemplate)"
|
|
||||||
></redaction-round-checkbox>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -142,19 +113,14 @@
|
|||||||
<div>
|
<div>
|
||||||
<mat-icon svgIcon="red:dictionary"></mat-icon>
|
<mat-icon svgIcon="red:dictionary"></mat-icon>
|
||||||
{{
|
{{
|
||||||
'dossier-templates-listing.dictionaries'
|
'dossier-templates-listing.dictionaries' | translate: { length: dossierTemplate.dictionariesCount }
|
||||||
| translate
|
|
||||||
: { length: dossierTemplate.dictionariesCount }
|
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="user-column">
|
<div class="user-column">
|
||||||
<redaction-initials-avatar
|
<redaction-initials-avatar [userId]="dossierTemplate.createdBy" [withName]="true"></redaction-initials-avatar>
|
||||||
[userId]="dossierTemplate.createdBy"
|
|
||||||
[withName]="true"
|
|
||||||
></redaction-initials-avatar>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="small-label">
|
<div class="small-label">
|
||||||
{{ dossierTemplate.dateAdded | date: 'd MMM. yyyy' }}
|
{{ dossierTemplate.dateAdded | date: 'd MMM. yyyy' }}
|
||||||
|
|||||||
@ -25,22 +25,17 @@
|
|||||||
<redaction-round-checkbox
|
<redaction-round-checkbox
|
||||||
(click)="toggleSelectAll()"
|
(click)="toggleSelectAll()"
|
||||||
[active]="areAllEntitiesSelected"
|
[active]="areAllEntitiesSelected"
|
||||||
[indeterminate]="
|
[indeterminate]="(areSomeEntitiesSelected$ | async) && !areAllEntitiesSelected"
|
||||||
(areSomeEntitiesSelected$ | async) && !areAllEntitiesSelected
|
|
||||||
"
|
|
||||||
></redaction-round-checkbox>
|
></redaction-round-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="all-caps-label">
|
<span class="all-caps-label">
|
||||||
{{
|
{{ 'file-attributes-listing.table-header.title' | translate: { length: (displayedEntities$ | async)?.length } }}
|
||||||
'file-attributes-listing.table-header.title'
|
|
||||||
| translate: { length: (displayedEntities$ | async)?.length }
|
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(click)="openConfirmDeleteAttributeDialog($event)"
|
(click)="openConfirmDeleteAttributeDialog($event)"
|
||||||
*ngIf="areSomeEntitiesSelected$ | async"
|
*ngIf="permissionsService.isAdmin() && areSomeEntitiesSelected$ | async"
|
||||||
icon="red:trash"
|
icon="red:trash"
|
||||||
tooltip="file-attributes-listing.bulk-actions.delete"
|
tooltip="file-attributes-listing.bulk-actions.delete"
|
||||||
type="dark-bg"
|
type="dark-bg"
|
||||||
@ -57,6 +52,7 @@
|
|||||||
|
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(action)="fileInput.click()"
|
(action)="fileInput.click()"
|
||||||
|
*ngIf="permissionsService.isAdmin()"
|
||||||
icon="red:upload"
|
icon="red:upload"
|
||||||
tooltip="file-attributes-listing.upload-csv"
|
tooltip="file-attributes-listing.upload-csv"
|
||||||
tooltipPosition="above"
|
tooltipPosition="above"
|
||||||
@ -65,6 +61,7 @@
|
|||||||
|
|
||||||
<redaction-icon-button
|
<redaction-icon-button
|
||||||
(action)="openAddEditAttributeDialog($event)"
|
(action)="openAddEditAttributeDialog($event)"
|
||||||
|
*ngIf="permissionsService.isAdmin()"
|
||||||
icon="red:plus"
|
icon="red:plus"
|
||||||
text="file-attributes-listing.add-new"
|
text="file-attributes-listing.add-new"
|
||||||
type="primary"
|
type="primary"
|
||||||
@ -72,11 +69,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div [class.no-data]="noData" class="table-header" redactionSyncWidth="table-item">
|
||||||
[class.no-data]="(allEntities$ | async)?.length === 0"
|
|
||||||
class="table-header"
|
|
||||||
redactionSyncWidth="table-item"
|
|
||||||
>
|
|
||||||
<div class="select-oval-placeholder"></div>
|
<div class="select-oval-placeholder"></div>
|
||||||
|
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name
|
||||||
@ -118,26 +111,14 @@
|
|||||||
<div class="scrollbar-placeholder"></div>
|
<div class="scrollbar-placeholder"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state *ngIf="noData" icon="red:attribute" screen="file-attributes-listing"></redaction-empty-state>
|
||||||
*ngIf="(allEntities$ | async)?.length === 0"
|
|
||||||
icon="red:attribute"
|
|
||||||
screen="file-attributes-listing"
|
|
||||||
></redaction-empty-state>
|
|
||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state *ngIf="noMatch" screen="file-attributes-listing" type="no-match"></redaction-empty-state>
|
||||||
*ngIf="(allEntities$ | async)?.length && (displayedEntities$ | async)?.length === 0"
|
|
||||||
screen="file-attributes-listing"
|
|
||||||
type="no-match"
|
|
||||||
></redaction-empty-state>
|
|
||||||
|
|
||||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||||
<!-- Table lines -->
|
<!-- Table lines -->
|
||||||
<div
|
<div
|
||||||
*cdkVirtualFor="
|
*cdkVirtualFor="let attribute of displayedEntities$ | async | sortBy: sortingOption.order:sortingOption.column"
|
||||||
let attribute of displayedEntities$
|
|
||||||
| async
|
|
||||||
| sortBy: sortingOption.order:sortingOption.column
|
|
||||||
"
|
|
||||||
class="table-item"
|
class="table-item"
|
||||||
>
|
>
|
||||||
<div (click)="toggleEntitySelected($event, attribute)" class="selection-column">
|
<div (click)="toggleEntitySelected($event, attribute)" class="selection-column">
|
||||||
@ -165,7 +146,7 @@
|
|||||||
<redaction-round-checkbox *ngIf="attribute.primaryAttribute" [active]="true" [size]="18"></redaction-round-checkbox>
|
<redaction-round-checkbox *ngIf="attribute.primaryAttribute" [active]="true" [size]="18"></redaction-round-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<div class="actions-container">
|
<div class="actions-container">
|
||||||
<div class="action-buttons">
|
<div *ngIf="permissionsService.isAdmin()" class="action-buttons">
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(action)="openAddEditAttributeDialog($event, attribute)"
|
(action)="openAddEditAttributeDialog($event, attribute)"
|
||||||
icon="red:edit"
|
icon="red:edit"
|
||||||
|
|||||||
@ -46,6 +46,7 @@
|
|||||||
<div class="heading" translate="reports-screen.report-documents"></div>
|
<div class="heading" translate="reports-screen.report-documents"></div>
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(action)="fileInput.click()"
|
(action)="fileInput.click()"
|
||||||
|
*ngIf="permissionsService.isAdmin()"
|
||||||
icon="red:upload"
|
icon="red:upload"
|
||||||
tooltip="reports-screen.upload-document"
|
tooltip="reports-screen.upload-document"
|
||||||
></redaction-circle-button>
|
></redaction-circle-button>
|
||||||
@ -53,7 +54,7 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
(click)="fileInput.click()"
|
(click)="fileInput.click()"
|
||||||
*ngIf="!availableTemplates?.length"
|
*ngIf="permissionsService.isAdmin() && !availableTemplates?.length"
|
||||||
class="template upload-button"
|
class="template upload-button"
|
||||||
translate="reports-screen.upload-document"
|
translate="reports-screen.upload-document"
|
||||||
></div>
|
></div>
|
||||||
@ -70,6 +71,7 @@
|
|||||||
></redaction-circle-button>
|
></redaction-circle-button>
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(action)="deleteTemplate(template)"
|
(action)="deleteTemplate(template)"
|
||||||
|
*ngIf="permissionsService.isAdmin()"
|
||||||
[iconSize]="12"
|
[iconSize]="12"
|
||||||
[size]="18"
|
[size]="18"
|
||||||
icon="red:trash"
|
icon="red:trash"
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
min-height: 34px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.template {
|
.template {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { ReportTemplate, ReportTemplateControllerService } from '@redaction/red-
|
|||||||
import { download } from '../../../../utils/file-download-utils';
|
import { download } from '../../../../utils/file-download-utils';
|
||||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||||
import { LoadingService } from '../../../../services/loading.service';
|
import { LoadingService } from '../../../../services/loading.service';
|
||||||
|
import { PermissionsService } from '../../../../services/permissions.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-reports-screen',
|
selector: 'redaction-reports-screen',
|
||||||
@ -22,7 +23,8 @@ export class ReportsScreenComponent implements OnInit {
|
|||||||
private readonly _appStateService: AppStateService,
|
private readonly _appStateService: AppStateService,
|
||||||
private readonly _reportTemplateService: ReportTemplateControllerService,
|
private readonly _reportTemplateService: ReportTemplateControllerService,
|
||||||
private readonly _dialogService: AdminDialogService,
|
private readonly _dialogService: AdminDialogService,
|
||||||
private readonly _loadingService: LoadingService
|
private readonly _loadingService: LoadingService,
|
||||||
|
readonly permissionsService: PermissionsService
|
||||||
) {
|
) {
|
||||||
this._appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
|
this._appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
<section>
|
<section>
|
||||||
<div class="overlay-shadow"></div>
|
<div class="overlay-shadow"></div>
|
||||||
|
|
||||||
<redaction-page-header
|
<redaction-page-header [pageLabel]="'trash.label' | translate" [showCloseButton]="true"></redaction-page-header>
|
||||||
[pageLabel]="'trash.label' | translate"
|
|
||||||
[showCloseButton]="true"
|
|
||||||
></redaction-page-header>
|
|
||||||
|
|
||||||
<div class="red-content-inner">
|
<div class="red-content-inner">
|
||||||
<div class="content-container">
|
<div class="content-container">
|
||||||
@ -13,105 +10,80 @@
|
|||||||
<redaction-round-checkbox
|
<redaction-round-checkbox
|
||||||
(click)="toggleSelectAll()"
|
(click)="toggleSelectAll()"
|
||||||
[active]="areAllEntitiesSelected"
|
[active]="areAllEntitiesSelected"
|
||||||
[indeterminate]="
|
[indeterminate]="(areSomeEntitiesSelected$ | async) && !areAllEntitiesSelected"
|
||||||
(areSomeEntitiesSelected$ | async) && !areAllEntitiesSelected
|
|
||||||
"
|
|
||||||
></redaction-round-checkbox>
|
></redaction-round-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="all-caps-label">
|
<span class="all-caps-label">
|
||||||
{{
|
{{ 'trash.table-header.title' | translate: { length: (displayedEntities$ | async)?.length } }}
|
||||||
'trash.table-header.title'
|
|
||||||
| translate: { length: (displayedEntities$ | async)?.length }
|
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(action)="bulkRestore()"
|
(action)="bulkRestore()"
|
||||||
*ngIf="areSomeEntitiesSelected$ | async"
|
*ngIf="areSomeEntitiesSelected$ | async"
|
||||||
icon="red:put-back"
|
|
||||||
[tooltip]="'trash.bulk.restore' | translate"
|
[tooltip]="'trash.bulk.restore' | translate"
|
||||||
|
icon="red:put-back"
|
||||||
type="dark-bg"
|
type="dark-bg"
|
||||||
></redaction-circle-button>
|
></redaction-circle-button>
|
||||||
|
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(action)="bulkDelete()"
|
(action)="bulkDelete()"
|
||||||
*ngIf="areSomeEntitiesSelected$ | async"
|
*ngIf="areSomeEntitiesSelected$ | async"
|
||||||
icon="red:trash"
|
|
||||||
[tooltip]="'trash.bulk.delete' | translate"
|
[tooltip]="'trash.bulk.delete' | translate"
|
||||||
|
icon="red:trash"
|
||||||
type="dark-bg"
|
type="dark-bg"
|
||||||
></redaction-circle-button>
|
></redaction-circle-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div [class.no-data]="noData" class="table-header" redactionSyncWidth="table-item">
|
||||||
[class.no-data]="(allEntities$ | async)?.length === 0"
|
|
||||||
class="table-header"
|
|
||||||
redactionSyncWidth="table-item"
|
|
||||||
>
|
|
||||||
<div class="select-oval-placeholder"></div>
|
<div class="select-oval-placeholder"></div>
|
||||||
|
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name
|
||||||
(toggleSort)="toggleSort($event)"
|
(toggleSort)="toggleSort($event)"
|
||||||
[activeSortingOption]="sortingOption"
|
[activeSortingOption]="sortingOption"
|
||||||
|
[label]="'trash.table-col-names.name' | translate"
|
||||||
[withSort]="true"
|
[withSort]="true"
|
||||||
column="name"
|
column="name"
|
||||||
[label]="'trash.table-col-names.name' | translate"
|
|
||||||
></redaction-table-col-name>
|
></redaction-table-col-name>
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name
|
||||||
class="user-column"
|
|
||||||
[label]="'trash.table-col-names.owner' | translate"
|
[label]="'trash.table-col-names.owner' | translate"
|
||||||
|
class="user-column"
|
||||||
></redaction-table-col-name>
|
></redaction-table-col-name>
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name
|
||||||
(toggleSort)="toggleSort($event)"
|
(toggleSort)="toggleSort($event)"
|
||||||
[activeSortingOption]="sortingOption"
|
[activeSortingOption]="sortingOption"
|
||||||
|
[label]="'trash.table-col-names.deleted-on' | translate"
|
||||||
[withSort]="true"
|
[withSort]="true"
|
||||||
column="dateDeleted"
|
column="dateDeleted"
|
||||||
[label]="'trash.table-col-names.deleted-on' | translate"
|
|
||||||
></redaction-table-col-name>
|
></redaction-table-col-name>
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name
|
||||||
(toggleSort)="toggleSort($event)"
|
(toggleSort)="toggleSort($event)"
|
||||||
[activeSortingOption]="sortingOption"
|
[activeSortingOption]="sortingOption"
|
||||||
|
[label]="'trash.table-col-names.time-to-restore' | translate"
|
||||||
[withSort]="true"
|
[withSort]="true"
|
||||||
column="timeToRestore"
|
column="timeToRestore"
|
||||||
[label]="'trash.table-col-names.time-to-restore' | translate"
|
|
||||||
></redaction-table-col-name>
|
></redaction-table-col-name>
|
||||||
<div class="scrollbar-placeholder"></div>
|
<div class="scrollbar-placeholder"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state *ngIf="noData" icon="red:template" screen="trash"></redaction-empty-state>
|
||||||
*ngIf="(allEntities$ | async)?.length === 0"
|
|
||||||
icon="red:template"
|
|
||||||
screen="trash"
|
|
||||||
></redaction-empty-state>
|
|
||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state *ngIf="noMatch" screen="trash" type="no-match"></redaction-empty-state>
|
||||||
*ngIf="(allEntities$ | async)?.length && (displayedEntities$ | async)?.length === 0"
|
|
||||||
screen="trash"
|
|
||||||
type="no-match"
|
|
||||||
></redaction-empty-state>
|
|
||||||
|
|
||||||
<cdk-virtual-scroll-viewport [itemSize]="itemSize" redactionHasScrollbar>
|
<cdk-virtual-scroll-viewport [itemSize]="itemSize" redactionHasScrollbar>
|
||||||
<div
|
<div
|
||||||
*cdkVirtualFor="
|
*cdkVirtualFor="
|
||||||
let entity of displayedEntities$
|
let entity of displayedEntities$ | async | sortBy: sortingOption.order:sortingOption.column;
|
||||||
| async
|
|
||||||
| sortBy: sortingOption.order:sortingOption.column;
|
|
||||||
trackBy: trackById
|
trackBy: trackById
|
||||||
"
|
"
|
||||||
class="table-item"
|
class="table-item"
|
||||||
>
|
>
|
||||||
<div (click)="toggleEntitySelected($event, entity)" class="selection-column">
|
<div (click)="toggleEntitySelected($event, entity)" class="selection-column">
|
||||||
<redaction-round-checkbox
|
<redaction-round-checkbox [active]="isSelected(entity)"></redaction-round-checkbox>
|
||||||
[active]="isSelected(entity)"
|
|
||||||
></redaction-round-checkbox>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="filename">
|
<div class="filename">
|
||||||
<div
|
<div [matTooltip]="entity.dossierName" class="table-item-title heading" matTooltipPosition="above">
|
||||||
class="table-item-title heading"
|
|
||||||
[matTooltip]="entity.dossierName"
|
|
||||||
matTooltipPosition="above"
|
|
||||||
>
|
|
||||||
{{ entity.dossierName }}
|
{{ entity.dossierName }}
|
||||||
</div>
|
</div>
|
||||||
<div class="small-label stats-subtitle">
|
<div class="small-label stats-subtitle">
|
||||||
@ -131,10 +103,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="user-column">
|
<div class="user-column">
|
||||||
<redaction-initials-avatar
|
<redaction-initials-avatar [userId]="entity.ownerId" [withName]="true"></redaction-initials-avatar>
|
||||||
[userId]="entity.ownerId"
|
|
||||||
[withName]="true"
|
|
||||||
></redaction-initials-avatar>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="small-label">
|
<div class="small-label">
|
||||||
@ -148,15 +117,15 @@
|
|||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(action)="bulkRestore([entity.dossierId])"
|
(action)="bulkRestore([entity.dossierId])"
|
||||||
icon="red:put-back"
|
|
||||||
[tooltip]="'trash.action.restore' | translate"
|
[tooltip]="'trash.action.restore' | translate"
|
||||||
|
icon="red:put-back"
|
||||||
type="dark-bg"
|
type="dark-bg"
|
||||||
></redaction-circle-button>
|
></redaction-circle-button>
|
||||||
|
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(action)="bulkDelete([entity.dossierId])"
|
(action)="bulkDelete([entity.dossierId])"
|
||||||
icon="red:trash"
|
|
||||||
[tooltip]="'trash.action.delete' | translate"
|
[tooltip]="'trash.action.delete' | translate"
|
||||||
|
icon="red:trash"
|
||||||
type="dark-bg"
|
type="dark-bg"
|
||||||
></redaction-circle-button>
|
></redaction-circle-button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ChangeDetectionStrategy, Component, Injector, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, Injector, OnInit } from '@angular/core';
|
||||||
import { AppStateService } from '@state/app-state.service';
|
import { AppStateService } from '@state/app-state.service';
|
||||||
import { PermissionsService } from '@services/permissions.service';
|
import { PermissionsService } from '@services/permissions.service';
|
||||||
import { Dossier, DossierTemplateModel, StatusControllerService } from '@redaction/red-ui-http';
|
import { Dossier, StatusControllerService } from '@redaction/red-ui-http';
|
||||||
import { LoadingService } from '../../../../services/loading.service';
|
import { LoadingService } from '../../../../services/loading.service';
|
||||||
import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service';
|
import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
@ -11,7 +11,6 @@ import { ScreenStateService } from '../../../shared/services/screen-state.servic
|
|||||||
import { ScreenNames, SortingService } from '../../../../services/sorting.service';
|
import { ScreenNames, SortingService } from '../../../../services/sorting.service';
|
||||||
import { BaseListingComponent } from '../../../shared/base/base-listing.component';
|
import { BaseListingComponent } from '../../../shared/base/base-listing.component';
|
||||||
import { DossiersService } from '../../../dossier/services/dossiers.service';
|
import { DossiersService } from '../../../dossier/services/dossiers.service';
|
||||||
import { tap } from 'rxjs/operators';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './trash-screen.component.html',
|
templateUrl: './trash-screen.component.html',
|
||||||
@ -21,9 +20,7 @@ import { tap } from 'rxjs/operators';
|
|||||||
})
|
})
|
||||||
export class TrashScreenComponent extends BaseListingComponent<Dossier> implements OnInit {
|
export class TrashScreenComponent extends BaseListingComponent<Dossier> implements OnInit {
|
||||||
readonly itemSize = 85;
|
readonly itemSize = 85;
|
||||||
private readonly _deleteRetentionHours = this._appConfigService.getConfig(
|
private readonly _deleteRetentionHours = this._appConfigService.getConfig(AppConfigKey.DELETE_RETENTION_HOURS);
|
||||||
AppConfigKey.DELETE_RETENTION_HOURS
|
|
||||||
);
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _appStateService: AppStateService,
|
private readonly _appStateService: AppStateService,
|
||||||
|
|||||||
@ -10,10 +10,7 @@
|
|||||||
<div class="content-container">
|
<div class="content-container">
|
||||||
<div class="header-item">
|
<div class="header-item">
|
||||||
<span class="all-caps-label">
|
<span class="all-caps-label">
|
||||||
{{
|
{{ 'dossier-listing.table-header.title' | translate: { length: (displayedEntities$ | async)?.length || 0 } }}
|
||||||
'dossier-listing.table-header.title'
|
|
||||||
| translate: { length: (displayedEntities$ | async)?.length || 0 }
|
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<redaction-quick-filters></redaction-quick-filters>
|
<redaction-quick-filters></redaction-quick-filters>
|
||||||
@ -28,53 +25,33 @@
|
|||||||
label="dossier-listing.table-col-names.name"
|
label="dossier-listing.table-col-names.name"
|
||||||
></redaction-table-col-name>
|
></redaction-table-col-name>
|
||||||
|
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name label="dossier-listing.table-col-names.needs-work"></redaction-table-col-name>
|
||||||
label="dossier-listing.table-col-names.needs-work"
|
|
||||||
></redaction-table-col-name>
|
|
||||||
|
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name class="user-column" label="dossier-listing.table-col-names.owner"></redaction-table-col-name>
|
||||||
class="user-column"
|
|
||||||
label="dossier-listing.table-col-names.owner"
|
|
||||||
></redaction-table-col-name>
|
|
||||||
|
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name class="flex-end" label="dossier-listing.table-col-names.status"></redaction-table-col-name>
|
||||||
class="flex-end"
|
|
||||||
label="dossier-listing.table-col-names.status"
|
|
||||||
></redaction-table-col-name>
|
|
||||||
<div class="scrollbar-placeholder"></div>
|
<div class="scrollbar-placeholder"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state
|
||||||
(action)="openAddDossierDialog()"
|
(action)="openAddDossierDialog()"
|
||||||
*ngIf="(allEntities$ | async)?.length === 0"
|
*ngIf="noData"
|
||||||
[showButton]="permissionsService.isManager()"
|
[showButton]="permissionsService.isManager()"
|
||||||
icon="red:folder"
|
icon="red:folder"
|
||||||
screen="dossier-listing"
|
screen="dossier-listing"
|
||||||
></redaction-empty-state>
|
></redaction-empty-state>
|
||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state *ngIf="noMatch" screen="dossier-listing" type="no-match"></redaction-empty-state>
|
||||||
*ngIf="(allEntities$ | async)?.length && (displayedEntities$ | async)?.length === 0"
|
|
||||||
screen="dossier-listing"
|
|
||||||
type="no-match"
|
|
||||||
></redaction-empty-state>
|
|
||||||
|
|
||||||
<cdk-virtual-scroll-viewport [itemSize]="itemSize" redactionHasScrollbar>
|
<cdk-virtual-scroll-viewport [itemSize]="itemSize" redactionHasScrollbar>
|
||||||
<div
|
<div
|
||||||
*cdkVirtualFor="
|
*cdkVirtualFor="let dw of displayedEntities$ | async | sortBy: sortingOption.order:sortingOption.column"
|
||||||
let dw of displayedEntities$
|
|
||||||
| async
|
|
||||||
| sortBy: sortingOption.order:sortingOption.column
|
|
||||||
"
|
|
||||||
[class.pointer]="!!dw"
|
[class.pointer]="!!dw"
|
||||||
[routerLink]="[!!dw ? '/main/dossiers/' + dw.dossier.dossierId : []]"
|
[routerLink]="[!!dw ? '/main/dossiers/' + dw.dossier.dossierId : []]"
|
||||||
class="table-item"
|
class="table-item"
|
||||||
>
|
>
|
||||||
<div class="filename">
|
<div class="filename">
|
||||||
<div
|
<div [matTooltip]="dw.dossierName" class="table-item-title heading" matTooltipPosition="above">
|
||||||
[matTooltip]="dw.dossierName"
|
|
||||||
class="table-item-title heading"
|
|
||||||
matTooltipPosition="above"
|
|
||||||
>
|
|
||||||
{{ dw.dossierName }}
|
{{ dw.dossierName }}
|
||||||
</div>
|
</div>
|
||||||
<div class="small-label stats-subtitle">
|
<div class="small-label stats-subtitle">
|
||||||
@ -107,15 +84,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<redaction-needs-work-badge
|
<redaction-needs-work-badge [needsWorkInput]="dw"></redaction-needs-work-badge>
|
||||||
[needsWorkInput]="dw"
|
|
||||||
></redaction-needs-work-badge>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="user-column">
|
<div class="user-column">
|
||||||
<redaction-initials-avatar
|
<redaction-initials-avatar [userId]="dw.dossier.ownerId" [withName]="true"></redaction-initials-avatar>
|
||||||
[userId]="dw.dossier.ownerId"
|
|
||||||
[withName]="true"
|
|
||||||
></redaction-initials-avatar>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="status-container">
|
<div class="status-container">
|
||||||
<redaction-dossier-listing-actions
|
<redaction-dossier-listing-actions
|
||||||
@ -127,10 +99,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</cdk-virtual-scroll-viewport>
|
</cdk-virtual-scroll-viewport>
|
||||||
|
|
||||||
<redaction-scroll-button
|
<redaction-scroll-button [itemSize]="itemSize" [scrollViewport]="scrollViewport"></redaction-scroll-button>
|
||||||
[itemSize]="itemSize"
|
|
||||||
[scrollViewport]="scrollViewport"
|
|
||||||
></redaction-scroll-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="right-container" redactionHasScrollbar>
|
<div class="right-container" redactionHasScrollbar>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { ChangeDetectionStrategy, Component, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
import { Component, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||||
import { Dossier, DossierTemplateModel } from '@redaction/red-ui-http';
|
import { Dossier, DossierTemplateModel } from '@redaction/red-ui-http';
|
||||||
import { AppStateService } from '@state/app-state.service';
|
import { AppStateService } from '@state/app-state.service';
|
||||||
import { UserService } from '@services/user.service';
|
import { UserService } from '@services/user.service';
|
||||||
@ -76,6 +76,18 @@ export class DossierListingScreenComponent extends BaseListingComponent<DossierW
|
|||||||
this._loadEntitiesFromState();
|
this._loadEntitiesFromState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get _user() {
|
||||||
|
return this._userService.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get _activeDossiersCount(): number {
|
||||||
|
return this._screenStateService.entities.filter(p => p.dossier.status === Dossier.StatusEnum.ACTIVE).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get _inactiveDossiersCount(): number {
|
||||||
|
return this._screenStateService.entities.length - this._activeDossiersCount;
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.calculateData();
|
this.calculateData();
|
||||||
|
|
||||||
@ -135,22 +147,6 @@ export class DossierListingScreenComponent extends BaseListingComponent<DossierW
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _loadEntitiesFromState() {
|
|
||||||
this._screenStateService.setEntities(this._appStateService.allDossiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
private get _user() {
|
|
||||||
return this._userService.user;
|
|
||||||
}
|
|
||||||
|
|
||||||
private get _activeDossiersCount(): number {
|
|
||||||
return this._screenStateService.entities.filter(p => p.dossier.status === Dossier.StatusEnum.ACTIVE).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
private get _inactiveDossiersCount(): number {
|
|
||||||
return this._screenStateService.entities.length - this._activeDossiersCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateData() {
|
calculateData() {
|
||||||
this._computeAllFilters();
|
this._computeAllFilters();
|
||||||
|
|
||||||
@ -173,6 +169,10 @@ export class DossierListingScreenComponent extends BaseListingComponent<DossierW
|
|||||||
this.documentsChartData = this._translateChartService.translateStatus(this.documentsChartData);
|
this.documentsChartData = this._translateChartService.translateStatus(this.documentsChartData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _loadEntitiesFromState() {
|
||||||
|
this._screenStateService.setEntities(this._appStateService.allDossiers);
|
||||||
|
}
|
||||||
|
|
||||||
private _computeAllFilters() {
|
private _computeAllFilters() {
|
||||||
const allDistinctFileStatus = new Set<string>();
|
const allDistinctFileStatus = new Set<string>();
|
||||||
const allDistinctPeople = new Set<string>();
|
const allDistinctPeople = new Set<string>();
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
<section *ngIf="!!activeDossier">
|
<section *ngIf="!!activeDossier">
|
||||||
<redaction-page-header
|
<redaction-page-header
|
||||||
[actionConfigs]="actionConfigs"
|
[actionConfigs]="actionConfigs"
|
||||||
[showCloseButton]="true"
|
|
||||||
[searchPlaceholder]="'dossier-overview.search' | translate"
|
[searchPlaceholder]="'dossier-overview.search' | translate"
|
||||||
|
[showCloseButton]="true"
|
||||||
>
|
>
|
||||||
<redaction-file-download-btn
|
<redaction-file-download-btn
|
||||||
[disabled]="areSomeEntitiesSelected$ | async"
|
[disabled]="areSomeEntitiesSelected$ | async"
|
||||||
@ -24,9 +24,9 @@
|
|||||||
|
|
||||||
<redaction-circle-button
|
<redaction-circle-button
|
||||||
(action)="fileInput.click()"
|
(action)="fileInput.click()"
|
||||||
|
[tooltip]="'dossier-overview.header-actions.upload-document' | translate"
|
||||||
class="ml-14"
|
class="ml-14"
|
||||||
icon="red:upload"
|
icon="red:upload"
|
||||||
[tooltip]="'dossier-overview.header-actions.upload-document' | translate"
|
|
||||||
tooltipPosition="below"
|
tooltipPosition="below"
|
||||||
type="primary"
|
type="primary"
|
||||||
></redaction-circle-button>
|
></redaction-circle-button>
|
||||||
@ -41,17 +41,12 @@
|
|||||||
<redaction-round-checkbox
|
<redaction-round-checkbox
|
||||||
(click)="toggleSelectAll()"
|
(click)="toggleSelectAll()"
|
||||||
[active]="areAllEntitiesSelected"
|
[active]="areAllEntitiesSelected"
|
||||||
[indeterminate]="
|
[indeterminate]="(areSomeEntitiesSelected$ | async) && !areAllEntitiesSelected"
|
||||||
(areSomeEntitiesSelected$ | async) && !areAllEntitiesSelected
|
|
||||||
"
|
|
||||||
></redaction-round-checkbox>
|
></redaction-round-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="all-caps-label">
|
<span class="all-caps-label">
|
||||||
{{
|
{{ 'dossier-overview.table-header.title' | translate: { length: (displayedEntities$ | async)?.length || 0 } }}
|
||||||
'dossier-overview.table-header.title'
|
|
||||||
| translate: { length: (displayedEntities$ | async)?.length || 0 }
|
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<redaction-dossier-overview-bulk-actions
|
<redaction-dossier-overview-bulk-actions
|
||||||
@ -62,11 +57,7 @@
|
|||||||
<redaction-quick-filters></redaction-quick-filters>
|
<redaction-quick-filters></redaction-quick-filters>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div [class.no-data]="noData" class="table-header" redactionSyncWidth="table-item">
|
||||||
[class.no-data]="(allEntities$ | async).length === 0"
|
|
||||||
class="table-header"
|
|
||||||
redactionSyncWidth="table-item"
|
|
||||||
>
|
|
||||||
<!-- Table column names-->
|
<!-- Table column names-->
|
||||||
<div class="select-oval-placeholder"></div>
|
<div class="select-oval-placeholder"></div>
|
||||||
|
|
||||||
@ -86,9 +77,7 @@
|
|||||||
label="dossier-overview.table-col-names.added-on"
|
label="dossier-overview.table-col-names.added-on"
|
||||||
></redaction-table-col-name>
|
></redaction-table-col-name>
|
||||||
|
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name label="dossier-overview.table-col-names.needs-work"></redaction-table-col-name>
|
||||||
label="dossier-overview.table-col-names.needs-work"
|
|
||||||
></redaction-table-col-name>
|
|
||||||
|
|
||||||
<redaction-table-col-name
|
<redaction-table-col-name
|
||||||
(toggleSort)="toggleSort($event)"
|
(toggleSort)="toggleSort($event)"
|
||||||
@ -120,24 +109,18 @@
|
|||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state
|
||||||
(action)="fileInput.click()"
|
(action)="fileInput.click()"
|
||||||
*ngIf="(allEntities$ | async)?.length === 0"
|
*ngIf="noData"
|
||||||
buttonIcon="red:upload"
|
buttonIcon="red:upload"
|
||||||
icon="red:document"
|
icon="red:document"
|
||||||
screen="dossier-overview"
|
screen="dossier-overview"
|
||||||
></redaction-empty-state>
|
></redaction-empty-state>
|
||||||
|
|
||||||
<redaction-empty-state
|
<redaction-empty-state *ngIf="noMatch" screen="dossier-overview" type="no-match"></redaction-empty-state>
|
||||||
*ngIf="(allEntities$ | async)?.length && (displayedEntities$ | async).length === 0"
|
|
||||||
screen="dossier-overview"
|
|
||||||
type="no-match"
|
|
||||||
></redaction-empty-state>
|
|
||||||
|
|
||||||
<cdk-virtual-scroll-viewport [itemSize]="itemSize" redactionHasScrollbar>
|
<cdk-virtual-scroll-viewport [itemSize]="itemSize" redactionHasScrollbar>
|
||||||
<div
|
<div
|
||||||
*cdkVirtualFor="
|
*cdkVirtualFor="
|
||||||
let fileStatus of displayedEntities$
|
let fileStatus of displayedEntities$ | async | sortBy: sortingOption.order:sortingOption.column;
|
||||||
| async
|
|
||||||
| sortBy: sortingOption.order:sortingOption.column;
|
|
||||||
trackBy: trackByFileId
|
trackBy: trackByFileId
|
||||||
"
|
"
|
||||||
[class.disabled]="fileStatus.isExcluded"
|
[class.disabled]="fileStatus.isExcluded"
|
||||||
@ -146,13 +129,8 @@
|
|||||||
[routerLink]="fileLink(fileStatus)"
|
[routerLink]="fileLink(fileStatus)"
|
||||||
class="table-item"
|
class="table-item"
|
||||||
>
|
>
|
||||||
<div
|
<div (click)="toggleEntitySelected($event, fileStatus)" class="selection-column">
|
||||||
(click)="toggleEntitySelected($event, fileStatus)"
|
<redaction-round-checkbox [active]="isSelected(fileStatus)"></redaction-round-checkbox>
|
||||||
class="selection-column"
|
|
||||||
>
|
|
||||||
<redaction-round-checkbox
|
|
||||||
[active]="isSelected(fileStatus)"
|
|
||||||
></redaction-round-checkbox>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -169,19 +147,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div *ngIf="fileStatus.primaryAttribute" class="small-label stats-subtitle">
|
<div *ngIf="fileStatus.primaryAttribute" class="small-label stats-subtitle">
|
||||||
<div class="primary-attribute text-overflow">
|
<div class="primary-attribute text-overflow">
|
||||||
<span
|
<span [matTooltip]="fileStatus.primaryAttribute" matTooltipPosition="above">
|
||||||
[matTooltip]="fileStatus.primaryAttribute"
|
|
||||||
matTooltipPosition="above"
|
|
||||||
>
|
|
||||||
{{ fileStatus.primaryAttribute }}
|
{{ fileStatus.primaryAttribute }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="fileStatus.ocrTime" class="small-label stats-subtitle">
|
<div *ngIf="fileStatus.ocrTime" class="small-label stats-subtitle">
|
||||||
<div
|
<div [matTooltipPosition]="'above'" [matTooltip]="'dossier-overview.ocr-performed' | translate">
|
||||||
[matTooltipPosition]="'above'"
|
|
||||||
[matTooltip]="'dossier-overview.ocr-performed' | translate"
|
|
||||||
>
|
|
||||||
<mat-icon svgIcon="red:ocr"></mat-icon>
|
<mat-icon svgIcon="red:ocr"></mat-icon>
|
||||||
{{ fileStatus.ocrTime | date: 'mediumDate' }}
|
{{ fileStatus.ocrTime | date: 'mediumDate' }}
|
||||||
</div>
|
</div>
|
||||||
@ -196,23 +168,14 @@
|
|||||||
|
|
||||||
<!-- always show A for error-->
|
<!-- always show A for error-->
|
||||||
<div *ngIf="fileStatus.isError">
|
<div *ngIf="fileStatus.isError">
|
||||||
<redaction-annotation-icon
|
<redaction-annotation-icon color="#dd4d50" label="A" type="square"></redaction-annotation-icon>
|
||||||
color="#dd4d50"
|
|
||||||
label="A"
|
|
||||||
type="square"
|
|
||||||
></redaction-annotation-icon>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="!fileStatus.isError">
|
<div *ngIf="!fileStatus.isError">
|
||||||
<redaction-needs-work-badge
|
<redaction-needs-work-badge [needsWorkInput]="fileStatus"></redaction-needs-work-badge>
|
||||||
[needsWorkInput]="fileStatus"
|
|
||||||
></redaction-needs-work-badge>
|
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="!fileStatus.isError" class="user-column">
|
<div *ngIf="!fileStatus.isError" class="user-column">
|
||||||
<redaction-initials-avatar
|
<redaction-initials-avatar [userId]="fileStatus.currentReviewer" [withName]="true"></redaction-initials-avatar>
|
||||||
[userId]="fileStatus.currentReviewer"
|
|
||||||
[withName]="true"
|
|
||||||
></redaction-initials-avatar>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="!fileStatus.isError">
|
<div *ngIf="!fileStatus.isError">
|
||||||
@ -259,10 +222,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</cdk-virtual-scroll-viewport>
|
</cdk-virtual-scroll-viewport>
|
||||||
|
|
||||||
<redaction-scroll-button
|
<redaction-scroll-button [itemSize]="itemSize" [scrollViewport]="scrollViewport"></redaction-scroll-button>
|
||||||
[itemSize]="itemSize"
|
|
||||||
[scrollViewport]="scrollViewport"
|
|
||||||
></redaction-scroll-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div [class.collapsed]="collapsedDetails" class="right-container" redactionHasScrollbar>
|
<div [class.collapsed]="collapsedDetails" class="right-container" redactionHasScrollbar>
|
||||||
@ -279,10 +239,4 @@
|
|||||||
<redaction-type-filter [filter]="filter"></redaction-type-filter>
|
<redaction-type-filter [filter]="filter"></redaction-type-filter>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<input
|
<input #fileInput (change)="uploadFiles($event.target['files'])" class="file-upload-input" multiple="true" type="file" />
|
||||||
#fileInput
|
|
||||||
(change)="uploadFiles($event.target['files'])"
|
|
||||||
class="file-upload-input"
|
|
||||||
multiple="true"
|
|
||||||
type="file"
|
|
||||||
/>
|
|
||||||
|
|||||||
@ -36,6 +36,10 @@ export abstract class BaseListingComponent<T> {
|
|||||||
return this._screenStateService.entities$;
|
return this._screenStateService.entities$;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get displayedEntities(): T[] {
|
||||||
|
return this._screenStateService.displayedEntities;
|
||||||
|
}
|
||||||
|
|
||||||
get allEntities(): T[] {
|
get allEntities(): T[] {
|
||||||
return this._screenStateService.entities;
|
return this._screenStateService.entities;
|
||||||
}
|
}
|
||||||
@ -52,14 +56,22 @@ export abstract class BaseListingComponent<T> {
|
|||||||
return this._sortingService.getSortingOption();
|
return this._sortingService.getSortingOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
getFilter$(slug: string): Observable<FilterModel[]> {
|
|
||||||
return this.filterService.getFilter$(slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
get searchForm() {
|
get searchForm() {
|
||||||
return this._searchService.searchForm;
|
return this._searchService.searchForm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get noMatch(): boolean {
|
||||||
|
return this.allEntities.length && this.displayedEntities?.length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get noData(): boolean {
|
||||||
|
return this.allEntities.length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFilter$(slug: string): Observable<FilterModel[]> {
|
||||||
|
return this.filterService.getFilter$(slug);
|
||||||
|
}
|
||||||
|
|
||||||
resetFilters() {
|
resetFilters() {
|
||||||
this.filterService.reset();
|
this.filterService.reset();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
import { Component, EventEmitter, Output } from '@angular/core';
|
||||||
import { FilterModel } from '../popup-filter/model/filter.model';
|
import { FilterModel } from '../popup-filter/model/filter.model';
|
||||||
import { FilterService } from '@shared/services/filter.service';
|
import { FilterService } from '@shared/services/filter.service';
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user