Pull request #61: Admin upload download

Merge in RED/ui from admin-upload-download to master

* commit 'fdd551f361bb810ac62b1ba71373676061dfa471':
  Upload rules and dictionary
  Download rules and dictionary
This commit is contained in:
Timo Bejan 2020-12-09 14:24:15 +01:00
commit 25c6cb2fff
5 changed files with 106 additions and 7 deletions

View File

@ -6,7 +6,8 @@
<redaction-circle-button <redaction-circle-button
(action)="openDeleteDictionaryDialog($event)" (action)="openDeleteDictionaryDialog($event)"
*ngIf="permissionsService.isAdmin()" *ngIf="permissionsService.isAdmin()"
tooltip="dictionary-listing.action.delete" tooltip="dictionary-overview.action.delete"
tooltipPosition="below"
type="dark-bg" type="dark-bg"
icon="red:trash" icon="red:trash"
> >
@ -15,12 +16,30 @@
<redaction-circle-button <redaction-circle-button
(action)="openEditDictionaryDialog($event)" (action)="openEditDictionaryDialog($event)"
*ngIf="permissionsService.isAdmin()" *ngIf="permissionsService.isAdmin()"
tooltip="dictionary-listing.action.edit" tooltip="dictionary-overview.action.edit"
tooltipPosition="below"
type="dark-bg" type="dark-bg"
icon="red:edit" icon="red:edit"
> >
</redaction-circle-button> </redaction-circle-button>
<redaction-circle-button
(action)="download()"
tooltip="dictionary-overview.action.download"
tooltipPosition="below"
icon="red:download"
></redaction-circle-button>
<redaction-circle-button
*ngIf="permissionsService.isAdmin()"
(action)="fileInput.click()"
tooltip="dictionary-overview.action.upload"
tooltipPosition="below"
icon="red:upload"
></redaction-circle-button>
<input #fileInput (change)="upload($event)" hidden class="file-upload-input" type="file" accept="text/plain" />
<redaction-circle-button <redaction-circle-button
class="ml-6" class="ml-6"
[routerLink]="['/ui/admin/dictionaries/']" [routerLink]="['/ui/admin/dictionaries/']"

View File

@ -1,4 +1,4 @@
import { Component, ViewChild } from '@angular/core'; import { Component, ElementRef, ViewChild } from '@angular/core';
import { DictionaryControllerService, TypeValue } from '@redaction/red-ui-http'; import { DictionaryControllerService, TypeValue } from '@redaction/red-ui-http';
import { DialogService } from '../../../dialogs/dialog.service'; import { DialogService } from '../../../dialogs/dialog.service';
import { AppStateService } from '../../../state/app-state.service'; import { AppStateService } from '../../../state/app-state.service';
@ -9,6 +9,7 @@ import { debounce } from '../../../utils/debounce';
import { NotificationService, NotificationType } from '../../../notification/notification.service'; import { NotificationService, NotificationType } from '../../../notification/notification.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { saveAs } from 'file-saver';
declare var ace; declare var ace;
@ -41,6 +42,9 @@ export class DictionaryOverviewScreenComponent {
processing = true; processing = true;
@ViewChild('fileInput')
private _fileInput: ElementRef;
constructor( constructor(
public readonly permissionsService: PermissionsService, public readonly permissionsService: PermissionsService,
private readonly _notificationService: NotificationService, private readonly _notificationService: NotificationService,
@ -240,4 +244,25 @@ export class DictionaryOverviewScreenComponent {
this.editorComponent.getEditor().scrollToLine(position.row, true, true, () => {}); this.editorComponent.getEditor().scrollToLine(position.row, true, true, () => {});
this.editorComponent.getEditor().gotoLine(position.row + 1, position.column, true); this.editorComponent.getEditor().gotoLine(position.row + 1, position.column, true);
} }
public download(): void {
const content = this.editorComponent.getEditor().getValue();
const blob = new Blob([content], {
type: 'text/plain;charset=utf-8'
});
saveAs(blob, `${this.dictionary.label}.txt`);
}
public upload($event): void {
const file = $event.target.files[0];
const fileReader = new FileReader();
if (file) {
fileReader.onload = () => {
this.editorComponent.getEditor().setValue(fileReader.result);
this._fileInput.nativeElement.value = null;
};
fileReader.readAsText(file);
}
}
} }

View File

