split up tree and detail

This commit is contained in:
Mads Rasmussen
2023-01-30 15:15:54 +01:00
parent 1aded90f56
commit f575c4b22e
13 changed files with 86 additions and 72 deletions

View File

@@ -149,3 +149,10 @@ export interface DocumentBlueprintDetails {
icon: string;
documentTypeKey: string;
}
export type DataSourceError = Record<string, any>;
export interface DataSourceResponse<T = undefined> {
data?: T;
error?: DataSourceError;
}

View File

@@ -32,8 +32,8 @@ import { UmbDocumentBlueprintDetailStore } from './documents/document-blueprints
import { UmbDocumentBlueprintTreeStore } from './documents/document-blueprints/document-blueprint.tree.store';
import { UmbDataTypeDetailStore } from './settings/data-types/data-type.detail.store';
import { UmbDataTypeTreeStore } from './settings/data-types/tree/data-type.tree.store';
import { UmbTemplateTreeStore } from './templating/templates/tree/template.tree.store';
import { UmbTemplateDetailStore } from './templating/templates/template.detail.store';
import { UmbTemplateTreeStore } from './templating/templates/tree/data/template.tree.store';
import { UmbTemplateDetailStore } from './templating/templates/workspace/data/template.detail.store';
import { UmbThemeService, UMB_THEME_SERVICE_CONTEXT_TOKEN } from './themes/theme.service';
import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';

View File

@@ -1,22 +0,0 @@
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[]>>;
}

View File

@@ -0,0 +1,8 @@
import { DataSourceResponse } from '../../../workspace/data';
import { EntityTreeItem, PagedEntityTreeItem } from '@umbraco-cms/backend-api';
export interface TemplateTreeDataSource {
getTreeRoot(): Promise<DataSourceResponse<PagedEntityTreeItem>>;
getTreeItemChildren(parentKey: string): Promise<DataSourceResponse<PagedEntityTreeItem>>;
getTreeItems(key: Array<string>): Promise<DataSourceResponse<EntityTreeItem[]>>;
}

View File

@@ -0,0 +1,43 @@
import { TemplateTreeDataSource } from '.';
import { ProblemDetails, TemplateResource } from '@umbraco-cms/backend-api';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
export class TemplateTreeServerDataSource implements TemplateTreeDataSource {
#host: UmbControllerHostInterface;
constructor(host: UmbControllerHostInterface) {
this.#host = host;
}
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,
})
);
}
}

View File

