Merge pull request #391 from umbraco/feature/tryExecute-for-stores

Feature/tryExecute-for-stores
This commit is contained in:
Jacob Overgaard
2023-01-12 09:23:33 +01:00
committed by GitHub
10 changed files with 134 additions and 221 deletions

View File

@@ -20,6 +20,7 @@ import { UmbDocumentBlueprintStore } from './documents/document-blueprints/docum
import { UmbSectionStore } from './shared/components/section/section.store';
import { UmbDataTypeStore } from './settings/data-types/data-type.store';
import { UmbLitElement } from '@umbraco-cms/element';
// Domains
import './settings';
@@ -31,7 +32,6 @@ import './users';
import './packages';
import './search';
import './shared';
import { UmbLitElement } from '@umbraco-cms/element';
@defineElement('umb-backoffice')
export class UmbBackofficeElement extends UmbLitElement {
@@ -53,23 +53,24 @@ export class UmbBackofficeElement extends UmbLitElement {
constructor() {
super();
this.provideContext('umbModalService', new UmbModalService());
this.provideContext('umbNotificationService', new UmbNotificationService());
// TODO: find a way this is possible outside this element. It needs to be possible to register stores in extensions
this.provideContext('umbCurrentUserStore', new UmbCurrentUserStore());
this.provideContext('umbDocumentStore', new UmbDocumentStore());
this.provideContext('umbMediaStore', new UmbMediaStore());
this.provideContext('umbDataTypeStore', new UmbDataTypeStore());
this.provideContext('umbDocumentTypeStore', new UmbDocumentTypeStore());
this.provideContext('umbMediaTypeStore', new UmbMediaTypeStore());
this.provideContext('umbMemberTypeStore', new UmbMemberTypeStore());
this.provideContext('umbUserStore', new UmbUserStore());
this.provideContext('umbUserGroupStore', new UmbUserGroupStore());
this.provideContext('umbMemberGroupStore', new UmbMemberGroupStore());
this.provideContext('umbNotificationService', new UmbNotificationService());
this.provideContext('umbModalService', new UmbModalService());
this.provideContext('umbDocumentStore', new UmbDocumentStore(this));
this.provideContext('umbMediaStore', new UmbMediaStore(this));
this.provideContext('umbDataTypeStore', new UmbDataTypeStore(this));
this.provideContext('umbDocumentTypeStore', new UmbDocumentTypeStore(this));
this.provideContext('umbMediaTypeStore', new UmbMediaTypeStore(this));
this.provideContext('umbMemberTypeStore', new UmbMemberTypeStore(this));
this.provideContext('umbUserStore', new UmbUserStore(this));
this.provideContext('umbUserGroupStore', new UmbUserGroupStore(this));
this.provideContext('umbMemberGroupStore', new UmbMemberGroupStore(this));
this.provideContext('umbSectionStore', new UmbSectionStore());
this.provideContext('umbCurrentUserHistoryStore', new UmbCurrentUserHistoryStore());
this.provideContext('umbDictionaryStore', new UmbDictionaryStore());
this.provideContext('umbDocumentBlueprintStore', new UmbDocumentBlueprintStore());
this.provideContext('umbDictionaryStore', new UmbDictionaryStore(this));
this.provideContext('umbDocumentBlueprintStore', new UmbDocumentBlueprintStore(this));
}
render() {

View File

@@ -1,7 +1,8 @@
import { map, Observable } from 'rxjs';
import { UmbDataStoreBase } from '../../../core/stores/store';
import { ApiError, DocumentTypeResource, DocumentTypeTreeItem, ProblemDetails } from '@umbraco-cms/backend-api';
import { DocumentTypeResource, DocumentTypeTreeItem } from '@umbraco-cms/backend-api';
import type { DocumentTypeDetails } from '@umbraco-cms/models';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
export const isDocumentTypeDetails = (
documentType: DocumentTypeDetails | DocumentTypeTreeItem
@@ -57,39 +58,26 @@ export class UmbDocumentTypeStore extends UmbDataStoreBase<UmbDocumentTypeStoreI
}
getTreeRoot(): Observable<Array<DocumentTypeTreeItem>> {
DocumentTypeResource.getTreeDocumentTypeRoot({}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(this.host, DocumentTypeResource.getTreeDocumentTypeRoot({})).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === null)));
}
getTreeItemChildren(key: string): Observable<Array<DocumentTypeTreeItem>> {
DocumentTypeResource.getTreeDocumentTypeChildren({
parentKey: key,
}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(
this.host,
DocumentTypeResource.getTreeDocumentTypeChildren({
parentKey: key,
})
).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === key)));
}

