add user collection repository

This commit is contained in:
Mads Rasmussen
2023-10-25 09:47:31 +02:00
parent 979963d3db
commit c3d01e48e9
14 changed files with 122 additions and 67 deletions

View File

@@ -0,0 +1,3 @@
import { manifests as collectionRepositoryManifests } from './repository/manifests.js';
export const manifests = [...collectionRepositoryManifests];

View File

@@ -0,0 +1 @@
export * from './user-collection.repository.js';

View File

@@ -0,0 +1,13 @@
import { UmbUserCollectionRepository } from './user-collection.repository.js';
import { ManifestRepository } from '@umbraco-cms/backoffice/extension-registry';
export const USER_COLLECTION_REPOSITORY_ALIAS = 'Umb.Repository.UserCollection';
const repository: ManifestRepository = {
type: 'repository',
alias: USER_COLLECTION_REPOSITORY_ALIAS,
name: 'User Collection Repository',
api: UmbUserCollectionRepository,
};
export const manifests = [repository];

View File

@@ -0,0 +1,39 @@
import { UmbUserCollectionFilterModel } from '../../types.js';
import { UMB_USER_STORE_CONTEXT_TOKEN, UmbUserStore } from '../../repository/user.store.js';
import { UmbUserCollectionServerDataSource } from './user-collection.server.data.js';
import { UserResponseModel } from '@umbraco-cms/backoffice/backend-api';
import { UmbCollectionDataSource, UmbCollectionRepository } from '@umbraco-cms/backoffice/repository';
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
export class UmbUserCollectionRepository implements UmbCollectionRepository {
#host: UmbControllerHostElement;
#init;
#detailStore?: UmbUserStore;
#collectionSource: UmbCollectionDataSource<UserResponseModel>;
constructor(host: UmbControllerHostElement) {
this.#host = host;
this.#collectionSource = new UmbUserCollectionServerDataSource(this.#host);
this.#init = Promise.all([
new UmbContextConsumerController(this.#host, UMB_USER_STORE_CONTEXT_TOKEN, (instance) => {
this.#detailStore = instance;
}).asPromise(),
]);
}
async requestCollection(filter: UmbUserCollectionFilterModel = { skip: 0, take: 100 }) {
await this.#init;
const { data, error } = await this.#collectionSource.filterCollection(filter);
if (data) {
this.#detailStore?.appendItems(data.items);
}
return { data, error, asObservable: () => this.#detailStore!.all() };
}
}

View File