@@ -1,5 +1,5 @@
import { Observable } from 'rxjs';
import { TemplateServerDataSource } from '../data/template.server';
import { TemplateTreeServerDataSource } from './sources/template.tree.server.data';
import { UmbTemplateTreeStore, UMB_TEMPLATE_TREE_STORE_CONTEXT_TOKEN } from './template.tree.store';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
@@ -8,7 +8,7 @@ import { EntityTreeItem, PagedEntityTreeItem, ProblemDetails } from '@umbraco-cm
export class UmbTemplateTreeRepository {
#host: UmbControllerHostInterface;
#dataSource: TemplateServerDataSource;
#dataSource: TemplateTreeServerDataSource;
#treeStore!: UmbTemplateTreeStore;
#notificationService?: UmbNotificationService;
#initResolver?: (value: unknown) => void;
@@ -17,7 +17,7 @@ export class UmbTemplateTreeRepository {
constructor(host: UmbControllerHostInterface) {
this.#host = host;
// TODO: figure out how spin up get the correct data source
this.#dataSource = new TemplateServerDataSource(this.#host);
this.#dataSource = new TemplateTreeServerDataSource(this.#host);
new UmbContextConsumerController(this.#host, UMB_TEMPLATE_TREE_STORE_CONTEXT_TOKEN, (instance) => {
this.#treeStore = instance;

View File

@@ -1,4 +1,4 @@
import { UmbTemplateTreeRepository } from './template.tree.repository';
import { UmbTemplateTreeRepository } from './data/template.tree.repository';
import type { ManifestTree, ManifestTreeItemAction } from '@umbraco-cms/models';
const tree: ManifestTree = {

View File

@@ -0,0 +1,10 @@
import { Template } from '@umbraco-cms/backend-api';
import type { DataSourceResponse } from '@umbraco-cms/models';
export interface TemplateDetailDataSource {
createScaffold(parentKey: string | null): Promise<DataSourceResponse<Template>>;
get(key: string): Promise<DataSourceResponse<Template>>;
insert(template: Template): Promise<DataSourceResponse>;
update(template: Template): Promise<DataSourceResponse>;
delete(key: string): Promise<DataSourceResponse>;
}

View File

@@ -1,10 +1,10 @@
import { v4 as uuid } from 'uuid';
import { TemplateDataSource } from '.';
import { TemplateDetailDataSource } from '.';
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 {
export class UmbTemplateDetailServerDataSource implements TemplateDetailDataSource {
#host: UmbControllerHostInterface;
constructor(host: UmbControllerHostInterface) {
this.#host = host;
@@ -71,36 +71,4 @@ export class TemplateServerDataSource implements TemplateDataSource {
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,
})
);
}
}

View File

@@ -1,5 +1,5 @@
import { UmbTemplateDetailStore, UMB_TEMPLATE_DETAIL_STORE_CONTEXT_TOKEN } from './template.detail.store';
import { TemplateServerDataSource } from './data/template.server';
import { UmbTemplateDetailServerDataSource } from './sources/template.detail.server.data';
import { ProblemDetails, Template } from '@umbraco-cms/backend-api';
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
@@ -9,7 +9,7 @@ import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '
// element -> context -> repository -> (store) -> data source
export class UmbTemplateDetailRepository {
#host: UmbControllerHostInterface;
#dataSource: TemplateServerDataSource;
#dataSource: UmbTemplateDetailServerDataSource;
#detailStore?: UmbTemplateDetailStore;
#notificationService?: UmbNotificationService;
#initResolver?: (value: unknown) => void;
@@ -18,7 +18,7 @@ export class UmbTemplateDetailRepository {
constructor(host: UmbControllerHostInterface) {
this.#host = host;
// TODO: figure out how spin up get the correct data source
this.#dataSource = new TemplateServerDataSource(this.#host);
this.#dataSource = new UmbTemplateDetailServerDataSource(this.#host);
new UmbContextConsumerController(this.#host, UMB_TEMPLATE_DETAIL_STORE_CONTEXT_TOKEN, (instance) => {
this.#detailStore = instance;

View File

@@ -1,11 +1,11 @@
import { UmbTemplateDetailRepository } from '../template.detail.repository';
import { UmbTemplateDetailRepository } from './data/template.detail.repository';
import { createObservablePart, DeepState } from '@umbraco-cms/observable-api';
import { Template } from '@umbraco-cms/backend-api';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
export class UmbTemplateWorkspaceContext {
#host: UmbControllerHostInterface;
#templateRepository: UmbTemplateDetailRepository;
#templateDetailRepo: UmbTemplateDetailRepository;
#data = new DeepState<Template | undefined>(undefined);
data = this.#data.asObservable();
@@ -14,7 +14,7 @@ export class UmbTemplateWorkspaceContext {
constructor(host: UmbControllerHostInterface) {
this.#host = host;
this.#templateRepository = new UmbTemplateDetailRepository(this.#host);
this.#templateDetailRepo = new UmbTemplateDetailRepository(this.#host);
}
setName(value: string) {
@@ -26,24 +26,24 @@ export class UmbTemplateWorkspaceContext {
}
async load(entityKey: string) {
const { data } = await this.#templateRepository.get(entityKey);
const { data } = await this.#templateDetailRepo.get(entityKey);
if (data) {
this.#data.next(data);
}
}
async createScaffold(parentKey: string | null) {
const { data } = await this.#templateRepository.createScaffold(parentKey);
const { data } = await this.#templateDetailRepo.createScaffold(parentKey);
if (!data) return;
this.#data.next(data);
}
async save(isNew: boolean) {
if (!this.#data.value) return;
isNew ? this.#templateRepository.insert(this.#data.value) : this.#templateRepository.update(this.#data.value);
isNew ? this.#templateDetailRepo.insert(this.#data.value) : this.#templateDetailRepo.update(this.#data.value);
}
async delete(key: string) {
await this.#templateRepository.delete(key);
await this.#templateDetailRepo.delete(key);
}
}