View File

@@ -1,7 +1,8 @@
import { map, Observable } from 'rxjs';
import { UmbNodeStoreBase } from '../../../core/stores/store';
import type { DocumentDetails } from '@umbraco-cms/models';
import { ApiError, DocumentResource, DocumentTreeItem, FolderTreeItem, ProblemDetails } from '@umbraco-cms/backend-api';
import { DocumentResource, DocumentTreeItem, FolderTreeItem } from '@umbraco-cms/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
export const isDocumentDetails = (document: DocumentDetails | DocumentTreeItem): document is DocumentDetails => {
return (document as DocumentDetails).data !== undefined;
@@ -79,19 +80,11 @@ export class UmbDocumentStore extends UmbNodeStoreBase<UmbDocumentStoreItemType>
}
getTreeRoot(): Observable<Array<DocumentTreeItem>> {
DocumentResource.getTreeDocumentRoot({}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(this.host, DocumentResource.getTreeDocumentRoot({})).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
// TODO: how do we handle trashed items?
// TODO: remove ignore when we know how to handle trashed items.
@@ -101,21 +94,16 @@ export class UmbDocumentStore extends UmbNodeStoreBase<UmbDocumentStoreItemType>
}
getTreeItemChildren(key: string): Observable<Array<FolderTreeItem>> {
DocumentResource.getTreeDocumentChildren({
parentKey: key,
}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(
this.host,
DocumentResource.getTreeDocumentChildren({
parentKey: key,
})
).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
// TODO: how do we handle trashed items?
// TODO: remove ignore when we know how to handle trashed items.
@@ -126,21 +114,16 @@ export class UmbDocumentStore extends UmbNodeStoreBase<UmbDocumentStoreItemType>
getTreeItems(keys: Array<string>): Observable<Array<FolderTreeItem>> {
if (keys?.length > 0) {
DocumentResource.getTreeDocumentItem({
key: keys,
}).then(
(items) => {
this.updateItems(items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(
this.host,
DocumentResource.getTreeDocumentItem({
key: keys,
})
).then(({ data }) => {
if (data) {
this.updateItems(data);
}
);
});
}
return this.items.pipe(map((items) => items.filter((item) => keys.includes(item.key ?? ''))));

View File

@@ -1,7 +1,8 @@
import { map, Observable } from 'rxjs';
import { UmbNodeStoreBase } from '../../../core/stores/store';
import { MediaTypeResource, ApiError, ProblemDetails, FolderTreeItem } from '@umbraco-cms/backend-api';
import { MediaTypeResource, FolderTreeItem } from '@umbraco-cms/backend-api';
import type { MediaTypeDetails } from '@umbraco-cms/models';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
export type UmbMediaTypeStoreItemType = MediaTypeDetails | FolderTreeItem;
/**
@@ -60,39 +61,26 @@ export class UmbMediaTypeStore extends UmbNodeStoreBase<UmbMediaTypeStoreItemTyp
}
getTreeRoot(): Observable<Array<FolderTreeItem>> {
MediaTypeResource.getTreeMediaTypeRoot({}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(this.host, MediaTypeResource.getTreeMediaTypeRoot({})).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === null)));
}
getTreeItemChildren(key: string): Observable<Array<FolderTreeItem>> {
MediaTypeResource.getTreeMediaTypeChildren({
parentKey: key,
}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(
this.host,
MediaTypeResource.getTreeMediaTypeChildren({
parentKey: key,
})
).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === key)));
}

View File

@@ -1,7 +1,8 @@
import { map, Observable } from 'rxjs';
import { UmbDataStoreBase } from '../../../core/stores/store';
import type { MediaDetails } from '@umbraco-cms/models';
import { ApiError, ContentTreeItem, MediaResource, ProblemDetails } from '@umbraco-cms/backend-api';
import { ContentTreeItem, MediaResource } from '@umbraco-cms/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
const isMediaDetails = (media: UmbMediaStoreItemType): media is MediaDetails => {
return (media as MediaDetails).data !== undefined;
@@ -75,19 +76,11 @@ export class UmbMediaStore extends UmbDataStoreBase<UmbMediaStoreItemType> {
}
getTreeRoot(): Observable<Array<ContentTreeItem>> {
MediaResource.getTreeMediaRoot({}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(this.host, MediaResource.getTreeMediaRoot({})).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
// TODO: how do we handle trashed items?
// TODO: remove ignore when we know how to handle trashed items.
@@ -97,21 +90,16 @@ export class UmbMediaStore extends UmbDataStoreBase<UmbMediaStoreItemType> {
}
getTreeItemChildren(key: string): Observable<Array<ContentTreeItem>> {
MediaResource.getTreeMediaChildren({
parentKey: key,
}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(
this.host,
MediaResource.getTreeMediaChildren({
parentKey: key,
})
).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
// TODO: how do we handle trashed items?
// TODO: remove ignore when we know how to handle trashed items.

View File

@@ -1,7 +1,8 @@
import { map, Observable } from 'rxjs';
import { UmbNodeStoreBase } from '../../../core/stores/store';
import { ApiError, EntityTreeItem, MemberGroupResource, ProblemDetails } from '@umbraco-cms/backend-api';
import { EntityTreeItem, MemberGroupResource } from '@umbraco-cms/backend-api';
import type { MemberGroupDetails } from '@umbraco-cms/models';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
export type UmbMemberGroupStoreItemType = MemberGroupDetails | EntityTreeItem;
@@ -23,19 +24,11 @@ export class UmbMemberGroupStore extends UmbNodeStoreBase<UmbMemberGroupStoreIte
}
getTreeRoot(): Observable<Array<EntityTreeItem>> {
MemberGroupResource.getTreeMemberGroupRoot({}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(this.host, MemberGroupResource.getTreeMemberGroupRoot({})).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === null)));
}

View File

@@ -1,7 +1,8 @@
import { map, Observable } from 'rxjs';
import { UmbDataStoreBase } from '../../../core/stores/store';
import { MemberTypeResource, ApiError, EntityTreeItem, ProblemDetails } from '@umbraco-cms/backend-api';
import { MemberTypeResource, EntityTreeItem } from '@umbraco-cms/backend-api';
import type { MemberTypeDetails } from '@umbraco-cms/models';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
export type UmbMemberTypeStoreItemType = MemberTypeDetails | EntityTreeItem;
@@ -23,19 +24,11 @@ export class UmbMemberTypeStore extends UmbDataStoreBase<UmbMemberTypeStoreItemT
}
getTreeRoot(): Observable<Array<EntityTreeItem>> {
MemberTypeResource.getTreeMemberTypeRoot({}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(this.host, MemberTypeResource.getTreeMemberTypeRoot({})).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === null)));
}

View File

@@ -1,7 +1,8 @@
import { map, Observable } from 'rxjs';
import { UmbDataStoreBase } from '../../../core/stores/store';
import type { DataTypeDetails } from '@umbraco-cms/models';
import { ApiError, DataTypeResource, FolderTreeItem, ProblemDetails } from '@umbraco-cms/backend-api';
import { DataTypeResource, FolderTreeItem } from '@umbraco-cms/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
const isDataTypeDetails = (dataType: DataTypeDetails | FolderTreeItem): dataType is DataTypeDetails => {
return (dataType as DataTypeDetails).data !== undefined;
@@ -14,7 +15,6 @@ export type UmbDataTypeStoreItemType = DataTypeDetails | FolderTreeItem;
// TODO: research how we write names of global consts.
export const STORE_ALIAS = 'umbDataTypeStore';
/**
* @export
* @class UmbDataTypesStore
@@ -22,7 +22,6 @@ export const STORE_ALIAS = 'umbDataTypeStore';
* @description - Data Store for Data Types
*/
export class UmbDataTypeStore extends UmbDataStoreBase<UmbDataTypeStoreItemType> {
public readonly storeAlias = STORE_ALIAS;
/**
@@ -95,19 +94,11 @@ export class UmbDataTypeStore extends UmbDataStoreBase<UmbDataTypeStoreItemType>
* @memberof UmbDataTypesStore
*/
getTreeRoot(): Observable<Array<FolderTreeItem>> {
DataTypeResource.getTreeDataTypeRoot({}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(this.host, DataTypeResource.getTreeDataTypeRoot({})).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === null)));
}
@@ -119,21 +110,16 @@ export class UmbDataTypeStore extends UmbDataStoreBase<UmbDataTypeStoreItemType>
* @memberof UmbDataTypesStore
*/
getTreeItemChildren(key: string): Observable<Array<FolderTreeItem>> {
DataTypeResource.getTreeDataTypeChildren({
parentKey: key,
}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(
this.host,
DataTypeResource.getTreeDataTypeChildren({
parentKey: key,
})
).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === key)));
}

View File

@@ -1,6 +1,7 @@
import { map, Observable } from 'rxjs';
import { UmbDataStoreBase } from '../../../core/stores/store';
import { ApiError, DictionaryResource, EntityTreeItem, ProblemDetails } from '@umbraco-cms/backend-api';
import { DictionaryResource, EntityTreeItem } from '@umbraco-cms/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
/**
* @export
@@ -17,19 +18,11 @@ export class UmbDictionaryStore extends UmbDataStoreBase<EntityTreeItem> {
* @memberof UmbDictionaryStore
*/
getTreeRoot(): Observable<Array<EntityTreeItem>> {
DictionaryResource.getTreeDictionaryRoot({}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(this.host, DictionaryResource.getTreeDictionaryRoot({})).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === null)));
}
@@ -41,21 +34,16 @@ export class UmbDictionaryStore extends UmbDataStoreBase<EntityTreeItem> {
* @memberof UmbDataTypesStore
*/
getTreeItemChildren(key: string): Observable<Array<EntityTreeItem>> {
DictionaryResource.getTreeDictionaryChildren({
parentKey: key,
}).then(
(res) => {
this.updateItems(res.items);
},
(e) => {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
console.log(error.detail);
}
}
tryExecuteAndNotify(
this.host,
DictionaryResource.getTreeDictionaryChildren({
parentKey: key,
})
).then(({ data }) => {
if (data) {
this.updateItems(data.items);
}
);
});
return this.items.pipe(map((items) => items.filter((item) => item.parentKey === key)));
}

View File

@@ -1,4 +1,5 @@
import type { Observable } from 'rxjs';
import { UmbControllerHostInterface } from '../controller/controller-host.mixin';
import { UniqueBehaviorSubject } from '../observable-api/unique-behavior-subject';
export interface UmbDataStoreIdentifiers {
@@ -30,6 +31,12 @@ export abstract class UmbDataStoreBase<T extends UmbDataStoreIdentifiers> implem
protected _items = new UniqueBehaviorSubject(<Array<T>>[]);
public readonly items = this._items.asObservable();
protected host: UmbControllerHostInterface;
constructor(host: UmbControllerHostInterface) {
this.host = host;
}
/**
* @description - Delete items from the store.
* @param {Array<string>} keys
@@ -40,8 +47,6 @@ export abstract class UmbDataStoreBase<T extends UmbDataStoreIdentifiers> implem
this._items.next(remainingItems);
}
/**
* @description - Update the store with new items. Existing items are updated, new items are added, old are kept. Items are matched by the compareKey.
* @param {Array<T>} items
@@ -52,7 +57,7 @@ export abstract class UmbDataStoreBase<T extends UmbDataStoreIdentifiers> implem
const newData = [...this._items.getValue()];
items.forEach((newItem) => {
const storedItemIndex = newData.findIndex((item) => item[compareKey] === newItem[compareKey]);
if(storedItemIndex !== -1) {
if (storedItemIndex !== -1) {
newData[storedItemIndex] = newItem;
} else {
newData.push(newItem);