@@ -1,14 +1,14 @@
import type { UmbUserCollectionFilterModel, UmbUserDetail } from '../../types.js';
import { USER_ENTITY_TYPE, type UmbUserCollectionFilterModel, type UmbUserDetail } from '../../types.js';
import { UmbCollectionDataSource, extendDataSourcePagedResponseData } from '@umbraco-cms/backoffice/repository';
import { UserResource } from '@umbraco-cms/backoffice/backend-api';
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
/**
* A data source for the User that fetches data from the server
* A data source that fetches the user collection data from the server.
* @export
* @class UmbUserCollectionServerDataSource
* @implements {RepositoryDetailDataSource}
* @implements {UmbCollectionDataSource}
*/
export class UmbUserCollectionServerDataSource implements UmbCollectionDataSource<UmbUserDetail> {
#host: UmbControllerHostElement;
@@ -22,15 +22,28 @@ export class UmbUserCollectionServerDataSource implements UmbCollectionDataSourc
this.#host = host;
}
/**
* Gets the user collection from the server.
* @return {*}
* @memberof UmbUserCollectionServerDataSource
*/
async getCollection() {
const response = await tryExecuteAndNotify(this.#host, UserResource.getUser({}));
return extendDataSourcePagedResponseData<UmbUserDetail>(response, {
entityType: 'user',
entityType: USER_ENTITY_TYPE,
});
}
filterCollection(filter: UmbUserCollectionFilterModel) {
return tryExecuteAndNotify(this.#host, UserResource.getUserFilter(filter));
// TODO: Most likely missing the right type, and should then extend the data set with entityType.
/**
* Gets the user collection filtered by the given filter.
* @param {UmbUserCollectionFilterModel} filter
* @return {*}
* @memberof UmbUserCollectionServerDataSource
*/
async filterCollection(filter: UmbUserCollectionFilterModel) {
const response = await tryExecuteAndNotify(this.#host, UserResource.getUserFilter(filter));
return extendDataSourcePagedResponseData<UmbUserDetail>(response, {
entityType: USER_ENTITY_TYPE,
});
}
}

View File

@@ -1,12 +1,12 @@
import { USER_REPOSITORY_ALIAS } from '../repository/manifests.js';
import { UmbUserCollectionFilterModel, UmbUserDetail } from '../types.js';
import { USER_ENTITY_TYPE, UmbUserCollectionFilterModel, UmbUserDetail } from '../types.js';
import { USER_COLLECTION_REPOSITORY_ALIAS } from './repository/manifests.js';
import { UmbCollectionContext } from '@umbraco-cms/backoffice/collection';
import { UserOrderModel, UserStateModel } from '@umbraco-cms/backoffice/backend-api';
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
export class UmbUserCollectionContext extends UmbCollectionContext<UmbUserDetail, UmbUserCollectionFilterModel> {
constructor(host: UmbControllerHostElement) {
super(host, 'user', USER_REPOSITORY_ALIAS);
super(host, USER_ENTITY_TYPE, USER_COLLECTION_REPOSITORY_ALIAS);
}
/**

View File

@@ -1,6 +1,6 @@
import { UmbUserCollectionContext } from './user-collection.context.js';
import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from "@umbraco-cms/backoffice/style";
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import type { UmbRoute } from '@umbraco-cms/backoffice/router';
@@ -40,7 +40,6 @@ export class UmbUserCollectionElement extends UmbLitElement {
<umb-router-slot id="router-slot" .routes=${this._routes}></umb-router-slot>
<umb-collection-selection-actions slot="footer"></umb-collection-selection-actions>
</umb-body-layout>
<!-- This should go in the footer slot -->
`;
}

View File

@@ -1,12 +1,11 @@
import { USER_REPOSITORY_ALIAS } from '../repository/manifests.js';
import { USER_ENTITY_TYPE } from '../types.js';
import { UmbEnableUserEntityBulkAction } from './enable/enable.action.js';
import { UmbSetGroupUserEntityBulkAction } from './set-group/set-group.action.js';
import { UmbUnlockUserEntityBulkAction } from './unlock/unlock.action.js';
import { UmbDisableUserEntityBulkAction } from './disable/disable.action.js';
import { ManifestEntityBulkAction } from '@umbraco-cms/backoffice/extension-registry';
const entityType = 'user';
const entityActions: Array<ManifestEntityBulkAction> = [
{
type: 'entityBulkAction',
@@ -18,10 +17,12 @@ const entityActions: Array<ManifestEntityBulkAction> = [
label: 'SetGroup',
repositoryAlias: USER_REPOSITORY_ALIAS,
},
conditions: [{
alias: 'Umb.Condition.CollectionEntityType',
match: entityType,
}],
conditions: [
{
alias: 'Umb.Condition.CollectionEntityType',
match: USER_ENTITY_TYPE,
},
],
},
{
type: 'entityBulkAction',
@@ -33,10 +34,12 @@ const entityActions: Array<ManifestEntityBulkAction> = [
label: 'Enable',
repositoryAlias: USER_REPOSITORY_ALIAS,
},
conditions: [{
alias: 'Umb.Condition.CollectionEntityType',
match: entityType,
}],
conditions: [
{
alias: 'Umb.Condition.CollectionEntityType',
match: USER_ENTITY_TYPE,
},
],
},
{
type: 'entityBulkAction',
@@ -48,10 +51,12 @@ const entityActions: Array<ManifestEntityBulkAction> = [
label: 'Unlock',
repositoryAlias: USER_REPOSITORY_ALIAS,
},
conditions: [{
alias: 'Umb.Condition.CollectionEntityType',
match: entityType,
}],
conditions: [
{
alias: 'Umb.Condition.CollectionEntityType',
match: USER_ENTITY_TYPE,
},
],
},
{
type: 'entityBulkAction',
@@ -63,10 +68,12 @@ const entityActions: Array<ManifestEntityBulkAction> = [
label: 'Disable',
repositoryAlias: USER_REPOSITORY_ALIAS,
},
conditions: [{
alias: 'Umb.Condition.CollectionEntityType',
match: entityType,
}],
conditions: [
{
alias: 'Umb.Condition.CollectionEntityType',
match: USER_ENTITY_TYPE,
},
],
},
];

View File

@@ -1,3 +1,4 @@
import { manifests as collectionManifests } from './collection/manifests.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
import { manifests as workspaceManifests } from './workspace/manifests.js';
import { manifests as modalManifests } from './modals/manifests.js';
@@ -7,6 +8,7 @@ import { manifests as entityBulkActionManifests } from './entity-bulk-actions/ma
import { manifests as conditionsManifests } from './conditions/manifests.js';
export const manifests = [
...collectionManifests,
...repositoryManifests,
...workspaceManifests,
...modalManifests,

View File

@@ -1,4 +1,4 @@
import { UmbUserDetail, UmbUserDetailDataSource } from '../../types.js';
import { USER_ENTITY_TYPE, UmbUserDetail, UmbUserDetailDataSource } from '../../types.js';
import { DataSourceResponse, extendDataSourceResponseData } from '@umbraco-cms/backoffice/repository';
import {
CreateUserRequestModel,
@@ -37,7 +37,7 @@ export class UmbUserServerDataSource implements UmbUserDetailDataSource {
if (!id) throw new Error('Id is missing');
const response = await tryExecuteAndNotify(this.#host, UserResource.getUserById({ id }));
return extendDataSourceResponseData<UmbUserDetail>(response, {
entityType: 'user',
entityType: USER_ENTITY_TYPE,
});
}

View File

@@ -1,25 +1,12 @@
import {
UmbUserCollectionFilterModel,
UmbUserDetail,
UmbUserDetailDataSource,
UmbUserSetGroupDataSource,
} from '../types.js';
import { UmbUserDetailDataSource, UmbUserSetGroupDataSource } from '../types.js';
import { UMB_USER_STORE_CONTEXT_TOKEN, UmbUserStore } from './user.store.js';
import { UmbUserServerDataSource } from './sources/user.server.data.js';
import { UmbUserCollectionServerDataSource } from './sources/user-collection.server.data.js';
import { UmbUserItemServerDataSource } from './sources/user-item.server.data.js';
import { UMB_USER_ITEM_STORE_CONTEXT_TOKEN, UmbUserItemStore } from './user-item.store.js';
import { UmbUserSetGroupsServerDataSource } from './sources/user-set-group.server.data.js';
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import {
UmbCollectionDataSource,
UmbCollectionRepository,
UmbDetailRepository,
UmbItemDataSource,
UmbItemRepository,
} from '@umbraco-cms/backoffice/repository';
import { UmbDetailRepository, UmbItemDataSource, UmbItemRepository } from '@umbraco-cms/backoffice/repository';
import {
CreateUserRequestModel,
CreateUserResponseModel,
@@ -37,9 +24,7 @@ export type UmbUserDetailRepository = UmbDetailRepository<
UserResponseModel
>;
export class UmbUserRepository
implements UmbUserDetailRepository, UmbCollectionRepository, UmbItemRepository<UserItemResponseModel>
{
export class UmbUserRepository implements UmbUserDetailRepository, UmbItemRepository<UserItemResponseModel> {
#host: UmbControllerHostElement;
#init;
@@ -49,15 +34,12 @@ export class UmbUserRepository
#itemStore?: UmbUserItemStore;
#setUserGroupsSource: UmbUserSetGroupDataSource;
#collectionSource: UmbCollectionDataSource<UmbUserDetail>;
#notificationContext?: UmbNotificationContext;
constructor(host: UmbControllerHostElement) {
this.#host = host;
this.#detailSource = new UmbUserServerDataSource(this.#host);
this.#collectionSource = new UmbUserCollectionServerDataSource(this.#host);
this.#itemSource = new UmbUserItemServerDataSource(this.#host);
this.#setUserGroupsSource = new UmbUserSetGroupsServerDataSource(this.#host);
@@ -76,16 +58,6 @@ export class UmbUserRepository
]);
}
// COLLECTION
async requestCollection(filter: UmbUserCollectionFilterModel = { skip: 0, take: 100000 }) {
//TODO: missing observable
return this.#collectionSource.filterCollection(filter);
}
async filterCollection(filter: UmbUserCollectionFilterModel) {
return this.#collectionSource.filterCollection(filter);
}
// ITEMS:
async requestItems(ids: Array<string>) {
if (!ids) throw new Error('Ids are missing');

View File

@@ -10,6 +10,8 @@ import type {
import { UmbDataSource, UmbDataSourceErrorResponse } from '@umbraco-cms/backoffice/repository';
export const USER_ENTITY_TYPE = 'user';
export type UmbUserDetail = UserResponseModel & {
entityType: 'user';
};

View File

@@ -1,3 +1,4 @@
import { USER_ENTITY_TYPE } from '../types.js';
import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace';
import type {
ManifestWorkspace,
@@ -11,7 +12,7 @@ const workspace: ManifestWorkspace = {
name: 'User Workspace',
loader: () => import('./user-workspace.element.js'),
meta: {
entityType: 'user',
entityType: USER_ENTITY_TYPE,
},
};

View File

@@ -1,5 +1,5 @@
import { UmbUserRepository } from '../repository/user.repository.js';
import { type UmbUserDetail } from '../index.js';
import { USER_ENTITY_TYPE, type UmbUserDetail } from '../index.js';
import { UmbSaveableWorkspaceContextInterface, UmbWorkspaceContext } from '@umbraco-cms/backoffice/workspace';
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import type { UpdateUserRequestModel } from '@umbraco-cms/backoffice/backend-api';
@@ -50,7 +50,7 @@ export class UmbUserWorkspaceContext
}
getEntityType(): string {
return 'user';
return USER_ENTITY_TYPE;
}
getData() {
@@ -97,4 +97,7 @@ export class UmbUserWorkspaceContext
export const UMB_USER_WORKSPACE_CONTEXT = new UmbContextToken<
UmbSaveableWorkspaceContextInterface,
UmbUserWorkspaceContext
>('UmbWorkspaceContext', (context): context is UmbUserWorkspaceContext => context.getEntityType?.() === 'user');
>(
'UmbWorkspaceContext',
(context): context is UmbUserWorkspaceContext => context.getEntityType?.() === USER_ENTITY_TYPE,
);