Pull request #110: Downloads list screen

Merge in RED/ui from downloads-list to master

* commit '8f6c0cb61415299197f42c14e8938a74116380a0':
  Downloads list screen
This commit is contained in:
Timo Bejan 2021-01-28 10:44:00 +01:00
commit ef2296a663
17 changed files with 186 additions and 20 deletions

View File

@ -109,6 +109,7 @@ import { FileDownloadBtnComponent } from './components/buttons/file-download-btn
import { LicenseInformationScreenComponent } from './screens/admin/license-information-screen/license-information-screen.component';
import { DefaultColorsScreenComponent } from './screens/admin/default-colors-screen/default-colors-screen.component';
import { EditColorDialogComponent } from './screens/admin/default-colors-screen/edit-color-dialog/edit-color-dialog.component';
import { DownloadsListScreenComponent } from './screens/downloads-list-screen/downloads-list-screen.component';
export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
@ -170,6 +171,14 @@ const routes = [
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
}
},
{
path: 'downloads',
component: DownloadsListScreenComponent,
canActivate: [CompositeRouteGuard],
data: {
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
}
},
{
path: 'admin',
children: [
@ -350,7 +359,8 @@ const matImports = [
RuleSetViewSwitchComponent,
LicenseInformationScreenComponent,
DefaultColorsScreenComponent,
EditColorDialogComponent
EditColorDialogComponent,
DownloadsListScreenComponent
],
imports: [
BrowserModule,

View File

@ -1,4 +1,5 @@
<button mat-button>
<button mat-button [class.overlay]="showDot">
<redaction-initials-avatar size="small" [userId]="user?.id" [withName]="true"></redaction-initials-avatar>
<mat-icon svgIcon="red:arrow-down"></mat-icon>
</button>
<div class="dot" *ngIf="showDot"></div>

View File

@ -3,11 +3,6 @@
:host {
button {
padding: 0 10px 0 5px;
font-weight: 400 !important;
&:hover {
background-color: $grey-6;
}
mat-icon {
width: 14px;
@ -19,4 +14,8 @@
background: rgba($primary, 0.1);
}
}
.dot {
left: -2px;
}
}

View File

@ -8,6 +8,7 @@ import { UserWrapper } from '../../../user/user.service';
})
export class UserButtonComponent implements OnInit {
@Input() user: UserWrapper;
@Input() showDot = false;
constructor() {}

View File

@ -1,4 +1,4 @@
<div class="">
<div>
<div class="red-input-group slider-row">
<mat-button-toggle-group [value]="screen" (change)="switchView($event)" appearance="legacy">
<mat-button-toggle [value]="'dictionaries'"> {{ 'dictionaries' | translate }}</mat-button-toggle>

View File

@ -30,13 +30,13 @@
<redaction-table-col-name label="default-colors-screen.table-col-names.color" class="flex-center"></redaction-table-col-name>
<div class="placeholder-bottom-border"></div>
<div class="placeholder-bottom-border scrollbar-placeholder"></div>
<div></div>
<div class="scrollbar-placeholder"></div>
</div>
<div class="grid-container" redactionHasScrollbar>
<!-- Table lines -->
<div class="table-item pointer" *ngFor="let color of colors | sortBy: sortingOption.order:sortingOption.column" [routerLink]="[color.type]">
<div class="table-item" *ngFor="let color of colors | sortBy: sortingOption.order:sortingOption.column">
<div>
<div class="table-item-title heading" [translate]="'default-colors-screen.types.' + color.key"></div>
</div>

View File

@ -69,7 +69,7 @@
</div>
<div class="table-header" redactionSyncWidth="table-item">
<div class="select-oval-placeholder placeholder-bottom-border"></div>
<div class="select-oval-placeholder"></div>
<redaction-table-col-name
label="dictionary-listing.table-col-names.type"
@ -89,8 +89,8 @@
></redaction-table-col-name>
<redaction-table-col-name label="dictionary-listing.table-col-names.hint-redaction" class="flex-center"></redaction-table-col-name>
<div class="placeholder-bottom-border"></div>
<div class="placeholder-bottom-border scrollbar-placeholder"></div>
<div></div>
<div class="scrollbar-placeholder"></div>
</div>
<div class="grid-container" redactionHasScrollbar>

View File

@ -60,7 +60,7 @@
</div>
<div class="table-header" redactionSyncWidth="table-item">
<div class="select-oval-placeholder placeholder-bottom-border"></div>
<div class="select-oval-placeholder"></div>
<redaction-table-col-name
label="project-templates-listing.table-col-names.name"
@ -84,7 +84,7 @@
[activeSortingOption]="sortingOption"
[withSort]="true"
></redaction-table-col-name>
<div class="placeholder-bottom-border scrollbar-placeholder"></div>
<div class="scrollbar-placeholder"></div>
</div>
<div class="grid-container" redactionHasScrollbar>

View File

@ -34,7 +34,7 @@
<redaction-table-col-name label="user-listing.table-col-names.email"></redaction-table-col-name>
<div class="placeholder-bottom-border scrollbar-placeholder"></div>
<div class="scrollbar-placeholder"></div>
</div>
<div class="grid-container" redactionHasScrollbar>

View File

@ -69,7 +69,11 @@
</div>
<div class="menu right flex-2">
<redaction-notifications class="mr-8" *ngIf="userPreferenceService.areDevFeaturesEnabled"></redaction-notifications>
<redaction-user-button [user]="user" [matMenuTriggerFor]="userMenu"></redaction-user-button>
<redaction-user-button
[user]="user"
[matMenuTriggerFor]="userMenu"
[showDot]="userPreferenceService.areDevFeaturesEnabled && appStateService.readyDownloads.length > 0"
></redaction-user-button>
<mat-menu #userMenu="matMenu">
<button
*ngIf="permissionsService.isManager()"
@ -78,6 +82,12 @@
mat-menu-item
translate="top-bar.navigation-items.my-account.children.admin"
></button>
<button
*ngIf="!permissionsService.isAdmin() && userPreferenceService.areDevFeaturesEnabled"
[routerLink]="'/ui/downloads'"
mat-menu-item
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 (click)="changeLanguage('en')" mat-menu-item translate="top-bar.navigation-items.my-account.children.language.english"></button>

View File

@ -0,0 +1,64 @@
<section>
<div class="page-header">
<div class="actions flex-1">
<redaction-circle-button [routerLink]="['../..']" tooltip="common.close" tooltipPosition="before" icon="red:close"></redaction-circle-button>
</div>
</div>
<div class="red-content-inner">
<div class="left-container">
<div class="header-item">
<span class="all-caps-label">
{{ 'downloads-list.table-header.title' | translate: { length: appStateService.allDownloads.length } }}
</span>
</div>
<div [class.no-data]="noData" class="table-header" redactionSyncWidth="table-item">
<redaction-table-col-name label="downloads-list.table-col-names.name"></redaction-table-col-name>
<redaction-table-col-name label="downloads-list.table-col-names.type"></redaction-table-col-name>
<redaction-table-col-name label="downloads-list.table-col-names.date"></redaction-table-col-name>
<redaction-table-col-name label="downloads-list.table-col-names.status"></redaction-table-col-name>
<div></div>
<div class="scrollbar-placeholder"></div>
</div>
<div *ngIf="noData" class="no-data heading-l" translate="downloads-list.no-data"></div>
<div class="grid-container" redactionHasScrollbar>
<!-- Table lines -->
<div *ngFor="let download of appStateService.allDownloads" class="table-item">
<div>
<div class="table-item-title heading">{{ download.name }}</div>
</div>
<div>
{{ download.type }}
</div>
<div>
<div class="small-label">
{{ download.date | date: 'd MMM. yyyy, hh:mm a' }}
</div>
</div>
<div>
<div class="small-label">
{{ download.status }}
</div>
</div>
<div class="actions-container">
<div class="action-buttons">
<redaction-circle-button
*ngIf="download.status === 'ready'"
(action)="downloadItem(download)"
tooltip="downloads-list.actions.download"
tooltipPosition="before"
type="dark-bg"
icon="red:download"
>
</redaction-circle-button>
</div>
</div>
<div class="scrollbar-placeholder"></div>
</div>
</div>
</div>
</div>
</section>

View File

@ -0,0 +1,21 @@
.left-container {
width: 100vw;
.grid-container {
grid-template-columns: 2fr 1fr 1fr 1fr auto 11px;
&.has-scrollbar:hover {
grid-template-columns: 2fr 1fr 1fr 1fr auto;
}
.table-item {
> div:not(.scrollbar-placeholder) {
padding-left: 24px;
}
}
}
}
.page-header .actions {
justify-content: flex-end;
}

View File

@ -0,0 +1,21 @@
import { Component } from '@angular/core';
import { AppStateService, Download } from '../../state/app-state.service';
@Component({
selector: 'redaction-downloads-list-screen',
templateUrl: './downloads-list-screen.component.html',
styleUrls: ['./downloads-list-screen.component.scss']
})
export class DownloadsListScreenComponent {
constructor(public appStateService: AppStateService) {
this.appStateService.reset();
}
public get noData(): boolean {
return this.appStateService.allDownloads.length === 0;
}
public downloadItem(download: Download) {
console.log('downloading', download);
}
}

View File

@ -123,7 +123,7 @@
<div class="table-header" redactionSyncWidth="table-item" [class.no-data]="noData">
<!-- Table column names-->
<div class="select-oval-placeholder placeholder-bottom-border"></div>
<div class="select-oval-placeholder"></div>
<redaction-table-col-name
(toggleSort)="toggleSort($event)"

View File

@ -23,6 +23,14 @@ import { FileStatusWrapper } from '../screens/file/model/file-status.wrapper';
import { ProjectWrapper } from './model/project.wrapper';
import { saveAs } from 'file-saver';
export interface Download {
name: string;
type: string;
date: Date;
status: string;
id: string;
}
export interface AppState {
projects: ProjectWrapper[];
ruleSets: RuleSetModel[];
@ -33,6 +41,7 @@ export interface AppState {
totalAnalysedPages?: number;
totalDocuments?: number;
totalPeople?: number;
downloads: Download[];
versions: { [key: string]: { dictionaryVersion?: number; rulesVersion?: number } };
}
@ -65,7 +74,12 @@ export class AppStateService {
activeFileId: null,
activeRuleSetId: null,
activeDictionaryType: null,
versions: {}
versions: {},
downloads: [
{ name: 'Download 1', id: '1', date: new Date(), status: 'processing', type: 'project' },
{ name: 'Download 2', id: '2', date: new Date(), status: 'queued', type: 'project' },
{ name: 'Download 3', id: '3', date: new Date(), status: 'ready', type: 'project' }
]
};
}
@ -125,6 +139,14 @@ export class AppStateService {
return result;
}
get allDownloads(): Download[] {
return this._appState.downloads;
}
get readyDownloads(): Download[] {
return this._appState.downloads.filter((d) => d.status === 'ready');
}
get activeRuleSetId(): string {
return this._appState.activeRuleSetId;
}

View File

@ -61,6 +61,7 @@
"my-account": {
"children": {
"admin": "Settings",
"downloads": "My Downloads",
"language": {
"label": "Language",
"english": "English",
@ -785,5 +786,20 @@
"color": "Color",
"color-placeholder": "Color"
}
},
"downloads-list": {
"table-header": {
"title": "{{length}} downloads"
},
"no-data": "No active downloads.",
"table-col-names": {
"name": "Name",
"type": "Type",
"date": "Date",
"status": "Status"
},
"actions": {
"download": "Download"
}
}
}

View File

@ -53,6 +53,7 @@
redaction-icon-button,
redaction-chevron-button,
redaction-user-button,
redaction-circle-button {
position: relative;
display: flex;