diff --git a/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html b/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html
index b4216e41c..ea57e1746 100644
--- a/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html
+++ b/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.html
@@ -28,6 +28,16 @@
}
+ @if (allSelectOptions.length > SELECT_OPTION_PAGE_SIZE) {
+
+ }
@if (object?.id) {
Warning: existing instances of this field will retain their current value index (e.g. option #1, #2, #3) after editing the options here
}
diff --git a/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.spec.ts b/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.spec.ts
index 62a0954a1..4486003de 100644
--- a/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.spec.ts
+++ b/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.spec.ts
@@ -125,4 +125,42 @@ describe('CustomFieldEditDialogComponent', () => {
fixture.detectChanges()
expect(document.activeElement).toBe(selectOptionInputs.last.nativeElement)
})
+
+ it('should send all select options including those changed in form on save', () => {
+ component.dialogMode = EditDialogMode.EDIT
+ component.object = {
+ id: 1,
+ name: 'Field 1',
+ data_type: CustomFieldDataType.Select,
+ extra_data: {
+ select_options: Array.from({ length: 50 }, (_, i) => ({
+ label: `Option ${i + 1}`,
+ id: `${i + 1}-xyz`,
+ })),
+ },
+ }
+ fixture.detectChanges()
+ component.ngOnInit()
+ component.selectOptionsPage = 2
+ fixture.detectChanges()
+ component.objectForm
+ .get('extra_data')
+ .get('select_options')
+ .get('0')
+ .get('label')
+ .setValue('Updated Option 9')
+ const formValues = (component as any).getFormValues()
+ // first item unchanged
+ expect(formValues.extra_data.select_options[0]).toEqual({
+ label: 'Option 1',
+ id: '1-xyz',
+ })
+ // page 2 first item updated
+ expect(
+ formValues.extra_data.select_options[component.SELECT_OPTION_PAGE_SIZE]
+ ).toEqual({
+ label: 'Updated Option 9',
+ id: '9-xyz',
+ })
+ })
})
diff --git a/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts b/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts
index ce3be7e66..617d825b2 100644
--- a/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts
+++ b/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts
@@ -14,6 +14,7 @@ import {
FormsModule,
ReactiveFormsModule,
} from '@angular/forms'
+import { NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap'
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
import { takeUntil } from 'rxjs'
import {
@@ -28,6 +29,8 @@ import { SelectComponent } from '../../input/select/select.component'
import { TextComponent } from '../../input/text/text.component'
import { EditDialogComponent, EditDialogMode } from '../edit-dialog.component'
+const SELECT_OPTION_PAGE_SIZE = 8
+
@Component({
selector: 'pngx-custom-field-edit-dialog',
templateUrl: './custom-field-edit-dialog.component.html',
@@ -37,6 +40,7 @@ import { EditDialogComponent, EditDialogMode } from '../edit-dialog.component'
TextComponent,
FormsModule,
ReactiveFormsModule,
+ NgbPaginationModule,
NgxBootstrapIconsModule,
],
})
@@ -45,6 +49,21 @@ export class CustomFieldEditDialogComponent
implements OnInit, AfterViewInit
{
CustomFieldDataType = CustomFieldDataType
+ SELECT_OPTION_PAGE_SIZE = SELECT_OPTION_PAGE_SIZE
+
+ private _allSelectOptions: any[] = []
+ public get allSelectOptions(): any[] {
+ return this._allSelectOptions
+ }
+
+ private _selectOptionsPage: number
+ public get selectOptionsPage(): number {
+ return this._selectOptionsPage
+ }
+ public set selectOptionsPage(v: number) {
+ this._selectOptionsPage = v
+ this.updateSelectOptions()
+ }
@ViewChildren('selectOption')
private selectOptionInputs: QueryList
@@ -67,17 +86,10 @@ export class CustomFieldEditDialogComponent
this.objectForm.get('data_type').disable()
}
if (this.object?.data_type === CustomFieldDataType.Select) {
- this.selectOptions.clear()
- this.object.extra_data.select_options
- .filter((option) => option)
- .forEach((option) =>
- this.selectOptions.push(
- new FormGroup({
- label: new FormControl(option.label),
- id: new FormControl(option.id),
- })
- )
- )
+ this._allSelectOptions = [
+ ...(this.object.extra_data.select_options ?? []),
+ ]
+ this.selectOptionsPage = 1
}
}
@@ -87,6 +99,19 @@ export class CustomFieldEditDialogComponent
.subscribe(() => {
this.selectOptionInputs.last?.nativeElement.focus()
})
+
+ this.objectForm.valueChanges
+ .pipe(takeUntil(this.unsubscribeNotifier))
+ .subscribe((change) => {
+ // Update the relevant select options values if changed in the form, which is only a page of the entire list
+ this.objectForm
+ .get('extra_data.select_options')
+ ?.value.forEach((option, index) => {
+ this._allSelectOptions[
+ index + (this.selectOptionsPage - 1) * SELECT_OPTION_PAGE_SIZE
+ ] = option
+ })
+ })
}
getCreateTitle() {
@@ -108,6 +133,17 @@ export class CustomFieldEditDialogComponent
})
}
+ protected getFormValues() {
+ const formValues = super.getFormValues()
+ if (
+ this.objectForm.get('data_type')?.value === CustomFieldDataType.Select
+ ) {
+ // Make sure we send all select options, with updated values
+ formValues.extra_data.select_options = this._allSelectOptions
+ }
+ return formValues
+ }
+
getDataTypes() {
return DATA_TYPE_LABELS
}
@@ -116,13 +152,35 @@ export class CustomFieldEditDialogComponent
return this.dialogMode === EditDialogMode.EDIT
}
+ private updateSelectOptions() {
+ this.selectOptions.clear()
+ this._allSelectOptions
+ .slice(
+ (this.selectOptionsPage - 1) * SELECT_OPTION_PAGE_SIZE,
+ this.selectOptionsPage * SELECT_OPTION_PAGE_SIZE
+ )
+ .forEach((option) =>
+ this.selectOptions.push(
+ new FormGroup({
+ label: new FormControl(option.label),
+ id: new FormControl(option.id),
+ })
+ )
+ )
+ }
+
public addSelectOption() {
- this.selectOptions.push(
- new FormGroup({ label: new FormControl(null), id: new FormControl(null) })
+ this._allSelectOptions.push({ label: null, id: null })
+ this.selectOptionsPage = Math.ceil(
+ this.allSelectOptions.length / SELECT_OPTION_PAGE_SIZE
)
}
public removeSelectOption(index: number) {
this.selectOptions.removeAt(index)
+ this._allSelectOptions.splice(
+ index + (this.selectOptionsPage - 1) * SELECT_OPTION_PAGE_SIZE,
+ 1
+ )
}
}
diff --git a/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts b/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts
index fa35dc6bf..75534a777 100644
--- a/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts
+++ b/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts
@@ -147,9 +147,13 @@ export abstract class EditDialogComponent<
)
}
+ protected getFormValues(): any {
+ return Object.assign({}, this.objectForm.value)
+ }
+
save() {
this.error = null
- const formValues = Object.assign({}, this.objectForm.value)
+ const formValues = this.getFormValues()
const permissionsObject: PermissionsFormObject =
this.objectForm.get('permissions_form')?.value
if (permissionsObject) {