wire up document picker

This commit is contained in:
Mads Rasmussen
2022-11-18 15:13:11 +01:00
parent 03ba6306a8
commit 108efcb029
8 changed files with 68 additions and 30 deletions

View File

@@ -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<Entity> = [];
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<Entity[]>(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<Entity[]>(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<string>) {
this.value = newValue;
this._observePickedEntities();
this._observePickedDocuments();
this.dispatchEvent(new CustomEvent('property-editor-change', { bubbles: true, composed: true }));
}

View File

@@ -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<unknown>) => {
@@ -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<boolean>(

View File

@@ -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<string> = [];
@@ -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'));
});
}

View File

@@ -12,7 +12,6 @@ export interface UmbTreeContext {
export class UmbTreeContextBase implements UmbTreeContext {
public tree: ManifestTree;
public rootKey = '';
private _selectable: BehaviorSubject<boolean> = new BehaviorSubject(false);
public readonly selectable: Observable<boolean> = 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));
}
}

View File

@@ -197,7 +197,7 @@ class UmbDocumentData extends UmbData<DocumentDetails> {
return { items, total };
}
getTreeItem(keys: Array<string>): Array<DocumentTreeItem> {
getTreeItems(keys: Array<string>): Array<DocumentTreeItem> {
return this.data.filter((item) => keys.includes(item.key ?? ''));
}
}

View File

@@ -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));
}),

View File

@@ -78,7 +78,7 @@ export class UmbModalLayoutContentPickerElement extends UmbModalLayoutElement<Um
<hr />
<umb-tree
alias="Umb.Tree.Documents"
@change=${this._handleSelectionChange}
@selected=${this._handleSelectionChange}
.selection=${this._selection}
selectable></umb-tree>
</uui-box>

View File

@@ -47,4 +47,26 @@ export class UmbDocumentStore extends UmbDataStoreBase<DocumentDetails | Documen
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === key)));
}
getTreeItems(keys: Array<string>): Observable<Array<FolderTreeItem>> {
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 ?? ''))));
}
}