From 9a2bc8c31aa6623a4f525711722ea09e24bfb3f2 Mon Sep 17 00:00:00 2001 From: Katrin Yordanova Date: Wed, 5 Apr 2023 13:20:41 +0300 Subject: [PATCH] Add option to allow duplicate values for single and each multi value fields --- .../ModuleFields/Configurator/Record.vue | 18 ++++++++++++++++++ .../ModuleFields/Configurator/Select.vue | 16 ++++++++++++++++ .../ModuleFields/Configurator/User.vue | 16 ++++++++++++++++ .../components/ModuleFields/Editor/Record.vue | 10 ++++------ .../components/ModuleFields/Editor/Select.vue | 4 +++- .../components/ModuleFields/Editor/User.vue | 7 ++++++- .../src/compose/types/module-field/record.ts | 3 +++ .../src/compose/types/module-field/select.ts | 3 +++ lib/js/src/compose/types/module-field/user.ts | 4 +++- locale/en/corteza-webapp-compose/field.yaml | 1 + 10 files changed, 73 insertions(+), 9 deletions(-) diff --git a/client/web/compose/src/components/ModuleFields/Configurator/Record.vue b/client/web/compose/src/components/ModuleFields/Configurator/Record.vue index 7d24fb2e5..81c062817 100644 --- a/client/web/compose/src/components/ModuleFields/Configurator/Record.vue +++ b/client/web/compose/src/components/ModuleFields/Configurator/Record.vue @@ -77,7 +77,17 @@ v-model="f.options.selectType" :options="selectOptions" stacked + @change="onUpdateIsUniqueMultiValue" /> + + {{ $t('kind.select.allow-duplicates') }} + @@ -203,5 +213,13 @@ export default { this.f.options.selectType = 'default' }, }, + + methods: { + onUpdateIsUniqueMultiValue () { + if (this.f.options.selectType === 'multiple') { + this.f.options.isUniqueMultiValue = true + } + }, + }, } diff --git a/client/web/compose/src/components/ModuleFields/Configurator/Select.vue b/client/web/compose/src/components/ModuleFields/Configurator/Select.vue index 0d1d737c5..4b78a058c 100644 --- a/client/web/compose/src/components/ModuleFields/Configurator/Select.vue +++ b/client/web/compose/src/components/ModuleFields/Configurator/Select.vue @@ -83,7 +83,17 @@ v-model="f.options.selectType" :options="selectOptions" stacked + @change="onUpdateIsUniqueMultiValue" /> + + {{ $t('kind.select.allow-duplicates') }} + @@ -157,6 +167,12 @@ export default { this.newOption = { value: undefined, text: undefined, new: true } } }, + + onUpdateIsUniqueMultiValue () { + if (this.f.options.selectType === 'multiple') { + this.f.options.isUniqueMultiValue = true + } + }, }, } diff --git a/client/web/compose/src/components/ModuleFields/Configurator/User.vue b/client/web/compose/src/components/ModuleFields/Configurator/User.vue index 5833d68d9..cf0649a96 100644 --- a/client/web/compose/src/components/ModuleFields/Configurator/User.vue +++ b/client/web/compose/src/components/ModuleFields/Configurator/User.vue @@ -35,7 +35,17 @@ v-model="f.options.selectType" :options="selectOptions" stacked + @change="onUpdateIsUniqueMultiValue" /> + + {{ $t('kind.select.allow-duplicates') }} + @@ -76,6 +86,12 @@ export default { getOptionKey ({ roleID }) { return roleID }, + + onUpdateIsUniqueMultiValue () { + if (this.f.options.selectType === 'multiple') { + this.f.options.isUniqueMultiValue = true + } + }, }, } diff --git a/client/web/compose/src/components/ModuleFields/Editor/Record.vue b/client/web/compose/src/components/ModuleFields/Editor/Record.vue index 63c939528..c76708243 100644 --- a/client/web/compose/src/components/ModuleFields/Editor/Record.vue +++ b/client/web/compose/src/components/ModuleFields/Editor/Record.vue @@ -308,7 +308,7 @@ export default { if (value !== crtValue) { if (value) { if (index !== undefined) { - this.value[index] = value + this.value.splice(index, 1, value) } else { this.value = value } @@ -330,7 +330,9 @@ export default { return { value: r.recordID, label: this.processing ? '' : this.recordValues[r.recordID] || r.recordID, - selectable: this.field.isMulti ? !(this.value || []).includes(r.recordID) : this.value !== r.recordID, + selectable: this.field.isMulti && !this.field.options.isUniqueMultiValue + ? this.value !== r.recordID + : !(this.value || []).includes(r.recordID), } }, @@ -495,10 +497,6 @@ export default { } }, - onOpen () { - // this.loadLatest() - }, - goToPage (next = true) { this.filter.pageCursor = next ? this.filter.nextPage : this.filter.prevPage }, diff --git a/client/web/compose/src/components/ModuleFields/Editor/Select.vue b/client/web/compose/src/components/ModuleFields/Editor/Select.vue index 2c9d52534..838f16f0b 100644 --- a/client/web/compose/src/components/ModuleFields/Editor/Select.vue +++ b/client/web/compose/src/components/ModuleFields/Editor/Select.vue @@ -109,7 +109,9 @@ export default { computed: { selectOptions () { return this.field.options.options.map(o => { - const disabled = o.value && this.field.isMulti ? (this.value || []).includes(o.value) : this.value === o.value + const disabled = o.value && this.field.isMulti && !this.field.options.isUniqueMultiValue + ? this.value === o.value + : (this.value || []).includes(o.value) return { ...o, disabled } }).filter(({ value = '' }) => value) }, diff --git a/client/web/compose/src/components/ModuleFields/Editor/User.vue b/client/web/compose/src/components/ModuleFields/Editor/User.vue index 111ad7ef4..53783b279 100644 --- a/client/web/compose/src/components/ModuleFields/Editor/User.vue +++ b/client/web/compose/src/components/ModuleFields/Editor/User.vue @@ -194,7 +194,12 @@ export default { options () { return this.users.map(u => { - return { ...u, selectable: this.field.isMulti ? !(this.value || []).includes(u.userID) : this.value !== u.userID } + return { + ...u, + selectable: this.field.isMulti && !this.field.options.isUniqueMultiValue + ? this.value !== u.userID + : !(this.value || []).includes(u.userID), + } }) }, diff --git a/lib/js/src/compose/types/module-field/record.ts b/lib/js/src/compose/types/module-field/record.ts index 13117b225..7f5f7be81 100644 --- a/lib/js/src/compose/types/module-field/record.ts +++ b/lib/js/src/compose/types/module-field/record.ts @@ -12,6 +12,7 @@ interface RecordOptions extends Options { queryFields: Array; selectType: string; multiDelimiter: string; + isUniqueMultiValue: boolean; prefilter?: string; } @@ -23,6 +24,7 @@ const defaults = (): Readonly => Object.freeze({ queryFields: [], selectType: '', multiDelimiter: '\n', + isUniqueMultiValue: false, prefilter: undefined, }) @@ -42,6 +44,7 @@ export class ModuleFieldRecord extends ModuleField { Apply(this.options, o, CortezaID, 'moduleID') Apply(this.options, o, String, 'labelField', 'recordLabelField', 'selectType', 'multiDelimiter', 'prefilter') + Apply(this.options, o, Boolean, 'isUniqueMultiValue') Apply(this.options, o, (o) => { if (!o) { return [] diff --git a/lib/js/src/compose/types/module-field/select.ts b/lib/js/src/compose/types/module-field/select.ts index b94b80e62..a1facd0bc 100644 --- a/lib/js/src/compose/types/module-field/select.ts +++ b/lib/js/src/compose/types/module-field/select.ts @@ -10,6 +10,7 @@ interface SelectOptions extends Options { options: Array; selectType: string; multiDelimiter: string; + isUniqueMultiValue: boolean; } const defaults = (): Readonly => Object.freeze({ @@ -17,6 +18,7 @@ const defaults = (): Readonly => Object.freeze({ options: [], selectType: 'default', multiDelimiter: '\n', + isUniqueMultiValue: false, }) export class ModuleFieldSelect extends ModuleField { @@ -34,6 +36,7 @@ export class ModuleFieldSelect extends ModuleField { super.applyOptions(o) Apply(this.options, o, String, 'selectType', 'multiDelimiter') + Apply(this.options, o, Boolean, 'isUniqueMultiValue') if (o.options) { let opt: Array<{ value: string; text: string }> = [] diff --git a/lib/js/src/compose/types/module-field/user.ts b/lib/js/src/compose/types/module-field/user.ts index 6b4c97701..8e8a0bd75 100644 --- a/lib/js/src/compose/types/module-field/user.ts +++ b/lib/js/src/compose/types/module-field/user.ts @@ -11,6 +11,7 @@ interface UserOptions extends Options { presetWithAuthenticated: boolean; selectType: string; multiDelimiter: string; + isUniqueMultiValue: boolean; } const defaults = (): Readonly => Object.freeze({ @@ -19,6 +20,7 @@ const defaults = (): Readonly => Object.freeze({ presetWithAuthenticated: false, selectType: 'default', multiDelimiter: '\n', + isUniqueMultiValue: false, }) export class ModuleFieldUser extends ModuleField { @@ -35,7 +37,7 @@ export class ModuleFieldUser extends ModuleField { if (!o) return super.applyOptions(o) - Apply(this.options, o, Boolean, 'presetWithAuthenticated') + Apply(this.options, o, Boolean, 'presetWithAuthenticated', 'isUniqueMultiValue') Apply(this.options, o, String, 'selectType', 'multiDelimiter') Apply(this.options, o, (o) => { if (!o) { diff --git a/locale/en/corteza-webapp-compose/field.yaml b/locale/en/corteza-webapp-compose/field.yaml index 952143d6c..6c65e0e91 100644 --- a/locale/en/corteza-webapp-compose/field.yaml +++ b/locale/en/corteza-webapp-compose/field.yaml @@ -107,6 +107,7 @@ kind: prefilterLabel: Prefilter records prefilterPlaceholder: field1 = 1 AND field2 = 232 select: + allow-duplicates: Allow duplicates label: Select optionAdd: Add optionLabelPlaceholder: Label