change download file types and report types form fields UI

This commit is contained in:
Dan Percic 2021-04-28 21:18:16 +03:00
parent 896cfef736
commit d8a299711a
16 changed files with 241 additions and 72 deletions

View File

@ -10,28 +10,6 @@
<input formControlName="name" name="name" type="text" placeholder="{{ 'add-edit-project-template.form.name-placeholder' | translate }}" />
</div>
<div class="red-input-group w-400">
<mat-form-field floatLabel="always">
<mat-label>{{ 'add-edit-project-template.form.download-file-types.label' | translate }}</mat-label>
<mat-select formControlName="downloadFileTypes" style="width: 100%;" multiple>
<mat-option *ngFor="let type of downloadTypesEnum" [value]="type">
{{ 'download-type.' + type | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="red-input-group required w-400">
<mat-form-field floatLabel="always">
<mat-label>{{ 'add-edit-project-template.form.report-types.label' | translate }}</mat-label>
<mat-select formControlName="reportTypes" style="width: 100%;" multiple>
<mat-option *ngFor="let type of reportTypesEnum" [value]="type">
{{ 'report-type.' + type | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="red-input-group w-400">
<label translate="add-edit-project-template.form.description"></label>
<textarea
@ -76,6 +54,24 @@
</div>
</div>
</div>
<p class="download-includes">{{ 'download-includes' | translate }}</p>
<div class="space-between">
<redaction-select
class="w-410"
[options]="reportTypesEnum"
[translatePrefix]="'report-type.'"
[label]="'report-type.label' | translate: { length: this.ruleSetForm.controls['reportTypes'].value.length }"
formControlName="reportTypes"
></redaction-select>
<redaction-select
class="w-410"
[options]="downloadTypesEnum"
[translatePrefix]="'download-type.'"
[label]="'download-type.label' | translate: { length: this.ruleSetForm.controls['downloadFileTypes'].value.length }"
formControlName="downloadFileTypes"
></redaction-select>
</div>
</div>
<div class="dialog-actions">

View File

@ -21,3 +21,12 @@
}
}
}
.w-410 {
width: 410px;
}
.download-includes {
margin: 16px 0 10px;
font-weight: 500;
}

View File

@ -101,10 +101,6 @@ export class AddEditRuleSetDialogComponent {
return false;
}
public humanize(value: string): string {
return value[0].toUpperCase() + value.substr(1).toLowerCase().replace(new RegExp('_', 'g'), ' ');
}
async saveRuleSet() {
const ruleSet = {
ruleSetId: this.ruleSet?.ruleSetId,

View File

@ -112,6 +112,7 @@ export class AdminDialogService {
public openAddEditRuleSetDialog(ruleSet: RuleSetModel, cb?: Function): MatDialogRef<AddEditRuleSetDialogComponent> {
const ref = this._dialog.open(AddEditRuleSetDialogComponent, {
...dialogConfig,
width: '900px',
data: ruleSet,
autoFocus: true
});

View File

@ -32,28 +32,6 @@
</mat-form-field>
</div>
<div class="red-input-group w-400">
<mat-form-field floatLabel="always">
<mat-label>{{ 'project-listing.add-edit-dialog.form.download-file-types.label' | translate }}</mat-label>
<mat-select formControlName="downloadFileTypes" style="width: 100%;" multiple>
<mat-option *ngFor="let type of downloadTypesEnum" [value]="type">
{{ 'download-type.' + type | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="red-input-group required w-400">
<mat-form-field floatLabel="always">
<mat-label>{{ 'project-listing.add-edit-dialog.form.report-types.label' | translate }}</mat-label>
<mat-select formControlName="reportTypes" style="width: 100%;" multiple>
<mat-option *ngFor="let type of reportTypesEnum" [value]="type">
{{ 'report-type.' + type | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="red-input-group w-400">
<label translate="project-listing.add-edit-dialog.form.description.label"></label>
<textarea
@ -79,6 +57,24 @@
<mat-datepicker #picker></mat-datepicker>
</div>
</div>
<p class="download-includes">{{ 'download-includes' | translate }}</p>
<div class="space-between">
<redaction-select
class="w-410"
[options]="reportTypesEnum"
[translatePrefix]="'report-type.'"
[label]="'report-type.label' | translate: { length: this.projectForm.controls['reportTypes'].value.length }"
formControlName="reportTypes"
></redaction-select>
<redaction-select
class="w-410"
[options]="downloadTypesEnum"
[translatePrefix]="'download-type.'"
[label]="'download-type.label' | translate: { length: this.projectForm.controls['downloadFileTypes'].value.length }"
formControlName="downloadFileTypes"
></redaction-select>
</div>
</div>
<div class="dialog-actions">

View File

@ -12,3 +12,12 @@
margin-right: 16px;
}
}
.w-410 {
width: 410px;
}
.download-includes {
margin: 16px 0 10px;
font-weight: 500;
}

View File

@ -47,10 +47,6 @@ export class AddEditProjectDialogComponent {
});
}
public humanize(value: string): string {
return value[0].toUpperCase() + value.substr(1).toLowerCase().replace(new RegExp('_', 'g'), ' ');
}
public get changed() {
if (!this.project) {
return true;

View File

@ -126,6 +126,7 @@ export class ProjectsDialogService {
$event.stopPropagation();
const ref = this._dialog.open(AddEditProjectDialogComponent, {
...dialogConfig,
width: '900px',
autoFocus: true,
data: project
});

View File

@ -13,8 +13,8 @@
<div class="filter-menu-header">
<div class="all-caps-label" translate="filter-menu.filter-types"></div>
<div class="actions">
<div class="all-caps-label primary pointer" translate="filter-menu.all" (click)="activateAllFilters(); $event.stopPropagation()"></div>
<div class="all-caps-label primary pointer" translate="filter-menu.none" (click)="deactivateAllFilters(); $event.stopPropagation()"></div>
<div class="all-caps-label primary pointer" [translate]="'actions.all'" (click)="activateAllFilters(); $event.stopPropagation()"></div>
<div class="all-caps-label primary pointer" [translate]="'actions.none'" (click)="deactivateAllFilters(); $event.stopPropagation()"></div>
</div>
</div>
<div *ngFor="let filter of primaryFilters">

View File

@ -0,0 +1,15 @@
<div class="wrapper">
<div class="label-header space-between">
<div class="all-caps-label">{{ label }}</div>
<div class="actions">
<div class="all-caps-label primary pointer" [translate]="'actions.all'" (click)="selectAll($event)"></div>
<div class="all-caps-label primary pointer" [translate]="'actions.none'" (click)="deselectAll($event)"></div>
</div>
</div>
<mat-chip-list class="options flex-center" selectable [multiple]="multiple" [disabled]="disabled">
<mat-chip *ngFor="let option of options" #chip="matChip" (click)="toggleSelection(chip)" [value]="option">
{{ translatePrefix + option | translate }}
</mat-chip>
</mat-chip-list>
</div>

View File

@ -0,0 +1,63 @@
@import 'apps/red-ui/src/assets/styles/red-variables';
.wrapper {
border-radius: 8px;
border: 1px solid $grey-5;
height: 100%;
}
.label-header {
padding: 16px 16px 14px 16px;
.actions {
display: flex;
> *:not(:last-child) {
margin-right: 8px;
}
}
}
.options {
padding: 0 16px 16px 16px;
}
.mat-standard-chip {
cursor: pointer;
}
mat-chip {
width: 100%;
height: 32px;
border-radius: 4px;
font-size: 13px;
font-weight: 400;
}
::ng-deep .mat-chip-list-wrapper {
width: 100%;
margin: 0;
}
.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary {
background-color: $grey-6;
color: $grey-1;
}
.mat-chip.mat-standard-chip {
background-color: $white;
color: $grey-1;
margin: 0 0 2px 0;
&:hover {
background-color: $grey-8;
}
}
.mat-chip.mat-standard-chip::after {
background: $grey-8;
}
.mat-standard-chip:focus::after {
opacity: 0;
}

View File

@ -0,0 +1,86 @@
import { AfterViewInit, ChangeDetectorRef, Component, Input, ViewChild } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { MatChip, MatChipList } from '@angular/material/chips';
import { map } from 'rxjs/operators';
@Component({
selector: 'redaction-select',
templateUrl: './select.component.html',
styleUrls: ['./select.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: SelectComponent,
multi: true
}
]
})
export class SelectComponent implements AfterViewInit, ControlValueAccessor {
@Input() label: string;
@Input() options: string[];
@Input() translatePrefix = '';
@Input() disabled = false;
@Input() multiple = true;
@ViewChild(MatChipList) chipList: MatChipList;
private _value: string[] = [];
private _onChange: (value: string[]) => void;
constructor(private readonly _changeDetector: ChangeDetectorRef) {}
ngAfterViewInit(): void {
this._selectChips(this._value);
this.chipList.chipSelectionChanges.pipe(map((event) => event.source)).subscribe((chip) => {
if (chip.selected) {
this._value = [...this._value, chip.value];
} else {
this._value = this._value.filter((o) => o !== chip.value);
}
this._propagateChange(this._value);
});
this._changeDetector.detectChanges();
}
registerOnChange(fn: any): void {
this._onChange = fn;
}
registerOnTouched(fn: any): void {}
writeValue(value: string[]): void {
if (this.chipList && value) this._selectChips(value);
else if (value) this._value = value;
}
setDisabledState?(isDisabled: boolean): void {
this.disabled = isDisabled;
}
toggleSelection(chip: MatChip): void {
if (!this.disabled) chip.toggleSelected();
}
selectAll($event) {
$event.stopPropagation();
this.chipList.chips.forEach((chip) => chip.select());
}
deselectAll($event) {
$event.stopPropagation();
this.chipList.chips.forEach((chip) => chip.deselect());
}
private _selectChips(value: string[]): void {
this.chipList.chips.forEach((chip) => chip.deselect());
const chipsToSelect = this.chipList.chips.filter((c) => value.includes(c.value));
chipsToSelect.forEach((chip) => chip.select());
}
private _propagateChange(value: string[]): void {
if (this._onChange) this._onChange(value);
}
}

View File

@ -31,6 +31,7 @@ import { SortByPipe } from './components/sort-pipe/sort-by.pipe';
import { RoundCheckboxComponent } from './components/checkbox/round-checkbox.component';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
import { MomentDateAdapter } from '@angular/material-moment-adapter';
import { SelectComponent } from './components/select/select.component';
const buttons = [ChevronButtonComponent, CircleButtonComponent, FileDownloadBtnComponent, IconButtonComponent, UserButtonComponent];
@ -51,18 +52,19 @@ const components = [
BaseListingComponent,
SortByPipe,
RoundCheckboxComponent,
SelectComponent,
...buttons
];
const utils = [HumanizePipe, SyncWidthDirective, HasScrollbarDirective];
const modules = [MatConfigModule, TranslateModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule];
const modules = [MatConfigModule, MatChipsModule, TranslateModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule];
@NgModule({
declarations: [...components, ...utils],
imports: [CommonModule, ...modules],
exports: [...modules, ...components, ...utils, RoundCheckboxComponent],
exports: [...modules, ...components, ...utils]
providers: [
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
{

View File

@ -144,13 +144,7 @@
"placeholder": "Enter Description"
},
"due-date": "Due Date",
"template": "Project Template",
"download-file-types": {
"label": "Download file types"
},
"report-types": {
"label": "Report types"
}
"template": "Project Template"
},
"errors": {
"project-already-exists": "Project with this name already exists!",
@ -518,8 +512,6 @@
},
"filter-menu": {
"label": "Filter",
"all": "All",
"none": "None",
"filter-types": "Filter types",
"filter-options": "Filter options",
"with-comments": "Show only annotations with comments"
@ -691,12 +683,6 @@
"description-placeholder": "Enter Description",
"valid-from": "Valid from",
"valid-to": "Valid to",
"download-file-types": {
"label": "Download file types"
},
"report-types": {
"label": "Report types"
}
},
"save": "Save Project Template"
},
@ -1242,15 +1228,22 @@
"title": "No file attributes defined. Select a column from the left panel to start defining file attributes."
}
},
"download-includes": "Choose what is included at download:",
"download-type": {
"label": "{{length}} document versions",
"PREVIEW": "Preview PDF",
"ORIGINAL": "Original PDF",
"REDACTED": "Redacted PDF"
},
"report-type": {
"label": "{{length}} report types",
"WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE": "Justification Appendix A1",
"WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE": "Justification Appendix A2",
"EXCEL_MULTI_FILE": "Excel (for all)",
"EXCEL_SINGLE_FILE": "Excel (per all)"
},
"actions": {
"all": "All",
"none": "None"
}
}

View File

@ -333,3 +333,8 @@ section.settings {
.fit-content {
width: fit-content;
}
.space-between {
display: flex;
justify-content: space-between;
}

View File

@ -8,6 +8,7 @@ $grey-4: #e2e4e9;
$grey-5: #d3d5da;
$grey-6: #f0f1f4;
$grey-7: #9398a0;
$grey-8: #f9fafb;
$blue-1: #4875f7;
$blue-2: #48c9f7;
@ -21,7 +22,7 @@ $yellow-2: #fdbd00;
$green-1: #00ff00;
$green-2: #5ce594;
$orange-1: #ff801a;
$pink-1: #F125DE;
$pink-1: #f125de;
$primary: $red-1;
$accent: $grey-1;