@ -2,6 +2,24 @@
<div class="page-header"> <div class="page-header">
<redaction-admin-breadcrumbs></redaction-admin-breadcrumbs> <redaction-admin-breadcrumbs></redaction-admin-breadcrumbs>
<div class="actions"> <div class="actions">
<redaction-circle-button
(action)="download()"
tooltip="rules-screen.action.download"
tooltipPosition="below"
icon="red:download"
></redaction-circle-button>
<redaction-circle-button
(action)="fileInput.click()"
*ngIf="permissionsService.isAdmin()"
tooltip="rules-screen.action.upload"
tooltipPosition="below"
icon="red:upload"
>
</redaction-circle-button>
<input #fileInput (change)="upload($event)" hidden class="file-upload-input" type="file" accept="text/plain" />
<redaction-circle-button <redaction-circle-button
class="ml-6" class="ml-6"
*ngIf="permissionsService.isUser()" *ngIf="permissionsService.isUser()"
@ -33,13 +51,13 @@
*ngIf="permissionsService.isAdmin()" *ngIf="permissionsService.isAdmin()"
icon="red:check" icon="red:check"
(action)="save()" (action)="save()"
text="dictionary-overview.save-changes" text="rules-screen.save-changes"
[primary]="true" [primary]="true"
></redaction-icon-button> ></redaction-icon-button>
<redaction-icon-button <redaction-icon-button
*ngIf="permissionsService.isAdmin()" *ngIf="permissionsService.isAdmin()"
(action)="revert()" (action)="revert()"
text="dictionary-overview.revert-changes" text="rules-screen.revert-changes"
[linkButton]="true" [linkButton]="true"
></redaction-icon-button> ></redaction-icon-button>
</div> </div>

View File

@ -1,9 +1,10 @@
import { Component, ViewChild } from '@angular/core'; import { Component, ElementRef, ViewChild } from '@angular/core';
import { PermissionsService } from '../../../common/service/permissions.service'; import { PermissionsService } from '../../../common/service/permissions.service';
import { AceEditorComponent } from 'ng2-ace-editor'; import { AceEditorComponent } from 'ng2-ace-editor';
import { RulesControllerService } from '@redaction/red-ui-http'; import { RulesControllerService } from '@redaction/red-ui-http';
import { NotificationService, NotificationType } from '../../../notification/notification.service'; import { NotificationService, NotificationType } from '../../../notification/notification.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { saveAs } from 'file-saver';
declare var ace; declare var ace;
@ -25,6 +26,9 @@ export class RulesScreenComponent {
@ViewChild('editorComponent', { static: true }) @ViewChild('editorComponent', { static: true })
editorComponent: AceEditorComponent; editorComponent: AceEditorComponent;
@ViewChild('fileInput')
private _fileInput: ElementRef;
constructor( constructor(
public readonly permissionsService: PermissionsService, public readonly permissionsService: PermissionsService,
private readonly _rulesControllerService: RulesControllerService, private readonly _rulesControllerService: RulesControllerService,
@ -95,4 +99,25 @@ export class RulesScreenComponent {
this.editorComponent.getEditor().clearSelection(); this.editorComponent.getEditor().clearSelection();
this.processing = false; this.processing = false;
} }
public download(): void {
const content = this.editorComponent.getEditor().getValue();
const blob = new Blob([content], {
type: 'text/plain;charset=utf-8'
});
saveAs(blob, 'rules.txt');
}
public upload($event): void {
const file = $event.target.files[0];
const fileReader = new FileReader();
if (file) {
fileReader.onload = () => {
this.editorComponent.getEditor().setValue(fileReader.result);
this._fileInput.nativeElement.value = null;
};
fileReader.readAsText(file);
}
}
} }

View File

@ -503,6 +503,12 @@
"save": "Save Dictionary" "save": "Save Dictionary"
}, },
"dictionary-overview": { "dictionary-overview": {
"action": {
"delete": "Delete Dictionary",
"edit": "Edit Dictionary",
"download": "Download Dictionary",
"upload": "Upload Dictionary"
},
"error": { "error": {
"entries-too-short": "Some entries of the dictionary are below the minimum length of 2. These are highlighted with red!", "entries-too-short": "Some entries of the dictionary are below the minimum length of 2. These are highlighted with red!",
"generic": "Something went wrong... Dictionary update failed!" "generic": "Something went wrong... Dictionary update failed!"
@ -552,7 +558,13 @@
}, },
"success": { "success": {
"generic": "Rules updated!" "generic": "Rules updated!"
} },
"action": {
"download": "Download Rules",
"upload": "Upload Rules"
},
"save-changes": "Save Changes",
"revert-changes": "Revert"
}, },
"dictionaries": "Dictionaries", "dictionaries": "Dictionaries",
"user-management": "User Management", "user-management": "User Management",