add stylesheet-input + map items to client side model

This commit is contained in:
Mads Rasmussen
2024-01-15 15:11:46 +01:00
parent 4140e78aec
commit baeeb802ff
25 changed files with 318 additions and 115 deletions

View File

@@ -5,9 +5,10 @@ import { umbracoPath } from '@umbraco-cms/backoffice/utils';
export const itemHandlers = [
rest.get(umbracoPath(`${UMB_SLUG}/item`), (req, res, ctx) => {
const paths = req.url.searchParams.getAll('paths');
const paths = req.url.searchParams.getAll('path');
if (!paths) return res(ctx.status(400, 'no body found'));
const items = umbPartialViewMockDB.item.getItems(paths);
const decodedPaths = paths.map((path) => decodeURI(path));
const items = umbPartialViewMockDB.item.getItems(decodedPaths);
return res(ctx.status(200), ctx.json(items));
}),
];

View File

@@ -5,9 +5,10 @@ import { umbracoPath } from '@umbraco-cms/backoffice/utils';
export const itemHandlers = [
rest.get(umbracoPath(`${UMB_SLUG}/item`), (req, res, ctx) => {
const paths = req.url.searchParams.getAll('paths');
const paths = req.url.searchParams.getAll('path');
if (!paths) return res(ctx.status(400, 'no body found'));
const items = umbScriptMockDb.item.getItems(paths);
const decodedPaths = paths.map((path) => decodeURI(path));
const items = umbScriptMockDb.item.getItems(decodedPaths);
return res(ctx.status(200), ctx.json(items));
}),
];

View File

@@ -5,9 +5,10 @@ import { umbracoPath } from '@umbraco-cms/backoffice/utils';
export const itemHandlers = [
rest.get(umbracoPath(`${UMB_SLUG}/item`), (req, res, ctx) => {
const paths = req.url.searchParams.getAll('paths');
const paths = req.url.searchParams.getAll('path');
if (!paths) return res(ctx.status(400, 'no body found'));
const items = umbStylesheetMockDb.item.getItems(paths);
const decodedPaths = paths.map((path) => decodeURI(path));
const items = umbStylesheetMockDb.item.getItems(decodedPaths);
return res(ctx.status(200), ctx.json(items));
}),
];

View File

