From 4913dabedf135925efaff272990c03b6a0b5adaf Mon Sep 17 00:00:00 2001 From: Abhishek Negi <108608673+Abhinegi2@users.noreply.github.com> Date: Wed, 17 Apr 2024 14:12:28 +0530 Subject: [PATCH] fix(Admin UI): add functionality to reorder toStringAttributes (#2334) --- ...min-entity-general-settings.component.html | 16 ++-- ...-entity-general-settings.component.spec.ts | 4 +- ...admin-entity-general-settings.component.ts | 82 ++++++++++--------- .../admin-entity/admin-entity.component.html | 3 +- .../basic-autocomplete.component.html | 53 ++++++++---- .../basic-autocomplete.component.ts | 35 ++++++++ 6 files changed, 128 insertions(+), 65 deletions(-) diff --git a/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html b/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html index cf7f413b29..ca313dc70d 100644 --- a/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html +++ b/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.html @@ -48,20 +48,24 @@

General Settings of "{{ entityConstructor.label }}" Records

- + Generated Title of Record - + #formDataType + [options]="toStringAttributesOptions" + [optionToString]="objectToLabel" + [valueMapper]="objectToValue" + [multi]="true" + [reorder]="true" + >
diff --git a/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.spec.ts b/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.spec.ts index 656fe0a764..0567d092db 100644 --- a/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.spec.ts +++ b/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { ReactiveFormsModule, FormsModule } from "@angular/forms"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; import { MatButtonModule } from "@angular/material/button"; import { MatInputModule } from "@angular/material/input"; import { MatTabsModule } from "@angular/material/tabs"; @@ -51,7 +51,7 @@ describe("AdminEntityGeneralSettingsComponent", () => { fixture = TestBed.createComponent(AdminEntityGeneralSettingsComponent); component = fixture.componentInstance; component.entityConstructor = mockEntityConstructor; - component.config = { label: "Test Label" }; + component.generalSettings = { label: "Test Label" }; fixture.detectChanges(); }); diff --git a/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.ts b/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.ts index 96bc7b473a..68b36ef30c 100644 --- a/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.ts +++ b/src/app/core/admin/admin-entity/admin-entity-general-settings/admin-entity-general-settings.component.ts @@ -1,12 +1,4 @@ -import { - Component, - EventEmitter, - Input, - Output, - OnChanges, - SimpleChanges, - OnInit, -} from "@angular/core"; +import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; import { EntityConstructor } from "../../../entity/model/entity"; import { MatButtonModule } from "@angular/material/button"; import { DialogCloseComponent } from "../../../common-components/dialog-close/dialog-close.component"; @@ -26,6 +18,7 @@ import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; import { MatTooltipModule } from "@angular/material/tooltip"; import { BasicAutocompleteComponent } from "../../../common-components/basic-autocomplete/basic-autocomplete.component"; import { EntityConfig } from "../../../entity/entity-config"; +import { StringDatatype } from "../../../basic-datatypes/string/string.datatype"; @Component({ selector: "app-admin-entity-general-settings", @@ -47,13 +40,15 @@ import { EntityConfig } from "../../../entity/entity-config"; BasicAutocompleteComponent, ], }) -export class AdminEntityGeneralSettingsComponent implements OnChanges, OnInit { +export class AdminEntityGeneralSettingsComponent implements OnInit { @Input() entityConstructor: EntityConstructor; @Output() generalSettingsChange: EventEmitter = new EventEmitter(); - @Input() config: EntityConfig; + @Input() generalSettings: EntityConfig; + form: FormGroup; basicSettingsForm: FormGroup; + toStringAttributesOptions: SimpleDropdownValue[] = []; constructor(private fb: FormBuilder) {} @@ -61,45 +56,58 @@ export class AdminEntityGeneralSettingsComponent implements OnChanges, OnInit { this.init(); } - ngOnChanges(changes: SimpleChanges): void { - if (changes.config) { - this.init(); - } - } - private init() { this.basicSettingsForm = this.fb.group({ - label: [this.config.label, Validators.required], - labelPlural: [this.config.labelPlural], - icon: [this.config.icon, Validators.required], - toStringAttributes: [this.config.toStringAttributes, Validators.required], + label: [this.generalSettings.label, Validators.required], + labelPlural: [this.generalSettings.labelPlural], + icon: [this.generalSettings.icon, Validators.required], + toStringAttributes: [ + this.generalSettings.toStringAttributes, + Validators.required, + ], }); this.form = this.fb.group({ basicSettings: this.basicSettingsForm, }); + this.initToStringAttributesOptions(); this.form.valueChanges.subscribe((value) => { - this.emitStaticDetails(); // Optionally, emit the initial value + // Emit the updated value + this.generalSettingsChange.emit(this.basicSettingsForm.getRawValue()); // Optionally, emit the initial value }); } - emitStaticDetails() { - const toStringAttributesControl = - this.basicSettingsForm.get("toStringAttributes"); - let toStringAttributesValue = toStringAttributesControl.value; - // Convert toStringAttributesValue to an array if it's a string - if (typeof toStringAttributesValue === "string") { - toStringAttributesValue = toStringAttributesValue - .split(",") - .map((item) => item.trim()); + private initToStringAttributesOptions() { + if (!this.generalSettings.toStringAttributes) { + return; } - // Update the form control with the modified value - toStringAttributesControl.setValue(toStringAttributesValue, { - emitEvent: false, - }); + const selectedOptions = this.generalSettings.toStringAttributes; + const unselectedOptions = Array.from( + this.entityConstructor.schema.entries(), + ) + .filter( + ([key, field]) => + field.dataType === StringDatatype.dataType && + field.label && + !selectedOptions.includes(key), + ) + .map(([key, field]) => ({ key: key, label: field.label })); - // Emit the updated value - this.generalSettingsChange.emit(this.basicSettingsForm.getRawValue()); + this.toStringAttributesOptions = [ + ...selectedOptions.map((key) => ({ + key: key, + label: this.entityConstructor.schema.get(key)?.label, + })), + ...unselectedOptions, + ]; } + + objectToLabel = (v: SimpleDropdownValue) => v?.label; + objectToValue = (v: SimpleDropdownValue) => v?.key; +} + +interface SimpleDropdownValue { + key: string; + label: string; } diff --git a/src/app/core/admin/admin-entity/admin-entity.component.html b/src/app/core/admin/admin-entity/admin-entity.component.html index 9d78eb6325..826d6f9ac5 100644 --- a/src/app/core/admin/admin-entity/admin-entity.component.html +++ b/src/app/core/admin/admin-entity/admin-entity.component.html @@ -54,8 +54,7 @@ @case ("general") { } } diff --git a/src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html b/src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html index b696caa698..fac149e2e0 100644 --- a/src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html +++ b/src/app/core/common-components/basic-autocomplete/basic-autocomplete.component.html @@ -33,25 +33,42 @@ autoActiveFirstOption [hideSingleSelectionIndicator]="multi" > - -
- - - - {{ item.asString }} - - - -
-
+ + +
+
+ +
+ + + {{ item.asString }} + + +
+
+
+ { initial: O; @@ -79,6 +84,7 @@ interface SelectableOption { MatTooltip, MatIcon, MatChipRemove, + DragDropModule, ], }) export class BasicAutocompleteComponent @@ -101,6 +107,8 @@ export class BasicAutocompleteComponent * Whether the user should be able to select multiple values. */ @Input() multi?: boolean; + @Input() reorder?: boolean; + autocompleteDraggableOptions: SelectableOption[] = []; autocompleteForm = new FormControl(""); autocompleteSuggestedOptions = this.autocompleteForm.valueChanges.pipe( @@ -164,6 +172,12 @@ export class BasicAutocompleteComponent ); } + ngOnInit() { + this.autocompleteSuggestedOptions.subscribe((options) => { + this.autocompleteDraggableOptions = options; + }); + } + ngOnChanges(changes: { [key in keyof this]?: any }) { if (changes.valueMapper) { this._options.forEach( @@ -185,6 +199,27 @@ export class BasicAutocompleteComponent } } + drop(event: CdkDragDrop) { + if (event.previousContainer === event.container) { + moveItemInArray( + this.autocompleteDraggableOptions, + event.previousIndex, + event.currentIndex, + ); + } + this._selectedOptions = this.autocompleteDraggableOptions.filter( + (o) => o.selected, + ); + if (this.multi) { + this.value = this._selectedOptions.map((o) => o.asValue); + } else { + this.value = undefined; + } + this.setInitialInputValue(); + this.onChange(this.value); + this.showAutocomplete(this.autocompleteForm.value); + } + showAutocomplete(valueToRevertTo?: string) { if (this.multi) { this.autocompleteForm.setValue("");