From 0bee06e8a738de91eeca0870ee59eb4b8593bf57 Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Tue, 7 Feb 2023 10:52:34 +0600 Subject: [PATCH] Editable presenters (#2594) Signed-off-by: Denis Bykhov --- models/view/src/index.ts | 2 +- models/view/src/plugin.ts | 3 +- .../ui/src/components/DropdownLabels.svelte | 2 +- .../presenters/DatePresenter.svelte | 3 +- .../components/EmployeeRefPresenter.svelte | 37 ++++++++---- .../state/DoneStatePresenter.svelte | 4 +- .../state/DoneStateRefPresenter.svelte | 4 +- .../components/state/StateRefPresenter.svelte | 8 ++- .../src/components/DatePresenter.svelte | 7 ++- .../src/components/EnumPresenter.svelte | 60 +++++++++++++++++++ .../src/components/Table.svelte | 34 ++++++++--- .../src/components/ViewletSetting.svelte | 1 + .../src/components/list/ListItem.svelte | 20 ++++++- plugins/view-resources/src/index.ts | 4 +- plugins/view-resources/src/utils.ts | 13 ++-- plugins/view/src/index.ts | 1 + 16 files changed, 167 insertions(+), 36 deletions(-) create mode 100644 plugins/view-resources/src/components/EnumPresenter.svelte diff --git a/models/view/src/index.ts b/models/view/src/index.ts index eec97f03ff..194fb7e8ca 100644 --- a/models/view/src/index.ts +++ b/models/view/src/index.ts @@ -713,7 +713,7 @@ export function createModel (builder: Builder): void { view.filter.FilterNestedDontMatch ) - classPresenter(builder, core.class.EnumOf, view.component.StringPresenter, view.component.EnumEditor) + classPresenter(builder, core.class.EnumOf, view.component.EnumPresenter, view.component.EnumEditor) createAction(builder, { action: view.actionImpl.ShowPopup, diff --git a/models/view/src/plugin.ts b/models/view/src/plugin.ts index ebcc6fc221..f9208668d8 100644 --- a/models/view/src/plugin.ts +++ b/models/view/src/plugin.ts @@ -66,7 +66,8 @@ export default mergeIds(viewId, view, { MarkupEditorPopup: '' as AnyComponent, ListView: '' as AnyComponent, IndexedDocumentPreview: '' as AnyComponent, - SpaceRefPresenter: '' as AnyComponent + SpaceRefPresenter: '' as AnyComponent, + EnumPresenter: '' as AnyComponent }, string: { Table: '' as IntlString, diff --git a/packages/ui/src/components/DropdownLabels.svelte b/packages/ui/src/components/DropdownLabels.svelte index aaffcf6055..eeaecf29c3 100644 --- a/packages/ui/src/components/DropdownLabels.svelte +++ b/packages/ui/src/components/DropdownLabels.svelte @@ -24,7 +24,7 @@ import Label from './Label.svelte' export let icon: Asset | AnySvelteComponent | undefined = undefined - export let label: IntlString + export let label: IntlString | undefined = undefined export let placeholder: IntlString | undefined = ui.string.SearchDots export let items: DropdownTextItem[] export let multiselect = false diff --git a/plugins/board-resources/src/components/presenters/DatePresenter.svelte b/plugins/board-resources/src/components/presenters/DatePresenter.svelte index 792724183e..3e2d0dabfa 100644 --- a/plugins/board-resources/src/components/presenters/DatePresenter.svelte +++ b/plugins/board-resources/src/components/presenters/DatePresenter.svelte @@ -1,5 +1,6 @@ - +{#if onChange !== undefined} + onChange?.(detail)} + /> +{:else} + +{/if} diff --git a/plugins/task-resources/src/components/state/DoneStatePresenter.svelte b/plugins/task-resources/src/components/state/DoneStatePresenter.svelte index 715bd35e6c..5a57f259bd 100644 --- a/plugins/task-resources/src/components/state/DoneStatePresenter.svelte +++ b/plugins/task-resources/src/components/state/DoneStatePresenter.svelte @@ -20,10 +20,10 @@ import Won from '../icons/Won.svelte' import Lost from '../icons/Lost.svelte' - export let value: DoneState + export let value: DoneState | null | undefined export let showTitle: boolean = true - $: color = value._class === task.class.WonState ? getPlatformColor(0) : getPlatformColor(11) + $: color = value?._class === task.class.WonState ? getPlatformColor(0) : getPlatformColor(11) {#if value} diff --git a/plugins/task-resources/src/components/state/DoneStateRefPresenter.svelte b/plugins/task-resources/src/components/state/DoneStateRefPresenter.svelte index c3bd043308..45ae413e9e 100644 --- a/plugins/task-resources/src/components/state/DoneStateRefPresenter.svelte +++ b/plugins/task-resources/src/components/state/DoneStateRefPresenter.svelte @@ -20,12 +20,12 @@ import task from '@hcengineering/task' import DoneStatePresenter from './DoneStatePresenter.svelte' - export let value: Ref + export let value: Ref | null | undefined export let showTitle: boolean = true let state: DoneState | undefined const query = createQuery() - $: query.query(task.class.DoneState, { _id: value }, (res) => ([state] = res), { limit: 1 }) + $: value && query.query(task.class.DoneState, { _id: value }, (res) => ([state] = res), { limit: 1 }) {#if state} diff --git a/plugins/task-resources/src/components/state/StateRefPresenter.svelte b/plugins/task-resources/src/components/state/StateRefPresenter.svelte index 1f87f9d577..12234350fe 100644 --- a/plugins/task-resources/src/components/state/StateRefPresenter.svelte +++ b/plugins/task-resources/src/components/state/StateRefPresenter.svelte @@ -17,9 +17,11 @@ import { Ref } from '@hcengineering/core' import { createQuery } from '@hcengineering/presentation' import task, { State } from '@hcengineering/task' + import StateEditor from './StateEditor.svelte' import StatePresenter from './StatePresenter.svelte' export let value: Ref + export let onChange: ((value: Ref) => void) | undefined = undefined let state: State | undefined const query = createQuery() @@ -27,5 +29,9 @@ {#if state} - + {#if onChange !== undefined} + + {:else} + + {/if} {/if} diff --git a/plugins/view-resources/src/components/DatePresenter.svelte b/plugins/view-resources/src/components/DatePresenter.svelte index ba7039f886..d41d302698 100644 --- a/plugins/view-resources/src/components/DatePresenter.svelte +++ b/plugins/view-resources/src/components/DatePresenter.svelte @@ -18,7 +18,12 @@ import { DateRangePresenter } from '@hcengineering/ui' export let value: number | null | undefined + export let onChange: ((value: number | null) => void) | undefined = undefined export let noShift: boolean = false - +{#if onChange !== undefined} + onChange?.(e.detail)} /> +{:else} + +{/if} diff --git a/plugins/view-resources/src/components/EnumPresenter.svelte b/plugins/view-resources/src/components/EnumPresenter.svelte new file mode 100644 index 0000000000..aa14e8b0f5 --- /dev/null +++ b/plugins/view-resources/src/components/EnumPresenter.svelte @@ -0,0 +1,60 @@ + + + +{#if onChange !== undefined && type !== undefined} + { + onChange?.(e.detail) + }} + /> +{:else} + +{/if} diff --git a/plugins/view-resources/src/components/Table.svelte b/plugins/view-resources/src/components/Table.svelte index a6431bac41..8d9e2b2a31 100644 --- a/plugins/view-resources/src/components/Table.svelte +++ b/plugins/view-resources/src/components/Table.svelte @@ -14,10 +14,10 @@ // limitations under the License. --> {#await buildModel({ client, _class, keys: config, lookup })} @@ -295,10 +311,12 @@ {#each model as attribute, cell}
+
diff --git a/plugins/view-resources/src/components/ViewletSetting.svelte b/plugins/view-resources/src/components/ViewletSetting.svelte index f5bb7d9aa0..159028e89d 100644 --- a/plugins/view-resources/src/components/ViewletSetting.svelte +++ b/plugins/view-resources/src/components/ViewletSetting.svelte @@ -121,6 +121,7 @@ if (viewlet.hiddenKeys?.includes(attribute.name)) return if (hierarchy.isDerived(attribute.type._class, core.class.Collection)) return const value = getValue(attribute.name, attribute.type) + if (result.findIndex((p) => p.value === attribute.name) !== -1) return if (result.findIndex((p) => p.value === value) !== -1) return const { attrClass, category } = getAttributePresenterClass(hierarchy, attribute) const typeClass = hierarchy.getClass(attrClass) diff --git a/plugins/view-resources/src/components/list/ListItem.svelte b/plugins/view-resources/src/components/list/ListItem.svelte index 9c91eb8897..829286aad1 100644 --- a/plugins/view-resources/src/components/list/ListItem.svelte +++ b/plugins/view-resources/src/components/list/ListItem.svelte @@ -13,8 +13,9 @@ // limitations under the License. -->
@@ -100,6 +116,7 @@ {...props} value={getObjectValue(attributeModel.key, docObject) ?? ''} object={docObject} + onChange={getOnChange(docObject, attributeModel)} kind={'list'} {...attributeModel.props} /> @@ -127,6 +144,7 @@ {...props} value={value ?? ''} objectId={docObject._id} + onChange={getOnChange(docObject, attributeModel)} groupBy={groupByKey} {...attributeModel.props} /> diff --git a/plugins/view-resources/src/index.ts b/plugins/view-resources/src/index.ts index 40ca2d25e7..cdd64f5047 100644 --- a/plugins/view-resources/src/index.ts +++ b/plugins/view-resources/src/index.ts @@ -64,6 +64,7 @@ import ValueSelector from './components/ValueSelector.svelte' import ViewletSettingButton from './components/ViewletSettingButton.svelte' import SpaceRefPresenter from './components/SpaceRefPresenter.svelte' import EnumArrayEditor from './components/EnumArrayEditor.svelte' +import EnumPresenter from './components/EnumPresenter.svelte' import { afterResult, @@ -176,7 +177,8 @@ export default async (): Promise => ({ GrowPresenter, IndexedDocumentPreview, SpaceRefPresenter, - EnumArrayEditor + EnumArrayEditor, + EnumPresenter }, popup: { PositionElementAlignment diff --git a/plugins/view-resources/src/utils.ts b/plugins/view-resources/src/utils.ts index abb77c31f7..4d2d08113d 100644 --- a/plugins/view-resources/src/utils.ts +++ b/plugins/view-resources/src/utils.ts @@ -92,7 +92,8 @@ export async function getObjectPresenter ( presenter, props: preserveKey.props, sortingKey, - collectionAttr: isCollectionAttr + collectionAttr: isCollectionAttr, + isLookup: false } } @@ -164,7 +165,8 @@ async function getAttributePresenter ( props: preserveKey.props, icon: presenterMixin.icon, attribute, - collectionAttr: isCollectionAttr + collectionAttr: isCollectionAttr, + isLookup: false } } @@ -185,7 +187,8 @@ export async function getPresenter ( label: label as IntlString, presenter: typeof presenter === 'string' ? await getResource(presenter) : presenter, props: preserveKey.props, - collectionAttr: isCollectionAttr + collectionAttr: isCollectionAttr, + isLookup: false } } if (key.key.length === 0) { @@ -293,7 +296,8 @@ export async function buildModel (options: BuildModelOptions): Promise ( const lookupKey = { ...key, key: lookupProperty[0] } const model = await getPresenter(client, lookupClass[0], lookupKey, preserveKey, undefined, lookupClass[2]) model.label = getLookupLabel(client, lookupClass[1], lookupClass[0], lookupKey, lookupProperty[1]) + model.isLookup = true return model } diff --git a/plugins/view/src/index.ts b/plugins/view/src/index.ts index 2e3eabf166..4ee0294459 100644 --- a/plugins/view/src/index.ts +++ b/plugins/view/src/index.ts @@ -416,6 +416,7 @@ export interface AttributeModel { attribute?: AnyAttribute collectionAttr: boolean + isLookup: boolean castRequest?: Ref> }