add template server data source
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
import { EntityTreeItem, PagedEntityTreeItem, ProblemDetails, Template } from '@umbraco-cms/backend-api';
|
||||
|
||||
export interface DataOrErrorResponse<T> {
|
||||
data?: T;
|
||||
error?: ProblemDetails;
|
||||
}
|
||||
|
||||
export interface ErrorResponse {
|
||||
data?: undefined;
|
||||
error?: ProblemDetails;
|
||||
}
|
||||
|
||||
export interface TemplateDataSource {
|
||||
createScaffold(parentKey: string | null): Promise<DataOrErrorResponse<Template>>;
|
||||
get(key: string): Promise<DataOrErrorResponse<Template>>;
|
||||
insert(template: Template): Promise<ErrorResponse>;
|
||||
update(template: Template): Promise<ErrorResponse>;
|
||||
delete(key: string): Promise<ErrorResponse>;
|
||||
getTreeRoot(): Promise<DataOrErrorResponse<PagedEntityTreeItem>>;
|
||||
getTreeItemChildren(parentKey: string): Promise<DataOrErrorResponse<PagedEntityTreeItem>>;
|
||||
getTreeItems(key: Array<string>): Promise<DataOrErrorResponse<EntityTreeItem[]>>;
|
||||
}
|
||||
@@ -1,23 +1,17 @@
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { Observable } from 'rxjs';
|
||||
import { UmbTemplateDetailStore, UMB_TEMPLATE_DETAIL_STORE_CONTEXT_TOKEN } from './template.detail.store';
|
||||
import { UmbTemplateTreeStore, UMB_TEMPLATE_TREE_STORE_CONTEXT_TOKEN } from './tree/template.tree.store';
|
||||
import { EntityTreeItem, Template, TemplateResource } from '@umbraco-cms/backend-api';
|
||||
import { TemplateServerDataSource } from './template.server';
|
||||
import { EntityTreeItem, PagedEntityTreeItem, ProblemDetails, Template } 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. */
|
||||
|
||||
/* We need to create a new instance of the repository from within the element context. We want the notifications to be displayed in the right context. */
|
||||
// element -> context -> repository -> (store) -> data source
|
||||
|
||||
/* TODO: don't call the server directly from the repository.
|
||||
We need to be able to swap it out with a local database in the future.
|
||||
Implement data sources */
|
||||
export class UmbTemplateRepository {
|
||||
#host: UmbControllerHostInterface;
|
||||
#dataSource: TemplateServerDataSource;
|
||||
#detailStore?: UmbTemplateDetailStore;
|
||||
#treeStore!: UmbTemplateTreeStore;
|
||||
#notificationService?: UmbNotificationService;
|
||||
@@ -26,6 +20,8 @@ export class UmbTemplateRepository {
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
this.#host = host;
|
||||
// TODO: figure out how spin up get the correct data source
|
||||
this.#dataSource = new TemplateServerDataSource(this.#host);
|
||||
|
||||
new UmbContextConsumerController(this.#host, UMB_TEMPLATE_DETAIL_STORE_CONTEXT_TOKEN, (instance) => {
|
||||
this.#detailStore = instance;
|
||||
@@ -56,55 +52,31 @@ export class UmbTemplateRepository {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
async createScaffold(parentKey: string | null): Promise<{ data?: Template; error?: ProblemDetails }> {
|
||||
if (!parentKey) {
|
||||
const error: ProblemDetails = { title: 'Parent key is missing' };
|
||||
return { error };
|
||||
}
|
||||
|
||||
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 };
|
||||
return this.#dataSource.createScaffold(parentKey);
|
||||
}
|
||||
|
||||
async get(key: string): Promise<{ data?: Template; error?: unknown }> {
|
||||
async get(key: string): Promise<{ data?: Template; error?: ProblemDetails }> {
|
||||
if (!key) {
|
||||
return { error: 'key is missing' };
|
||||
const error: ProblemDetails = { title: 'Key is missing' };
|
||||
return { error };
|
||||
}
|
||||
|
||||
const { data, error } = await tryExecuteAndNotify(this.#host, TemplateResource.getTemplateByKey({ key }));
|
||||
return { data, error };
|
||||
return this.#dataSource.get(key);
|
||||
}
|
||||
|
||||
async insert(template: Template): Promise<{ error?: unknown }> {
|
||||
async insert(template: Template): Promise<{ error?: ProblemDetails }> {
|
||||
if (!template) {
|
||||
return { error: 'Template is missing' };
|
||||
const error: ProblemDetails = { title: 'Template is missing' };
|
||||
return { error };
|
||||
}
|
||||
|
||||
const payload = { requestBody: template };
|
||||
const { error } = await tryExecuteAndNotify(this.#host, TemplateResource.postTemplate(payload));
|
||||
const { error } = await this.#dataSource.insert(template);
|
||||
|
||||
if (!error) {
|
||||
const notification = { data: { message: `Template created` } };
|
||||
@@ -118,13 +90,13 @@ export class UmbTemplateRepository {
|
||||
return { error };
|
||||
}
|
||||
|
||||
async update(template: Template): Promise<{ error?: unknown }> {
|
||||
if (!template.key) {
|
||||
return { error: 'Template key is missing' };
|
||||
async update(template: Template): Promise<{ error?: ProblemDetails }> {
|
||||
if (!template) {
|
||||
const error: ProblemDetails = { title: 'Template is missing' };
|
||||
return { error };
|
||||
}
|
||||
|
||||
const payload = { key: template.key, requestBody: template };
|
||||
const { error } = await tryExecuteAndNotify(this.#host, TemplateResource.putTemplateByKey(payload));
|
||||
const { error } = await this.#dataSource.update(template);
|
||||
|
||||
if (!error) {
|
||||
const notification = { data: { message: `Template saved` } };
|
||||
@@ -138,15 +110,16 @@ export class UmbTemplateRepository {
|
||||
return { error };
|
||||
}
|
||||
|
||||
async delete(key: string): Promise<{ error?: unknown }> {
|
||||
if (key) {
|
||||
return { error: 'Key is missing' };
|
||||
async delete(key: string): Promise<{ error?: ProblemDetails }> {
|
||||
if (!key) {
|
||||
const error: ProblemDetails = { title: 'Key is missing' };
|
||||
return { error };
|
||||
}
|
||||
|
||||
const { error } = await tryExecuteAndNotify(this.#host, TemplateResource.deleteTemplateByKey({ key }));
|
||||
const { error } = await this.#dataSource.delete(key);
|
||||
|
||||
if (!error) {
|
||||
const notification = { data: { message: `Template saved` } };
|
||||
const notification = { data: { message: `Template deleted` } };
|
||||
this.#notificationService?.peek('positive', notification);
|
||||
}
|
||||
|
||||
@@ -155,11 +128,9 @@ export class UmbTemplateRepository {
|
||||
return { error };
|
||||
}
|
||||
|
||||
// TODO: add delete
|
||||
// TODO: split into multiple repositories
|
||||
|
||||
async getTreeRoot(): Promise<{ data?: unknown; error?: unknown }> {
|
||||
const { data, error } = await tryExecuteAndNotify(this.#host, TemplateResource.getTreeTemplateRoot({}));
|
||||
async getTreeRoot(): Promise<{ data?: PagedEntityTreeItem; error?: ProblemDetails }> {
|
||||
const { data, error } = await this.#dataSource.getTreeRoot();
|
||||
|
||||
if (data) {
|
||||
this.#treeStore?.appendTreeItems(data.items);
|
||||
@@ -168,17 +139,13 @@ export class UmbTemplateRepository {
|
||||
return { data, error };
|
||||
}
|
||||
|
||||
async getTreeItemChildren(key: string): Promise<{ data?: unknown; error?: unknown }> {
|
||||
if (key) {
|
||||
return { error: 'Key is missing' };
|
||||
async getTreeItemChildren(parentKey: string): Promise<{ data?: PagedEntityTreeItem; error?: ProblemDetails }> {
|
||||
if (!parentKey) {
|
||||
const error: ProblemDetails = { title: 'Parent key is missing' };
|
||||
return { error };
|
||||
}
|
||||
|
||||
const { data, error } = await tryExecuteAndNotify(
|
||||
this.#host,
|
||||
TemplateResource.getTreeTemplateChildren({
|
||||
parentKey: key,
|
||||
})
|
||||
);
|
||||
const { data, error } = await this.#dataSource.getTreeItemChildren(parentKey);
|
||||
|
||||
if (data) {
|
||||
this.#treeStore?.appendTreeItems(data.items);
|
||||
@@ -187,17 +154,13 @@ export class UmbTemplateRepository {
|
||||
return { data, error };
|
||||
}
|
||||
|
||||
async getTreeItems(keys: Array<string>): Promise<{ data?: unknown; error?: unknown }> {
|
||||
if (keys) {
|
||||
return { error: 'Keys are missing' };
|
||||
async getTreeItems(keys: Array<string>): Promise<{ data?: EntityTreeItem[]; error?: ProblemDetails }> {
|
||||
if (!keys) {
|
||||
const error: ProblemDetails = { title: 'Keys are missing' };
|
||||
return { error };
|
||||
}
|
||||
|
||||
const { data, error } = await tryExecuteAndNotify(
|
||||
this.#host,
|
||||
TemplateResource.getTreeTemplateItem({
|
||||
key: keys,
|
||||
})
|
||||
);
|
||||
const { data, error } = await this.#dataSource.getTreeItems(keys);
|
||||
|
||||
if (data) {
|
||||
this.#treeStore?.appendTreeItems(data);
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { TemplateDataSource } from './data';
|
||||
import { ProblemDetails, Template, TemplateResource } from '@umbraco-cms/backend-api';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
|
||||
export class TemplateServerDataSource implements TemplateDataSource {
|
||||
#host: UmbControllerHostInterface;
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
this.#host = host;
|
||||
}
|
||||
|
||||
get(key: string) {
|
||||
return tryExecuteAndNotify(this.#host, TemplateResource.getTemplateByKey({ key }));
|
||||
}
|
||||
|
||||
async createScaffold(parentKey: string | null) {
|
||||
let masterTemplateAlias: string | undefined = undefined;
|
||||
let error = undefined;
|
||||
let data = undefined;
|
||||
|
||||
// TODO: update when backend is updated so we don't have to do two calls
|
||||
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 insert(template: Template) {
|
||||
const payload = { requestBody: template };
|
||||
return tryExecuteAndNotify(this.#host, TemplateResource.postTemplate(payload));
|
||||
}
|
||||
|
||||
async update(template: Template) {
|
||||
if (!template.key) {
|
||||
const error: ProblemDetails = { title: 'Template key is missing' };
|
||||
return { error };
|
||||
}
|
||||
|
||||
const payload = { key: template.key, requestBody: template };
|
||||
return tryExecuteAndNotify(this.#host, TemplateResource.putTemplateByKey(payload));
|
||||
}
|
||||
|
||||
async delete(key: string) {
|
||||
if (!key) {
|
||||
const error: ProblemDetails = { title: 'Key is missing' };
|
||||
return { error };
|
||||
}
|
||||
|
||||
return await tryExecuteAndNotify(this.#host, TemplateResource.deleteTemplateByKey({ key }));
|
||||
}
|
||||
|
||||
async getTreeRoot() {
|
||||
return tryExecuteAndNotify(this.#host, TemplateResource.getTreeTemplateRoot({}));
|
||||
}
|
||||
|
||||
async getTreeItemChildren(parentKey: string | null) {
|
||||
if (!parentKey) {
|
||||
const error: ProblemDetails = { title: 'Parent key is missing' };
|
||||
return { error };
|
||||
}
|
||||
|
||||
return tryExecuteAndNotify(
|
||||
this.#host,
|
||||
TemplateResource.getTreeTemplateChildren({
|
||||
parentKey,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async getTreeItems(keys: Array<string>) {
|
||||
if (keys) {
|
||||
const error: ProblemDetails = { title: 'Keys are missing' };
|
||||
return { error };
|
||||
}
|
||||
|
||||
return tryExecuteAndNotify(
|
||||
this.#host,
|
||||
TemplateResource.getTreeTemplateItem({
|
||||
key: keys,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ export class UmbTemplateWorkspaceContext {
|
||||
}
|
||||
|
||||
async createScaffold(parentKey: string | null) {
|
||||
const { data } = await this.#templateRepository.new(parentKey);
|
||||
const { data } = await this.#templateRepository.createScaffold(parentKey);
|
||||
if (!data) return;
|
||||
this.#data.next(data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user