diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/template.detail.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/template.detail.store.ts index 5d8909f19e..0ba26e6c7e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/template.detail.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/template.detail.store.ts @@ -18,36 +18,9 @@ export class UmbTemplateDetailStore extends UmbStoreBase { super(host, UmbTemplateDetailStore.name); } - getByKey(key: string) { - tryExecuteAndNotify(this._host, TemplateResource.getTemplateByKey({ key })).then(({ data }) => { - if (data) { - // TODO: how do we handle if an item has been removed during this session(like in another tab or by another user)? - this.#data.append([data]); - } - }); - - return createObservablePart(this.#data, (items) => items.find((item) => item.key === key)); - } - - async save(template: Template) { - if (!template.key) return; - - const { error } = await tryExecuteAndNotify( - this._host, - TemplateResource.putTemplateByKey({ key: template.key, requestBody: template }) - ); - - if (error) throw error; - + append(template: Template) { this.#data.append([template]); } - - async create(template: TemplateCreateModel) { - const { data } = await tryExecuteAndNotify(this._host, TemplateResource.postTemplate({ requestBody: template })); - if (data) { - this.#data.append([data]); - } - } } export const UMB_TEMPLATE_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken( diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/template.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/template.repository.ts new file mode 100644 index 0000000000..09476ef73a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/template.repository.ts @@ -0,0 +1,104 @@ +import { v4 as uuid } from 'uuid'; +import { UmbTemplateDetailStore, UMB_TEMPLATE_DETAIL_STORE_CONTEXT_TOKEN } from './template.detail.store'; +import { Template, TemplateResource } from '@umbraco-cms/backend-api'; +import { UmbContextConsumerController } from '@umbraco-cms/context-api'; +import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification'; + +/* we need to new up the repository from within the element context. We want the correct context for +the notifications to be displayed in the correct place. */ + +// element -> context -> repository -> (store) -> data source + +// TODO: implement data sources +export class UmbTemplateRepository { + #host: UmbControllerHostInterface; + #detailStore?: UmbTemplateDetailStore; + #notificationService?: UmbNotificationService; + + constructor(host: UmbControllerHostInterface) { + this.#host = host; + + new UmbContextConsumerController(this.#host, UMB_TEMPLATE_DETAIL_STORE_CONTEXT_TOKEN, (instance) => { + this.#detailStore = instance; + }); + + new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => { + this.#notificationService = instance; + }); + } + + async new(parentKey: string | null): Promise<{ data?: Template; error?: unknown }> { + let masterTemplateAlias: string | undefined = undefined; + let error = undefined; + let data = undefined; + + // TODO: can we do something so we don't have to call two endpoints? + if (parentKey) { + const { data: parentData, error: parentError } = await tryExecuteAndNotify( + this.#host, + TemplateResource.getTemplateByKey({ key: parentKey }) + ); + masterTemplateAlias = parentData?.alias; + error = parentError; + } + + const { data: scaffoldData, error: scaffoldError } = await tryExecuteAndNotify( + this.#host, + TemplateResource.getTemplateScaffold({ masterTemplateAlias }) + ); + error = scaffoldError; + + if (scaffoldData?.content) { + data = { + key: uuid(), + name: '', + alias: '', + content: scaffoldData?.content, + }; + } + + return { data, error }; + } + + async get(key: string): Promise<{ data?: Template; error?: unknown }> { + const { data, error } = await tryExecuteAndNotify(this.#host, TemplateResource.getTemplateByKey({ key })); + return { data, error }; + } + + async insert(template: Template): Promise<{ error?: unknown }> { + const payload = { requestBody: template }; + const { error } = await tryExecuteAndNotify(this.#host, TemplateResource.postTemplate(payload)); + + if (!error) { + const notification = { data: { message: `Template created` } }; + this.#notificationService?.peek('positive', notification); + } + + this.#detailStore?.append(template); + + return { error }; + } + + async update(template: Template): Promise<{ error?: unknown }> { + if (!template.key) { + return { error: 'Template key is missing' }; + } + + const payload = { key: template.key, requestBody: template }; + const { error } = await tryExecuteAndNotify(this.#host, TemplateResource.putTemplateByKey(payload)); + + if (!error) { + const notification = { data: { message: `Template saved` } }; + this.#notificationService?.peek('positive', notification); + } + + this.#detailStore?.append(template); + + return { error }; + } + + // TODO: delete + // TODO: tree +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/workspace/template-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/workspace/template-workspace.context.ts index 6b91fb5299..0e72d1d328 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/workspace/template-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/workspace/template-workspace.context.ts @@ -1,19 +1,11 @@ -import { v4 as uuid } from 'uuid'; -import { UmbTemplateDetailStore, UMB_TEMPLATE_DETAIL_STORE_CONTEXT_TOKEN } from '../template.detail.store'; -import { createObservablePart, DeepState, UmbObserverController } from '@umbraco-cms/observable-api'; -import { Template, TemplateResource } from '@umbraco-cms/backend-api'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; +import { UmbTemplateRepository } from '../template.repository'; +import { createObservablePart, DeepState } from '@umbraco-cms/observable-api'; +import { Template } from '@umbraco-cms/backend-api'; import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification'; export class UmbTemplateWorkspaceContext { #host: UmbControllerHostInterface; - #store?: UmbTemplateDetailStore; - #notificationService?: UmbNotificationService; - #storeObserver?: UmbObserverController; - #initResolver?: (value: unknown) => void; - ready = false; + #templateRepository: UmbTemplateRepository; #data = new DeepState