diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts
index 55655d7ed..27079af96 100644
--- a/apps/red-ui/src/app/app.module.ts
+++ b/apps/red-ui/src/app/app.module.ts
@@ -108,6 +108,8 @@ import { OverwriteFilesDialogComponent } from './dialogs/overwrite-files-dialog/
import { KeycloakService } from 'keycloak-angular';
import { FileDownloadBtnComponent } from './components/buttons/file-download-btn/file-download-btn.component';
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';
export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
@@ -230,6 +232,14 @@ const routes = [
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
}
},
+ {
+ path: 'default-colors',
+ component: DefaultColorsScreenComponent,
+ canActivate: [CompositeRouteGuard],
+ data: {
+ routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
+ }
+ },
{ path: '', redirectTo: 'dictionaries', pathMatch: 'full' }
]
}
@@ -344,7 +354,9 @@ const matImports = [
ProjectListingActionsComponent,
RuleSetActionsComponent,
RuleSetViewSwitchComponent,
- LicenseInformationScreenComponent
+ LicenseInformationScreenComponent,
+ DefaultColorsScreenComponent,
+ EditColorDialogComponent
],
imports: [
BrowserModule,
diff --git a/apps/red-ui/src/app/components/rule-set-actions/rule-set-actions.component.html b/apps/red-ui/src/app/components/rule-set-actions/rule-set-actions.component.html
index 04d19f2f8..22df77320 100644
--- a/apps/red-ui/src/app/components/rule-set-actions/rule-set-actions.component.html
+++ b/apps/red-ui/src/app/components/rule-set-actions/rule-set-actions.component.html
@@ -1,6 +1,6 @@
();
constructor(
@@ -20,28 +19,32 @@ export class RuleSetActionsComponent implements OnInit {
private readonly _router: Router,
public readonly permissionsService: PermissionsService
) {
- if (!this.ruleSet) {
- this.ruleSet = this._appStateService.activeRuleSet;
+ if (!this.ruleSetId) {
+ this.ruleSetId = this._appStateService.activeRuleSetId;
}
}
- ngOnInit(): void {}
+ public get ruleSet() {
+ return this._appStateService.getRuleSetById(this.ruleSetId);
+ }
- openEditRuleSetDialog($event: any, ruleSet: RuleSetModel) {
+ openEditRuleSetDialog($event: any) {
$event.stopPropagation();
- this._dialogService.openAddEditRuleSetDialog(ruleSet, async (newRuleSet) => {
- if (newRuleSet) {
+ this._dialogService.openAddEditRuleSetDialog(this.ruleSet, async (newRuleSet) => {
+ if (newRuleSet && this.loadRuleSetsData) {
this.loadRuleSetsData.emit();
}
});
}
- openDeleteRuleSetDialog($event: any, ruleSet: RuleSetModel) {
- this._dialogService.openDeleteRuleSetDialog($event, ruleSet, async () => {
+ openDeleteRuleSetDialog($event: any) {
+ this._dialogService.openDeleteRuleSetDialog($event, this.ruleSet, async () => {
await this._appStateService.loadAllRuleSets();
await this._appStateService.loadDictionaryData();
await this._router.navigate(['ui', 'admin']);
- this.loadRuleSetsData.emit();
+ if (this.loadRuleSetsData) {
+ this.loadRuleSetsData.emit();
+ }
});
}
}
diff --git a/apps/red-ui/src/app/components/rule-set-view-switch/rule-set-view-switch.component.html b/apps/red-ui/src/app/components/rule-set-view-switch/rule-set-view-switch.component.html
index c4596349b..d4963056f 100644
--- a/apps/red-ui/src/app/components/rule-set-view-switch/rule-set-view-switch.component.html
+++ b/apps/red-ui/src/app/components/rule-set-view-switch/rule-set-view-switch.component.html
@@ -3,6 +3,7 @@
{{ 'dictionaries' | translate }}
{{ 'rule-editor' | translate }}
+ {{ 'default-colors' | translate }}
{{ 'watermark' | translate }}
diff --git a/apps/red-ui/src/app/components/rule-set-view-switch/rule-set-view-switch.component.ts b/apps/red-ui/src/app/components/rule-set-view-switch/rule-set-view-switch.component.ts
index 57b78173b..7ff1508c8 100644
--- a/apps/red-ui/src/app/components/rule-set-view-switch/rule-set-view-switch.component.ts
+++ b/apps/red-ui/src/app/components/rule-set-view-switch/rule-set-view-switch.component.ts
@@ -9,7 +9,7 @@ import { UserPreferenceService } from '../../common/service/user-preference.serv
styleUrls: ['./rule-set-view-switch.component.scss']
})
export class RuleSetViewSwitchComponent implements OnInit {
- @Input() public screen: 'rules' | 'dictionaries' | 'watermark';
+ @Input() public screen: 'rules' | 'dictionaries' | 'watermark' | 'default-colors';
constructor(
public readonly userPreferenceService: UserPreferenceService,
diff --git a/apps/red-ui/src/app/dialogs/dialog.service.ts b/apps/red-ui/src/app/dialogs/dialog.service.ts
index 5c82b0e2f..b1db7ce03 100644
--- a/apps/red-ui/src/app/dialogs/dialog.service.ts
+++ b/apps/red-ui/src/app/dialogs/dialog.service.ts
@@ -1,6 +1,7 @@
import { Injectable } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import {
+ Colors,
DictionaryControllerService,
FileManagementControllerService,
FileStatus,
@@ -23,6 +24,7 @@ import { ProjectWrapper } from '../state/model/project.wrapper';
import { AddEditDictionaryDialogComponent } from '../screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component';
import { AddEditRuleSetDialogComponent } from '../screens/admin/rule-sets-listing-screen/add-edit-rule-set-dialog/add-edit-rule-set-dialog.component';
import { OverwriteFilesDialogComponent } from './overwrite-files-dialog/overwrite-files-dialog.component';
+import { EditColorDialogComponent } from '../screens/admin/default-colors-screen/edit-color-dialog/edit-color-dialog.component';
const dialogConfig = {
width: '662px',
@@ -293,6 +295,22 @@ export class DialogService {
return ref;
}
+ public openEditColorsDialog(colors: Colors, colorKey: string, ruleSetId: string, cb?: Function): MatDialogRef {
+ const ref = this._dialog.open(EditColorDialogComponent, {
+ ...dialogConfig,
+ data: { colors, colorKey, ruleSetId },
+ autoFocus: true
+ });
+
+ ref.afterClosed().subscribe((result) => {
+ if (result && cb) {
+ cb(result);
+ }
+ });
+
+ return ref;
+ }
+
public openAddEditRuleSetDialog(ruleSet: RuleSetModel, cb?: Function): MatDialogRef {
const ref = this._dialog.open(AddEditRuleSetDialogComponent, {
...dialogConfig,
diff --git a/apps/red-ui/src/app/screens/admin/default-colors-screen/default-colors-screen.component.html b/apps/red-ui/src/app/screens/admin/default-colors-screen/default-colors-screen.component.html
new file mode 100644
index 000000000..bea85b27f
--- /dev/null
+++ b/apps/red-ui/src/app/screens/admin/default-colors-screen/default-colors-screen.component.html
@@ -0,0 +1,67 @@
+
+
+
diff --git a/apps/red-ui/src/app/screens/admin/default-colors-screen/default-colors-screen.component.scss b/apps/red-ui/src/app/screens/admin/default-colors-screen/default-colors-screen.component.scss
new file mode 100644
index 000000000..217b76e67
--- /dev/null
+++ b/apps/red-ui/src/app/screens/admin/default-colors-screen/default-colors-screen.component.scss
@@ -0,0 +1,32 @@
+.left-container {
+ width: 100vw;
+
+ .grid-container {
+ grid-template-columns: 2fr 1fr 2fr 11px;
+
+ &.has-scrollbar:hover {
+ grid-template-columns: 2fr 1fr 2fr;
+ }
+
+ .table-item {
+ > div:not(.scrollbar-placeholder) {
+ padding-left: 24px;
+ }
+
+ .color-wrapper {
+ align-items: center;
+
+ .color-square {
+ width: 16px;
+ height: 16px;
+ min-width: 16px;
+ }
+ }
+ }
+ }
+}
+
+.page-header .actions {
+ display: flex;
+ justify-content: flex-end;
+}
diff --git a/apps/red-ui/src/app/screens/admin/default-colors-screen/default-colors-screen.component.ts b/apps/red-ui/src/app/screens/admin/default-colors-screen/default-colors-screen.component.ts
new file mode 100644
index 000000000..eb686c824
--- /dev/null
+++ b/apps/red-ui/src/app/screens/admin/default-colors-screen/default-colors-screen.component.ts
@@ -0,0 +1,63 @@
+import { Component } from '@angular/core';
+import { AppStateService } from '../../../state/app-state.service';
+import { Colors, DictionaryControllerService, TypeValue } from '@redaction/red-ui-http';
+import { ActivatedRoute } from '@angular/router';
+import { SortingOption, SortingService } from '../../../utils/sorting.service';
+import { PermissionsService } from '../../../common/service/permissions.service';
+import { DialogService } from '../../../dialogs/dialog.service';
+
+@Component({
+ selector: 'redaction-default-colors-screen',
+ templateUrl: './default-colors-screen.component.html',
+ styleUrls: ['./default-colors-screen.component.scss']
+})
+export class DefaultColorsScreenComponent {
+ public viewReady = false;
+ private _colorsObj: Colors;
+ public colors: { key: string; value: string }[] = [];
+
+ constructor(
+ private readonly _appStateService: AppStateService,
+ private readonly _activatedRoute: ActivatedRoute,
+ private readonly _dictionaryControllerService: DictionaryControllerService,
+ private readonly _sortingService: SortingService,
+ private readonly _dialogService: DialogService,
+ public readonly permissionsService: PermissionsService
+ ) {
+ this._appStateService.activateRuleSet(_activatedRoute.snapshot.params.ruleSetId);
+ this._loadColors();
+ }
+
+ public get sortingOption(): SortingOption {
+ return this._sortingService.getSortingOption('default-colors');
+ }
+
+ public toggleSort($event) {
+ this._sortingService.toggleSort('default-colors', $event);
+ }
+
+ public async loadRuleSetsData(): Promise {
+ await this._appStateService.loadAllRuleSets();
+ }
+
+ private _loadColors() {
+ this._dictionaryControllerService
+ .getColors(this._appStateService.activeRuleSetId)
+ .toPromise()
+ .then((data) => {
+ this._colorsObj = data;
+ this.colors = Object.keys(data).map((key) => ({
+ key,
+ value: data[key]
+ }));
+ this.viewReady = true;
+ });
+ }
+
+ openEditColorDialog($event: any, color: { key: string; value: string }) {
+ $event.stopPropagation();
+ this._dialogService.openEditColorsDialog(this._colorsObj, color.key, this._appStateService.activeRuleSetId, async () => {
+ this._loadColors();
+ });
+ }
+}
diff --git a/apps/red-ui/src/app/screens/admin/default-colors-screen/edit-color-dialog/edit-color-dialog.component.html b/apps/red-ui/src/app/screens/admin/default-colors-screen/edit-color-dialog/edit-color-dialog.component.html
new file mode 100644
index 000000000..e2ef05935
--- /dev/null
+++ b/apps/red-ui/src/app/screens/admin/default-colors-screen/edit-color-dialog/edit-color-dialog.component.html
@@ -0,0 +1,35 @@
+
diff --git a/apps/red-ui/src/app/screens/admin/default-colors-screen/edit-color-dialog/edit-color-dialog.component.scss b/apps/red-ui/src/app/screens/admin/default-colors-screen/edit-color-dialog/edit-color-dialog.component.scss
new file mode 100644
index 000000000..06e7fa1ed
--- /dev/null
+++ b/apps/red-ui/src/app/screens/admin/default-colors-screen/edit-color-dialog/edit-color-dialog.component.scss
@@ -0,0 +1,3 @@
+.red-input-group {
+ width: fit-content;
+}
diff --git a/apps/red-ui/src/app/screens/admin/default-colors-screen/edit-color-dialog/edit-color-dialog.component.ts b/apps/red-ui/src/app/screens/admin/default-colors-screen/edit-color-dialog/edit-color-dialog.component.ts
new file mode 100644
index 000000000..d7290ff44
--- /dev/null
+++ b/apps/red-ui/src/app/screens/admin/default-colors-screen/edit-color-dialog/edit-color-dialog.component.ts
@@ -0,0 +1,60 @@
+import { Component, Inject } from '@angular/core';
+import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
+import { Colors, DictionaryControllerService } from '@redaction/red-ui-http';
+import { NotificationService, NotificationType } from '../../../../notification/notification.service';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { TranslateService } from '@ngx-translate/core';
+
+@Component({
+ selector: 'redaction-edit-color-dialog',
+ templateUrl: './edit-color-dialog.component.html',
+ styleUrls: ['./edit-color-dialog.component.scss']
+})
+export class EditColorDialogComponent {
+ public readonly colors: Colors;
+ public readonly colorKey: string;
+ private readonly _initialColor: string;
+ private readonly _ruleSetId: string;
+ public colorForm: FormGroup;
+
+ constructor(
+ private readonly _formBuilder: FormBuilder,
+ private readonly _dictionaryControllerService: DictionaryControllerService,
+ private readonly _notificationService: NotificationService,
+ private readonly _translateService: TranslateService,
+ public dialogRef: MatDialogRef,
+ @Inject(MAT_DIALOG_DATA) public data: { colors: Colors; colorKey: string; ruleSetId: string }
+ ) {
+ this.colors = data.colors;
+ this.colorKey = data.colorKey;
+ this._ruleSetId = data.ruleSetId;
+ this._initialColor = data.colors[this.colorKey];
+
+ this.colorForm = this._formBuilder.group({
+ color: [this.colors[this.colorKey], [Validators.required, Validators.minLength(7)]]
+ });
+ }
+
+ public get changed(): boolean {
+ return this.colorForm.get('color').value !== this._initialColor;
+ }
+
+ async saveColors() {
+ const colors = {
+ ...this.colors,
+ [this.colorKey]: this.colorForm.get('color').value
+ };
+
+ try {
+ await this._dictionaryControllerService.setColors(colors, this._ruleSetId).toPromise();
+ this.dialogRef.close(true);
+ this._notificationService.showToastNotification(
+ this._translateService.instant('edit-color-dialog.success', {
+ color: this._translateService.instant('default-colors-screen.types.' + this.colorKey)
+ })
+ );
+ } catch (e) {
+ this._notificationService.showToastNotification(this._translateService.instant('edit-color-dialog.error'), null, NotificationType.ERROR);
+ }
+ }
+}
diff --git a/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/dictionary-listing-screen.component.html b/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/dictionary-listing-screen.component.html
index 4ccb548bb..d093da2ce 100644
--- a/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/dictionary-listing-screen.component.html
+++ b/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/dictionary-listing-screen.component.html
@@ -5,7 +5,7 @@
-
+
diff --git a/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/dictionary-listing-screen.component.ts b/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/dictionary-listing-screen.component.ts
index ea920cff6..b511b141a 100644
--- a/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/dictionary-listing-screen.component.ts
+++ b/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/dictionary-listing-screen.component.ts
@@ -142,8 +142,4 @@ export class DictionaryListingScreenComponent implements OnInit {
this._loadDictionaryData();
});
}
-
- public async loadRuleSetsData(): Promise {
- await this._appStateService.loadAllRuleSets();
- }
}
diff --git a/apps/red-ui/src/app/screens/admin/rule-sets-listing-screen/rule-sets-listing-screen.component.html b/apps/red-ui/src/app/screens/admin/rule-sets-listing-screen/rule-sets-listing-screen.component.html
index 2db5280cc..72a6cb048 100644
--- a/apps/red-ui/src/app/screens/admin/rule-sets-listing-screen/rule-sets-listing-screen.component.html
+++ b/apps/red-ui/src/app/screens/admin/rule-sets-listing-screen/rule-sets-listing-screen.component.html
@@ -128,7 +128,7 @@
diff --git a/apps/red-ui/src/app/screens/admin/rules-screen/rules-screen.component.html b/apps/red-ui/src/app/screens/admin/rules-screen/rules-screen.component.html
index cdfdb09c7..3fb484ad7 100644
--- a/apps/red-ui/src/app/screens/admin/rules-screen/rules-screen.component.html
+++ b/apps/red-ui/src/app/screens/admin/rules-screen/rules-screen.component.html
@@ -5,7 +5,7 @@
-
+
diff --git a/apps/red-ui/src/app/screens/admin/rules-screen/rules-screen.component.ts b/apps/red-ui/src/app/screens/admin/rules-screen/rules-screen.component.ts
index 1fafe16cc..33be7fbc2 100644
--- a/apps/red-ui/src/app/screens/admin/rules-screen/rules-screen.component.ts
+++ b/apps/red-ui/src/app/screens/admin/rules-screen/rules-screen.component.ts
@@ -133,8 +133,4 @@ export class RulesScreenComponent extends ComponentHasChanges {
fileReader.readAsText(file);
}
}
-
- public loadRuleSetsData(): void {
- console.log('load rule sets data');
- }
}
diff --git a/apps/red-ui/src/app/utils/sorting.service.ts b/apps/red-ui/src/app/utils/sorting.service.ts
index 0ab24c33b..45ffa97a8 100644
--- a/apps/red-ui/src/app/utils/sorting.service.ts
+++ b/apps/red-ui/src/app/utils/sorting.service.ts
@@ -5,7 +5,7 @@ export class SortingOption {
column: string;
}
-type Screen = 'project-listing' | 'project-overview' | 'dictionary-listing' | 'rule-sets-listing';
+type Screen = 'project-listing' | 'project-overview' | 'dictionary-listing' | 'rule-sets-listing' | 'default-colors';
@Injectable({
providedIn: 'root'
@@ -15,7 +15,8 @@ export class SortingService {
'project-listing': { column: 'project.projectName', order: 'asc' },
'project-overview': { column: 'filename', order: 'asc' },
'dictionary-listing': { column: 'label', order: 'asc' },
- 'rule-sets-listing': { column: 'name', order: 'asc' }
+ 'rule-sets-listing': { column: 'name', order: 'asc' },
+ 'default-colors': { column: 'key', order: 'asc' }
};
constructor() {}
diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json
index c266e6bc9..5fd919082 100644
--- a/apps/red-ui/src/assets/i18n/en.json
+++ b/apps/red-ui/src/assets/i18n/en.json
@@ -757,5 +757,33 @@
"total-analyzed": "Total Analyzed Pages Since {{date}}",
"current-analyzed": "Analyzed Pages in Current Licensing Period",
"unlicensed-analyzed": "Unlicensed Analyzed Pages"
+ },
+ "default-colors": "Default Colors",
+ "default-colors-screen": {
+ "table-header": {
+ "title": "{{length}} Default Colors"
+ },
+ "table-col-names": {
+ "key": "Type",
+ "color": "Color"
+ },
+ "types": {
+ "defaultColor": "Default Color",
+ "requestAdd": "Request Add",
+ "requestRemove": "Request Remove",
+ "notRedacted": "Not Redacted"
+ },
+ "action": {
+ "edit": "Edit Color"
+ }
+ },
+ "edit-color-dialog": {
+ "success": "Successfully updated color for {{color}}.",
+ "error": "Failed to update colors.",
+ "save": "Save",
+ "form": {
+ "color": "Color",
+ "color-placeholder": "Color"
+ }
}
}