map server models to client models

This commit is contained in:
Mads Rasmussen
2023-11-23 13:15:15 +01:00
parent f6ac3eec4c
commit 9300a4717e
6 changed files with 60 additions and 29 deletions

View File

@@ -35,7 +35,7 @@ export class UmbDataTypeServerDataSource implements UmbDetailDataSource<UmbDataT
*/
async createScaffold(parentUnique: string | null) {
const data: UmbDataTypeDetailModel = {
entityType: 'data-type',
type: 'data-type',
unique: UmbId.new(),
parentUnique,
name: '',

View File

@@ -1,3 +1,4 @@
import { UmbDataTypeTreeItemModel } from './types.js';
import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
import { DataTypeResource, DataTypeTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
@@ -9,7 +10,7 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
* @class UmbDataTypeTreeServerDataSource
* @implements {DocumentTreeDataSource}
*/
export class UmbDataTypeTreeServerDataSource implements UmbTreeDataSource<DataTypeTreeItemResponseModel> {
export class UmbDataTypeTreeServerDataSource implements UmbTreeDataSource<UmbDataTypeTreeItemModel> {
#host: UmbControllerHost;
/**
@@ -27,45 +28,72 @@ export class UmbDataTypeTreeServerDataSource implements UmbTreeDataSource<DataTy
* @memberof UmbDataTypeTreeServerDataSource
*/
async getRootItems() {
return tryExecuteAndNotify(this.#host, DataTypeResource.getTreeDataTypeRoot({}));
const { data, error } = await tryExecuteAndNotify(this.#host, DataTypeResource.getTreeDataTypeRoot({}));
if (data) {
const items = data?.items.map((item) => mapper(item));
return { data: { total: data.total, items } };
}
return { error };
}
/**
* Fetches the children of a given parent id from the server
* @param {(string)} parentId
* Fetches the children of a given parent unique from the server
* @param {(string)} parentUnique
* @return {*}
* @memberof UmbDataTypeTreeServerDataSource
*/
async getChildrenOf(parentId: string | null) {
if (parentId === undefined) throw new Error('Parent id is missing');
async getChildrenOf(parentUnique: string | null) {
if (parentUnique === undefined) throw new Error('Parent unique is missing');
/* TODO: should we make getRootItems() internal
so it only is a server concern that there are two endpoints? */
if (parentId === null) {
if (parentUnique === null) {
return this.getRootItems();
} else {
return tryExecuteAndNotify(
this.#host,
DataTypeResource.getTreeDataTypeChildren({
parentId,
}),
);
}
const { data, error } = await tryExecuteAndNotify(
this.#host,
DataTypeResource.getTreeDataTypeChildren({
parentId: parentUnique,
}),
);
if (data) {
const items = data?.items.map((item) => mapper(item));
return { data: { total: data.total, items } };
}
return { error };
}
/**
* Fetches the items for the given ids from the server
* @param {Array<string>} ids
* @param {Array<string>} uniques
* @return {*}
* @memberof UmbDataTypeTreeServerDataSource
*/
async getItems(ids: Array<string>) {
if (!ids) throw new Error('Ids are missing');
async getItems(uniques: Array<string>) {
if (!uniques) throw new Error('Uniques are missing');
return tryExecuteAndNotify(
this.#host,
DataTypeResource.getDataTypeItem({
id: ids,
id: uniques,
}),
);
}
}
const mapper = (item: DataTypeTreeItemResponseModel): UmbDataTypeTreeItemModel => {
return {
unique: item.id!,
parentUnique: item.parentId || null,
name: item.name!,
type: item.isFolder ? 'data-type-folder' : 'data-type',
isFolder: item.isFolder!,
isContainer: item.isContainer!,
hasChildren: item.hasChildren!,
};
};

View File

@@ -35,7 +35,7 @@ export class UmbDataTypeTreeStore extends UmbUniqueTreeStore {
unique: item.unique!,
parentUnique: item.parentUnique,
name: item.name,
entityType: item.entityType,
type: item.type,
isFolder: false,
isContainer: false,
hasChildren: false,

View File

@@ -7,7 +7,7 @@ export type UmbDataTypeTreeItemModel = {
isFolder: boolean;
isContainer: boolean;
name: string;
entityType: string;
type: string;
hasChildren: boolean;
};

View File

@@ -1,7 +1,7 @@
import { DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
export type UmbDataTypeDetailModel = Omit<DataTypeResponseModel, 'id' | 'parentId'> & {
entityType: string;
type: string;
unique: string | undefined; // TODO - remove this when server doesn't allow undefined
parentUnique: string | null | undefined; // TODO - remove this when server doesn't allow undefined
};

View File

@@ -4,19 +4,22 @@ import { UmbStore } from './store.interface.js';
import { UmbContextConsumerController, UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
export class UmbStoreConnector {
export class UmbStoreConnector<StoreType, ConnectedStoreType> {
#store: UmbStoreBase;
#connectedStore?: UmbStore<any>;
#mapperFunction: (item: any) => any;
#connectedStore?: UmbStore<ConnectedStoreType>;
#createMapperFunction: (item: ConnectedStoreType) => StoreType;
#updateMapperFunction?: (item: ConnectedStoreType) => StoreType;
constructor(
host: UmbControllerHost,
store: UmbStoreBase,
connectToStoreAlias: UmbContextToken<any, any> | string,
mapperFunction: (item: any) => any,
createMapperFunction: (item: ConnectedStoreType) => StoreType,
updateMapperFunction: (item: ConnectedStoreType) => StoreType,
) {
this.#store = store;
this.#mapperFunction = mapperFunction;
this.#createMapperFunction = createMapperFunction;
this.#updateMapperFunction = updateMapperFunction;
new UmbContextConsumerController(host, connectToStoreAlias, (instance) => {
this.#connectedStore = instance;
@@ -36,14 +39,14 @@ export class UmbStoreConnector {
#onConnectedStoreCreate = (event: UmbStoreCreateEvent) => {
const items = this.#connectedStore!.getItems(event.uniques);
const mappedItems = items.map((item) => this.#mapperFunction(item));
const mappedItems = items.map((item) => this.#createMapperFunction(item));
this.#store.appendItems(mappedItems);
};
#onConnectedStoreUpdate = (event: UmbStoreUpdateEvent) => {
const uniques = event.uniques;
const items = this.#connectedStore!.getItems(uniques);
const mappedItems = items.map((item) => this.#mapperFunction(item));
const mappedItems = items.map((item) => this.#updateMapperFunction(item));
mappedItems.forEach((mappedItem, index) => this.#store.updateItem(uniques[index], mappedItem));
};