data type

This commit is contained in:
Niels Lyngsø
2023-01-23 15:47:46 +01:00
parent 9d5b0befbc
commit 090e2fbc2c
7 changed files with 209 additions and 12 deletions

View File

@@ -12,7 +12,7 @@ export const UMB_DOCUMENT_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDo
/**
* @export
* @class UmbDocumentStore
* @extends {UmbStoreBase<DocumentDetails>}
* @extends {UmbStoreBase}
* @description - Data Store for Documents
*/
export class UmbDocumentDetailStore extends UmbStoreBase implements UmbContentStore<DocumentDetails> {

View File

@@ -1,4 +1,3 @@
import type { Observable } from 'rxjs';
import { DocumentResource, DocumentTreeItem } from '@umbraco-cms/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
import { UmbContextToken } from '@umbraco-cms/context-api';
@@ -13,7 +12,7 @@ export const UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDocu
/**
* @export
* @class UmbDocumentStore
* @extends {UmbStoreBase<DocumentTree>}
* @extends {UmbStoreBase}
* @description - Data Store for Documents
*/
export class UmbDocumentTreeStore extends UmbStoreBase {

View File

@@ -12,7 +12,7 @@ export const UMB_MEDIA_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbMedia
/**
* @export
* @class UmbMediaStore
* @extends {UmbStoreBase<DocumentDetails>}
* @extends {UmbStoreBase}
* @description - Data Store for Media
*/
export class UmbMediaDetailStore extends UmbStoreBase implements UmbContentStore<MediaDetails> {

View File

@@ -15,7 +15,7 @@ type MediaTreeItem = ContentTreeItem;
/**
* @export
* @class UmbMediaTreeStore
* @extends {UmbStoreBase<MediaTree>}
* @extends {UmbStoreBase}
* @description - Data Store for Media
*/
export class UmbMediaTreeStore extends UmbStoreBase {

View File

@@ -0,0 +1,99 @@
import type { DataTypeDetails } from '@umbraco-cms/models';
import { UmbContextToken } from '@umbraco-cms/context-api';
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
import { UmbStoreBase } from '@umbraco-cms/stores/store-base';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import { DataTypeResource } from '@umbraco-cms/backend-api';
export const UMB_DATA_TYPE_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDataTypeDetailStore>('UmbDataTypeDetailStore');
/**
* @export
* @class UmbDataTypeDetailStore
* @extends {UmbStoreBase}
* @description - Details Data Store for Data Types
*/
export class UmbDataTypeDetailStore extends UmbStoreBase {
private _data = new UniqueArrayBehaviorSubject<DataTypeDetails>([], (x) => x.key);
constructor(host: UmbControllerHostInterface) {
super(host, UMB_DATA_TYPE_DETAIL_STORE_CONTEXT_TOKEN.toString());
}
/**
* @description - Request a Data Type by key. The Data Type is added to the store and is returned as an Observable.
* @param {string} key
* @return {*} {(Observable<DataTypeDetails | undefined>)}
* @memberof UmbDataTypesStore
*/
getByKey(key: string) {
// TODO: use backend cli when available.
fetch(`/umbraco/management/api/v1/document/data-type/${key}`)
.then((res) => res.json())
.then((data) => {
this._data.append(data);
});
return createObservablePart(this._data, (documents) =>
documents.find((document) => document.key === key)
);
}
// TODO: make sure UI somehow can follow the status of this action.
/**
* @description - Save a Data Type.
* @param {Array<DataTypeDetails>} dataTypes
* @memberof UmbDataTypesStore
* @return {*} {Promise<void>}
*/
save(data: DataTypeDetails[]) {
// fetch from server and update store
// TODO: use Fetcher API.
let body: string;
try {
body = JSON.stringify(data);
} catch (error) {
console.error(error);
return Promise.reject();
}
// TODO: use backend cli when available.
return fetch('/umbraco/management/api/v1/data-type/save', {
method: 'POST',
body: body,
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => res.json())
.then((data: Array<DataTypeDetails>) => {
this._data.append(data);
});
}
// TODO: How can we avoid having this in both stores?
/**
* @description - Delete a Data Type.
* @param {string[]} keys
* @memberof UmbDataTypesStore
* @return {*} {Promise<void>}
*/
async delete(keys: string[]) {
// TODO: use backend cli when available.
await fetch('/umbraco/backoffice/data-type/delete', {
method: 'POST',
body: JSON.stringify(keys),
headers: {
'Content-Type': 'application/json',
},
});
this._data.remove(keys);
}
}

View File

@@ -0,0 +1,96 @@
import { DataTypeResource, DocumentTreeItem } from '@umbraco-cms/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
import { UmbContextToken } from '@umbraco-cms/context-api';
import { createObservablePart, UniqueArrayBehaviorSubject } from '@umbraco-cms/observable-api';
import { UmbStoreBase } from '@umbraco-cms/stores/store-base';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
export const UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDocumentTreeStore>('UmbDocumentTreeStore');
/**
* @export
* @class UmbDocumentStore
* @extends {UmbStoreBase<DocumentTree>}
* @description - Tree Data Store for Data Types
*/
export class UmbDocumentTreeStore extends UmbStoreBase {
private _data = new UniqueArrayBehaviorSubject<DocumentTreeItem>([], (x) => x.key);
constructor(host: UmbControllerHostInterface) {
super(host, UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN.toString());
}
// TODO: How can we avoid having this in both stores?
/**
* @description - Delete a Data Type.
* @param {string[]} keys
* @memberof UmbDataTypesStore
* @return {*} {Promise<void>}
*/
async delete(keys: string[]) {
// TODO: use backend cli when available.
await fetch('/umbraco/backoffice/data-type/delete', {
method: 'POST',
body: JSON.stringify(keys),
headers: {
'Content-Type': 'application/json',
},
});
this._data.remove(keys);
}
getTreeRoot() {
tryExecuteAndNotify(this._host, DataTypeResource.getTreeDataTypeRoot({})).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.items);
}
});
// TODO: how do we handle trashed items?
// TODO: remove ignore when we know how to handle trashed items.
return createObservablePart(this._data, (items) => items.filter((item) => item.parentKey === null && !item.isTrashed));
}
getTreeItemChildren(key: string) {
tryExecuteAndNotify(
this._host,
DataTypeResource.getTreeDataTypeChildren({
parentKey: 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.items);
}
});
// TODO: how do we handle trashed items?
// TODO: remove ignore when we know how to handle trashed items.
return createObservablePart(this._data, (items) => items.filter((item) => item.parentKey === key && !item.isTrashed));
}
getTreeItems(keys: Array<string>) {
if (keys?.length > 0) {
tryExecuteAndNotify(
this._host,
DataTypeResource.getTreeDataTypeItem({
key: keys,
})
).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.filter((item) => keys.includes(item.key ?? '')));
}
}

View File

@@ -28,16 +28,19 @@ export class UniqueArrayBehaviorSubject<T> extends UniqueBehaviorSubject<T[]> {
* { key: 2, value: 'bar'}
* ];
* const mySubject = new UniqueArrayBehaviorSubject(data, (x) => x.key);
* mySubject.remove(1);
* mySubject.remove([1]);
*/
remove(unique: unknown) {
remove(uniques: unknown[]) {
const unFrozenDataSet = [...this.getValue()];
if (this._getUnique) {
unFrozenDataSet.filter(x => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return this._getUnique(x) !== unique;
});
uniques.forEach( unique =>
unFrozenDataSet.filter(x => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return this._getUnique(x) !== unique;
})
);
this.next(unFrozenDataSet);
}
}