wip template repository
This commit is contained in:
@@ -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<UmbTemplateDetailStore>(
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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<Template | undefined>(undefined);
|
||||
data = this.#data.asObservable();
|
||||
@@ -22,16 +14,7 @@ export class UmbTemplateWorkspaceContext {
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
this.#host = host;
|
||||
|
||||
new UmbContextConsumerController(host, UMB_TEMPLATE_DETAIL_STORE_CONTEXT_TOKEN, (instance) => {
|
||||
this.#store = instance;
|
||||
this.ready = true;
|
||||
this.#initResolver?.(true);
|
||||
});
|
||||
|
||||
new UmbContextConsumerController(host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => {
|
||||
this.#notificationService = instance;
|
||||
});
|
||||
this.#templateRepository = new UmbTemplateRepository(host);
|
||||
}
|
||||
|
||||
setName(value: string) {
|
||||
@@ -42,76 +25,21 @@ export class UmbTemplateWorkspaceContext {
|
||||
this.#data.next({ ...this.#data.value, content: value });
|
||||
}
|
||||
|
||||
init() {
|
||||
return new Promise((resolve) => {
|
||||
this.ready ? resolve(true) : (this.#initResolver = resolve);
|
||||
});
|
||||
}
|
||||
|
||||
load(entityKey: string) {
|
||||
if (!this.ready || !this.#store) return;
|
||||
|
||||
this.#storeObserver?.destroy();
|
||||
this.#storeObserver = new UmbObserverController(this.#host, this.#store.getByKey(entityKey), (data) => {
|
||||
if (!data) return;
|
||||
async load(entityKey: string) {
|
||||
const { data } = await this.#templateRepository.get(entityKey);
|
||||
if (data) {
|
||||
this.#data.next(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async createScaffold(parentKey: string | null) {
|
||||
if (!this.ready || !this.#store) return;
|
||||
|
||||
let masterTemplateAlias: string | undefined = undefined;
|
||||
|
||||
// TODO: handle errors
|
||||
// TODO: can we do something so we don't have to call two endpoints?
|
||||
|
||||
if (parentKey) {
|
||||
const { data: parentData } = await tryExecuteAndNotify(
|
||||
this.#host,
|
||||
TemplateResource.getTemplateByKey({ key: parentKey })
|
||||
);
|
||||
masterTemplateAlias = parentData?.alias;
|
||||
}
|
||||
|
||||
const { data: scaffoldData } = await tryExecuteAndNotify(
|
||||
this.#host,
|
||||
TemplateResource.getTemplateScaffold({ masterTemplateAlias })
|
||||
);
|
||||
|
||||
const template = {
|
||||
key: uuid(),
|
||||
name: '',
|
||||
alias: '',
|
||||
content: scaffoldData?.content,
|
||||
};
|
||||
|
||||
this.#data.next(template);
|
||||
const { data } = await this.#templateRepository.new(parentKey);
|
||||
if (!data) return;
|
||||
this.#data.next(data);
|
||||
}
|
||||
|
||||
async create() {
|
||||
// TODO: handle error
|
||||
async save(isNew: boolean) {
|
||||
if (!this.#data.value) return;
|
||||
|
||||
try {
|
||||
await this.#store?.create(this.#data.value);
|
||||
this.#notificationService?.peek('positive', { data: { message: `Template created` } });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
isNew ? this.#templateRepository.insert(this.#data.value) : this.#templateRepository.update(this.#data.value);
|
||||
}
|
||||
|
||||
async update() {
|
||||
// TODO: handle error
|
||||
if (!this.#data.value) return;
|
||||
|
||||
try {
|
||||
await this.#store?.save(this.#data.value);
|
||||
this.#notificationService?.peek('positive', { data: { message: `Template saved` } });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add delete method
|
||||
}
|
||||
|
||||
@@ -22,14 +22,8 @@ export class UmbTemplateWorkspaceElement extends UmbLitElement {
|
||||
`,
|
||||
];
|
||||
|
||||
private _entityKey!: string;
|
||||
@property()
|
||||
public get entityKey(): string {
|
||||
return this._entityKey;
|
||||
}
|
||||
public set entityKey(value: string) {
|
||||
this._entityKey = value;
|
||||
}
|
||||
public entityKey?: string;
|
||||
|
||||
@property()
|
||||
public create?: string | null;
|
||||
@@ -40,14 +34,13 @@ export class UmbTemplateWorkspaceElement extends UmbLitElement {
|
||||
@state()
|
||||
private _content?: string | null = '';
|
||||
|
||||
private isNew = false;
|
||||
|
||||
#templateWorkspaceContext = new UmbTemplateWorkspaceContext(this);
|
||||
|
||||
async connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
// make sure the the context has received all dependencies
|
||||
await this.#templateWorkspaceContext.init();
|
||||
|
||||
this.observe(this.#templateWorkspaceContext.name, (name) => {
|
||||
this._name = name;
|
||||
});
|
||||
@@ -56,12 +49,15 @@ export class UmbTemplateWorkspaceElement extends UmbLitElement {
|
||||
this._content = content;
|
||||
});
|
||||
|
||||
if (!this._entityKey && this.create !== undefined) {
|
||||
if (!this.entityKey && this.create !== undefined) {
|
||||
this.isNew = true;
|
||||
this.#templateWorkspaceContext.createScaffold(this.create);
|
||||
return;
|
||||
}
|
||||
|
||||
this.#templateWorkspaceContext.load(this._entityKey);
|
||||
if (this.entityKey) {
|
||||
this.#templateWorkspaceContext.load(this.entityKey);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: temp code for testing create and save
|
||||
@@ -78,13 +74,7 @@ export class UmbTemplateWorkspaceElement extends UmbLitElement {
|
||||
}
|
||||
|
||||
#onSave() {
|
||||
this.#templateWorkspaceContext.update();
|
||||
}
|
||||
|
||||
#onCreate() {
|
||||
if (this.create !== undefined) {
|
||||
this.#templateWorkspaceContext.create();
|
||||
}
|
||||
this.#templateWorkspaceContext.save(this.isNew);
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -93,7 +83,6 @@ export class UmbTemplateWorkspaceElement extends UmbLitElement {
|
||||
<uui-input .value=${this._name} @input=${this.#onNameInput}></uui-input>
|
||||
<uui-textarea id="content" .value=${this._content} @input="${this.#onTextareaInput}"></uui-textarea>
|
||||
<uui-button label="Save" look="primary" color="positive" @click=${this.#onSave}></uui-button>
|
||||
<uui-button label="Create" look="primary" color="positive" @click=${this.#onCreate}></uui-button>
|
||||
</umb-workspace-layout>`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user