split tree from repo

This commit is contained in:
Mads Rasmussen
2023-11-15 19:58:36 +01:00
parent 14a0ec2ef5
commit 631f867474
13 changed files with 120 additions and 147 deletions

View File

@@ -0,0 +1,2 @@
export const UMB_DICTIONARY_ROOT_ENTITY_TYPE = 'dictionary-root';
export const UMB_DICTIONARY_ENTITY_TYPE = 'dictionary-item';

View File

@@ -1,4 +1,5 @@
import { DICTIONARY_REPOSITORY_ALIAS } from '../repository/manifests.js';
import { UMB_DICTIONARY_REPOSITORY_ALIAS } from '../repository/manifests.js';
import { UMB_DICTIONARY_ENTITY_TYPE } from '../entities.js';
import UmbReloadDictionaryEntityAction from './reload.action.js';
import UmbImportDictionaryEntityAction from './import/import.action.js';
import UmbExportDictionaryEntityAction from './export/export.action.js';
@@ -6,9 +7,6 @@ import UmbCreateDictionaryEntityAction from './create/create.action.js';
import { UmbDeleteEntityAction, UmbMoveEntityAction } from '@umbraco-cms/backoffice/entity-action';
import type { ManifestEntityAction, ManifestModal } from '@umbraco-cms/backoffice/extension-registry';
const entityType = 'dictionary-item';
const repositoryAlias = DICTIONARY_REPOSITORY_ALIAS;
const entityActions: Array<ManifestEntityAction> = [
{
type: 'entityAction',
@@ -19,8 +17,8 @@ const entityActions: Array<ManifestEntityAction> = [
meta: {
icon: 'icon-add',
label: 'Create',
repositoryAlias,
entityTypes: [entityType],
repositoryAlias: UMB_DICTIONARY_REPOSITORY_ALIAS,
entityTypes: [UMB_DICTIONARY_ENTITY_TYPE],
},
},
{
@@ -32,8 +30,8 @@ const entityActions: Array<ManifestEntityAction> = [
meta: {
icon: 'icon-enter',
label: 'Move',
repositoryAlias,
entityTypes: [entityType],
repositoryAlias: UMB_DICTIONARY_REPOSITORY_ALIAS,
entityTypes: [UMB_DICTIONARY_ENTITY_TYPE],
},
},
{
@@ -45,8 +43,8 @@ const entityActions: Array<ManifestEntityAction> = [
meta: {
icon: 'icon-download-alt',
label: 'Export',
repositoryAlias,
entityTypes: [entityType],
repositoryAlias: UMB_DICTIONARY_REPOSITORY_ALIAS,
entityTypes: [UMB_DICTIONARY_ENTITY_TYPE],
},
},
{
@@ -58,8 +56,8 @@ const entityActions: Array<ManifestEntityAction> = [
meta: {
icon: 'icon-page-up',
label: 'Import',
repositoryAlias,
entityTypes: [entityType],
repositoryAlias: UMB_DICTIONARY_REPOSITORY_ALIAS,
entityTypes: [UMB_DICTIONARY_ENTITY_TYPE],
},
},
{
@@ -71,8 +69,8 @@ const entityActions: Array<ManifestEntityAction> = [
meta: {
icon: 'icon-refresh',
label: 'Reload',
repositoryAlias,
entityTypes: [entityType],
repositoryAlias: UMB_DICTIONARY_REPOSITORY_ALIAS,
entityTypes: [UMB_DICTIONARY_ENTITY_TYPE],
},
},
{
@@ -84,8 +82,8 @@ const entityActions: Array<ManifestEntityAction> = [
meta: {
icon: 'icon-trash',
label: 'Delete',
repositoryAlias,
entityTypes: [entityType],
repositoryAlias: UMB_DICTIONARY_REPOSITORY_ALIAS,
entityTypes: [UMB_DICTIONARY_ENTITY_TYPE],
},
},
];

View File

@@ -1 +1,2 @@
export * from './repository/index.js';
export * from './tree/index.js';

View File

@@ -1,15 +1,18 @@
import type { ManifestMenuItem } from '@umbraco-cms/backoffice/extension-registry';
import { UMB_DICTIONARY_ENTITY_TYPE } from '../entities.js';
import { UMB_DICTIONARY_TREE_ALIAS } from '../tree/index.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
const menuItem: ManifestMenuItem = {
const menuItem: ManifestTypes = {
type: 'menuItem',
kind: 'tree',
alias: 'Umb.MenuItem.Dictionary',
name: 'Dictionary Menu Item',
weight: 400,
loader: () => import('./dictionary-menu-item.element.js'),
meta: {
label: 'Dictionary',
icon: 'icon-book-alt',
entityType: 'dictionary-item',
entityType: UMB_DICTIONARY_ENTITY_TYPE,
treeAlias: UMB_DICTIONARY_TREE_ALIAS,
menus: ['Umb.Menu.Dictionary'],
},
};

View File

@@ -1,14 +1,11 @@
import { type UmbDictionaryTreeStore, UMB_DICTIONARY_TREE_STORE_CONTEXT } from '../tree/index.js';
import { UmbDictionaryStore, UMB_DICTIONARY_STORE_CONTEXT_TOKEN } from './dictionary.store.js';
import { UmbDictionaryDetailServerDataSource } from './sources/dictionary.detail.server.data.js';
import { UmbDictionaryTreeStore, UMB_DICTIONARY_TREE_STORE_CONTEXT_TOKEN } from './dictionary.tree.store.js';
import { UmbDictionaryTreeServerDataSource } from './sources/dictionary.tree.server.data.js';
import { UmbBaseController, UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import { UmbDetailRepository } from '@umbraco-cms/backoffice/repository';
import { UmbTreeRepository, UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
import {
CreateDictionaryItemRequestModel,
DictionaryOverviewResponseModel,
EntityTreeItemResponseModel,
ImportDictionaryRequestModel,
UpdateDictionaryItemRequestModel,
} from '@umbraco-cms/backoffice/backend-api';
@@ -18,7 +15,6 @@ import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
export class UmbDictionaryRepository
extends UmbBaseController
implements
UmbTreeRepository<EntityTreeItemResponseModel>,
UmbDetailRepository<
CreateDictionaryItemRequestModel,
any,
@@ -29,7 +25,6 @@ export class UmbDictionaryRepository
{
#init!: Promise<unknown>;
#treeSource: UmbTreeDataSource;
#treeStore?: UmbDictionaryTreeStore;
#detailSource: UmbDictionaryDetailServerDataSource;
@@ -41,7 +36,6 @@ export class UmbDictionaryRepository
super(host);
// TODO: figure out how spin up get the correct data source
this.#treeSource = new UmbDictionaryTreeServerDataSource(this);
this.#detailSource = new UmbDictionaryDetailServerDataSource(this);
this.#init = Promise.all([
@@ -49,7 +43,7 @@ export class UmbDictionaryRepository
this.#detailStore = instance;
}),
this.consumeContext(UMB_DICTIONARY_TREE_STORE_CONTEXT_TOKEN, (instance) => {
this.consumeContext(UMB_DICTIONARY_TREE_STORE_CONTEXT, (instance) => {
this.#treeStore = instance;
}),
@@ -59,82 +53,6 @@ export class UmbDictionaryRepository
]);
}
// TREE:
async requestTreeRoot() {
await this.#init;
const data = {
id: null,
type: 'dictionary-root',
name: 'Dictionary',
icon: 'icon-folder',
hasChildren: true,
};
return { data };
}
async requestRootTreeItems() {
await this.#init;
const { data, error } = await this.#treeSource.getRootItems();
if (data) {
this.#treeStore?.appendItems(data.items);
}
return { data, error, asObservable: () => this.#treeStore!.rootItems };
}
async requestTreeItemsOf(parentId: string | null) {
if (parentId === undefined) throw new Error('Parent id is missing');
await this.#init;
const { data, error } = await this.#treeSource.getChildrenOf(parentId);
if (data) {
this.#treeStore?.appendItems(data.items);
}
return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentId) };
}
async requestItemsLegacy(ids: Array<string>) {
await this.#init;
if (!ids) {
throw new Error('Ids are missing');
}
const { data, error } = await this.#treeSource.getItems(ids);
return { data, error, asObservable: () => this.#treeStore!.items(ids) };
}
async requestItems(ids: Array<string>) {
// TODO: There is a bug where the item gets removed from the tree before we confirm the delete via the modal. It doesn't delete the item unless we confirm the delete.
if (!ids) throw new Error('Dictionary Ids are missing');
await this.#init;
const { data, error } = await this.#treeSource.getItems(ids);
if (data) {
this.#treeStore?.appendItems(data);
}
return { data, error, asObservable: () => this.#treeStore!.items(ids) };
}
async rootTreeItems() {
await this.#init;
return this.#treeStore!.rootItems;
}
async treeItemsOf(parentId: string | null) {
await this.#init;
return this.#treeStore!.childrenOf(parentId);
}
async itemsLegacy(ids: Array<string>) {
await this.#init;
return this.#treeStore!.items(ids);

View File

@@ -1,3 +1 @@
export * from './dictionary.repository.js';
export * from './dictionary.store.js';
export * from './dictionary.tree.store.js';

View File

@@ -1,32 +1,23 @@
import { UmbDictionaryRepository } from './dictionary.repository.js';
import { UmbDictionaryTreeStore } from './dictionary.tree.store.js';
import { UmbDictionaryStore } from './dictionary.store.js';
import { ManifestStore, ManifestTreeStore, ManifestRepository } from '@umbraco-cms/backoffice/extension-registry';
import { ManifestStore, ManifestRepository } from '@umbraco-cms/backoffice/extension-registry';
export const DICTIONARY_REPOSITORY_ALIAS = 'Umb.Repository.Dictionary';
export const UMB_DICTIONARY_REPOSITORY_ALIAS = 'Umb.Repository.Dictionary';
const repository: ManifestRepository = {
type: 'repository',
alias: DICTIONARY_REPOSITORY_ALIAS,
alias: UMB_DICTIONARY_REPOSITORY_ALIAS,
name: 'Dictionary Repository',
api: UmbDictionaryRepository,
};
export const DICTIONARY_STORE_ALIAS = 'Umb.Store.Dictionary';
export const DICTIONARY_TREE_STORE_ALIAS = 'Umb.Store.DictionaryTree';
export const UMB_DICTIONARY_STORE_ALIAS = 'Umb.Store.Dictionary';
const store: ManifestStore = {
type: 'store',
alias: DICTIONARY_STORE_ALIAS,
alias: UMB_DICTIONARY_STORE_ALIAS,
name: 'Dictionary Store',
api: UmbDictionaryStore,
};
const treeStore: ManifestTreeStore = {
type: 'treeStore',
alias: DICTIONARY_TREE_STORE_ALIAS,
name: 'Dictionary Tree Store',
api: UmbDictionaryTreeStore,
};
export const manifests = [repository, store, treeStore];
export const manifests = [repository, store];

View File

@@ -0,0 +1,28 @@
import { UMB_DICTIONARY_ROOT_ENTITY_TYPE } from '../entities.js';
import { UmbDictionaryTreeServerDataSource } from './dictionary-tree.server.data-source.js';
import { UmbDictionaryTreeItemModel, UmbDictionaryTreeRootModel } from './types.js';
import { UMB_DICTIONARY_TREE_STORE_CONTEXT } from './dictionary-tree.store.js';
import { UmbTreeRepositoryBase } from '@umbraco-cms/backoffice/tree';
import { type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbApi } from '@umbraco-cms/backoffice/extension-api';
export class UmbDictionaryTreeRepository
extends UmbTreeRepositoryBase<UmbDictionaryTreeItemModel, UmbDictionaryTreeRootModel>
implements UmbApi
{
constructor(host: UmbControllerHost) {
super(host, UmbDictionaryTreeServerDataSource, UMB_DICTIONARY_TREE_STORE_CONTEXT);
}
async requestTreeRoot() {
const data = {
id: null,
type: UMB_DICTIONARY_ROOT_ENTITY_TYPE,
name: 'Hello World',
icon: 'icon-folder',
hasChildren: true,
};
return { data };
}
}

View File

@@ -1,21 +1,21 @@
import { DictionaryResource } from '@umbraco-cms/backoffice/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
import { DictionaryResource, EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
/**
* A data source for the Dictionary tree that fetches data from the server
* @export
* @class UmbDictionaryTreeServerDataSource
* @implements {DictionaryTreeDataSource}
* @implements {UmbTreeDataSource}
*/
export class UmbDictionaryTreeServerDataSource implements UmbTreeDataSource {
export class UmbDictionaryTreeServerDataSource implements UmbTreeDataSource<EntityTreeItemResponseModel> {
#host: UmbControllerHost;
/**
* Creates an instance of DictionaryTreeDataSource.
* Creates an instance of UmbDictionaryTreeServerDataSource.
* @param {UmbControllerHost} host
* @memberof DictionaryTreeDataSource
* @memberof UmbDictionaryTreeServerDataSource
*/
constructor(host: UmbControllerHost) {
this.#host = host;
@@ -32,7 +32,7 @@ export class UmbDictionaryTreeServerDataSource implements UmbTreeDataSource {
/**
* Fetches the children of a given parent id from the server
* @param {(string | null)} parentId
* @param {(string)} parentId
* @return {*}
* @memberof UmbDictionaryTreeServerDataSource
*/
@@ -60,10 +60,7 @@ export class UmbDictionaryTreeServerDataSource implements UmbTreeDataSource {
* @memberof UmbDictionaryTreeServerDataSource
*/
async getItems(ids: Array<string>) {
if (!ids || ids.length === 0) {
throw new Error('Ids are missing');
}
if (!ids) throw new Error('Ids are missing');
return tryExecuteAndNotify(
this.#host,
DictionaryResource.getDictionaryItem({

View File

@@ -1,12 +1,12 @@
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/tree';
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/tree';
/**
* @export
* @class UmbDictionaryTreeStore
* @extends {UmbEntityTreeStore}
* @description - Tree Data Store for Dictionary
* @extends {UmbStoreBase}
* @description - Tree Data Store for Dictionary Items
*/
export class UmbDictionaryTreeStore extends UmbEntityTreeStore {
/**
@@ -15,10 +15,8 @@ export class UmbDictionaryTreeStore extends UmbEntityTreeStore {
* @memberof UmbDictionaryTreeStore
*/
constructor(host: UmbControllerHostElement) {
super(host, UMB_DICTIONARY_TREE_STORE_CONTEXT_TOKEN.toString());
super(host, UMB_DICTIONARY_TREE_STORE_CONTEXT.toString());
}
}
export const UMB_DICTIONARY_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDictionaryTreeStore>(
'UmbDictionaryTreeStore',
);
export const UMB_DICTIONARY_TREE_STORE_CONTEXT = new UmbContextToken<UmbDictionaryTreeStore>('UmbDictionaryTreeStore');

View File

@@ -0,0 +1,9 @@
export { UmbDictionaryTreeRepository } from './dictionary-tree.repository.js';
export {
UMB_DICTIONARY_TREE_REPOSITORY_ALIAS,
UMB_DICTIONARY_TREE_STORE_ALIAS,
UMB_DICTIONARY_TREE_ALIAS,
} from './manifests.js';
export { UMB_DICTIONARY_TREE_STORE_CONTEXT } from './dictionary-tree.store.js';
export { type UmbDictionaryTreeStore } from './dictionary-tree.store.js';
export * from './types.js';

View File

@@ -1,23 +1,48 @@
import { DICTIONARY_REPOSITORY_ALIAS } from '../repository/manifests.js';
import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extension-registry';
import { UMB_DICTIONARY_ENTITY_TYPE, UMB_DICTIONARY_ROOT_ENTITY_TYPE } from '../entities.js';
import { UmbDictionaryTreeRepository } from './dictionary-tree.repository.js';
import { UmbDictionaryTreeStore } from './dictionary-tree.store.js';
import type {
ManifestRepository,
ManifestTree,
ManifestTreeItem,
ManifestTreeStore,
} from '@umbraco-cms/backoffice/extension-registry';
export const UMB_DICTIONARY_TREE_REPOSITORY_ALIAS = 'Umb.Repository.Dictionary.Tree';
export const UMB_DICTIONARY_TREE_STORE_ALIAS = 'Umb.Store.Dictionary.Tree';
export const UMB_DICTIONARY_TREE_ALIAS = 'Umb.Tree.Dictionary';
const treeRepository: ManifestRepository = {
type: 'repository',
alias: UMB_DICTIONARY_TREE_REPOSITORY_ALIAS,
name: 'Dictionary Tree Repository',
api: UmbDictionaryTreeRepository,
};
const treeStore: ManifestTreeStore = {
type: 'treeStore',
alias: UMB_DICTIONARY_TREE_STORE_ALIAS,
name: 'Dictionary Tree Store',
api: UmbDictionaryTreeStore,
};
const tree: ManifestTree = {
type: 'tree',
alias: 'Umb.Tree.Dictionary',
alias: UMB_DICTIONARY_TREE_ALIAS,
name: 'Dictionary Tree',
meta: {
repositoryAlias: DICTIONARY_REPOSITORY_ALIAS,
repositoryAlias: UMB_DICTIONARY_TREE_REPOSITORY_ALIAS,
},
};
const treeItem: ManifestTreeItem = {
type: 'treeItem',
kind: 'entity',
alias: 'Umb.TreeItem.DictionaryItem',
name: 'Dictionary Item Tree Item',
alias: 'Umb.TreeItem.Dictionary',
name: 'Dictionary Tree Item',
meta: {
entityTypes: ['dictionary-root', 'dictionary-item'],
entityTypes: [UMB_DICTIONARY_ROOT_ENTITY_TYPE, UMB_DICTIONARY_ENTITY_TYPE],
},
};
export const manifests = [tree, treeItem];
export const manifests = [treeRepository, treeStore, tree, treeItem];

View File

@@ -0,0 +1,5 @@
import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
import type { UmbEntityTreeItemModel, UmbEntityTreeRootModel } from '@umbraco-cms/backoffice/tree';
export type UmbDictionaryTreeItemModel = EntityTreeItemResponseModel & UmbEntityTreeItemModel;
export type UmbDictionaryTreeRootModel = EntityTreeItemResponseModel & UmbEntityTreeRootModel;