templates render correctly

This commit is contained in:
Niels Lyngsø
2023-06-09 22:10:28 +02:00
parent 9ef6a2bf88
commit 2fab18fada
5 changed files with 120 additions and 16 deletions

View File

@@ -9,7 +9,7 @@ import {
UMB_MODAL_MANAGER_CONTEXT_TOKEN,
} from '@umbraco-cms/backoffice/modal';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import { TemplateResponseModel } from '@umbraco-cms/backoffice/backend-api';
import { ItemResponseModelBaseModel, TemplateResponseModel } from '@umbraco-cms/backoffice/backend-api';
@customElement('umb-input-template')
export class UmbInputTemplateElement extends FormControlMixin(UmbLitElement) {
@@ -49,12 +49,12 @@ export class UmbInputTemplateElement extends FormControlMixin(UmbLitElement) {
@property({ type: String, attribute: 'min-message' })
maxMessage = 'This field exceeds the allowed amount of items';
_selectedIds: Array<string | null> = [];
@property({ type: Array<string | null> })
_selectedIds: Array<string> = [];
@property({ type: Array<string> })
public get selectedIds() {
return this._selectedIds;
}
public set selectedIds(newKeys: Array<string | null>) {
public set selectedIds(newKeys: Array<string>) {
this._selectedIds = newKeys;
this.#observePickedTemplates();
}
@@ -74,7 +74,7 @@ export class UmbInputTemplateElement extends FormControlMixin(UmbLitElement) {
private _templateRepository: UmbTemplateRepository = new UmbTemplateRepository(this);
@state()
_pickedTemplates: TemplateResponseModel[] = [];
_pickedTemplates: ItemResponseModelBaseModel[] = [];
constructor() {
super();
@@ -86,13 +86,13 @@ export class UmbInputTemplateElement extends FormControlMixin(UmbLitElement) {
async #observePickedTemplates() {
this.observe(
await this._templateRepository.itemsLegacy(this._selectedIds),
(await this._templateRepository.requestItems(this._selectedIds)).asObservable(),
(data) => {
const oldValue = this._pickedTemplates;
this._pickedTemplates = data;
this.requestUpdate('_pickedTemplates', oldValue);
},
'_pickedTemplates'
'_observeTemplates'
);
}
@@ -112,11 +112,12 @@ export class UmbInputTemplateElement extends FormControlMixin(UmbLitElement) {
const modalContext = this._modalContext?.open(UMB_TEMPLATE_PICKER_MODAL, {
multiple: true,
selection: [...this.selectedIds],
pickableFilter: (template: TemplateResponseModel) => template.id !== null,
});
modalContext?.onSubmit().then((data) => {
if (!data.selection) return;
this.selectedIds = data.selection;
this.selectedIds = data.selection.filter((x) => x !== null) as Array<string>;
this.dispatchEvent(new CustomEvent('change'));
});
}

View File

@@ -1,7 +1,13 @@
import { UmbTemplateRepository } from '../repository/template.repository.js';
import { UmbTemplateTreeStore } from './template.tree.store.js';
import { UmbTemplateStore } from './template.store.js';
import { ManifestStore, ManifestTreeStore, ManifestRepository } from '@umbraco-cms/backoffice/extension-registry';
import { UmbTemplateItemStore } from './template-item.store.js';
import {
ManifestStore,
ManifestTreeStore,
ManifestRepository,
ManifestItemStore,
} from '@umbraco-cms/backoffice/extension-registry';
export const TEMPLATE_REPOSITORY_ALIAS = 'Umb.Repository.Template';
@@ -14,6 +20,7 @@ const repository: ManifestRepository = {
export const TEMPLATE_STORE_ALIAS = 'Umb.Store.Template';
export const TEMPLATE_TREE_STORE_ALIAS = 'Umb.Store.TemplateTree';
export const TEMPLATE_ITEM_STORE_ALIAS = 'Umb.Store.TemplateItem';
const store: ManifestStore = {
type: 'store',
@@ -29,4 +36,11 @@ const treeStore: ManifestTreeStore = {
class: UmbTemplateTreeStore,
};
export const manifests = [repository, store, treeStore];
const itemStore: ManifestItemStore = {
type: 'itemStore',
alias: TEMPLATE_ITEM_STORE_ALIAS,
name: 'Template Item Store',
class: UmbTemplateItemStore,
};
export const manifests = [repository, store, treeStore, itemStore];

View File

@@ -0,0 +1,39 @@
import type { UmbItemDataSource } from '@umbraco-cms/backoffice/repository';
import { TemplateItemResponseModel, TemplateResource } from '@umbraco-cms/backoffice/backend-api';
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
/**
* A data source for Data Type items that fetches data from the server
* @export
* @class UmbTemplateItemServerDataSource
* @implements {DocumentTreeDataSource}
*/
export class UmbTemplateItemServerDataSource implements UmbItemDataSource<TemplateItemResponseModel> {
#host: UmbControllerHostElement;
/**
* Creates an instance of UmbTemplateItemServerDataSource.
* @param {UmbControllerHostElement} host
* @memberof UmbTemplateItemServerDataSource
*/
constructor(host: UmbControllerHostElement) {
this.#host = host;
}
/**
* Fetches the items for the given ids from the server
* @param {Array<string>} ids
* @return {*}
* @memberof UmbTemplateItemServerDataSource
*/
async getItems(ids: Array<string>) {
if (!ids) throw new Error('Ids are missing');
return tryExecuteAndNotify(
this.#host,
TemplateResource.getTemplateItem({
id: ids,
})
);
}
}

View File

@@ -0,0 +1,36 @@
import { TemplateItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import { UmbItemStore, UmbStoreBase } from '@umbraco-cms/backoffice/store';
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
/**
* @export
* @class UmbTemplateItemStore
* @extends {UmbStoreBase}
* @description - Data Store for Template items
*/
export class UmbTemplateItemStore
extends UmbStoreBase<TemplateItemResponseModel>
implements UmbItemStore<TemplateItemResponseModel>
{
/**
* Creates an instance of UmbTemplateItemStore.
* @param {UmbControllerHostElement} host
* @memberof UmbTemplateItemStore
*/
constructor(host: UmbControllerHostElement) {
super(
host,
UMB_TEMPLATE_ITEM_STORE_CONTEXT_TOKEN.toString(),
new UmbArrayState<TemplateItemResponseModel>([], (x) => x.id)
);
}
items(ids: Array<string>) {
return this._data.getObservablePart((items) => items.filter((item) => ids.includes(item.id ?? '')));
}
}
export const UMB_TEMPLATE_ITEM_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbTemplateItemStore>('UmbTemplateItemStore');

View File

@@ -2,9 +2,12 @@ import { UmbTemplateTreeStore, UMB_TEMPLATE_TREE_STORE_CONTEXT_TOKEN } from './t
import { UmbTemplateStore, UMB_TEMPLATE_STORE_CONTEXT_TOKEN } from './template.store.js';
import { UmbTemplateTreeServerDataSource } from './sources/template.tree.server.data.js';
import { UmbTemplateDetailServerDataSource } from './sources/template.detail.server.data.js';
import { UMB_TEMPLATE_ITEM_STORE_CONTEXT_TOKEN, UmbTemplateItemStore } from './template-item.store.js';
import { UmbTemplateItemServerDataSource } from './sources/template.item.server.data.js';
import { Observable } from '@umbraco-cms/backoffice/external/rxjs';
import type {
UmbDetailRepository,
UmbItemDataSource,
UmbItemRepository,
UmbTreeDataSource,
UmbTreeRepository,
@@ -32,7 +35,9 @@ export class UmbTemplateRepository
#treeDataSource: UmbTreeDataSource<EntityTreeItemResponseModel>;
#detailDataSource: UmbTemplateDetailServerDataSource;
#itemSource: UmbItemDataSource<TemplateItemResponseModel>;
#itemStore?: UmbTemplateItemStore;
#treeStore?: UmbTemplateTreeStore;
#store?: UmbTemplateStore;
@@ -43,8 +48,13 @@ export class UmbTemplateRepository
this.#treeDataSource = new UmbTemplateTreeServerDataSource(this.#host);
this.#detailDataSource = new UmbTemplateDetailServerDataSource(this.#host);
this.#itemSource = new UmbTemplateItemServerDataSource(this.#host);
this.#init = Promise.all([
new UmbContextConsumerController(this.#host, UMB_TEMPLATE_ITEM_STORE_CONTEXT_TOKEN, (instance) => {
this.#itemStore = instance;
}),
new UmbContextConsumerController(this.#host, UMB_TEMPLATE_TREE_STORE_CONTEXT_TOKEN, (instance) => {
this.#treeStore = instance;
}),
@@ -147,17 +157,21 @@ export class UmbTemplateRepository
this.#store?.append(data);
}
return { data, error };
return { data, error, asObservable: () => this.#treeStore!.items([id]) };
}
async requestItems(id: string[]) {
// ITEMS:
async requestItems(ids: Array<string>) {
if (!ids) throw new Error('Ids are missing');
await this.#init;
if (!id) {
throw new Error('Id is missing');
const { data, error } = await this.#itemSource.getItems(ids);
if (data) {
this.#itemStore?.appendItems(data);
}
const { data, error } = await this.#detailDataSource.getItem(id);
return { data, error };
return { data, error, asObservable: () => this.#itemStore!.items(ids) };
}
async items(uniques: string[]): Promise<Observable<ItemResponseModelBaseModel[]>> {