diff --git a/models/setting/src/index.ts b/models/setting/src/index.ts index 606f6b56d0..62356f0a82 100644 --- a/models/setting/src/index.ts +++ b/models/setting/src/index.ts @@ -302,6 +302,10 @@ export function createModel (builder: Builder): void { editor: setting.component.EnumTypeEditor }) + builder.mixin(core.class.ArrOf, core.class.Class, view.mixin.ObjectEditor, { + editor: setting.component.ArrayEditor + }) + builder.mixin(core.class.Class, core.class.Class, view.mixin.IgnoreActions, { actions: [view.action.Delete] }) diff --git a/models/setting/src/plugin.ts b/models/setting/src/plugin.ts index 44945b2373..987572a17b 100644 --- a/models/setting/src/plugin.ts +++ b/models/setting/src/plugin.ts @@ -40,7 +40,8 @@ export default mergeIds(settingId, setting, { RefEditor: '' as AnyComponent, EnumTypeEditor: '' as AnyComponent, Owners: '' as AnyComponent, - CreateMixin: '' as AnyComponent + CreateMixin: '' as AnyComponent, + ArrayEditor: '' as AnyComponent }, category: { Settings: '' as Ref diff --git a/models/view/src/index.ts b/models/view/src/index.ts index 5778485794..eec97f03ff 100644 --- a/models/view/src/index.ts +++ b/models/view/src/index.ts @@ -383,6 +383,9 @@ export function createModel (builder: Builder): void { builder.mixin(core.class.Class, core.class.Class, view.mixin.ObjectPresenter, { presenter: view.component.ClassPresenter }) + builder.mixin(core.class.EnumOf, core.class.Class, view.mixin.ArrayEditor, { + inlineEditor: view.component.EnumArrayEditor + }) classPresenter(builder, core.class.TypeRelatedDocument, view.component.ObjectPresenter) diff --git a/models/view/src/plugin.ts b/models/view/src/plugin.ts index afc7f13e10..ebcc6fc221 100644 --- a/models/view/src/plugin.ts +++ b/models/view/src/plugin.ts @@ -60,6 +60,7 @@ export default mergeIds(viewId, view, { ClassPresenter: '' as AnyComponent, ClassRefPresenter: '' as AnyComponent, EnumEditor: '' as AnyComponent, + EnumArrayEditor: '' as AnyComponent, HTMLEditor: '' as AnyComponent, MarkupEditor: '' as AnyComponent, MarkupEditorPopup: '' as AnyComponent, diff --git a/packages/ui/src/components/DropdownLabels.svelte b/packages/ui/src/components/DropdownLabels.svelte index 976e7a4dd2..aaffcf6055 100644 --- a/packages/ui/src/components/DropdownLabels.svelte +++ b/packages/ui/src/components/DropdownLabels.svelte @@ -27,7 +27,8 @@ export let label: IntlString export let placeholder: IntlString | undefined = ui.string.SearchDots export let items: DropdownTextItem[] - export let selected: DropdownTextItem['id'] | undefined = undefined + export let multiselect = false + export let selected: DropdownTextItem['id'] | DropdownTextItem['id'][] | undefined = multiselect ? [] : undefined export let kind: ButtonKind = 'no-border' export let size: ButtonSize = 'small' @@ -41,13 +42,10 @@ let container: HTMLElement let opened: boolean = false - let isDisabled = false - $: isDisabled = items.length === 0 - let selectedItem = items.find((x) => x.id === selected) - $: selectedItem = items.find((x) => x.id === selected) + $: selectedItem = multiselect ? items.filter((p) => selected?.includes(p.id)) : items.find((x) => x.id === selected) $: if (autoSelect && selected === undefined && items[0] !== undefined) { - selected = items[0].id + selected = multiselect ? [items[0].id] : items[0].id } const dispatch = createEventDispatcher() @@ -66,19 +64,42 @@ on:click={() => { if (!opened) { opened = true - showPopup(DropdownLabelsPopup, { placeholder, items, selected }, container, (result) => { - if (result) { - selected = result - dispatch('selected', result) + showPopup( + DropdownLabelsPopup, + { placeholder, items, multiselect, selected }, + container, + (result) => { + if (result) { + selected = result + dispatch('selected', result) + } + opened = false + mgr?.setFocusPos(focusIndex) + }, + (result) => { + if (result) { + selected = result + dispatch('selected', result) + } } - opened = false - mgr?.setFocusPos(focusIndex) - }) + ) } }} > - {#if selectedItem}{selectedItem.label}{:else} diff --git a/packages/ui/src/components/DropdownLabelsPopup.svelte b/packages/ui/src/components/DropdownLabelsPopup.svelte index 7a1cd2068a..24f63a2007 100644 --- a/packages/ui/src/components/DropdownLabelsPopup.svelte +++ b/packages/ui/src/components/DropdownLabelsPopup.svelte @@ -24,7 +24,8 @@ export let placeholder: IntlString = plugin.string.SearchDots export let items: DropdownTextItem[] - export let selected: DropdownTextItem['id'] | undefined = undefined + export let selected: DropdownTextItem['id'] | DropdownTextItem['id'][] | undefined = undefined + export let multiselect: boolean = false let search: string = '' let phTraslate: string = '' @@ -45,8 +46,18 @@ async function handleSelection (evt: Event | undefined, selection: number): Promise { const item = objects[selection] - - dispatch('close', item.id) + if (multiselect && Array.isArray(selected)) { + const index = selected.indexOf(item.id) + if (index !== -1) { + selected.splice(index, 1) + selected = selected + } else { + selected = selected === undefined ? [item.id] : [...selected, item.id] + } + dispatch('update', selected) + } else { + dispatch('close', item.id) + } } function onKeydown (key: KeyboardEvent): void { @@ -71,6 +82,17 @@ dispatch('close') } } + + function isSelected ( + selected: DropdownTextItem['id'] | DropdownTextItem['id'][] | undefined, + item: DropdownTextItem + ): boolean { + if (Array.isArray(selected)) { + return selected.includes(item.id) + } else { + return item.id === selected + } + }