Pull request #148: Empty states
Merge in RED/ui from empty-states to master * commit 'e200d339eb155259f8fff5983be22d84c7479f27': Bulk actions on csv import file attributes dialog Empty state component & other fixes Fixed circle button Small UI fixes
This commit is contained in:
commit
b360d3c5ba
@ -1,18 +1,17 @@
|
||||
<div class='red-top-bar'>
|
||||
<div class='top-bar-row'>
|
||||
<div class='menu-placeholder' *ngIf='!permissionsService.isUser()'></div>
|
||||
<div class='menu visible-lt-lg' *ngIf='permissionsService.isUser()'>
|
||||
<button [matMenuTriggerFor]='menuNav' mat-flat-button>
|
||||
<mat-icon svgIcon='red:menu'></mat-icon>
|
||||
<div class="red-top-bar">
|
||||
<div class="top-bar-row">
|
||||
<div class="menu-placeholder" *ngIf="!permissionsService.isUser()"></div>
|
||||
<div class="menu visible-lt-lg" *ngIf="permissionsService.isUser()">
|
||||
<button [matMenuTriggerFor]="menuNav" mat-flat-button>
|
||||
<mat-icon svgIcon="red:menu"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuNav='matMenu'>
|
||||
<button mat-menu-item routerLink='/ui/projects' translate='top-bar.navigation-items.projects'></button>
|
||||
<button *ngIf='appStateService.activeProject'
|
||||
[routerLink]="'/ui/projects/' + appStateService.activeProjectId" mat-menu-item>
|
||||
<mat-menu #menuNav="matMenu">
|
||||
<button mat-menu-item routerLink="/ui/projects" translate="top-bar.navigation-items.projects"></button>
|
||||
<button *ngIf="appStateService.activeProject" [routerLink]="'/ui/projects/' + appStateService.activeProjectId" mat-menu-item>
|
||||
{{ appStateService.activeProject.project.projectName }}
|
||||
</button>
|
||||
<button
|
||||
*ngIf='appStateService.activeFile'
|
||||
*ngIf="appStateService.activeFile"
|
||||
[routerLink]="'/ui/projects/' + appStateService.activeProjectId + '/file/' + appStateService.activeFile.fileId"
|
||||
mat-menu-item
|
||||
>
|
||||
@ -20,97 +19,91 @@
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<div class='menu flex-2 visible-lg breadcrumbs-container' *ngIf='permissionsService.isUser()'>
|
||||
<div class="menu flex-2 visible-lg breadcrumbs-container" *ngIf="permissionsService.isUser()">
|
||||
<a
|
||||
class='breadcrumb'
|
||||
routerLink='/ui/projects'
|
||||
translate='top-bar.navigation-items.projects'
|
||||
routerLinkActive='active'
|
||||
*ngIf='projectsView'
|
||||
[routerLinkActiveOptions]='{ exact: true }'
|
||||
class="breadcrumb"
|
||||
routerLink="/ui/projects"
|
||||
translate="top-bar.navigation-items.projects"
|
||||
routerLinkActive="active"
|
||||
*ngIf="projectsView"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
></a>
|
||||
<a
|
||||
class='breadcrumb back-to-projects'
|
||||
routerLink='/ui/projects'
|
||||
routerLinkActive='active'
|
||||
*ngIf='settingsView'
|
||||
[routerLinkActiveOptions]='{ exact: true }'
|
||||
class="breadcrumb back-to-projects"
|
||||
routerLink="/ui/projects"
|
||||
routerLinkActive="active"
|
||||
*ngIf="settingsView"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<mat-icon svgIcon='red:expand'></mat-icon>
|
||||
<mat-icon svgIcon="red:expand"></mat-icon>
|
||||
{{ 'top-bar.navigation-items.back-to-projects' | translate }}
|
||||
</a>
|
||||
<ng-container *ngIf='projectsView'>
|
||||
<mat-icon class='primary' *ngIf='!appStateService.activeProject' svgIcon='red:arrow-down'></mat-icon>
|
||||
<mat-icon *ngIf='appStateService.activeProject' svgIcon='red:arrow-right'></mat-icon>
|
||||
<ng-container *ngIf="projectsView">
|
||||
<mat-icon class="primary" *ngIf="!appStateService.activeProject" svgIcon="red:arrow-down"></mat-icon>
|
||||
<mat-icon *ngIf="appStateService.activeProject" svgIcon="red:arrow-right"></mat-icon>
|
||||
<a
|
||||
*ngIf='appStateService.activeProject'
|
||||
class='breadcrumb'
|
||||
*ngIf="appStateService.activeProject"
|
||||
class="breadcrumb"
|
||||
[routerLink]="'/ui/projects/' + appStateService.activeProjectId"
|
||||
routerLinkActive='active'
|
||||
[routerLinkActiveOptions]='{ exact: true }'
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
{{ appStateService.activeProject.project.projectName }}
|
||||
</a>
|
||||
<mat-icon svgIcon='red:arrow-right' *ngIf='appStateService.activeFile'></mat-icon>
|
||||
<mat-icon svgIcon="red:arrow-right" *ngIf="appStateService.activeFile"></mat-icon>
|
||||
<a
|
||||
*ngIf='appStateService.activeFile'
|
||||
class='breadcrumb'
|
||||
*ngIf="appStateService.activeFile"
|
||||
class="breadcrumb"
|
||||
[routerLink]="'/ui/projects/' + appStateService.activeProjectId + '/file/' + appStateService.activeFile.fileId"
|
||||
routerLinkActive='active'
|
||||
routerLinkActive="active"
|
||||
>
|
||||
{{ appStateService.activeFile.filename }}
|
||||
</a>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div class='center flex-1'>
|
||||
<redaction-hidden-action (action)='userPreferenceService.toggleDevFeatures()'>
|
||||
<div class="center flex-1">
|
||||
<redaction-hidden-action (action)="userPreferenceService.toggleDevFeatures()">
|
||||
<redaction-logo></redaction-logo>
|
||||
</redaction-hidden-action>
|
||||
<div class='app-name'>{{ titleService.getTitle() }}</div>
|
||||
<span class='dev-mode' *ngIf='userPreferenceService.areDevFeaturesEnabled' translate='dev-mode'></span>
|
||||
<div class="app-name">{{ titleService.getTitle() }}</div>
|
||||
<span class="dev-mode" *ngIf="userPreferenceService.areDevFeaturesEnabled" translate="dev-mode"></span>
|
||||
</div>
|
||||
<div class='menu right flex-2'>
|
||||
<redaction-notifications class='mr-8'
|
||||
*ngIf='userPreferenceService.areDevFeaturesEnabled'></redaction-notifications>
|
||||
<redaction-user-button [user]='user' [matMenuTriggerFor]='userMenu'
|
||||
[showDot]='showPendingDownloadsDot'></redaction-user-button>
|
||||
<mat-menu #userMenu='matMenu'>
|
||||
<div class="menu right flex-2">
|
||||
<redaction-notifications class="mr-8" *ngIf="userPreferenceService.areDevFeaturesEnabled"></redaction-notifications>
|
||||
<redaction-user-button [user]="user" [matMenuTriggerFor]="userMenu" [showDot]="showPendingDownloadsDot"></redaction-user-button>
|
||||
<mat-menu #userMenu="matMenu" class="user-menu" xPosition="before">
|
||||
<button
|
||||
*ngIf='permissionsService.isUser()'
|
||||
*ngIf="permissionsService.isUser()"
|
||||
[routerLink]="'/ui/my-profile'"
|
||||
mat-menu-item
|
||||
translate='top-bar.navigation-items.my-account.children.my-profile'
|
||||
translate="top-bar.navigation-items.my-account.children.my-profile"
|
||||
></button>
|
||||
<button
|
||||
*ngIf='permissionsService.isManager()'
|
||||
(click)='appStateService.reset()'
|
||||
*ngIf="permissionsService.isManager()"
|
||||
(click)="appStateService.reset()"
|
||||
[routerLink]="'/ui/admin'"
|
||||
mat-menu-item
|
||||
translate='top-bar.navigation-items.my-account.children.admin'
|
||||
translate="top-bar.navigation-items.my-account.children.admin"
|
||||
></button>
|
||||
<button
|
||||
*ngIf='permissionsService.isUser()'
|
||||
*ngIf="permissionsService.isUser()"
|
||||
[routerLink]="'/ui/downloads'"
|
||||
mat-menu-item
|
||||
translate='top-bar.navigation-items.my-account.children.downloads'
|
||||
translate="top-bar.navigation-items.my-account.children.downloads"
|
||||
></button>
|
||||
<button [matMenuTriggerFor]='language' mat-menu-item
|
||||
translate='top-bar.navigation-items.my-account.children.language.label'></button>
|
||||
<mat-menu #language='matMenu'>
|
||||
<button
|
||||
*ngFor='let lang of languages'
|
||||
(click)='changeLanguage(lang)'
|
||||
mat-menu-item
|
||||
translate
|
||||
>top-bar.navigation-items.my-account.children.language.{{lang}}</button>
|
||||
<button [matMenuTriggerFor]="language" mat-menu-item translate="top-bar.navigation-items.my-account.children.language.label"></button>
|
||||
<mat-menu #language="matMenu">
|
||||
<button *ngFor="let lang of languages" (click)="changeLanguage(lang)" mat-menu-item translate>
|
||||
top-bar.navigation-items.my-account.children.language.{{ lang }}
|
||||
</button>
|
||||
</mat-menu>
|
||||
<button (click)='logout()' mat-menu-item>
|
||||
<mat-icon svgIcon='red:logout'></mat-icon>
|
||||
<span translate='top-bar.navigation-items.my-account.children.logout'> </span>
|
||||
<button (click)="logout()" mat-menu-item>
|
||||
<mat-icon svgIcon="red:logout"></mat-icon>
|
||||
<span translate="top-bar.navigation-items.my-account.children.logout"> </span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
<div class='divider'></div>
|
||||
<div class="divider"></div>
|
||||
</div>
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<redaction-circle-button [matMenuTriggerFor]="overlay" icon="red:notification" [showDot]="hasUnread"></redaction-circle-button>
|
||||
<mat-menu #overlay="matMenu" class="notifications-menu" backdropClass="notifications-backdrop">
|
||||
<mat-menu #overlay="matMenu" class="notifications-menu" backdropClass="notifications-backdrop" xPosition="before">
|
||||
<div *ngFor="let group of groupedNotifications | sortBy: 'desc':'dateString'">
|
||||
<div class="all-caps-label">{{ day(group) }}</div>
|
||||
<div
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
.notifications-menu {
|
||||
min-width: 400px !important;
|
||||
padding: 0 8px 16px;
|
||||
margin-right: 8px;
|
||||
max-height: calc(100vh - 200px);
|
||||
|
||||
.all-caps-label {
|
||||
|
||||
@ -89,6 +89,8 @@
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<redaction-empty-state *ngIf="!logs?.totalHits" icon="red:document" screen="audit-screen"></redaction-empty-state>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<div class="table-item pointer" *cdkVirtualFor="let log of logs?.data">
|
||||
<div>
|
||||
|
||||
@ -13,141 +13,141 @@
|
||||
|
||||
<div class="red-content-inner">
|
||||
<div class="content-container">
|
||||
<div *ngIf="dictionaries.length === 0" class="empty-state">
|
||||
<mat-icon svgIcon="red:dictionary"></mat-icon>
|
||||
<div class="heading-l" translate="dictionary-listing.no-data.title"></div>
|
||||
<redaction-icon-button (action)="openAddEditDictionaryDialog()" icon="red:plus" text="dictionary-listing.no-data.action" type="primary">
|
||||
</redaction-icon-button>
|
||||
<div class="header-item">
|
||||
<div class="select-all-container">
|
||||
<div
|
||||
(click)="toggleSelectAll()"
|
||||
[class.active]="areAllDictsSelected"
|
||||
class="select-oval always-visible"
|
||||
*ngIf="!areAllDictsSelected && !areSomeDictsSelected"
|
||||
></div>
|
||||
<mat-icon *ngIf="areAllDictsSelected" (click)="toggleSelectAll()" class="selection-icon active" svgIcon="red:radio-selected"></mat-icon>
|
||||
<mat-icon
|
||||
*ngIf="areSomeDictsSelected && !areAllDictsSelected"
|
||||
(click)="toggleSelectAll()"
|
||||
class="selection-icon"
|
||||
svgIcon="red:radio-indeterminate"
|
||||
></mat-icon>
|
||||
</div>
|
||||
|
||||
<span class="all-caps-label">
|
||||
{{ 'dictionary-listing.table-header.title' | translate: { length: displayedDictionaries.length } }}
|
||||
</span>
|
||||
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-search-input [form]="searchForm" [placeholder]="'dictionary-listing.search'"></redaction-search-input>
|
||||
<div class="actions">
|
||||
<redaction-icon-button
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
icon="red:plus"
|
||||
(action)="openAddEditDictionaryDialog()"
|
||||
text="dictionary-listing.add-new"
|
||||
type="primary"
|
||||
></redaction-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="dictionaries.length > 0">
|
||||
<div class="header-item">
|
||||
<div class="select-all-container">
|
||||
<div
|
||||
(click)="toggleSelectAll()"
|
||||
[class.active]="areAllDictsSelected"
|
||||
class="select-oval always-visible"
|
||||
*ngIf="!areAllDictsSelected && !areSomeDictsSelected"
|
||||
></div>
|
||||
<mat-icon *ngIf="areAllDictsSelected" (click)="toggleSelectAll()" class="selection-icon active" svgIcon="red:radio-selected"></mat-icon>
|
||||
<mat-icon
|
||||
*ngIf="areSomeDictsSelected && !areAllDictsSelected"
|
||||
(click)="toggleSelectAll()"
|
||||
class="selection-icon"
|
||||
svgIcon="red:radio-indeterminate"
|
||||
></mat-icon>
|
||||
<div class="table-header" redactionSyncWidth="table-item" [class.no-data]="!dictionaries.length">
|
||||
<div class="select-oval-placeholder"></div>
|
||||
|
||||
<redaction-table-col-name
|
||||
label="dictionary-listing.table-col-names.type"
|
||||
column="label"
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name
|
||||
label="dictionary-listing.table-col-names.order-of-importance"
|
||||
column="rank"
|
||||
class="flex-center"
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name label="dictionary-listing.table-col-names.hint-redaction" class="flex-center"></redaction-table-col-name>
|
||||
<div></div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<redaction-empty-state
|
||||
*ngIf="!dictionaries.length"
|
||||
icon="red:dictionary"
|
||||
(action)="openAddEditDictionaryDialog()"
|
||||
[showButton]="permissionsService.isAdmin()"
|
||||
screen="dictionary-listing"
|
||||
></redaction-empty-state>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<div
|
||||
class="table-item pointer"
|
||||
*cdkVirtualFor="let dict of displayedDictionaries | sortBy: sortingOption.order:sortingOption.column"
|
||||
[routerLink]="[dict.type]"
|
||||
>
|
||||
<div class="pr-0" (click)="toggleDictSelected($event, dict)">
|
||||
<div *ngIf="!isDictSelected(dict)" class="select-oval"></div>
|
||||
<mat-icon class="selection-icon active" *ngIf="isDictSelected(dict)" svgIcon="red:radio-selected"></mat-icon>
|
||||
</div>
|
||||
|
||||
<span class="all-caps-label">
|
||||
{{ 'dictionary-listing.table-header.title' | translate: { length: displayedDictionaries.length } }}
|
||||
</span>
|
||||
|
||||
<div class="attributes-actions-container">
|
||||
<redaction-search-input [form]="searchForm" [placeholder]="'dictionary-listing.search'"></redaction-search-input>
|
||||
<div class="actions">
|
||||
<redaction-icon-button
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
icon="red:plus"
|
||||
(action)="openAddEditDictionaryDialog()"
|
||||
text="dictionary-listing.add-new"
|
||||
type="primary"
|
||||
></redaction-icon-button>
|
||||
<div>
|
||||
<div class="color-square" [ngStyle]="{ 'background-color': dict.hexColor }"></div>
|
||||
<div class="dict-name">
|
||||
<div class="table-item-title heading">
|
||||
{{ dict.label }}
|
||||
</div>
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:entries"></mat-icon>
|
||||
{{ dict.entries?.length }}
|
||||
</div>
|
||||
<div *ngIf="!dict.caseInsensitive">
|
||||
<mat-icon svgIcon="red:case-sensitive"></mat-icon>
|
||||
{{ 'dictionary-listing.case-sensitive' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-header" redactionSyncWidth="table-item">
|
||||
<div class="select-oval-placeholder"></div>
|
||||
<div class="center small-label">
|
||||
{{ dict.rank }}
|
||||
</div>
|
||||
|
||||
<redaction-table-col-name
|
||||
label="dictionary-listing.table-col-names.type"
|
||||
column="label"
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
></redaction-table-col-name>
|
||||
<div class="center">
|
||||
<redaction-annotation-icon [dictType]="dict" [type]="dict.hint ? 'circle' : 'square'"></redaction-annotation-icon>
|
||||
</div>
|
||||
|
||||
<redaction-table-col-name
|
||||
label="dictionary-listing.table-col-names.order-of-importance"
|
||||
column="rank"
|
||||
class="flex-center"
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
></redaction-table-col-name>
|
||||
<div class="actions-container">
|
||||
<div class="action-buttons">
|
||||
<redaction-circle-button
|
||||
(action)="openDeleteDictionaryDialog($event, dict)"
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
tooltip="dictionary-listing.action.delete"
|
||||
type="dark-bg"
|
||||
icon="red:trash"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-table-col-name label="dictionary-listing.table-col-names.hint-redaction" class="flex-center"></redaction-table-col-name>
|
||||
<div></div>
|
||||
<redaction-circle-button
|
||||
(action)="openEditDictionaryDialog($event, dict)"
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
tooltip="dictionary-listing.action.edit"
|
||||
type="dark-bg"
|
||||
icon="red:edit"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<div
|
||||
class="table-item pointer"
|
||||
*cdkVirtualFor="let dict of displayedDictionaries | sortBy: sortingOption.order:sortingOption.column"
|
||||
[routerLink]="[dict.type]"
|
||||
>
|
||||
<div class="pr-0" (click)="toggleDictSelected($event, dict)">
|
||||
<div *ngIf="!isDictSelected(dict)" class="select-oval"></div>
|
||||
<mat-icon class="selection-icon active" *ngIf="isDictSelected(dict)" svgIcon="red:radio-selected"></mat-icon>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="color-square" [ngStyle]="{ 'background-color': dict.hexColor }"></div>
|
||||
<div class="dict-name">
|
||||
<div class="table-item-title heading">
|
||||
{{ dict.label }}
|
||||
</div>
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:entries"></mat-icon>
|
||||
{{ dict.entries?.length }}
|
||||
</div>
|
||||
<div *ngIf="!dict.caseInsensitive">
|
||||
<mat-icon svgIcon="red:case-sensitive"></mat-icon>
|
||||
{{ 'dictionary-listing.case-sensitive' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="center small-label">
|
||||
{{ dict.rank }}
|
||||
</div>
|
||||
|
||||
<div class="center">
|
||||
<redaction-annotation-icon [dictType]="dict" [type]="dict.hint ? 'circle' : 'square'"></redaction-annotation-icon>
|
||||
</div>
|
||||
|
||||
<div class="actions-container">
|
||||
<div class="action-buttons">
|
||||
<redaction-circle-button
|
||||
(action)="openDeleteDictionaryDialog($event, dict)"
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
tooltip="dictionary-listing.action.delete"
|
||||
type="dark-bg"
|
||||
icon="red:trash"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="openEditDictionaryDialog($event, dict)"
|
||||
*ngIf="permissionsService.isAdmin()"
|
||||
tooltip="dictionary-listing.action.edit"
|
||||
type="dark-bg"
|
||||
icon="red:edit"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
</ng-container>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
</div>
|
||||
|
||||
<div class="right-container" redactionHasScrollbar>
|
||||
<redaction-simple-doughnut-chart
|
||||
*ngIf="dictionaries.length"
|
||||
[config]="chartData"
|
||||
[strokeWidth]="15"
|
||||
[radius]="82"
|
||||
|
||||
@ -123,6 +123,20 @@
|
||||
</span>
|
||||
|
||||
<ng-container *ngIf="areSomeFieldsSelected">
|
||||
<redaction-circle-button
|
||||
[matMenuTriggerFor]="readOnlyMenu"
|
||||
tooltip="file-attributes-csv-import.table-header.actions.read-only"
|
||||
type="dark-bg"
|
||||
icon="red:read-only"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
<redaction-circle-button
|
||||
[matMenuTriggerFor]="displayMenu"
|
||||
tooltip="file-attributes-csv-import.table-header.actions.display"
|
||||
type="dark-bg"
|
||||
icon="red:visibility"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
<redaction-circle-button
|
||||
(action)="deactivateSelection()"
|
||||
tooltip="file-attributes-csv-import.table-header.actions.remove-selected"
|
||||
@ -130,6 +144,45 @@
|
||||
icon="red:trash"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
<redaction-chevron-button
|
||||
text="file-attributes-csv-import.table-header.actions.type"
|
||||
[matMenuTriggerFor]="typeMenu"
|
||||
></redaction-chevron-button>
|
||||
|
||||
<mat-menu #readOnlyMenu="matMenu" class="no-padding-bottom">
|
||||
<button
|
||||
mat-menu-item
|
||||
(click)="setAttributeForSelection('readonly', true)"
|
||||
translate="file-attributes-csv-import.table-header.actions.enable-read-only"
|
||||
></button>
|
||||
<button
|
||||
mat-menu-item
|
||||
(click)="setAttributeForSelection('readonly', false)"
|
||||
translate="file-attributes-csv-import.table-header.actions.disable-read-only"
|
||||
></button>
|
||||
</mat-menu>
|
||||
|
||||
<mat-menu #displayMenu="matMenu" class="no-padding-bottom">
|
||||
<button
|
||||
mat-menu-item
|
||||
(click)="setAttributeForSelection('display', true)"
|
||||
translate="file-attributes-csv-import.table-header.actions.enable-display"
|
||||
></button>
|
||||
<button
|
||||
mat-menu-item
|
||||
(click)="setAttributeForSelection('display', false)"
|
||||
translate="file-attributes-csv-import.table-header.actions.disable-display"
|
||||
></button>
|
||||
</mat-menu>
|
||||
|
||||
<mat-menu #typeMenu="matMenu" class="no-padding-bottom">
|
||||
<button *ngFor="let type of ['Text', 'Number', 'Date']" mat-menu-item (click)="setAttributeForSelection('type', type)">
|
||||
{{ 'file-attributes-csv-import.types.' + type | translate }}
|
||||
</button>
|
||||
</mat-menu>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
@ -156,6 +209,8 @@
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<redaction-empty-state *ngIf="!activeFields.length" icon="red:attribute" screen="file-attributes-csv-import"> </redaction-empty-state>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="50" redactionHasScrollbar>
|
||||
<!-- Table lines -->
|
||||
<div
|
||||
@ -222,6 +277,7 @@
|
||||
<div class="action-buttons">
|
||||
<redaction-circle-button
|
||||
(action)="toggleFieldActive(field)"
|
||||
[removeTooltip]="true"
|
||||
tooltip="file-attributes-csv-import.action.remove"
|
||||
type="dark-bg"
|
||||
icon="red:trash"
|
||||
|
||||
@ -153,7 +153,7 @@
|
||||
}
|
||||
|
||||
> .content-container {
|
||||
width: 100%;
|
||||
width: calc(100% - 527px);
|
||||
|
||||
redaction-table-col-name::ng-deep {
|
||||
> div {
|
||||
@ -173,6 +173,18 @@
|
||||
.all-caps-label {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
redaction-circle-button {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.separator {
|
||||
margin-left: 14px;
|
||||
background-color: $separator;
|
||||
width: 1px;
|
||||
height: 30px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
cdk-virtual-scroll-viewport {
|
||||
|
||||
@ -63,7 +63,10 @@ export class FileAttributesCsvImportDialogComponent implements OnInit {
|
||||
|
||||
ngOnInit(): void {
|
||||
setTimeout(() => {
|
||||
this.cdkVirtualScrollViewport.checkViewportSize();
|
||||
// Calculate viewport size after dialog is completely expanded
|
||||
if (this.cdkVirtualScrollViewport) {
|
||||
this.cdkVirtualScrollViewport.checkViewportSize();
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
@ -174,6 +177,12 @@ export class FileAttributesCsvImportDialogComponent implements OnInit {
|
||||
this.selectedFields = [];
|
||||
}
|
||||
|
||||
public setAttributeForSelection(attribute: string, value: any) {
|
||||
for (const csvColumn of this.selectedFields) {
|
||||
this.activeFields.find((f) => f.csvColumn === csvColumn)[attribute] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public async save() {
|
||||
await this._fileAttributesControllerService
|
||||
.addOrUpdateFileAttributesConfig(
|
||||
|
||||
@ -58,7 +58,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div [class.no-data]="noData" class="table-header" redactionSyncWidth="table-item">
|
||||
<div [class.no-data]="!attributes.length" class="table-header" redactionSyncWidth="table-item">
|
||||
<div class="select-oval-placeholder"></div>
|
||||
|
||||
<redaction-table-col-name
|
||||
@ -78,7 +78,7 @@
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="noData" class="no-data heading-l" translate="file-attributes-listing.no-data"></div>
|
||||
<redaction-empty-state *ngIf="!attributes.length" screen="file-attributes-listing" icon="red:attribute"></redaction-empty-state>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<!-- Table lines -->
|
||||
|
||||
@ -56,10 +56,6 @@ export class FileAttributesListingScreenComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
public get noData(): boolean {
|
||||
return this.displayedAttributes.length === 0;
|
||||
}
|
||||
|
||||
public get sortingOption(): SortingOption {
|
||||
return this._sortingService.getSortingOption('file-attributes-listing');
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<section>
|
||||
<section *ngIf="viewReady">
|
||||
<div class="page-header">
|
||||
<redaction-admin-breadcrumbs [root]="true" class="flex-1"></redaction-admin-breadcrumbs>
|
||||
|
||||
@ -96,7 +96,6 @@
|
||||
</div>
|
||||
|
||||
<combo-chart-component
|
||||
*ngIf="viewReady"
|
||||
[view]="[1000, 300]"
|
||||
[scheme]="comboBarScheme"
|
||||
[legend]="true"
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="table-header" redactionSyncWidth="table-item">
|
||||
<div class="table-header" redactionSyncWidth="table-item" [class.no-data]="!ruleSets.length">
|
||||
<div class="select-oval-placeholder"></div>
|
||||
|
||||
<redaction-table-col-name
|
||||
@ -76,6 +76,8 @@
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<redaction-empty-state *ngIf="!ruleSets.length" icon="red:template" screen="project-templates-listing"></redaction-empty-state>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="100" redactionHasScrollbar>
|
||||
<div
|
||||
class="table-item pointer"
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
{{ 'user-listing.table-header.title' | translate: { length: displayedUsers.length } }}
|
||||
</span>
|
||||
|
||||
<ng-container *ngIf="true || (areSomeUsersSelected && !loading)">
|
||||
<ng-container *ngIf="areSomeUsersSelected && !loading">
|
||||
<redaction-circle-button
|
||||
(action)="bulkDelete()"
|
||||
[disabled]="!canDeleteSelected"
|
||||
@ -73,6 +73,8 @@
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<!--No empty state necessary because there will always be at least the current user.-->
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<!-- Table lines -->
|
||||
<div class="table-item" *cdkVirtualFor="let user of displayedUsers">
|
||||
|
||||
@ -19,6 +19,7 @@ export class IconsModule {
|
||||
'arrow-up',
|
||||
'assign',
|
||||
'assign-me',
|
||||
'attribute',
|
||||
'calendar',
|
||||
'case-sensitive',
|
||||
'check',
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
@import '../../../../../assets/styles/red-mixins';
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
background: white;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
@include inset-shadow;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 40px;
|
||||
|
||||
flex-direction: column;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid $separator;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
height: 48px;
|
||||
width: 234px;
|
||||
text-align: center;
|
||||
color: #9398a0;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
opacity: 10%;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-disabled-for-redaction',
|
||||
template:
|
||||
"<div class='section flex-align-items-center'>\n" +
|
||||
' <mat-icon [svgIcon]="\'red:needs-work\'"></mat-icon>\n' +
|
||||
" <p class='heading-l'>{{'file-preview.tabs.is-excluded' | translate}}</p>\n" +
|
||||
'</div>',
|
||||
styleUrls: ['./disabled-for-redaction.component.scss']
|
||||
})
|
||||
export class DisabledForRedactionComponent {}
|
||||
@ -1,7 +0,0 @@
|
||||
<div class="empty-state-container">
|
||||
<div class="heading-xl" translate="project-listing.no-projects"></div>
|
||||
<button (click)="addProjectRequest.emit()" *ngIf="userService.isManager()" class="add-project-btn" color="primary" mat-flat-button>
|
||||
<mat-icon svgIcon="red:plus"></mat-icon>
|
||||
<span translate="project-listing.add-new"></span>
|
||||
</button>
|
||||
</div>
|
||||
@ -1,13 +0,0 @@
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
import { UserService } from '../../../../../services/user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-project-listing-empty',
|
||||
templateUrl: './project-listing-empty.component.html',
|
||||
styleUrls: ['./project-listing-empty.component.scss']
|
||||
})
|
||||
export class ProjectListingEmptyComponent {
|
||||
@Output() addProjectRequest = new EventEmitter();
|
||||
|
||||
constructor(public userService: UserService) {}
|
||||
}
|
||||
@ -123,11 +123,7 @@
|
||||
|
||||
<ng-template #annotationFilterActionTemplate let-filter="filter">
|
||||
<ng-container *ngIf="filter.key === 'skipped'">
|
||||
<redaction-circle-button
|
||||
[icon]="hideSkipped ? 'red:visibility-off' : 'red:visibility'"
|
||||
(action)="toggleSkipped.emit($event)"
|
||||
class="skipped-toggle-button"
|
||||
>
|
||||
<redaction-circle-button [icon]="hideSkipped ? 'red:visibility-off' : 'red:visibility'" (action)="toggleSkipped.emit($event)" type="dark-bg">
|
||||
</redaction-circle-button>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
|
||||
@ -14,7 +14,6 @@ import { CommentsComponent } from './components/comments/comments.component';
|
||||
import { ProjectDetailsComponent } from './components/project-details/project-details.component';
|
||||
import { PageIndicatorComponent } from './components/page-indicator/page-indicator.component';
|
||||
import { NeedsWorkBadgeComponent } from './components/needs-work-badge/needs-work-badge.component';
|
||||
import { ProjectListingEmptyComponent } from './components/empty-states/project-listing-empty/project-listing-empty.component';
|
||||
import { AnnotationActionsComponent } from './components/annotation-actions/annotation-actions.component';
|
||||
import { ProjectListingDetailsComponent } from './components/project-listing-details/project-listing-details.component';
|
||||
import { FileActionsComponent } from './components/file-actions/file-actions.component';
|
||||
@ -35,7 +34,6 @@ import { PdfViewerDataService } from './services/pdf-viewer-data.service';
|
||||
import { ManualAnnotationService } from './services/manual-annotation.service';
|
||||
import { AnnotationDrawService } from './services/annotation-draw.service';
|
||||
import { AnnotationProcessingService } from './services/annotation-processing.service';
|
||||
import { DisabledForRedactionComponent } from './components/disabled-for-redaction/disabled-for-redaction.component';
|
||||
|
||||
const screens = [ProjectListingScreenComponent, ProjectOverviewScreenComponent, FilePreviewScreenComponent];
|
||||
|
||||
@ -55,7 +53,6 @@ const components = [
|
||||
PageIndicatorComponent,
|
||||
NeedsWorkBadgeComponent,
|
||||
AnnotationActionsComponent,
|
||||
ProjectListingEmptyComponent,
|
||||
ProjectListingDetailsComponent,
|
||||
TypeAnnotationIconComponent,
|
||||
TypeFilterComponent,
|
||||
@ -65,7 +62,6 @@ const components = [
|
||||
ProjectListingActionsComponent,
|
||||
DocumentInfoComponent,
|
||||
FileWorkloadComponent,
|
||||
DisabledForRedactionComponent,
|
||||
|
||||
...screens,
|
||||
...dialogs
|
||||
|
||||
@ -208,7 +208,12 @@
|
||||
</div>
|
||||
|
||||
<div class="right-container">
|
||||
<redaction-disabled-for-redaction *ngIf="viewReady && appStateService.activeFile.isExcluded"> </redaction-disabled-for-redaction>
|
||||
<redaction-empty-state
|
||||
*ngIf="viewReady && appStateService.activeFile.isExcluded && !viewDocumentInfo"
|
||||
icon="red:needs-work"
|
||||
text="file-preview.tabs.is-excluded"
|
||||
[horizontalPadding]="40"
|
||||
></redaction-empty-state>
|
||||
|
||||
<redaction-document-info
|
||||
*ngIf="viewReady && viewDocumentInfo"
|
||||
@ -218,6 +223,7 @@
|
||||
</redaction-document-info>
|
||||
|
||||
<redaction-file-workload
|
||||
*ngIf="!appStateService.activeFile.isExcluded"
|
||||
#fileWorkloadComponent
|
||||
[annotations]="annotations"
|
||||
[selectedAnnotations]="selectedAnnotations"
|
||||
|
||||
@ -187,7 +187,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
redaction-dictionary-annotation-icon {
|
||||
::ng-deep redaction-dictionary-annotation-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
@ -203,13 +203,6 @@ redaction-dictionary-annotation-icon {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.skipped-toggle-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.analysis-progress {
|
||||
padding: 12px 20px;
|
||||
max-width: 400px;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<section *ngIf="appStateService.hasProjects">
|
||||
<section>
|
||||
<div class="page-header">
|
||||
<div class="filters">
|
||||
<div translate="filters.filter-by"></div>
|
||||
@ -52,7 +52,7 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div [class.no-data]="noData" class="table-header" redactionSyncWidth="table-item">
|
||||
<div class="table-header" redactionSyncWidth="table-item">
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="sortingService.toggleSort('project-listing', $event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
@ -69,7 +69,15 @@
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="noData" class="no-data heading-l" translate="project-listing.no-projects-match"></div>
|
||||
<redaction-empty-state
|
||||
*ngIf="!appStateService.hasProjects"
|
||||
icon="red:folder"
|
||||
screen="project-listing"
|
||||
(action)="openAddProjectDialog()"
|
||||
[showButton]="permissionsService.isManager()"
|
||||
></redaction-empty-state>
|
||||
|
||||
<div *ngIf="appStateService.hasProjects && !displayedProjects.length" class="no-data heading-l" translate="project-listing.no-projects-match"></div>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="85" redactionHasScrollbar>
|
||||
<div
|
||||
@ -127,6 +135,7 @@
|
||||
|
||||
<div class="right-container" redactionHasScrollbar>
|
||||
<redaction-project-listing-details
|
||||
*ngIf="appStateService.hasProjects"
|
||||
(filtersChanged)="filtersChanged($event)"
|
||||
[documentsChartData]="documentsChartData"
|
||||
[filters]="detailsContainerFilters"
|
||||
@ -136,7 +145,7 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<redaction-project-listing-empty (addProjectRequest)="openAddProjectDialog()" *ngIf="!appStateService.hasProjects"></redaction-project-listing-empty>
|
||||
<!--<redaction-project-listing-empty (addProjectRequest)="openAddProjectDialog()" *ngIf="!appStateService.hasProjects"></redaction-project-listing-empty>-->
|
||||
|
||||
<ng-template #needsWorkTemplate let-filter="filter">
|
||||
<redaction-type-filter [filter]="filter"></redaction-type-filter>
|
||||
|
||||
@ -109,7 +109,7 @@ export class ProjectListingScreenComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public get noData() {
|
||||
return this.displayedProjects?.length === 0;
|
||||
return this.appStateService.allProjects?.length === 0;
|
||||
}
|
||||
|
||||
public resetFilters() {
|
||||
|
||||
@ -83,172 +83,171 @@
|
||||
</div>
|
||||
<div class="red-content-inner">
|
||||
<div class="content-container" [class.extended]="collapsedDetails">
|
||||
<div *ngIf="!appStateService.activeProject?.hasFiles" class="empty-state">
|
||||
<mat-icon svgIcon="red:document"></mat-icon>
|
||||
<div class="heading-l" translate="project-overview.no-data.title"></div>
|
||||
<redaction-icon-button (action)="fileInput.click()" icon="red:upload" text="project-overview.no-data.action" type="primary">
|
||||
</redaction-icon-button>
|
||||
<div class="header-item">
|
||||
<div class="select-all-container">
|
||||
<div
|
||||
(click)="toggleSelectAll()"
|
||||
[class.active]="areAllFilesSelected"
|
||||
class="select-oval always-visible"
|
||||
*ngIf="!areAllFilesSelected && !areSomeFilesSelected"
|
||||
></div>
|
||||
<mat-icon *ngIf="areAllFilesSelected" (click)="toggleSelectAll()" class="selection-icon active" svgIcon="red:radio-selected"></mat-icon>
|
||||
<mat-icon
|
||||
*ngIf="areSomeFilesSelected && !areAllFilesSelected"
|
||||
(click)="toggleSelectAll()"
|
||||
class="selection-icon"
|
||||
svgIcon="red:radio-indeterminate"
|
||||
></mat-icon>
|
||||
</div>
|
||||
|
||||
<span class="all-caps-label">
|
||||
{{ 'project-overview.table-header.title' | translate: { length: displayedFiles.length || 0 } }}
|
||||
</span>
|
||||
|
||||
<redaction-project-overview-bulk-actions
|
||||
[selectedFileIds]="selectedFileIds"
|
||||
(reload)="bulkActionPerformed()"
|
||||
></redaction-project-overview-bulk-actions>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="appStateService.activeProject?.hasFiles">
|
||||
<div class="header-item">
|
||||
<div class="select-all-container">
|
||||
<div
|
||||
(click)="toggleSelectAll()"
|
||||
[class.active]="areAllFilesSelected"
|
||||
class="select-oval always-visible"
|
||||
*ngIf="!areAllFilesSelected && !areSomeFilesSelected"
|
||||
></div>
|
||||
<mat-icon *ngIf="areAllFilesSelected" (click)="toggleSelectAll()" class="selection-icon active" svgIcon="red:radio-selected"></mat-icon>
|
||||
<mat-icon
|
||||
*ngIf="areSomeFilesSelected && !areAllFilesSelected"
|
||||
(click)="toggleSelectAll()"
|
||||
class="selection-icon"
|
||||
svgIcon="red:radio-indeterminate"
|
||||
></mat-icon>
|
||||
<div class="table-header" redactionSyncWidth="table-item" [class.no-data]="!appStateService.activeProject?.hasFiles">
|
||||
<!-- Table column names-->
|
||||
<div class="select-oval-placeholder"></div>
|
||||
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="filename"
|
||||
label="project-overview.table-col-names.name"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="added"
|
||||
label="project-overview.table-col-names.added-on"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name label="project-overview.table-col-names.needs-work"></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="reviewerName"
|
||||
label="project-overview.table-col-names.assigned-to"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="pages"
|
||||
label="project-overview.table-col-names.pages"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
class="flex-end"
|
||||
column="statusSort"
|
||||
label="project-overview.table-col-names.status"
|
||||
></redaction-table-col-name>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<redaction-empty-state
|
||||
*ngIf="!appStateService.activeProject?.hasFiles"
|
||||
icon="red:document"
|
||||
screen="project-overview"
|
||||
(action)="fileInput.click()"
|
||||
buttonIcon="red:upload"
|
||||
></redaction-empty-state>
|
||||
|
||||
<div
|
||||
*ngIf="appStateService.activeProject?.hasFiles && !displayedFiles.length"
|
||||
class="no-data heading-l"
|
||||
translate="project-overview.no-files-match"
|
||||
></div>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<div
|
||||
*cdkVirtualFor="let fileStatus of displayedFiles | sortBy: sortingOption.order:sortingOption.column; trackBy: fileId"
|
||||
[class.pointer]="permissionsService.canOpenFile(fileStatus)"
|
||||
[routerLink]="fileLink(fileStatus)"
|
||||
class="table-item"
|
||||
[class.disabled]="fileStatus.isExcluded"
|
||||
>
|
||||
<div class="pr-0" (click)="toggleFileSelected($event, fileStatus)">
|
||||
<div *ngIf="!isFileSelected(fileStatus)" class="select-oval"></div>
|
||||
<mat-icon class="selection-icon active" *ngIf="isFileSelected(fileStatus)" svgIcon="red:radio-selected"></mat-icon>
|
||||
</div>
|
||||
|
||||
<span class="all-caps-label">
|
||||
{{ 'project-overview.table-header.title' | translate: { length: displayedFiles.length || 0 } }}
|
||||
</span>
|
||||
<div [title]="'[' + fileStatus.status + '] ' + fileStatus.filename">
|
||||
<div class="filename-wrapper">
|
||||
<div [class.disabled]="fileStatus.isPending || fileStatus.isProcessing" [class.error]="fileStatus.isError" class="table-item-title">
|
||||
{{ fileStatus.filename }}
|
||||
</div>
|
||||
<!-- <span *ngIf="permissionsService.fileRequiresReanalysis(fileStatus)" class="pill" translate="project-overview.new-rule.label"></span>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<redaction-project-overview-bulk-actions
|
||||
[selectedFileIds]="selectedFileIds"
|
||||
(reload)="bulkActionPerformed()"
|
||||
></redaction-project-overview-bulk-actions>
|
||||
</div>
|
||||
<div>
|
||||
<div [class.error]="fileStatus.isError" class="small-label">
|
||||
{{ fileStatus.added | date: 'd MMM. yyyy, hh:mm a' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-header" redactionSyncWidth="table-item" [class.no-data]="noData">
|
||||
<!-- Table column names-->
|
||||
<div class="select-oval-placeholder"></div>
|
||||
<!-- always show A for error-->
|
||||
<div *ngIf="fileStatus.isError">
|
||||
<redaction-annotation-icon type="square" label="A" color="#dd4d50"></redaction-annotation-icon>
|
||||
</div>
|
||||
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="filename"
|
||||
label="project-overview.table-col-names.name"
|
||||
></redaction-table-col-name>
|
||||
<div *ngIf="!fileStatus.isError">
|
||||
<redaction-needs-work-badge [needsWorkInput]="fileStatus"></redaction-needs-work-badge>
|
||||
</div>
|
||||
<div *ngIf="!fileStatus.isError" class="assigned-to">
|
||||
<redaction-initials-avatar [userId]="fileStatus.currentReviewer" [withName]="true"></redaction-initials-avatar>
|
||||
</div>
|
||||
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="added"
|
||||
label="project-overview.table-col-names.added-on"
|
||||
></redaction-table-col-name>
|
||||
<div *ngIf="!fileStatus.isError">
|
||||
<div class="quick-navigation">
|
||||
<mat-icon svgIcon="red:pages"></mat-icon>
|
||||
{{ fileStatus.numberOfPages }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<redaction-table-col-name label="project-overview.table-col-names.needs-work"></redaction-table-col-name>
|
||||
<div [class.extend-cols]="fileStatus.isError" class="status-container">
|
||||
<div *ngIf="fileStatus.isError" class="small-label error" translate="project-overview.file-listing.file-entry.file-error"></div>
|
||||
<div *ngIf="fileStatus.isPending" class="small-label" translate="project-overview.file-listing.file-entry.file-pending"></div>
|
||||
<div
|
||||
*ngIf="fileStatus.isProcessing"
|
||||
class="small-label loading"
|
||||
translate="project-overview.file-listing.file-entry.file-processing"
|
||||
></div>
|
||||
<redaction-status-bar
|
||||
*ngIf="fileStatus.isWorkable"
|
||||
[config]="[
|
||||
{
|
||||
color: fileStatus.status,
|
||||
length: 1
|
||||
}
|
||||
]"
|
||||
></redaction-status-bar>
|
||||
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="reviewerName"
|
||||
label="project-overview.table-col-names.assigned-to"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
column="pages"
|
||||
label="project-overview.table-col-names.pages"
|
||||
></redaction-table-col-name>
|
||||
|
||||
<redaction-table-col-name
|
||||
(toggleSort)="toggleSort($event)"
|
||||
[activeSortingOption]="sortingOption"
|
||||
[withSort]="true"
|
||||
class="flex-end"
|
||||
column="statusSort"
|
||||
label="project-overview.table-col-names.status"
|
||||
></redaction-table-col-name>
|
||||
<redaction-file-actions
|
||||
[fileStatus]="fileStatus"
|
||||
(actionPerformed)="calculateData()"
|
||||
*ngIf="!fileStatus.isProcessing"
|
||||
class="mr-4"
|
||||
></redaction-file-actions>
|
||||
</div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="noData" class="no-data heading-l" translate="project-overview.no-files-match"></div>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
|
||||
<div
|
||||
*cdkVirtualFor="let fileStatus of displayedFiles | sortBy: sortingOption.order:sortingOption.column; trackBy: fileId"
|
||||
[class.pointer]="permissionsService.canOpenFile(fileStatus)"
|
||||
[routerLink]="fileLink(fileStatus)"
|
||||
class="table-item"
|
||||
[class.disabled]="fileStatus.isExcluded"
|
||||
>
|
||||
<div class="pr-0" (click)="toggleFileSelected($event, fileStatus)">
|
||||
<div *ngIf="!isFileSelected(fileStatus)" class="select-oval"></div>
|
||||
<mat-icon class="selection-icon active" *ngIf="isFileSelected(fileStatus)" svgIcon="red:radio-selected"></mat-icon>
|
||||
</div>
|
||||
|
||||
<div [title]="'[' + fileStatus.status + '] ' + fileStatus.filename">
|
||||
<div class="filename-wrapper">
|
||||
<div
|
||||
[class.disabled]="fileStatus.isPending || fileStatus.isProcessing"
|
||||
[class.error]="fileStatus.isError"
|
||||
class="table-item-title"
|
||||
>
|
||||
{{ fileStatus.filename }}
|
||||
</div>
|
||||
<!-- <span *ngIf="permissionsService.fileRequiresReanalysis(fileStatus)" class="pill" translate="project-overview.new-rule.label"></span>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div [class.error]="fileStatus.isError" class="small-label">
|
||||
{{ fileStatus.added | date: 'd MMM. yyyy, hh:mm a' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- always show A for error-->
|
||||
<div *ngIf="fileStatus.isError">
|
||||
<redaction-annotation-icon type="square" label="A" color="#dd4d50"></redaction-annotation-icon>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!fileStatus.isError">
|
||||
<redaction-needs-work-badge [needsWorkInput]="fileStatus"></redaction-needs-work-badge>
|
||||
</div>
|
||||
<div *ngIf="!fileStatus.isError" class="assigned-to">
|
||||
<redaction-initials-avatar [userId]="fileStatus.currentReviewer" [withName]="true"></redaction-initials-avatar>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!fileStatus.isError">
|
||||
<div class="quick-navigation">
|
||||
<mat-icon svgIcon="red:pages"></mat-icon>
|
||||
{{ fileStatus.numberOfPages }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div [class.extend-cols]="fileStatus.isError" class="status-container">
|
||||
<div *ngIf="fileStatus.isError" class="small-label error" translate="project-overview.file-listing.file-entry.file-error"></div>
|
||||
<div *ngIf="fileStatus.isPending" class="small-label" translate="project-overview.file-listing.file-entry.file-pending"></div>
|
||||
<div
|
||||
*ngIf="fileStatus.isProcessing"
|
||||
class="small-label loading"
|
||||
translate="project-overview.file-listing.file-entry.file-processing"
|
||||
></div>
|
||||
<redaction-status-bar
|
||||
*ngIf="fileStatus.isWorkable"
|
||||
[config]="[
|
||||
{
|
||||
color: fileStatus.status,
|
||||
length: 1
|
||||
}
|
||||
]"
|
||||
></redaction-status-bar>
|
||||
|
||||
<redaction-file-actions
|
||||
[fileStatus]="fileStatus"
|
||||
(actionPerformed)="calculateData()"
|
||||
*ngIf="!fileStatus.isProcessing"
|
||||
class="mr-4"
|
||||
></redaction-file-actions>
|
||||
</div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
</ng-container>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
</div>
|
||||
|
||||
<div class="right-container" redactionHasScrollbar [class.collapsed]="collapsedDetails">
|
||||
|
||||
@ -143,10 +143,6 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
return [FileStatus.StatusEnum.REPROCESS, FileStatus.StatusEnum.FULLREPROCESS, FileStatus.StatusEnum.PROCESSING].includes(fileStatusWrapper.status);
|
||||
}
|
||||
|
||||
public get noData() {
|
||||
return this.displayedFiles?.length === 0;
|
||||
}
|
||||
|
||||
public get sortingOption(): SortingOption {
|
||||
return this._sortingService.getSortingOption('project-overview');
|
||||
}
|
||||
@ -179,6 +175,9 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
calculateData(): void {
|
||||
if (!this.appStateService.activeProjectId) {
|
||||
return;
|
||||
}
|
||||
this._computeAllFilters();
|
||||
this._filterFiles();
|
||||
this._projectDetailsComponent?.calculateChartConfig();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<div #matTooltip="matTooltip" [matTooltipClass]="tooltipClass" [matTooltipPosition]="tooltipPosition" [matTooltip]="tooltip | translate">
|
||||
<div [matTooltipClass]="tooltipClass" [matTooltipPosition]="tooltipPosition" [matTooltip]="tooltip | translate">
|
||||
<button
|
||||
(click)="matTooltip.hide(0); performAction($event)"
|
||||
(click)="performAction($event)"
|
||||
[class.dark-bg]="type === 'dark-bg'"
|
||||
[class.primary]="type === 'primary'"
|
||||
[class.warn]="type === 'warn'"
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
:host {
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
button {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-circle-button',
|
||||
@ -15,18 +16,26 @@ export class CircleButtonComponent implements OnInit {
|
||||
@Input() small = false;
|
||||
@Input() type: 'default' | 'primary' | 'warn' | 'dark-bg' = 'default';
|
||||
@Input() dummy = false;
|
||||
@Input() removeTooltip = false;
|
||||
@Output() action = new EventEmitter<any>();
|
||||
|
||||
@ViewChild(MatTooltip) matTooltip: MatTooltip;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
performAction($event: any) {
|
||||
if (!this.disabled) {
|
||||
// Timeout to allow tooltip to disappear first
|
||||
setTimeout(() => {
|
||||
if (this.removeTooltip) {
|
||||
this.matTooltip.hide();
|
||||
// Timeout to allow tooltip to disappear first, useful when removing an item from the list without a confirmation dialog
|
||||
setTimeout(() => {
|
||||
this.action.emit($event);
|
||||
}, 0);
|
||||
} else {
|
||||
this.action.emit($event);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
<div class="empty-state" [ngStyle]="{ 'padding-left': horizontalPadding + 'px', 'padding-right': horizontalPadding + 'px' }">
|
||||
<mat-icon [svgIcon]="icon"></mat-icon>
|
||||
<div class="heading-l" [translate]="text || screen + '.no-data.title'"></div>
|
||||
<redaction-icon-button *ngIf="showButton" (action)="action.emit()" [icon]="buttonIcon" [text]="screen + '.no-data.action'" type="primary">
|
||||
</redaction-icon-button>
|
||||
</div>
|
||||
@ -0,0 +1,24 @@
|
||||
@import '../../../../../assets/styles/red-mixins';
|
||||
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 120px;
|
||||
text-align: center;
|
||||
|
||||
> mat-icon {
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
.heading-l {
|
||||
color: $grey-7;
|
||||
}
|
||||
|
||||
> .heading-l,
|
||||
redaction-icon-button {
|
||||
margin-top: 24px;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-empty-state',
|
||||
templateUrl: './empty-state.component.html',
|
||||
styleUrls: ['./empty-state.component.scss']
|
||||
})
|
||||
export class EmptyStateComponent implements OnInit {
|
||||
@Input() screen: string;
|
||||
@Input() text: string;
|
||||
@Input() icon: string;
|
||||
@Input() showButton = true;
|
||||
@Input() buttonIcon = 'red:plus';
|
||||
@Input() horizontalPadding = 100;
|
||||
@Output() action = new EventEmitter();
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.showButton = this.showButton && this.action.observers.length > 0;
|
||||
}
|
||||
}
|
||||
@ -36,7 +36,7 @@
|
||||
</mat-checkbox>
|
||||
<ng-template *ngTemplateOutlet="actionsTemplate ? actionsTemplate : null; context: { filter: filter }"> </ng-template>
|
||||
</div>
|
||||
<div *ngIf="filter.filters && filter.expanded">
|
||||
<div *ngIf="filter.filters?.length && filter.expanded">
|
||||
<div *ngFor="let subFilter of filter.filters" class="padding-left mat-menu-item" (click)="$event.stopPropagation()">
|
||||
<mat-checkbox
|
||||
[checked]="subFilter.checked"
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
<div class="wrapper">
|
||||
<div [className]="colorClass + ' oval ' + size + (hasBorder ? ' border' : '')" [matTooltipPosition]="'above'" [matTooltip]="displayName">
|
||||
<div
|
||||
[className]="colorClass + ' oval ' + size + (hasBorder ? ' border' : '')"
|
||||
[matTooltipPosition]="'above'"
|
||||
[matTooltip]="displayName || ('initials-avatar.unassigned' | translate)"
|
||||
>
|
||||
{{ initials }}
|
||||
</div>
|
||||
<div *ngIf="withName" class="clamp-2 username" [class.always-visible]="alwaysShowName" [class.disabled]="disabled">
|
||||
|
||||
@ -25,12 +25,14 @@ export class SyncWidthDirective implements AfterViewInit, OnDestroy {
|
||||
@debounce(10)
|
||||
matchWidth() {
|
||||
const headerItems = this.el.nativeElement.children;
|
||||
const tableRows = document.getElementsByClassName(this.redactionSyncWidth);
|
||||
const tableRows = this.el.nativeElement.parentElement.getElementsByClassName(this.redactionSyncWidth);
|
||||
|
||||
if (!tableRows || !tableRows.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.el.nativeElement.setAttribute('synced', true);
|
||||
|
||||
const { tableRow, length } = this._sampleRow;
|
||||
|
||||
const hasExtraColumns = headerItems.length !== length ? 1 : 0;
|
||||
|
||||
@ -26,6 +26,7 @@ import { DictionaryAnnotationIconComponent } from './components/dictionary-annot
|
||||
import { HiddenActionComponent } from './components/hidden-action/hidden-action.component';
|
||||
import { ConfirmationDialogComponent } from './dialogs/confirmation-dialog/confirmation-dialog.component';
|
||||
import { FilterComponent } from './components/filter/filter.component';
|
||||
import { EmptyStateComponent } from './components/empty-state/empty-state.component';
|
||||
|
||||
const buttons = [ChevronButtonComponent, CircleButtonComponent, FileDownloadBtnComponent, IconButtonComponent, UserButtonComponent];
|
||||
|
||||
@ -42,6 +43,7 @@ const components = [
|
||||
HiddenActionComponent,
|
||||
FilterComponent,
|
||||
ConfirmationDialogComponent,
|
||||
EmptyStateComponent,
|
||||
|
||||
...buttons
|
||||
];
|
||||
|
||||
@ -126,6 +126,11 @@
|
||||
"total-documents": "Total Document(s)"
|
||||
}
|
||||
},
|
||||
"no-data": {
|
||||
"title": "You currently have no projects.",
|
||||
"action": "New Project"
|
||||
},
|
||||
"add-new": "New Project",
|
||||
"add-edit-dialog": {
|
||||
"header-new": "Create Project",
|
||||
"header-edit": "Edit Project",
|
||||
@ -158,8 +163,6 @@
|
||||
"action": "Delete Project",
|
||||
"delete-failed": "Failed to delete project: {{projectName}}"
|
||||
},
|
||||
"add-new": "New Project",
|
||||
"no-projects": "You currently have no projects.",
|
||||
"no-projects-match": "No Projects match your current filters"
|
||||
},
|
||||
"project-details": {
|
||||
@ -737,6 +740,9 @@
|
||||
"created-by": "Created by",
|
||||
"created-on": "Created on",
|
||||
"modified-on": "Modified on"
|
||||
},
|
||||
"no-data": {
|
||||
"title": "There are no project templates yet."
|
||||
}
|
||||
},
|
||||
"file-attributes-listing": {
|
||||
@ -750,7 +756,9 @@
|
||||
"created-by": "Created by",
|
||||
"read-only": "Read-Only"
|
||||
},
|
||||
"no-data": "No file attributes.",
|
||||
"no-data": {
|
||||
"title": "There are no file attributes yet."
|
||||
},
|
||||
"read-only": "Read-only",
|
||||
"action": {
|
||||
"edit": "Edit attribute",
|
||||
@ -955,7 +963,10 @@
|
||||
},
|
||||
"all-categories": "All Categories",
|
||||
"all-users": "All Users",
|
||||
"to": "to"
|
||||
"to": "to",
|
||||
"no-data": {
|
||||
"title": "No available logs."
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"previous": "Prev",
|
||||
@ -1124,7 +1135,14 @@
|
||||
"table-header": {
|
||||
"title": "{{length}} file attributes",
|
||||
"actions": {
|
||||
"remove-selected": "Remove Selected"
|
||||
"remove-selected": "Remove Selected",
|
||||
"read-only": "Make Read-only",
|
||||
"enable-read-only": "Enable Read-only for all attributes",
|
||||
"disable-read-only": "Disable Read-only for all attributes",
|
||||
"display": "Toggle Display",
|
||||
"enable-display": "Enable Display for all attributes",
|
||||
"disable-display": "Disable Display for all attributes",
|
||||
"type": "Type"
|
||||
}
|
||||
},
|
||||
"file": "File:",
|
||||
@ -1148,6 +1166,9 @@
|
||||
"save-name": "Save",
|
||||
"cancel-edit-name": "Cancel",
|
||||
"remove": "Remove"
|
||||
},
|
||||
"no-data": {
|
||||
"title": "No file attributes defined. Select a column from the left panel to start defining file attributes."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
apps/red-ui/src/assets/icons/general/attribute.svg
Normal file
13
apps/red-ui/src/assets/icons/general/attribute.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>status</title>
|
||||
<g id="Styleguide" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Styleguide-Actions" transform="translate(-608.000000, -651.000000)" fill="currentColor" fill-rule="nonzero">
|
||||
<g id="Group-6" transform="translate(598.000000, 641.000000)">
|
||||
<g id="status" transform="translate(10.000000, 10.000000)">
|
||||
<path d="M14,8.8817842e-15 L14,6.7673716 L7.2326284,13.5347432 C6.612286,14.1550856 5.59718026,14.1550856 4.97683787,13.5347432 L4.97683787,13.5347432 L0.465256798,9.02316213 C-0.155085599,8.40281974 -0.155085599,7.387714 0.465256798,6.7673716 L0.465256798,6.7673716 L7.2326284,8.8817842e-15 L14,8.8817842e-15 Z M12.4209466,1.57905337 L7.90936556,1.57905337 L1.59315206,7.89526687 L6.10473313,12.4068479 L12.4209466,6.09063444 L12.4209466,1.57905337 Z M9.48841893,3.3836858 C9.79987861,3.07222612 10.3048545,3.07222612 10.6163142,3.3836858 C10.9277739,3.69514548 10.9277739,4.20012139 10.6163142,4.51158107 C10.3048545,4.82304075 9.79987861,4.82304075 9.48841893,4.51158107 C9.17695925,4.20012139 9.17695925,3.69514548 9.48841893,3.3836858 Z" id="Combined-Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@ -12,6 +12,10 @@
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
|
||||
&.no-padding-bottom .mat-menu-content:not(:empty) {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.mat-menu-item {
|
||||
font-size: 13px;
|
||||
color: $accent;
|
||||
|
||||
@ -79,126 +79,103 @@ body {
|
||||
height: calc(100% - 110px);
|
||||
z-index: 1;
|
||||
transition: height ease-in-out 0.2s;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
.overlay-shadow {
|
||||
@include inset-shadow;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
z-index: 1;
|
||||
.content-container {
|
||||
.overlay-shadow {
|
||||
@include inset-shadow;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
overflow: hidden;
|
||||
transition: width ease-in-out 0.2s, min-width ease-in-out 0.2s;
|
||||
position: relative;
|
||||
|
||||
&.extended {
|
||||
width: calc(100vw - 60px) !important;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
border-radius: 8px;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 70px;
|
||||
background-color: $white;
|
||||
max-width: 650px;
|
||||
height: fit-content;
|
||||
box-shadow: 0 1px 5px 0 rgba(40, 50, 65, 0.19);
|
||||
position: unset;
|
||||
|
||||
.heading-l {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
overflow: hidden;
|
||||
transition: width ease-in-out 0.2s, min-width ease-in-out 0.2s;
|
||||
position: relative;
|
||||
|
||||
&.extended {
|
||||
width: calc(100vw - 60px) !important;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
.dialog-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 120px;
|
||||
@include inset-shadow;
|
||||
|
||||
> mat-icon {
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
opacity: 0.1;
|
||||
.dialog-content-left {
|
||||
min-width: 300px;
|
||||
margin-right: 64px;
|
||||
}
|
||||
|
||||
.heading-l {
|
||||
color: $grey-7;
|
||||
}
|
||||
|
||||
> mat-icon,
|
||||
.heading-l {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog {
|
||||
border-radius: 8px;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 70px;
|
||||
background-color: $white;
|
||||
max-width: 650px;
|
||||
height: fit-content;
|
||||
box-shadow: 0 1px 5px 0 rgba(40, 50, 65, 0.19);
|
||||
position: unset;
|
||||
|
||||
.heading-l {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
display: flex;
|
||||
|
||||
.dialog-content-left {
|
||||
min-width: 300px;
|
||||
margin-right: 64px;
|
||||
}
|
||||
|
||||
.link-action {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1600px) {
|
||||
redaction-initials-avatar .username:not(.always-visible) {
|
||||
display: none;
|
||||
.link-action {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-container {
|
||||
border-left: 1px solid $grey-4;
|
||||
box-sizing: border-box;
|
||||
background: $white;
|
||||
z-index: 1;
|
||||
overflow: hidden;
|
||||
@include inset-shadow;
|
||||
transition: width ease-in-out 0.2s, min-width ease-in-out 0.2s;
|
||||
|
||||
&:hover {
|
||||
overflow-y: auto;
|
||||
@include scroll-bar;
|
||||
@media only screen and (max-width: 1600px) {
|
||||
redaction-initials-avatar .username:not(.always-visible) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.collapsed-wrapper {
|
||||
.right-container {
|
||||
border-left: 1px solid $grey-4;
|
||||
box-sizing: border-box;
|
||||
background: $white;
|
||||
z-index: 1;
|
||||
overflow: hidden;
|
||||
@include inset-shadow;
|
||||
transition: width ease-in-out 0.2s, min-width ease-in-out 0.2s;
|
||||
|
||||
&:hover {
|
||||
overflow-y: auto;
|
||||
@include scroll-bar;
|
||||
}
|
||||
|
||||
.collapsed-wrapper {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
width: 60px !important;
|
||||
min-width: 60px !important;
|
||||
display: flex;
|
||||
|
||||
div:not(.collapsed-wrapper) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
width: 60px !important;
|
||||
min-width: 60px;
|
||||
.collapsed-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 60px;
|
||||
|
||||
div:not(.collapsed-wrapper) {
|
||||
display: none;
|
||||
div {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.collapsed-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 60px;
|
||||
|
||||
div {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.all-caps-label {
|
||||
transform: rotate(90deg) translateX(50%);
|
||||
white-space: nowrap;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.all-caps-label {
|
||||
transform: rotate(90deg) translateX(50%);
|
||||
white-space: nowrap;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -337,19 +314,6 @@ body {
|
||||
margin-right: 8px !important;
|
||||
}
|
||||
|
||||
.empty-state-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 61px);
|
||||
position: relative;
|
||||
|
||||
> *:not(:last-child) {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.fit-content {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@ -12,17 +12,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.no-data {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
border-bottom: 1px solid $separator;
|
||||
|
||||
&.no-data {
|
||||
justify-content: space-between;
|
||||
padding: initial;
|
||||
&.no-data:not([synced='true']) {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
redaction-table-col-name:last-of-type {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user