@@ -50,7 +50,11 @@ export class UmbTreePickerModalElement<TreeItemType extends UmbTreeItemModelBase
</uui-box>
<div slot="actions">
<uui-button label=${this.localize.term('general_close')} @click=${this._rejectModal}></uui-button>
<uui-button label=${this.localize.term('general_choose')} look="primary" color="positive" @click=${this._submitModal}></uui-button>
<uui-button
label=${this.localize.term('general_choose')}
look="primary"
color="positive"
@click=${this._submitModal}></uui-button>
</div>
</umb-body-layout>
`;

View File

@@ -1,8 +1,8 @@
export interface UmbPickerModalData<ItemType> {
export interface UmbPickerModalData<TreeItemType> {
multiple?: boolean;
hideTreeRoot?: boolean;
filter?: (item: ItemType) => boolean;
pickableFilter?: (item: ItemType) => boolean;
filter?: (item: TreeItemType) => boolean;
pickableFilter?: (item: TreeItemType) => boolean;
}
export interface UmbPickerModalValue {
selection: Array<string | null>;

View File

@@ -1,9 +1,10 @@
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit';
import { css, customElement, html, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import { UmbStylesheetDetailRepository } from '@umbraco-cms/backoffice/stylesheet';
import { StylesheetOverviewResponseModel } from '@umbraco-cms/backoffice/backend-api';
import { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import {
UmbPropertyEditorConfigCollection,
UmbPropertyValueChangeEvent,
} from '@umbraco-cms/backoffice/property-editor';
import { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
/**
@@ -20,30 +21,8 @@ export class UmbPropertyEditorUITinyMceStylesheetsConfigurationElement
@property({ type: Object, attribute: false })
public config?: UmbPropertyEditorConfigCollection;
@state()
stylesheetList: Array<StylesheetOverviewResponseModel & Partial<{ selected: boolean }>> = [];
#repository;
constructor() {
super();
this.#repository = new UmbStylesheetDetailRepository(this);
this.#getAllStylesheets();
}
async #getAllStylesheets() {
const { data } = await this.#repository.getAll();
if (!data) return;
const styles = data.items;
this.stylesheetList = styles.map((stylesheet) => ({
...stylesheet,
selected: this.value?.some((path) => path === stylesheet.path),
}));
}
#onChange(event: CustomEvent) {
debugger;
const checkbox = event.target as HTMLInputElement;
if (checkbox.checked) {
@@ -56,36 +35,14 @@ export class UmbPropertyEditorUITinyMceStylesheetsConfigurationElement
this.value = this.value.filter((v) => v !== checkbox.value);
}
this.dispatchEvent(new CustomEvent('property-value-change'));
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {
return html`<ul>
${this.stylesheetList.map(
(stylesheet) =>
html`<li>
<uui-checkbox
.label=${stylesheet.name}
.value=${stylesheet.path ?? ''}
@change=${this.#onChange}
?checked=${stylesheet.selected}>
${stylesheet.name}
</uui-checkbox>
</li>`,
)}
</ul>`;
return html`<umb-stylesheet-input></umb-stylesheet-input>`;
}
static styles = [
UmbTextStyles,
css`
ul {
list-style: none;
padding: 0;
margin: 0;
}
`,
];
static styles = [UmbTextStyles, css``];
}
export default UmbPropertyEditorUITinyMceStylesheetsConfigurationElement;

View File

@@ -72,8 +72,7 @@ export class UmbRepositoryItemsManager<ItemType> extends UmbBaseController {
// TODO: Test if its just some items that is gone now, if so then just filter them out. (maybe use code from #removeItem)
// This is where this.#getUnique comes in play. Unless that can come from the repository, but that collides with the idea of having a multi-type repository. If that happens.
const { asObservable } = await this.repository.requestItems(this.getUniques());
const { data, asObservable } = await this.repository.requestItems(this.getUniques());
if (asObservable) {
this.observe(asObservable(), (data) => this.#items.next(data), '_observeRequestedItems');

View File

@@ -1,10 +1,13 @@
export * from './item-store.interface.js';
export * from './store-base.js';
export * from './store.interface.js';
export * from './store.js';
export * from './entity-item.store.js';
export * from './file-system-item.store.js';
export { UmbStoreConnector } from './store-connector.js';
export { UmbDetailStoreBase } from './detail-store-base.js';
export type { UmbDetailStore } from './detail-store.interface.js';
export { UmbItemStoreBase } from './item-store-base.js';
export type { UmbItemStore } from './item-store.interface.js';
export { UmbStoreConnector } from './store-connector.js';

View File

@@ -0,0 +1,28 @@
import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbItemStore, UmbStoreBase } from '@umbraco-cms/backoffice/store';
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
/**
* @export
* @class UmbItemStoreBase
* @extends {UmbStoreBase}
* @description - Data Store for items with a unique property
*/
export abstract class UmbItemStoreBase<T extends { unique: string }>
extends UmbStoreBase<T>
implements UmbItemStore<T>
{
/**
* Creates an instance of UmbItemStoreBase.
* @param {UmbControllerHost} host
* @memberof UmbItemStoreBase
*/
constructor(host: UmbControllerHost, storeAlias: string) {
super(host, storeAlias, new UmbArrayState<T>([], (x) => x.unique));
}
items(uniques: Array<string>) {
return this._data.asObservablePart((items) => items.filter((item) => uniques.includes(item.unique)));
}
}

View File

@@ -2,6 +2,6 @@ import { UmbStore } from './store.interface.js';
import type { Observable } from '@umbraco-cms/backoffice/external/rxjs';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
export interface UmbItemStore<T = any> extends UmbStore<T>, UmbApi {
export interface UmbItemStore<T extends { unique: string }> extends UmbStore<T>, UmbApi {
items: (uniques: Array<string>) => Observable<Array<T>>;
}

View File

@@ -1,34 +1,24 @@
import { UmbStylesheetCollectionFilterModel, UmbStylesheetCollectionItemModel } from '../types.js';
import { UmbStylesheetDetailStore, UMB_STYLESHEET_DETAIL_STORE_CONTEXT } from '../../repository/index.js';
import { UmbStylesheetCollectionServerDataSource } from './stylesheet-collection.server.data-source.js';
import { UmbCollectionDataSource, UmbCollectionRepository } from '@umbraco-cms/backoffice/repository';
import { type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbBaseController } from '@umbraco-cms/backoffice/class-api';
export class UmbStylesheetCollectionRepository extends UmbBaseController implements UmbCollectionRepository {
#init;
#detailStore?: UmbStylesheetDetailStore;
#collectionSource: UmbCollectionDataSource<UmbStylesheetCollectionItemModel>;
constructor(host: UmbControllerHost) {
super(host);
this.#collectionSource = new UmbStylesheetCollectionServerDataSource(this._host);
this.#init = this.consumeContext(UMB_STYLESHEET_DETAIL_STORE_CONTEXT, (instance) => {
this.#detailStore = instance;
}).asPromise();
}
async requestCollection(filter: UmbStylesheetCollectionFilterModel = { take: 100, skip: 0 }) {
await this.#init;
const { data, error } = await this.#collectionSource.getCollection(filter);
if (data) {
this.#detailStore?.appendItems(data.items);
}
return { data, error, asObservable: () => this.#detailStore!.all() };
/**
* Requests the stylesheet collection
* @param {UmbStylesheetCollectionFilterModel} [filter={ take: 100, skip: 0 }]
* @return {*}
* @memberof UmbStylesheetCollectionRepository
*/
requestCollection(filter: UmbStylesheetCollectionFilterModel = { take: 100, skip: 0 }) {
return this.#collectionSource.getCollection(filter);
}
}

View File

@@ -1,3 +1,4 @@
import { UmbServerFilePathUniqueSerializer } from '@umbraco-cms/backoffice/server-file-system';
import { UmbStylesheetCollectionFilterModel, UmbStylesheetCollectionItemModel } from '../types.js';
import type { UmbCollectionDataSource } from '@umbraco-cms/backoffice/repository';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
@@ -14,6 +15,7 @@ export class UmbStylesheetCollectionServerDataSource
implements UmbCollectionDataSource<UmbStylesheetCollectionItemModel>
{
#host: UmbControllerHost;
#serverFilePathUniqueSerializer = new UmbServerFilePathUniqueSerializer();
/**
* Creates an instance of UmbStylesheetCollectionServerDataSource.
@@ -24,7 +26,26 @@ export class UmbStylesheetCollectionServerDataSource
this.#host = host;
}
getCollection(filter: UmbStylesheetCollectionFilterModel) {
return tryExecuteAndNotify(this.#host, StylesheetResource.getStylesheetAll(filter));
/**
* Gets the stylesheet collection items from the server
* @param {UmbStylesheetCollectionFilterModel} filter
* @return {*}
* @memberof UmbStylesheetCollectionServerDataSource
*/
async getCollection(filter: UmbStylesheetCollectionFilterModel) {
const { data, error } = await tryExecuteAndNotify(this.#host, StylesheetResource.getStylesheetOverview(filter));
if (data) {
const items: Array<UmbStylesheetCollectionItemModel> = data.items.map((item) => {
return {
name: item.name,
unique: this.#serverFilePathUniqueSerializer.toUnique(item.path),
};
});
return { data: { items, total: data.total } };
}
return { error };
}
}

View File

@@ -12,5 +12,5 @@ export interface UmbStylesheetCollectionFilterModel {
export interface UmbStylesheetCollectionItemModel {
name: string;
path: string;
unique: string;
}

View File

@@ -1,5 +1,7 @@
import './stylesheet-input/stylesheet-input.element.js';
import './stylesheet-rule-input/stylesheet-rule-input.element.js';
import './stylesheet-rule-ref/stylesheet-rule-ref.element.js';
export * from './stylesheet-input/stylesheet-input.element.js';
export * from './stylesheet-rule-input/stylesheet-rule-input.element.js';
export * from './stylesheet-rule-ref/stylesheet-rule-ref.element.js';

View File

@@ -1,3 +1,3 @@
import { manifests as stylesheetRuleInputManifests } from './stylesheet-rule-input/manifests.js';
export const manifests = [...stylesheetRuleInputManifests];
export const manifests = [...stylesheetPickerModalManifests, ...stylesheetRuleInputManifests];

View File

@@ -0,0 +1,14 @@
import { UMB_STYLESHEET_ITEM_REPOSITORY_ALIAS } from '../../repository/index.js';
import { UmbStylesheetItemModel } from '../../types.js';
import { UMB_STYLESHEET_PICKER_MODAL } from './stylesheet-picker-modal.token.js';
import { UmbPickerInputContext } from '@umbraco-cms/backoffice/picker-input';
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
export class UmbStylesheetPickerContext extends UmbPickerInputContext<UmbStylesheetItemModel> {
constructor(host: UmbControllerHostElement) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// TODO: Item and tree item types collide
super(host, UMB_STYLESHEET_ITEM_REPOSITORY_ALIAS, UMB_STYLESHEET_PICKER_MODAL, (item) => item.unique);
}
}

View File

@@ -0,0 +1,136 @@
import { UmbStylesheetItemModel } from '../../types.js';
import { UmbStylesheetPickerContext } from './stylesheet-input.context.js';
import { css, html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import { FormControlMixin } from '@umbraco-cms/backoffice/external/uui';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import { splitStringToArray } from '@umbraco-cms/backoffice/utils';
@customElement('umb-stylesheet-input')
export class UmbStylesheetInputElement extends FormControlMixin(UmbLitElement) {
/**
* This is a minimum amount of selected items in this input.
* @type {number}
* @attr
* @default 0
*/
@property({ type: Number })
public get min(): number {
return this.#pickerContext.min;
}
public set min(value: number) {
this.#pickerContext.min = value;
}
/**
* Min validation message.
* @type {boolean}
* @attr
* @default
*/
@property({ type: String, attribute: 'min-message' })
minMessage = 'This field need more items';
/**
* This is a maximum amount of selected items in this input.
* @type {number}
* @attr
* @default Infinity
*/
@property({ type: Number })
public get max(): number {
return this.#pickerContext.max;
}
public set max(value: number) {
this.#pickerContext.max = value;
}
/**
* Max validation message.
* @type {boolean}
* @attr
* @default
*/
@property({ type: String, attribute: 'min-message' })
maxMessage = 'This field exceeds the allowed amount of items';
public get selectedIds(): Array<string> {
return this.#pickerContext.getSelection();
}
public set selectedIds(ids: Array<string>) {
this.#pickerContext.setSelection(ids);
}
@property()
public set value(idsString: string) {
// Its with full purpose we don't call super.value, as thats being handled by the observation of the context selection.
this.selectedIds = splitStringToArray(idsString);
}
@state()
private _items?: Array<UmbStylesheetItemModel>;
#pickerContext = new UmbStylesheetPickerContext(this);
constructor() {
super();
this.addValidator(
'rangeUnderflow',
() => this.minMessage,
() => !!this.min && this.#pickerContext.getSelection().length < this.min,
);
this.addValidator(
'rangeOverflow',
() => this.maxMessage,
() => !!this.max && this.#pickerContext.getSelection().length > this.max,
);
this.observe(this.#pickerContext.selection, (selection) => (super.value = selection.join(',')));
this.observe(this.#pickerContext.selectedItems, (selectedItems) => (this._items = selectedItems));
}
protected getFormElement() {
return undefined;
}
render() {
return html`
<uui-ref-list>${this._items?.map((item) => this._renderItem(item))}</uui-ref-list>
<uui-button id="add-button" look="placeholder" @click=${() => this.#pickerContext.openPicker()} label="open"
>Add</uui-button
>
`;
}
private _renderItem(item: UmbStylesheetItemModel) {
if (!item.unique) return;
return html`
<uui-ref-node-data-type name=${item.name}>
<uui-action-bar slot="actions">
<uui-button
@click=${() => this.#pickerContext.requestRemoveItem(item.unique!)}
label="Remove Data Type ${item.name}"
>Remove</uui-button
>
</uui-action-bar>
</uui-ref-node-data-type>
`;
}
static styles = [
css`
#add-button {
width: 100%;
}
`,
];
}
export default UmbStylesheetInputElement;
declare global {
interface HTMLElementTagNameMap {
'umb-stylesheet-input': UmbStylesheetInputElement;
}
}

View File

@@ -0,0 +1,18 @@
import { UmbStylesheetTreeItemModel } from '../../tree/types.js';
import { UmbModalToken, UmbPickerModalValue, UmbTreePickerModalData } from '@umbraco-cms/backoffice/modal';
export type UmbStylesheetPickerModalData = UmbTreePickerModalData<UmbStylesheetTreeItemModel>;
export type UmbStylesheetPickerModalValue = UmbPickerModalValue;
export const UMB_STYLESHEET_PICKER_MODAL = new UmbModalToken<
UmbStylesheetPickerModalData,
UmbStylesheetPickerModalValue
>('Umb.Modal.TreePicker', {
modal: {
type: 'sidebar',
size: 'small',
},
data: {
treeAlias: 'Umb.Tree.Stylesheet',
},
});

View File

@@ -1,10 +1,10 @@
import { UmbStylesheetItemModel } from '../../types.js';
import { UmbStylesheetItemServerDataSource } from './stylesheet-item.server.data-source.js';
import { UMB_STYLESHEET_ITEM_STORE_CONTEXT } from './stylesheet-item.store.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { StylesheetItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
import { UmbItemRepositoryBase } from '@umbraco-cms/backoffice/repository';
export class UmbStylesheetItemRepository extends UmbItemRepositoryBase<StylesheetItemResponseModel> {
export class UmbStylesheetItemRepository extends UmbItemRepositoryBase<UmbStylesheetItemModel> {
constructor(host: UmbControllerHost) {
super(host, UmbStylesheetItemServerDataSource, UMB_STYLESHEET_ITEM_STORE_CONTEXT);
}

View File

@@ -1,7 +1,10 @@
import { UmbServerFilePathUniqueSerializer } from '@umbraco-cms/backoffice/server-file-system';
import { UMB_STYLESHEET_ENTITY_TYPE, UMB_STYLESHEET_FOLDER_ENTITY_TYPE } from '../../entity.js';
import { UmbStylesheetItemModel } from '../../types.js';
import type { UmbItemDataSource } from '@umbraco-cms/backoffice/repository';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
import { StylesheetItemResponseModel, StylesheetResource } from '@umbraco-cms/backoffice/backend-api';
import { StylesheetResource } from '@umbraco-cms/backoffice/backend-api';
/**
* A data source for stylesheet items that fetches data from the server
@@ -9,8 +12,9 @@ import { StylesheetItemResponseModel, StylesheetResource } from '@umbraco-cms/ba
* @class UmbStylesheetItemServerDataSource
* @implements {UmbItemDataSource}
*/
export class UmbStylesheetItemServerDataSource implements UmbItemDataSource<StylesheetItemResponseModel> {
export class UmbStylesheetItemServerDataSource implements UmbItemDataSource<UmbStylesheetItemModel> {
#host: UmbControllerHost;
#serverFilePathUniqueSerializer = new UmbServerFilePathUniqueSerializer();
/**
* Creates an instance of UmbStylesheetItemServerDataSource.
@@ -22,19 +26,42 @@ export class UmbStylesheetItemServerDataSource implements UmbItemDataSource<Styl
}
/**
* Fetches the items for the given paths from the server
* @param {Array<string>} paths
* Fetches the items for the given uniques from the server
* @param {Array<string>} uniques
* @return {*}
* @memberof UmbStylesheetItemServerDataSource
*/
async getItems(paths: Array<string>) {
if (!paths) throw new Error('Paths are missing');
async getItems(uniques: Array<string>) {
if (!uniques) throw new Error('Uniques are missing');
return tryExecuteAndNotify(
const paths = uniques
.map((unique) => {
const serverPath = this.#serverFilePathUniqueSerializer.toServerPath(unique);
return serverPath ? encodeURI(serverPath) : null;
})
.filter((x) => x !== null) as string[];
const { data, error } = await tryExecuteAndNotify(
this.#host,
StylesheetResource.getStylesheetItem({
path: paths,
}),
);
if (data) {
const items: Array<UmbStylesheetItemModel> = data.map((item) => {
return {
entityType: item.isFolder ? UMB_STYLESHEET_FOLDER_ENTITY_TYPE : UMB_STYLESHEET_ENTITY_TYPE,
unique: this.#serverFilePathUniqueSerializer.toUnique(item.path),
parentUnique: item.parent ? this.#serverFilePathUniqueSerializer.toUnique(item.parent.path) : null,
name: item.name,
isFolder: item.isFolder,
};
});
return { data: items };
}
return { error };
}
}

View File

@@ -1,16 +1,16 @@
import type { StylesheetItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
import { UmbStylesheetItemModel } from '../../types.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import { UmbFileSystemItemStore } from '@umbraco-cms/backoffice/store';
import { UmbItemStoreBase } from '@umbraco-cms/backoffice/store';
/**
* @export
* @class UmbStylesheetItemStore
* @extends {UmbFileSystemItemStore}
* @extends {UmbItemStoreBase}
* @description - Data Store for Stylesheet items
*/
export class UmbStylesheetItemStore extends UmbFileSystemItemStore<StylesheetItemResponseModel> {
export class UmbStylesheetItemStore extends UmbItemStoreBase<UmbStylesheetItemModel> {
/**
* Creates an instance of UmbStylesheetItemStore.
* @param {UmbControllerHostElement} host

View File

@@ -1,4 +1,4 @@
import { UmbStylesheetEntityType } from './entity.js';
import { UmbStylesheetEntityType, UmbStylesheetFolderEntityType } from './entity.js';
export interface UmbStylesheetDetailModel {
entityType: UmbStylesheetEntityType;
@@ -9,6 +9,14 @@ export interface UmbStylesheetDetailModel {
content: string;
}
export interface UmbStylesheetItemModel {
entityType: UmbStylesheetEntityType | UmbStylesheetFolderEntityType;
unique: string;
parentUnique: string | null;
name: string;
isFolder: boolean;
}
export interface UmbStylesheetRule {
name: string;
selector: string;

View File

@@ -11,10 +11,7 @@ import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
* @description - Data Store for Template items
*/
export class UmbTemplateItemStore
extends UmbStoreBase<TemplateItemResponseModel>
implements UmbItemStore<TemplateItemResponseModel>
{
export class UmbTemplateItemStore extends UmbStoreBase<TemplateItemResponseModel> {
/**
* Creates an instance of UmbTemplateItemStore.
* @param {UmbControllerHostElement} host

View File

@@ -11,10 +11,8 @@ import type { UserGroupItemResponseModel } from '@umbraco-cms/backoffice/backend
* @description - Data Store for user group items
*/
export class UmbUserGroupItemStore
extends UmbStoreBase<UserGroupItemResponseModel>
implements UmbItemStore<UserGroupItemResponseModel>
{
// TODO: add UmbItemStoreInterface when changed to uniques
export class UmbUserGroupItemStore extends UmbStoreBase<UserGroupItemResponseModel> {
/**
* Creates an instance of UmbUserGroupItemStore.
* @param {UmbControllerHostElement} host

View File

@@ -11,10 +11,8 @@ import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
* @description - Data Store for user items
*/
export class UmbUserItemStore
extends UmbStoreBase<UserItemResponseModel>
implements UmbItemStore<UserItemResponseModel>
{
// TODO: add UmbItemStoreInterface when changed to uniques
export class UmbUserItemStore extends UmbStoreBase<UserItemResponseModel> {
/**
* Creates an instance of UmbUserItemStore.
* @param {UmbControllerHostElement} host