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("");