From 108efcb0293a0d913ec4047e45099e1bf1df3f3a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 18 Nov 2022 15:13:11 +0100 Subject: [PATCH] wire up document picker --- ...operty-editor-ui-content-picker.element.ts | 23 +++++++++--------- .../trees/shared/tree-item.element.ts | 24 ++++++++++++------- .../backoffice/trees/shared/tree.element.ts | 15 +++++++----- .../src/backoffice/trees/tree.context.ts | 6 ++++- .../src/core/mocks/data/document.data.ts | 2 +- .../mocks/domains/tree-document.handlers.ts | 4 ++-- .../modal-layout-content-picker.element.ts | 2 +- .../core/stores/document/document.store.ts | 22 +++++++++++++++++ 8 files changed, 68 insertions(+), 30 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/property-editor-uis/content-picker/property-editor-ui-content-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/property-editor-uis/content-picker/property-editor-ui-content-picker.element.ts index 55b35a698a..48e61a8b89 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/property-editor-uis/content-picker/property-editor-ui-content-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/property-editor-uis/content-picker/property-editor-ui-content-picker.element.ts @@ -3,10 +3,10 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; import type { UmbModalService } from '../../../core/services/modal'; -import type { UmbEntityStore } from '../../../core/stores/entity.store'; import type { Entity } from '../../../core/mocks/data/entities'; import { UmbObserverMixin } from '@umbraco-cms/observable-api'; import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; +import { UmbDocumentStore } from 'src/core/stores/document/document.store'; @customElement('umb-property-editor-ui-content-picker') export class UmbPropertyEditorUIContentPickerElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { @@ -44,29 +44,30 @@ export class UmbPropertyEditorUIContentPickerElement extends UmbContextConsumerM private _items: Array = []; private _modalService?: UmbModalService; - private _entityStore?: UmbEntityStore; + private _documentStore?: UmbDocumentStore; constructor() { super(); - this.consumeAllContexts(['umbEntityStore', 'umbModalService'], (instances) => { - this._entityStore = instances['umbEntityStore']; + this.consumeAllContexts(['umbDocumentStore', 'umbModalService'], (instances) => { + this._documentStore = instances['umbDocumentStore']; this._modalService = instances['umbModalService']; - this._observePickedEntities(); + this._observePickedDocuments(); }); } - private _observePickedEntities() { - if (!this._entityStore) return; - this.observe(this._entityStore.getByKeys(this.value), (entities) => { - this._items = entities; + private _observePickedDocuments() { + if (!this._documentStore) return; + // TODO: consider changing this to the list data endpoint when it is available + this.observe(this._documentStore.getTreeItems(this.value), (items) => { + this._items = items; }); } private _openPicker() { const modalHandler = this._modalService?.contentPicker({ multiple: true, selection: this.value }); modalHandler?.onClose().then(({ selection }: any) => { - this._setValue([...this.value, ...selection]); + this._setValue([...selection]); }); } @@ -88,7 +89,7 @@ export class UmbPropertyEditorUIContentPickerElement extends UmbContextConsumerM private _setValue(newValue: Array) { this.value = newValue; - this._observePickedEntities(); + this._observePickedDocuments(); this.dispatchEvent(new CustomEvent('property-editor-change', { bubbles: true, composed: true })); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-item.element.ts index 395632736e..7abf917411 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree-item.element.ts @@ -4,7 +4,7 @@ import { customElement, property, state } from 'lit/decorators.js'; import { UUIMenuItemEvent } from '@umbraco-ui/uui'; import { map } from 'rxjs'; import { repeat } from 'lit/directives/repeat.js'; -import { UmbTreeContextBase } from '../tree.context'; +import type { UmbTreeContextBase } from '../tree.context'; import { UmbSectionContext } from '../../sections/section.context'; import { Entity } from '../../../core/mocks/data/entities'; import type { ManifestSection } from '../../../core/models'; @@ -49,7 +49,7 @@ export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitEle this.consumeContext('umbTreeContext', (treeContext: UmbTreeContextBase) => { this._treeContext = treeContext; this._observeSelectable(); - this._observeSelection(); + this._observeIsSelected(); }); this.consumeContext('umbTreeStore', (store: UmbDataStore) => { @@ -69,11 +69,19 @@ export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitEle connectedCallback(): void { super.connectedCallback(); - this.addEventListener('selected', (e) => { - e.stopPropagation(); - this._treeContext?.select(this.treeItem.key); - this.dispatchEvent(new CustomEvent('change', { composed: true, bubbles: true })); - }); + + this.addEventListener('selected', this._handleSelectedItem); + this.addEventListener('unselected', this._handleDeselectedItem); + } + + private _handleSelectedItem(event: Event) { + event.stopPropagation(); + this._treeContext?.select(this.treeItem.key); + } + + private _handleDeselectedItem(event: Event) { + event.stopPropagation(); + this._treeContext?.deselect(this.treeItem.key); } private _observeSection() { @@ -92,7 +100,7 @@ export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitEle }); } - private _observeSelection() { + private _observeIsSelected() { if (!this._treeContext) return; this.observe( diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree.element.ts index d3347bee93..45e8ffcff1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/trees/shared/tree.element.ts @@ -32,6 +32,10 @@ export class UmbTreeElement extends UmbContextProviderMixin(UmbContextConsumerMi this._selectable = newVal; this.requestUpdate('selectable', oldVal); this._treeContext?.setSelectable(newVal); + + if (newVal) { + this._observeSelection(); + } } private _selection: Array = []; @@ -71,23 +75,22 @@ export class UmbTreeElement extends UmbContextProviderMixin(UmbContextConsumerMi } private _provideTreeContext() { - if (!this._tree) return; + if (!this._tree || this._treeContext) return; + this._treeContext = new UmbTreeContextBase(this._tree); this._treeContext.setSelectable(this.selectable); this._treeContext.setSelection(this.selection); - this.provideContext('umbTreeContext', this._treeContext); - if (this.selectable) { - this._observeSelection(); - } + this.provideContext('umbTreeContext', this._treeContext); } private _observeSelection() { if (!this._treeContext) return; this.observe(this._treeContext.selection, (selection) => { + if (this._selection === selection) return; this._selection = selection; - this.dispatchEvent(new CustomEvent('change')); + this.dispatchEvent(new CustomEvent('selected')); }); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/trees/tree.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/trees/tree.context.ts index 91ee2535bd..dfa57ae5b5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/trees/tree.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/trees/tree.context.ts @@ -12,7 +12,6 @@ export interface UmbTreeContext { export class UmbTreeContextBase implements UmbTreeContext { public tree: ManifestTree; - public rootKey = ''; private _selectable: BehaviorSubject = new BehaviorSubject(false); public readonly selectable: Observable = this._selectable.asObservable(); @@ -37,4 +36,9 @@ export class UmbTreeContextBase implements UmbTreeContext { const selection = this._selection.getValue(); this._selection.next([...selection, key]); } + + public deselect(key: string) { + const selection = this._selection.getValue(); + this._selection.next(selection.filter((x) => x !== key)); + } } diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/document.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/document.data.ts index b1028e432c..ec0e5e066c 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/document.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/document.data.ts @@ -197,7 +197,7 @@ class UmbDocumentData extends UmbData { return { items, total }; } - getTreeItem(keys: Array): Array { + getTreeItems(keys: Array): Array { return this.data.filter((item) => keys.includes(item.key ?? '')); } } diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-document.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-document.handlers.ts index 84d95558ee..ab361bfab4 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-document.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-document.handlers.ts @@ -16,10 +16,10 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/document/item', (req, res, ctx) => { - const keys = req.params.keys as string; + const keys = req.url.searchParams.getAll('key'); if (!keys) return; - const items = umbDocumentData.getTreeItem(keys.split(',')); + const items = umbDocumentData.getTreeItems(keys); return res(ctx.status(200), ctx.json(items)); }), diff --git a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/content-picker/modal-layout-content-picker.element.ts b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/content-picker/modal-layout-content-picker.element.ts index 1c60ce0cb9..4ef52ea23d 100644 --- a/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/content-picker/modal-layout-content-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/services/modal/layouts/content-picker/modal-layout-content-picker.element.ts @@ -78,7 +78,7 @@ export class UmbModalLayoutContentPickerElement extends UmbModalLayoutElement diff --git a/src/Umbraco.Web.UI.Client/src/core/stores/document/document.store.ts b/src/Umbraco.Web.UI.Client/src/core/stores/document/document.store.ts index 32acdeb94d..7aeecbc364 100644 --- a/src/Umbraco.Web.UI.Client/src/core/stores/document/document.store.ts +++ b/src/Umbraco.Web.UI.Client/src/core/stores/document/document.store.ts @@ -47,4 +47,26 @@ export class UmbDocumentStore extends UmbDataStoreBase items.filter((item) => item.parentKey === key))); } + + getTreeItems(keys: Array): Observable> { + if (keys.length > 0) { + DocumentResource.getTreeDocumentItem({ + key: keys, + }).then( + (items) => { + this.update(items); + }, + (e) => { + if (e instanceof ApiError) { + const error = e.body as ProblemDetails; + if (e.status === 400) { + console.log(error.detail); + } + } + } + ); + } + + return this.items.pipe(map((items) => items.filter((item) => keys.includes(item.key ?? '')))); + } }