Merge remote-tracking branch 'origin/main' into feature/workspace-context-as-extension
# Conflicts: # src/packages/documents/document-types/workspace/document-type-workspace.context.ts
This commit is contained in:
@@ -44,7 +44,7 @@ jobs:
|
||||
- name: Comment on PR
|
||||
# azure/static-web-apps-deploy doesn't support workflow_dispatch, so we need to manually comment on the PR
|
||||
if: github.event_name == 'workflow_dispatch' && inputs.issue_number != null
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
ISSUE_NUMBER: ${{ inputs.issue_number }}
|
||||
SITE_URL: ${{ steps.builddeploy.outputs.static_web_app_url }}
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Fetch random comment 🗣️ and add it to the PR
|
||||
uses: actions/github-script@v6
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const response = await fetch('https://collaboratorsv2.euwest01.umbraco.io/umbraco/api/comments/PostComment', {
|
||||
|
||||
@@ -10,10 +10,10 @@ import { setCustomElements } from '@storybook/web-components';
|
||||
import { startMockServiceWorker } from '../src/mocks';
|
||||
|
||||
import { UMB_MODAL_MANAGER_CONTEXT_TOKEN, UmbModalManagerContext } from '../src/packages/core/modal';
|
||||
import { UmbDataTypeStore } from '../src/packages/settings/data-types/repository/data-type.store.ts';
|
||||
import { UmbDocumentStore } from '../src/packages/documents/documents/repository/document.store.ts';
|
||||
import { UmbDocumentTreeStore } from '../src/packages/documents/documents/repository/document.tree.store.ts';
|
||||
import { UmbDocumentTypeStore } from '../src/packages/documents/document-types/repository/document-type.store.ts';
|
||||
import { UmbDataTypeTreeStore } from '../src/packages/core/data-type/tree/data-type.tree.store';
|
||||
import { UmbDocumentStore } from '../src/packages/documents/documents/repository/document.store';
|
||||
import { UmbDocumentTreeStore } from '../src/packages/documents/documents/repository/document.tree.store';
|
||||
import { UmbDocumentTypeStore } from '../src/packages/documents/document-types/repository/document-type.store';
|
||||
import { umbExtensionsRegistry } from '../src/packages/core/extension-registry';
|
||||
import { UmbIconRegistry } from '../src/shared/icon-registry/icon.registry';
|
||||
import { UmbLitElement } from '../src/shared/lit-element';
|
||||
@@ -21,7 +21,6 @@ import { umbLocalizationRegistry } from '../src/packages/core/localization';
|
||||
import customElementManifests from '../dist-cms/custom-elements.json';
|
||||
|
||||
import '../src/libs/context-api/provide/context-provider.element';
|
||||
import '../src/libs/controller-api/controller-host-initializer.element.ts';
|
||||
import '../src/packages/core/components';
|
||||
|
||||
import { manifests as documentManifests } from '../src/packages/documents';
|
||||
@@ -61,7 +60,7 @@ customElements.define('umb-storybook', UmbStoryBookElement);
|
||||
const storybookProvider = (story) => html` <umb-storybook>${story()}</umb-storybook> `;
|
||||
|
||||
const dataTypeStoreProvider = (story) => html`
|
||||
<umb-controller-host-provider .create=${(host) => new UmbDataTypeStore(host)}
|
||||
<umb-controller-host-provider .create=${(host) => new UmbDataTypeTreeStore(host)}
|
||||
>${story()}</umb-controller-host-provider
|
||||
>
|
||||
`;
|
||||
|
||||
1326
src/Umbraco.Web.UI.Client/package-lock.json
generated
1326
src/Umbraco.Web.UI.Client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -150,13 +150,13 @@
|
||||
"@rollup/plugin-commonjs": "^25.0.4",
|
||||
"@rollup/plugin-json": "^6.0.1",
|
||||
"@rollup/plugin-node-resolve": "^15.2.1",
|
||||
"@storybook/addon-a11y": "7.5.2",
|
||||
"@storybook/addon-actions": "7.5.2",
|
||||
"@storybook/addon-essentials": "7.5.2",
|
||||
"@storybook/addon-links": "7.5.2",
|
||||
"@storybook/addon-a11y": "7.5.3",
|
||||
"@storybook/addon-actions": "7.5.3",
|
||||
"@storybook/addon-essentials": "7.5.3",
|
||||
"@storybook/addon-links": "7.5.3",
|
||||
"@storybook/mdx2-csf": "^1.1.0",
|
||||
"@storybook/web-components": "7.5.2",
|
||||
"@storybook/web-components-vite": "7.5.2",
|
||||
"@storybook/web-components": "7.5.3",
|
||||
"@storybook/web-components-vite": "7.5.3",
|
||||
"@types/chai": "^4.3.5",
|
||||
"@types/lodash-es": "^4.17.8",
|
||||
"@types/mocha": "^10.0.1",
|
||||
@@ -191,7 +191,7 @@
|
||||
"rollup-plugin-esbuild": "^5.0.0",
|
||||
"rollup-plugin-import-css": "^3.3.4",
|
||||
"rollup-plugin-web-worker-loader": "^1.6.1",
|
||||
"storybook": "7.5.2",
|
||||
"storybook": "7.5.3",
|
||||
"tiny-glob": "^0.2.9",
|
||||
"tsc-alias": "^1.8.7",
|
||||
"typescript": "^5.1.6",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { handlers as dataTypeHandlers } from './handlers/data-type/index.js';
|
||||
import { handlers as relationTypeHandlers } from './handlers/relation-type.handlers.js';
|
||||
import { handlers as documentTypeHandlers } from './handlers/document-type.handlers.js';
|
||||
import { handlers as documentTypeHandlers } from './handlers/document-type/index.js';
|
||||
import { handlers as installHandlers } from './handlers/install.handlers.js';
|
||||
import * as manifestsHandlers from './handlers/manifests.handlers.js';
|
||||
import { handlers as publishedStatusHandlers } from './handlers/published-status.handlers.js';
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
DocumentTypeTreeItemResponseModel,
|
||||
DocumentTypeResponseModel,
|
||||
ContentTypeCompositionTypeModel,
|
||||
DocumentTypeItemResponseModel,
|
||||
} from '@umbraco-cms/backoffice/backend-api';
|
||||
|
||||
export const data: Array<DocumentTypeResponseModel> = [
|
||||
@@ -1166,6 +1167,20 @@ class UmbDocumentTypeData extends UmbEntityData<DocumentTypeResponseModel> {
|
||||
const items = this.treeData.filter((item) => allowedTypeKeys.includes(item.id ?? ''));
|
||||
return items.map((item) => item);
|
||||
}
|
||||
|
||||
getItems(ids: Array<string>): Array<DocumentTypeItemResponseModel> {
|
||||
const items = this.data.filter((item) => ids.includes(item.id ?? ''));
|
||||
return items.map((item) => createDocumentTypeItem(item));
|
||||
}
|
||||
}
|
||||
|
||||
const createDocumentTypeItem = (item: DocumentTypeResponseModel): DocumentTypeItemResponseModel => {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
isElement: item.isElement,
|
||||
icon: item.icon,
|
||||
};
|
||||
};
|
||||
|
||||
export const umbDocumentTypeData = new UmbDocumentTypeData();
|
||||
|
||||
@@ -87,7 +87,7 @@ h1 {
|
||||
path: 'Folder 1/Stylesheet File 3.css',
|
||||
name: 'Stylesheet File 3.css',
|
||||
type: 'stylesheet',
|
||||
hasChildren: true,
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
content: `h1 {
|
||||
color: pink;
|
||||
@@ -225,9 +225,10 @@ ${rule.selector} {
|
||||
}
|
||||
|
||||
insertStyleSheet(item: CreateTextFileViewModelBaseModel) {
|
||||
const parentPath = item.parentPath ? `${item.parentPath}/` : '';
|
||||
const newItem: StylesheetDBItem = {
|
||||
...item,
|
||||
path: `${item.parentPath}/${item.name}.css`,
|
||||
path: `${parentPath}${item.name}`,
|
||||
isFolder: false,
|
||||
hasChildren: false,
|
||||
type: 'stylesheet',
|
||||
@@ -238,7 +239,6 @@ ${rule.selector} {
|
||||
return newItem;
|
||||
}
|
||||
|
||||
|
||||
insert(item: StylesheetDBItem) {
|
||||
const exits = this.data.find((i) => i.path === item.path);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { handlers as dataTypeHandlers } from './handlers/data-type/index.js';
|
||||
import { handlers as documentTypeHandlers } from './handlers/document-type.handlers.js';
|
||||
import { handlers as documentTypeHandlers } from './handlers/document-type/index.js';
|
||||
import { handlers as installHandlers } from './handlers/install.handlers.js';
|
||||
import * as manifestsHandlers from './handlers/manifests.handlers.js';
|
||||
import { handlers as publishedStatusHandlers } from './handlers/published-status.handlers.js';
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
const { rest } = window.MockServiceWorker;
|
||||
import { umbDocumentTypeData } from '../data/document-type.data.js';
|
||||
import type { DocumentTypeResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { umbracoPath } from '@umbraco-cms/backoffice/utils';
|
||||
|
||||
// TODO: add schema
|
||||
export const handlers = [
|
||||
rest.post(umbracoPath(`/document-type`), async (req, res, ctx) => {
|
||||
const data = await req.json();
|
||||
if (!data) return;
|
||||
|
||||
// TODO: This is something that is missing in the Full model, but which we need to for the tree model. This should be fixed in the Full model.
|
||||
data.parentId ??= null;
|
||||
|
||||
const created = umbDocumentTypeData.insert(data);
|
||||
|
||||
// TODO: remove this hack, as we get the right end-point, in that case we will be in control of the Ids. (I choose this URL to make it clear thats its a hack/mocked URL)
|
||||
return res(ctx.status(200), ctx.set({ location: '/header/location/id/' + created.id }));
|
||||
}),
|
||||
|
||||
rest.put(umbracoPath(`/document-type/:id`), async (req, res, ctx) => {
|
||||
const id = req.params.id as string;
|
||||
if (!id) return;
|
||||
const data = await req.json();
|
||||
if (!data) return;
|
||||
|
||||
const saved = umbDocumentTypeData.save(id, data);
|
||||
|
||||
return res(ctx.status(200), ctx.json(saved));
|
||||
}),
|
||||
|
||||
rest.get('/umbraco/management/api/v1/document-type/details/:id', (req, res, ctx) => {
|
||||
const id = req.params.id as string;
|
||||
if (!id) return;
|
||||
|
||||
const document = umbDocumentTypeData.getById(id);
|
||||
|
||||
return res(ctx.status(200), ctx.json([document]));
|
||||
}),
|
||||
|
||||
rest.post<DocumentTypeResponseModel>('/umbraco/management/api/v1/document-type/details/save', (req, res, ctx) => {
|
||||
const data = req.body;
|
||||
if (!data) return;
|
||||
|
||||
const saved = umbDocumentTypeData.save(data.id!, data);
|
||||
|
||||
return res(ctx.status(200), ctx.json(saved));
|
||||
}),
|
||||
|
||||
rest.get('/umbraco/management/api/v1/tree/document-type/root', (req, res, ctx) => {
|
||||
const rootItems = umbDocumentTypeData.getTreeRoot();
|
||||
const response = {
|
||||
total: rootItems.length,
|
||||
items: rootItems,
|
||||
};
|
||||
return res(ctx.status(200), ctx.json(response));
|
||||
}),
|
||||
|
||||
rest.get('/umbraco/management/api/v1/tree/document-type/children', (req, res, ctx) => {
|
||||
const parentId = req.url.searchParams.get('parentId');
|
||||
if (!parentId) return;
|
||||
|
||||
const children = umbDocumentTypeData.getTreeItemChildren(parentId);
|
||||
|
||||
const response = {
|
||||
total: children.length,
|
||||
items: children,
|
||||
};
|
||||
|
||||
return res(ctx.status(200), ctx.json(response));
|
||||
}),
|
||||
|
||||
rest.get('/umbraco/management/api/v1/tree/document-type/item', (req, res, ctx) => {
|
||||
const ids = req.url.searchParams.getAll('id');
|
||||
if (!ids) return;
|
||||
|
||||
const items = umbDocumentTypeData.getTreeItem(ids);
|
||||
|
||||
return res(ctx.status(200), ctx.json(items));
|
||||
}),
|
||||
|
||||
rest.get('/umbraco/management/api/v1/document-type/:id', (req, res, ctx) => {
|
||||
const id = req.params.id as string;
|
||||
if (!id) return;
|
||||
|
||||
const documentType = umbDocumentTypeData.getById(id);
|
||||
|
||||
return res(ctx.status(200), ctx.json(documentType));
|
||||
}),
|
||||
|
||||
rest.get('/umbraco/management/api/v1/document-type/allowed-children-of/:id', (req, res, ctx) => {
|
||||
const id = req.params.id as string;
|
||||
if (!id) return;
|
||||
|
||||
const items = umbDocumentTypeData.getAllowedTypesOf(id);
|
||||
|
||||
return res(ctx.status(200), ctx.json(items));
|
||||
}),
|
||||
];
|
||||
@@ -0,0 +1,36 @@
|
||||
const { rest } = window.MockServiceWorker;
|
||||
import { umbDocumentTypeData } from '../../data/document-type.data.js';
|
||||
import { slug } from './slug.js';
|
||||
import { umbracoPath } from '@umbraco-cms/backoffice/utils';
|
||||
|
||||
export const handlers = [
|
||||
rest.get(umbracoPath(`${slug}/:id`), (req, res, ctx) => {
|
||||
const id = req.params.id as string;
|
||||
if (!id) return;
|
||||
const document = umbDocumentTypeData.getById(id);
|
||||
return res(ctx.status(200), ctx.json(document));
|
||||
}),
|
||||
|
||||
rest.delete(umbracoPath(`${slug}/:id`), (req, res, ctx) => {
|
||||
const id = req.params.id as string;
|
||||
if (!id) return;
|
||||
const document = umbDocumentTypeData.getById(id);
|
||||
return res(ctx.status(200), ctx.json(document));
|
||||
}),
|
||||
|
||||
rest.put(umbracoPath(`${slug}/:id`), async (req, res, ctx) => {
|
||||
const id = req.params.id as string;
|
||||
if (!id) return;
|
||||
const data = await req.json();
|
||||
if (!data) return;
|
||||
const saved = umbDocumentTypeData.save(id, data);
|
||||
return res(ctx.status(200), ctx.json(saved));
|
||||
}),
|
||||
|
||||
rest.post(umbracoPath(`${slug}`), async (req, res, ctx) => {
|
||||
const data = await req.json();
|
||||
if (!data) return;
|
||||
umbDocumentTypeData.insert(data);
|
||||
return res(ctx.status(200));
|
||||
}),
|
||||
];
|
||||
@@ -0,0 +1,5 @@
|
||||
import { handlers as treeHandlers } from './tree.handlers.js';
|
||||
import { handlers as detailHandlers } from './detail.handlers.js';
|
||||
import { handlers as itemHandlers } from './item.handlers.js';
|
||||
|
||||
export const handlers = [...treeHandlers, ...itemHandlers, ...detailHandlers];
|
||||
@@ -0,0 +1,13 @@
|
||||
const { rest } = window.MockServiceWorker;
|
||||
import { umbDocumentTypeData } from '../../data/document-type.data.js';
|
||||
import { slug } from './slug.js';
|
||||
import { umbracoPath } from '@umbraco-cms/backoffice/utils';
|
||||
|
||||
export const handlers = [
|
||||
rest.get(umbracoPath(`${slug}/item`), (req, res, ctx) => {
|
||||
const ids = req.url.searchParams.getAll('id');
|
||||
if (!ids) return;
|
||||
const items = umbDocumentTypeData.getItems(ids);
|
||||
return res(ctx.status(200), ctx.json(items));
|
||||
}),
|
||||
];
|
||||
@@ -0,0 +1 @@
|
||||
export const slug = '/document-type';
|
||||
@@ -0,0 +1,29 @@
|
||||
const { rest } = window.MockServiceWorker;
|
||||
import { umbDocumentTypeData } from '../../data/document-type.data.js';
|
||||
import { slug } from './slug.js';
|
||||
import { umbracoPath } from '@umbraco-cms/backoffice/utils';
|
||||
|
||||
export const handlers = [
|
||||
rest.get(umbracoPath(`/tree${slug}/root`), (req, res, ctx) => {
|
||||
const rootItems = umbDocumentTypeData.getTreeRoot();
|
||||
const response = {
|
||||
total: rootItems.length,
|
||||
items: rootItems,
|
||||
};
|
||||
return res(ctx.status(200), ctx.json(response));
|
||||
}),
|
||||
|
||||
rest.get(umbracoPath(`/tree${slug}/children`), (req, res, ctx) => {
|
||||
const parentId = req.url.searchParams.get('parentId');
|
||||
if (!parentId) return;
|
||||
|
||||
const children = umbDocumentTypeData.getTreeItemChildren(parentId);
|
||||
|
||||
const response = {
|
||||
total: children.length,
|
||||
items: children,
|
||||
};
|
||||
|
||||
return res(ctx.status(200), ctx.json(response));
|
||||
}),
|
||||
];
|
||||
@@ -39,8 +39,8 @@ const detailHandlers = [
|
||||
const response = umbStylesheetData.getStylesheet(path);
|
||||
return res(ctx.status(200), ctx.json(response));
|
||||
}),
|
||||
rest.post(umbracoPath('/stylesheet'), (req, res, ctx) => {
|
||||
const requestBody = req.json() as CreateTextFileViewModelBaseModel;
|
||||
rest.post(umbracoPath('/stylesheet'), async (req, res, ctx) => {
|
||||
const requestBody = (await req.json()) as CreateTextFileViewModelBaseModel;
|
||||
if (!requestBody) return res(ctx.status(400, 'no body found'));
|
||||
const response = umbStylesheetData.insertStyleSheet(requestBody);
|
||||
return res(ctx.status(200), ctx.json(response));
|
||||
@@ -53,7 +53,7 @@ const detailHandlers = [
|
||||
return res(ctx.status(200), ctx.json(response));
|
||||
}),
|
||||
rest.put(umbracoPath('/stylesheet'), async (req, res, ctx) => {
|
||||
const requestBody = await req.json() as UpdateStylesheetRequestModel;
|
||||
const requestBody = (await req.json()) as UpdateStylesheetRequestModel;
|
||||
if (!requestBody) return res(ctx.status(400, 'no body found'));
|
||||
umbStylesheetData.updateData(requestBody);
|
||||
return res(ctx.status(200));
|
||||
@@ -75,7 +75,6 @@ const detailHandlers = [
|
||||
}),
|
||||
];
|
||||
|
||||
|
||||
const rulesHandlers = [
|
||||
rest.post(umbracoPath('/stylesheet/rich-text/extract-rules'), async (req, res, ctx) => {
|
||||
const requestBody = req.json() as ExtractRichTextStylesheetRulesRequestModel;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DATA_TYPE_ITEM_REPOSITORY_ALIAS } from '../../repository/index.js';
|
||||
import { UmbPickerInputContext } from '@umbraco-cms/backoffice/picker-input';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UMB_DATA_TYPE_PICKER_MODAL } from '@umbraco-cms/backoffice/modal';
|
||||
@@ -5,6 +6,6 @@ import { DataTypeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
|
||||
export class UmbDataTypePickerContext extends UmbPickerInputContext<DataTypeItemResponseModel> {
|
||||
constructor(host: UmbControllerHostElement) {
|
||||
super(host, 'Umb.Repository.DataType', UMB_DATA_TYPE_PICKER_MODAL);
|
||||
super(host, DATA_TYPE_ITEM_REPOSITORY_ALIAS, UMB_DATA_TYPE_PICKER_MODAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,13 +84,13 @@ export class UmbDataTypeInputElement extends FormControlMixin(UmbLitElement) {
|
||||
this.addValidator(
|
||||
'rangeUnderflow',
|
||||
() => this.minMessage,
|
||||
() => !!this.min && this.#pickerContext.getSelection().length < this.min
|
||||
() => !!this.min && this.#pickerContext.getSelection().length < this.min,
|
||||
);
|
||||
|
||||
this.addValidator(
|
||||
'rangeOverflow',
|
||||
() => this.maxMessage,
|
||||
() => !!this.max && this.#pickerContext.getSelection().length > this.max
|
||||
() => !!this.max && this.#pickerContext.getSelection().length > this.max,
|
||||
);
|
||||
|
||||
this.observe(this.#pickerContext.selection, (selection) => (super.value = selection.join(',')));
|
||||
|
||||
@@ -1,47 +1,11 @@
|
||||
import { UmbDataTypeRepositoryBase } from '../data-type-repository-base.js';
|
||||
import { UmbDataTypeItemServerDataSource } from './data-type-item.server.data.js';
|
||||
import { UMB_DATA_TYPE_ITEM_STORE_CONTEXT } from './data-type-item.store.js';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbItemDataSource, UmbItemRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { UmbItemRepositoryBase } from '@umbraco-cms/backoffice/repository';
|
||||
import { DataTypeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
|
||||
export class UmbDataTypeItemRepository
|
||||
extends UmbDataTypeRepositoryBase
|
||||
implements UmbItemRepository<DataTypeItemResponseModel>
|
||||
{
|
||||
#itemSource: UmbItemDataSource<DataTypeItemResponseModel>;
|
||||
|
||||
export class UmbDataTypeItemRepository extends UmbItemRepositoryBase<DataTypeItemResponseModel> {
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host);
|
||||
this.#itemSource = new UmbDataTypeItemServerDataSource(host);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the Data Type items for the given ids
|
||||
* @param {Array<string>} ids
|
||||
* @return {*}
|
||||
* @memberof UmbDataTypeItemRepository
|
||||
*/
|
||||
async requestItems(ids: Array<string>) {
|
||||
if (!ids) throw new Error('Ids are missing');
|
||||
await this._init;
|
||||
|
||||
const { data, error } = await this.#itemSource.getItems(ids);
|
||||
|
||||
if (data) {
|
||||
this._itemStore!.appendItems(data);
|
||||
}
|
||||
|
||||
return { data, error, asObservable: () => this._itemStore!.items(ids) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise with an observable of the Data Type items for the given ids
|
||||
* @param {Array<string>} ids
|
||||
* @return {Promise<Observable<DataTypeItemResponseModel[]>>}
|
||||
* @memberof UmbDataTypeItemRepository
|
||||
*/
|
||||
async items(ids: Array<string>) {
|
||||
await this._init;
|
||||
return this._itemStore!.items(ids);
|
||||
super(host, UmbDataTypeItemServerDataSource, UMB_DATA_TYPE_ITEM_STORE_CONTEXT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,20 @@
|
||||
import { UmbTreeRepositoryBase } from '../../tree/tree-repository-base.js';
|
||||
import { DATA_TYPE_ROOT_ENTITY_TYPE } from '../entities.js';
|
||||
import { UmbDataTypeRepositoryBase } from '../repository/data-type-repository-base.js';
|
||||
import { UmbDataTypeTreeServerDataSource } from './data-type.tree.server.data.js';
|
||||
import type { UmbTreeRepository, UmbTreeDataSource } from '@umbraco-cms/backoffice/repository';
|
||||
import { UMB_DATA_TYPE_TREE_STORE_CONTEXT } from './data-type.tree.store.js';
|
||||
import { UmbDataTypeTreeItemModel, UmbDataTypeTreeRootModel } from './types.js';
|
||||
import { type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { FolderTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
export class UmbDataTypeTreeRepository
|
||||
extends UmbDataTypeRepositoryBase
|
||||
implements UmbTreeRepository<FolderTreeItemResponseModel>, UmbApi
|
||||
{
|
||||
#treeSource: UmbTreeDataSource<FolderTreeItemResponseModel>;
|
||||
|
||||
export class UmbDataTypeTreeRepository
|
||||
extends UmbTreeRepositoryBase<UmbDataTypeTreeItemModel, UmbDataTypeTreeRootModel>
|
||||
implements UmbApi
|
||||
{
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host);
|
||||
this.#treeSource = new UmbDataTypeTreeServerDataSource(this);
|
||||
super(host, UmbDataTypeTreeServerDataSource, UMB_DATA_TYPE_TREE_STORE_CONTEXT);
|
||||
}
|
||||
|
||||
async requestTreeRoot() {
|
||||
await this._init;
|
||||
|
||||
const data = {
|
||||
id: null,
|
||||
type: DATA_TYPE_ROOT_ENTITY_TYPE,
|
||||
@@ -29,40 +25,4 @@ export class UmbDataTypeTreeRepository
|
||||
|
||||
return { data };
|
||||
}
|
||||
|
||||
async requestRootTreeItems() {
|
||||
await this._init;
|
||||
|
||||
const { data, error } = await this.#treeSource.getRootItems();
|
||||
|
||||
if (data) {
|
||||
this._treeStore!.appendItems(data.items);
|
||||
}
|
||||
|
||||
return { data, error, asObservable: () => this._treeStore!.rootItems };
|
||||
}
|
||||
|
||||
async requestTreeItemsOf(parentId: string | null) {
|
||||
await this._init;
|
||||
if (parentId === undefined) throw new Error('Parent id is missing');
|
||||
|
||||
const { data, error } = await this.#treeSource.getChildrenOf(parentId);
|
||||
|
||||
if (data) {
|
||||
this._treeStore!.appendItems(data.items);
|
||||
}
|
||||
|
||||
return { data, error, asObservable: () => this._treeStore!.childrenOf(parentId) };
|
||||
}
|
||||
|
||||
async rootTreeItems() {
|
||||
await this._init;
|
||||
return this._treeStore!.rootItems;
|
||||
}
|
||||
|
||||
async treeItemsOf(parentId: string | null) {
|
||||
if (parentId === undefined) throw new Error('Parent id is missing');
|
||||
await this._init;
|
||||
return this._treeStore!.childrenOf(parentId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository';
|
||||
import { DataTypeResource } from '@umbraco-cms/backoffice/backend-api';
|
||||
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';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
@@ -9,7 +9,7 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
* @class UmbDataTypeTreeServerDataSource
|
||||
* @implements {DocumentTreeDataSource}
|
||||
*/
|
||||
export class UmbDataTypeTreeServerDataSource implements UmbTreeDataSource {
|
||||
export class UmbDataTypeTreeServerDataSource implements UmbTreeDataSource<DataTypeTreeItemResponseModel> {
|
||||
#host: UmbControllerHost;
|
||||
|
||||
/**
|
||||
@@ -48,7 +48,7 @@ export class UmbDataTypeTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
DataTypeResource.getTreeDataTypeChildren({
|
||||
parentId,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ export class UmbDataTypeTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
DataTypeResource.getDataTypeItem({
|
||||
id: ids,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
/**
|
||||
* @export
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { type DataTypeTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import type { UmbEntityTreeItemModel, UmbEntityTreeRootModel } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
export type UmbDataTypeTreeItemModel = DataTypeTreeItemResponseModel & UmbEntityTreeItemModel;
|
||||
export type UmbDataTypeTreeRootModel = DataTypeTreeItemResponseModel & UmbEntityTreeRootModel;
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { ManifestApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { UmbItemStore, UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store';
|
||||
import { type ManifestApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { UmbItemStore, UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||
import { type UmbTreeStore } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
export interface ManifestStore extends ManifestApi<UmbStoreBase> {
|
||||
type: 'store';
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
UmbModalBaseElement,
|
||||
} from '@umbraco-cms/backoffice/modal';
|
||||
import { generateAlias } from '@umbraco-cms/backoffice/utils';
|
||||
import { UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/document-type';
|
||||
import { UMB_DOCUMENT_TYPE_DETAIL_STORE_CONTEXT } from '@umbraco-cms/backoffice/document-type';
|
||||
// TODO: Could base take a token to get its types?.
|
||||
// TODO: Missing a workspace context... unless this should not be a workspace any way.
|
||||
@customElement('umb-property-settings-modal')
|
||||
@@ -53,7 +53,7 @@ export class UmbPropertySettingsModalElement extends UmbModalBaseElement<
|
||||
super.connectedCallback();
|
||||
|
||||
// TODO: This is actually not good enough, we need to be able to get to the DOCUMENT_WORKSPACE_CONTEXT, so we can have a look at the draft/runtime version of the document. Otherwise 'Vary by culture' is first updated when saved.
|
||||
this.consumeContext(UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN, (instance) => {
|
||||
this.consumeContext(UMB_DOCUMENT_TYPE_DETAIL_STORE_CONTEXT, (instance) => {
|
||||
this.observe(
|
||||
instance.byId(this.data?.documentTypeId),
|
||||
(documentType) => {
|
||||
|
||||
@@ -14,6 +14,6 @@ export const UMB_DOCUMENT_TYPE_PICKER_MODAL = new UmbModalToken<
|
||||
size: 'small',
|
||||
},
|
||||
{
|
||||
treeAlias: 'Umb.Tree.DocumentTypes',
|
||||
treeAlias: 'Umb.Tree.DocumentType',
|
||||
},
|
||||
);
|
||||
|
||||
@@ -5,7 +5,5 @@ export * from './data-source.interface.js';
|
||||
export * from './extend-data-source-paged-response-data.function.js';
|
||||
export * from './extend-data-source-response-data.function.js';
|
||||
export * from './folder-data-source.interface.js';
|
||||
export * from './item-data-source.interface.js';
|
||||
export * from './move-data-source.interface.js';
|
||||
export * from './tree-data-source.interface.js';
|
||||
export * from './types.js';
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository';
|
||||
|
||||
export interface UmbItemDataSource<ItemType> {
|
||||
getItems(unique: Array<string>): Promise<DataSourceResponse<Array<ItemType>>>;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { UmbPagedData } from './types.js';
|
||||
import type { DataSourceResponse } from './data-source-response.interface.js';
|
||||
|
||||
export interface UmbTreeDataSource<ItemType = any, PagedItemType = UmbPagedData<ItemType>> {
|
||||
getRootItems(): Promise<DataSourceResponse<PagedItemType>>;
|
||||
getChildrenOf(parentUnique: string | null): Promise<DataSourceResponse<PagedItemType>>;
|
||||
// TODO: remove this when all repositories are migrated to the new items interface
|
||||
getItems(unique: Array<string>): Promise<DataSourceResponse<Array<any>>>;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
export interface UmbPagedData<T> {
|
||||
total: number;
|
||||
items: Array<T>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
export * from './data-source/index.js';
|
||||
export * from './detail-repository.interface.js';
|
||||
export * from './tree-repository.interface.js';
|
||||
export * from './folder-repository.interface.js';
|
||||
export * from './collection-repository.interface.js';
|
||||
export * from './item-repository.interface.js';
|
||||
export * from './move-repository.interface.js';
|
||||
export * from './copy-repository.interface.js';
|
||||
export * from './repository-items.manager.js';
|
||||
export * from './repository-base.js';
|
||||
|
||||
export * from './item/index.js';
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './item-data-source.interface.js';
|
||||
export * from './item-repository-base.js';
|
||||
export * from './item-repository.interface.js';
|
||||
@@ -0,0 +1,9 @@
|
||||
import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository';
|
||||
|
||||
export interface UmbItemDataSourceConstructor<ItemType = any> {
|
||||
new (host: UmbControllerHost): UmbItemDataSource<ItemType>;
|
||||
}
|
||||
export interface UmbItemDataSource<ItemType = any> {
|
||||
getItems(unique: Array<string>): Promise<DataSourceResponse<Array<ItemType>>>;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { UmbRepositoryBase } from '../repository-base.js';
|
||||
import { UmbItemDataSource, UmbItemDataSourceConstructor } from './item-data-source.interface.js';
|
||||
import { UmbItemRepository } from './item-repository.interface.js';
|
||||
import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbItemStore } from '@umbraco-cms/backoffice/store';
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
|
||||
export class UmbItemRepositoryBase<ItemType = any> extends UmbRepositoryBase implements UmbItemRepository<ItemType> {
|
||||
protected _init: Promise<unknown>;
|
||||
protected _itemStore?: UmbItemStore;
|
||||
#itemSource: UmbItemDataSource;
|
||||
|
||||
constructor(
|
||||
host: UmbControllerHost,
|
||||
itemSource: UmbItemDataSourceConstructor,
|
||||
itemStoreContextAlias: string | UmbContextToken<any, any>,
|
||||
) {
|
||||
super(host);
|
||||
this.#itemSource = new itemSource(host);
|
||||
|
||||
this._init = this.consumeContext(itemStoreContextAlias, (instance) => {
|
||||
this._itemStore = instance as UmbItemStore;
|
||||
}).asPromise();
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the items for the given uniques
|
||||
* @param {Array<string>} uniques
|
||||
* @return {*}
|
||||
* @memberof UmbItemRepositoryBase
|
||||
*/
|
||||
async requestItems(uniques: Array<string>) {
|
||||
if (!uniques) throw new Error('Uniques are missing');
|
||||
await this._init;
|
||||
|
||||
const { data, error } = await this.#itemSource.getItems(uniques);
|
||||
|
||||
if (data) {
|
||||
this._itemStore!.appendItems(data);
|
||||
}
|
||||
|
||||
return { data, error, asObservable: () => this._itemStore!.items(uniques) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise with an observable of the items for the given uniques
|
||||
* @param {Array<string>} uniques
|
||||
* @return {*}
|
||||
* @memberof UmbItemRepositoryBase
|
||||
*/
|
||||
async items(uniques: Array<string>) {
|
||||
await this._init;
|
||||
return this._itemStore!.items(uniques);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { Observable } from '@umbraco-cms/backoffice/external/rxjs';
|
||||
import { ItemResponseModelBaseModel, ProblemDetails } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { ProblemDetails } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export interface UmbItemRepository<ItemType extends ItemResponseModelBaseModel> extends UmbApi {
|
||||
export interface UmbItemRepository<ItemType = any> extends UmbApi {
|
||||
requestItems: (uniques: string[]) => Promise<{
|
||||
data?: Array<ItemType> | undefined;
|
||||
error?: ProblemDetails | undefined;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { UmbBaseController, UmbControllerHost } from "@umbraco-cms/backoffice/controller-api";
|
||||
import { UmbBaseController, UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
export class UmbRepositoryBase extends UmbBaseController {
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host);
|
||||
}
|
||||
}
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UmbTextStyles } from "@umbraco-cms/backoffice/style";
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { css, html, nothing, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router';
|
||||
import {
|
||||
@@ -110,8 +110,8 @@ export class UmbSectionMainViewElement extends UmbLitElement {
|
||||
const dashboardPath = this.#constructDashboardPath(dashboard);
|
||||
return html`
|
||||
<uui-tab
|
||||
.label="${dashboardName}"
|
||||
href="${this._routerPath}/${dashboardPath}"
|
||||
label="${dashboardName}"
|
||||
?active="${this._activePath === dashboardPath}"></uui-tab>
|
||||
`;
|
||||
})}
|
||||
@@ -129,8 +129,8 @@ export class UmbSectionMainViewElement extends UmbLitElement {
|
||||
const viewPath = this.#constructViewPath(view);
|
||||
return html`
|
||||
<uui-tab
|
||||
.label="${viewName}"
|
||||
href="${this._routerPath}/${viewPath}"
|
||||
label="${viewName}"
|
||||
?active="${this._activePath === viewPath}">
|
||||
<uui-icon slot="icon" name=${view.meta.icon}></uui-icon>
|
||||
${viewName}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { UmbStoreBase } from './store-base.js';
|
||||
import { UmbItemStore } from './item-store.interface.js';
|
||||
import type { FileItemResponseModelBaseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class UmbFileSystemItemStore
|
||||
* @extends {UmbStoreBase}
|
||||
* @description - Data Store for File system items
|
||||
*/
|
||||
|
||||
export class UmbFileSystemItemStore<T extends FileItemResponseModelBaseModel>
|
||||
extends UmbStoreBase<T>
|
||||
implements UmbItemStore<T>
|
||||
{
|
||||
constructor(host: UmbControllerHost, storeAlias: string) {
|
||||
super(host, storeAlias, new UmbArrayState<T>([], (x) => x.path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an observable to observe file system items
|
||||
* @param {Array<string>} paths
|
||||
* @return {*}
|
||||
* @memberof UmbFileSystemItemStore
|
||||
*/
|
||||
items(paths: Array<string>) {
|
||||
return this._data.asObservablePart((items) => items.filter((item) => paths.includes(item.path ?? '')));
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
export * from './entity-tree-store.js';
|
||||
export * from './file-system-tree.store.js';
|
||||
export * from './item-store.interface.js';
|
||||
export * from './store-base.js';
|
||||
export * from './store.interface.js';
|
||||
export * from './store.js';
|
||||
export * from './tree-store.interface.js';
|
||||
export * from './entity-item.store.js';
|
||||
export * from './file-system-item.store.js';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbStoreBase } from './store-base.js';
|
||||
import type { UmbTreeStore } from './tree-store.interface.js';
|
||||
import { type UmbTreeStore } from './tree-store.interface.js';
|
||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||
import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbStoreBase } from './store-base.js';
|
||||
import { UmbTreeStore } from './tree-store.interface.js';
|
||||
import { type UmbTreeStore } from './tree-store.interface.js';
|
||||
import { UmbStoreBase } from '@umbraco-cms/backoffice/store';
|
||||
import { FileSystemTreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
@@ -31,9 +31,11 @@ export class UmbFileSystemTreeStore
|
||||
* @memberof UmbFileSystemTreeStore
|
||||
*/
|
||||
childrenOf(parentPath: string | null) {
|
||||
return this._data.asObservablePart((items) =>
|
||||
items.filter((item) => item.path?.startsWith(parentPath + '/') || parentPath === null)
|
||||
);
|
||||
if (parentPath === null) {
|
||||
return this.rootItems;
|
||||
}
|
||||
|
||||
return this._data.asObservablePart((items) => items.filter((item) => item.path?.startsWith(parentPath + '/')));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './components/index.js';
|
||||
export * from './entity-tree-item/index.js';
|
||||
export * from './file-system-tree-item/index.js';
|
||||
export * from './tree-item/index.js';
|
||||
@@ -5,19 +6,11 @@ export * from './tree-item-base/index.js';
|
||||
export * from './tree-menu-item/index.js';
|
||||
export * from './tree.context.js';
|
||||
export * from './tree.element.js';
|
||||
export * from './components/index.js';
|
||||
export * from './types.js';
|
||||
export * from './tree-repository.interface.js';
|
||||
export * from './tree-data-source.interface.js';
|
||||
export * from './tree-store.interface.js';
|
||||
export * from './entity-tree-store.js';
|
||||
export * from './file-system-tree.store.js';
|
||||
|
||||
export interface UmbTreeRootModel {
|
||||
type: string;
|
||||
name: string;
|
||||
hasChildren: boolean;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
export interface UmbTreeRootEntityModel extends UmbTreeRootModel {
|
||||
id: string | null;
|
||||
}
|
||||
|
||||
export interface UmbTreeRootFileSystemModel extends UmbTreeRootModel {
|
||||
path: string | null;
|
||||
}
|
||||
export { UmbTreeRepositoryBase } from './tree-repository-base.js';
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { UmbPagedData, DataSourceResponse } from '@umbraco-cms/backoffice/repository';
|
||||
import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
export interface UmbTreeDataSourceConstructor<TreeItemType = any, TreeRootType = any> {
|
||||
new (host: UmbControllerHost): UmbTreeDataSource<TreeItemType, TreeRootType>;
|
||||
}
|
||||
|
||||
export interface UmbTreeDataSource<TreeItemType = any, TreeRootType = any> {
|
||||
getTreeRoot?(): Promise<DataSourceResponse<TreeRootType>>;
|
||||
getRootItems(): Promise<DataSourceResponse<UmbPagedData<TreeItemType>>>;
|
||||
getChildrenOf(parentUnique: string | null): Promise<DataSourceResponse<UmbPagedData<TreeItemType>>>;
|
||||
// TODO: remove this when all repositories are migrated to the new items interface
|
||||
getItems(unique: Array<string>): Promise<DataSourceResponse<Array<any>>>;
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
import { UmbTreeStore } from './tree-store.interface.js';
|
||||
import type { UmbEntityTreeItemModel, UmbEntityTreeRootModel } from './types.js';
|
||||
import { UmbTreeRepository } from './tree-repository.interface.js';
|
||||
import type { UmbTreeDataSource, UmbTreeDataSourceConstructor } from './tree-data-source.interface.js';
|
||||
import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository';
|
||||
import { type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
|
||||
export class UmbTreeRepositoryBase<
|
||||
TreeItemType extends UmbEntityTreeItemModel,
|
||||
TreeRootType extends UmbEntityTreeRootModel,
|
||||
>
|
||||
extends UmbRepositoryBase
|
||||
implements UmbTreeRepository<TreeItemType, TreeRootType>, UmbApi
|
||||
{
|
||||
protected _init: Promise<unknown>;
|
||||
protected _treeStore?: UmbTreeStore;
|
||||
#treeSource: UmbTreeDataSource;
|
||||
|
||||
constructor(
|
||||
host: UmbControllerHost,
|
||||
treeSource: UmbTreeDataSourceConstructor,
|
||||
treeStoreContextAlias: string | UmbContextToken<any, any>,
|
||||
) {
|
||||
super(host);
|
||||
this.#treeSource = new treeSource(this);
|
||||
|
||||
this._init = this.consumeContext(treeStoreContextAlias, (instance) => {
|
||||
this._treeStore = instance as UmbTreeStore;
|
||||
}).asPromise();
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the tree root item
|
||||
* @return {*}
|
||||
* @memberof UmbTreeRepositoryBase
|
||||
*/
|
||||
async requestTreeRoot() {
|
||||
if (!this.#treeSource.getTreeRoot?.()) {
|
||||
return { data: undefined, error: undefined };
|
||||
}
|
||||
|
||||
return this.#treeSource.getTreeRoot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests root items of a tree
|
||||
* @return {*}
|
||||
* @memberof UmbTreeRepositoryBase
|
||||
*/
|
||||
async requestRootTreeItems() {
|
||||
await this._init;
|
||||
|
||||
const { data, error } = await this.#treeSource.getRootItems();
|
||||
|
||||
if (data) {
|
||||
this._treeStore!.appendItems(data.items);
|
||||
}
|
||||
|
||||
return { data, error, asObservable: () => this._treeStore!.rootItems };
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests tree items of a given parent
|
||||
* @param {(string | null)} parentUnique
|
||||
* @return {*}
|
||||
* @memberof UmbTreeRepositoryBase
|
||||
*/
|
||||
async requestTreeItemsOf(parentUnique: string | null) {
|
||||
if (parentUnique === undefined) throw new Error('Parent unique is missing');
|
||||
await this._init;
|
||||
|
||||
const { data, error } = await this.#treeSource.getChildrenOf(parentUnique);
|
||||
|
||||
if (data) {
|
||||
this._treeStore!.appendItems(data.items);
|
||||
}
|
||||
|
||||
return { data, error, asObservable: () => this._treeStore!.childrenOf(parentUnique) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise with an observable of tree root items
|
||||
* @return {*}
|
||||
* @memberof UmbTreeRepositoryBase
|
||||
*/
|
||||
async rootTreeItems() {
|
||||
await this._init;
|
||||
return this._treeStore!.rootItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a promise with an observable of children items of a given parent
|
||||
* @param {(string | null)} parentUnique
|
||||
* @return {*}
|
||||
* @memberof UmbTreeRepositoryBase
|
||||
*/
|
||||
async treeItemsOf(parentUnique: string | null) {
|
||||
if (parentUnique === undefined) throw new Error('Parent unique is missing');
|
||||
await this._init;
|
||||
return this._treeStore!.childrenOf(parentUnique);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,39 @@
|
||||
import { type UmbPagedData } from './data-source/types.js';
|
||||
import type { UmbTreeItemModelBase, UmbTreeItemModel, UmbEntityTreeRootModel } from './types.js';
|
||||
import type { UmbPagedData } from '@umbraco-cms/backoffice/repository';
|
||||
import { type Observable } from '@umbraco-cms/backoffice/external/rxjs';
|
||||
import type { UmbTreeRootEntityModel, UmbTreeRootModel } from '@umbraco-cms/backoffice/tree';
|
||||
import { ProblemDetails, EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { ProblemDetails } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export interface UmbTreeRepository<
|
||||
TreeItemType extends EntityTreeItemResponseModel,
|
||||
TreeRootType extends UmbTreeRootModel = UmbTreeRootEntityModel
|
||||
TreeItemType extends UmbTreeItemModel = UmbTreeItemModel,
|
||||
TreeRootType extends UmbTreeItemModelBase = UmbEntityTreeRootModel,
|
||||
> extends UmbApi {
|
||||
requestTreeRoot: () => Promise<{
|
||||
data?: TreeRootType;
|
||||
error?: ProblemDetails;
|
||||
}>;
|
||||
|
||||
requestRootTreeItems: () => Promise<{
|
||||
data?: UmbPagedData<TreeItemType>;
|
||||
error?: ProblemDetails;
|
||||
asObservable?: () => Observable<TreeItemType[]>;
|
||||
}>;
|
||||
|
||||
requestTreeItemsOf: (parentUnique: string | null) => Promise<{
|
||||
data?: UmbPagedData<TreeItemType>;
|
||||
error?: ProblemDetails;
|
||||
asObservable?: () => Observable<TreeItemType[]>;
|
||||
}>;
|
||||
|
||||
treeItemsOf: (parentUnique: string | null) => Promise<Observable<TreeItemType[]>>;
|
||||
|
||||
/* TODO: remove this. It is not used client side.
|
||||
Logic to call the root endpoint should be in the data source
|
||||
because it is a server decision to split them
|
||||
*/
|
||||
requestRootTreeItems: () => Promise<{
|
||||
data?: UmbPagedData<TreeItemType>;
|
||||
error?: ProblemDetails;
|
||||
asObservable?: () => Observable<TreeItemType[]>;
|
||||
}>;
|
||||
|
||||
// TODO: remove
|
||||
rootTreeItems: () => Promise<Observable<TreeItemType[]>>;
|
||||
|
||||
// TODO: remove this when all repositories are migrated to the new interface items interface
|
||||
requestItemsLegacy?: (uniques: string[]) => Promise<{
|
||||
data?: Array<TreeItemType>;
|
||||
@@ -32,10 +41,6 @@ export interface UmbTreeRepository<
|
||||
asObservable?: () => Observable<any[]>;
|
||||
}>;
|
||||
|
||||
rootTreeItems: () => Promise<Observable<TreeItemType[]>>;
|
||||
|
||||
treeItemsOf: (parentUnique: string | null) => Promise<Observable<TreeItemType[]>>;
|
||||
|
||||
// TODO: remove this when all repositories are migrated to the new items interface
|
||||
itemsLegacy?: (uniques: string[]) => Promise<Observable<any[]>>;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UmbStore } from './store.interface.js';
|
||||
import { UmbStore } from '@umbraco-cms/backoffice/store';
|
||||
import type { Observable } from '@umbraco-cms/backoffice/external/rxjs';
|
||||
import { TreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
@@ -1,15 +1,21 @@
|
||||
import { type UmbTreeItemModelBase } from './types.js';
|
||||
import { type UmbTreeRepository } from './tree-repository.interface.js';
|
||||
import { Observable } from '@umbraco-cms/backoffice/external/rxjs';
|
||||
import { UmbPagedData, UmbTreeRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { type ManifestRepository, type ManifestTree, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UmbPagedData } from '@umbraco-cms/backoffice/repository';
|
||||
import {
|
||||
type ManifestRepository,
|
||||
type ManifestTree,
|
||||
umbExtensionsRegistry,
|
||||
} from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbBaseController, UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { ProblemDetails, TreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { ProblemDetails } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { UmbSelectionManager } from '@umbraco-cms/backoffice/utils';
|
||||
import { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
|
||||
// TODO: update interface
|
||||
export interface UmbTreeContext<TreeItemType extends TreeItemPresentationModel> extends UmbBaseController {
|
||||
export interface UmbTreeContext<TreeItemType extends UmbTreeItemModelBase> extends UmbBaseController {
|
||||
readonly selectable: Observable<boolean>;
|
||||
readonly selection: Observable<Array<string | null>>;
|
||||
setSelectable(value: boolean): void;
|
||||
@@ -27,7 +33,7 @@ export interface UmbTreeContext<TreeItemType extends TreeItemPresentationModel>
|
||||
}>;
|
||||
}
|
||||
|
||||
export class UmbTreeContextBase<TreeItemType extends TreeItemPresentationModel>
|
||||
export class UmbTreeContextBase<TreeItemType extends UmbTreeItemModelBase>
|
||||
extends UmbBaseController
|
||||
implements UmbTreeContext<TreeItemType>
|
||||
{
|
||||
@@ -153,9 +159,15 @@ export class UmbTreeContextBase<TreeItemType extends TreeItemPresentationModel>
|
||||
const repositoryAlias = treeManifest.meta.repositoryAlias;
|
||||
if (!repositoryAlias) throw new Error('Tree must have a repository alias.');
|
||||
|
||||
new UmbExtensionApiInitializer<ManifestRepository<UmbTreeRepository<TreeItemType>>>(this, umbExtensionsRegistry, repositoryAlias, [this._host], (permitted, ctrl) => {
|
||||
this.repository = permitted ? ctrl.api : undefined;
|
||||
this.#checkIfInitialized();
|
||||
});
|
||||
new UmbExtensionApiInitializer<ManifestRepository<UmbTreeRepository<TreeItemType>>>(
|
||||
this,
|
||||
umbExtensionsRegistry,
|
||||
repositoryAlias,
|
||||
[this._host],
|
||||
(permitted, ctrl) => {
|
||||
this.repository = permitted ? ctrl.api : undefined;
|
||||
this.#checkIfInitialized();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
27
src/Umbraco.Web.UI.Client/src/packages/core/tree/types.ts
Normal file
27
src/Umbraco.Web.UI.Client/src/packages/core/tree/types.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
export interface UmbTreeItemModelBase {
|
||||
type?: string; // TODO: remove option to be undefined when we have our own types
|
||||
name?: string;
|
||||
hasChildren?: boolean;
|
||||
icon?: string | null;
|
||||
}
|
||||
|
||||
export interface UmbTreeItemModel extends UmbTreeItemModelBase {
|
||||
parentId?: string | null; // TODO: remove option to be undefined when server returns the same or when we get our own types
|
||||
}
|
||||
|
||||
export interface UmbEntityTreeItemModel extends UmbTreeItemModel {
|
||||
id?: string; // TODO: remove option to be undefined when server returns the same or when we get our own types
|
||||
}
|
||||
|
||||
export interface UmbFileSystemTreeItemModel extends UmbTreeItemModel {
|
||||
path?: string; // TODO: remove option to be undefined when server returns the same or when we get our own types
|
||||
}
|
||||
|
||||
// Root
|
||||
export interface UmbEntityTreeRootModel extends UmbTreeItemModelBase {
|
||||
id: null;
|
||||
}
|
||||
|
||||
export interface UmbFileSystemTreeRootModel extends UmbTreeItemModelBase {
|
||||
path: null;
|
||||
}
|
||||
@@ -1,54 +1,16 @@
|
||||
import { UmbDictionaryRepository } from '../../repository/dictionary.repository.js';
|
||||
import { UmbTextStyles } from "@umbraco-cms/backoffice/style";
|
||||
import { UmbSectionSidebarContext, UMB_SECTION_SIDEBAR_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/section';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import {
|
||||
UmbModalManagerContext,
|
||||
UMB_MODAL_MANAGER_CONTEXT_TOKEN,
|
||||
UMB_CREATE_DICTIONARY_MODAL,
|
||||
} from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
export default class UmbCreateDictionaryEntityAction extends UmbEntityActionBase<UmbDictionaryRepository> {
|
||||
static styles = [UmbTextStyles];
|
||||
|
||||
#modalContext?: UmbModalManagerContext;
|
||||
|
||||
#sectionSidebarContext!: UmbSectionSidebarContext;
|
||||
|
||||
constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) {
|
||||
super(host, repositoryAlias, unique);
|
||||
|
||||
this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => {
|
||||
this.#modalContext = instance;
|
||||
});
|
||||
|
||||
this.consumeContext(UMB_SECTION_SIDEBAR_CONTEXT_TOKEN, (instance) => {
|
||||
this.#sectionSidebarContext = instance;
|
||||
});
|
||||
}
|
||||
|
||||
async execute() {
|
||||
// TODO: what to do if modal service is not available?
|
||||
if (!this.#modalContext) return;
|
||||
if (!this.repository) return;
|
||||
|
||||
// TODO: how can we get the current entity detail in the modal? Passing the observable
|
||||
// feels a bit hacky. Works, but hacky.
|
||||
const modalContext = this.#modalContext?.open(UMB_CREATE_DICTIONARY_MODAL, {
|
||||
parentId: this.unique,
|
||||
parentName: this.#sectionSidebarContext.headline,
|
||||
});
|
||||
|
||||
const { name, parentId } = await modalContext.onSubmit();
|
||||
if (!name || parentId === undefined) return;
|
||||
|
||||
const { data: url } = await this.repository.create({ name, parentId });
|
||||
if (!url) return;
|
||||
|
||||
//TODO: Why do we need to extract the id like this?
|
||||
const id = url.substring(url.lastIndexOf('/') + 1);
|
||||
|
||||
history.pushState({}, '', `/section/dictionary/workspace/dictionary-item/edit/${id}`);
|
||||
history.pushState({}, '', `/section/dictionary/workspace/dictionary-item/create/${this.unique ?? 'null'}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ import { UmbDictionaryDetailServerDataSource } from './sources/dictionary.detail
|
||||
import { UmbDictionaryTreeStore, UMB_DICTIONARY_TREE_STORE_CONTEXT_TOKEN } from './dictionary.tree.store.js';
|
||||
import { UmbDictionaryTreeServerDataSource } from './sources/dictionary.tree.server.data.js';
|
||||
import { UmbBaseController, UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbTreeDataSource, UmbDetailRepository, UmbTreeRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { UmbDetailRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { UmbTreeRepository, UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import {
|
||||
CreateDictionaryItemRequestModel,
|
||||
DictionaryOverviewResponseModel,
|
||||
@@ -14,7 +15,8 @@ import {
|
||||
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
|
||||
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export class UmbDictionaryRepository extends UmbBaseController
|
||||
export class UmbDictionaryRepository
|
||||
extends UmbBaseController
|
||||
implements
|
||||
UmbTreeRepository<EntityTreeItemResponseModel>,
|
||||
UmbDetailRepository<
|
||||
@@ -109,6 +111,20 @@ export class UmbDictionaryRepository extends UmbBaseController
|
||||
return { data, error, asObservable: () => this.#treeStore!.items(ids) };
|
||||
}
|
||||
|
||||
async requestItems(ids: Array<string>) {
|
||||
// TODO: There is a bug where the item gets removed from the tree before we confirm the delete via the modal. It doesn't delete the item unless we confirm the delete.
|
||||
if (!ids) throw new Error('Dictionary Ids are missing');
|
||||
await this.#init;
|
||||
|
||||
const { data, error } = await this.#treeSource.getItems(ids);
|
||||
|
||||
if (data) {
|
||||
this.#treeStore?.appendItems(data);
|
||||
}
|
||||
|
||||
return { data, error, asObservable: () => this.#treeStore!.items(ids) };
|
||||
}
|
||||
|
||||
async rootTreeItems() {
|
||||
await this.#init;
|
||||
return this.#treeStore!.rootItems;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
/**
|
||||
@@ -20,5 +20,5 @@ export class UmbDictionaryTreeStore extends UmbEntityTreeStore {
|
||||
}
|
||||
|
||||
export const UMB_DICTIONARY_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDictionaryTreeStore>(
|
||||
'UmbDictionaryTreeStore'
|
||||
'UmbDictionaryTreeStore',
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { DictionaryResource } from '@umbraco-cms/backoffice/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository';
|
||||
import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
/**
|
||||
@@ -48,7 +48,7 @@ export class UmbDictionaryTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
DictionaryResource.getTreeDictionaryChildren({
|
||||
parentId,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ export class UmbDictionaryTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
DictionaryResource.getDictionaryItem({
|
||||
id: ids,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,9 +68,8 @@ export class UmbDictionaryWorkspaceContext
|
||||
const { data } = await this.repository.createScaffold(parentId);
|
||||
if (!data) return;
|
||||
this.setIsNew(true);
|
||||
// TODO: This is a hack to get around the fact that the data is not typed correctly.
|
||||
// Create and response models are different. We need to look into this.
|
||||
this.#data.next(data as unknown as DictionaryItemResponseModel);
|
||||
|
||||
this.#data.next(data as DictionaryItemResponseModel);
|
||||
}
|
||||
|
||||
async save() {
|
||||
|
||||
@@ -26,7 +26,6 @@ export class UmbWorkspaceDictionaryElement extends UmbLitElement {
|
||||
component: () => this.#element,
|
||||
setup: async (_component, info) => {
|
||||
const parentId = info.match.params.parentId === 'null' ? null : info.match.params.parentId;
|
||||
|
||||
await this.#workspaceContext.create(parentId);
|
||||
|
||||
new UmbWorkspaceIsNewRedirectController(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/tree';
|
||||
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
export const UMB_DOCUMENT_BLUEPRINT_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDocumentBlueprintTreeStore>(
|
||||
'UmbDocumentBlueprintTreeStore'
|
||||
'UmbDocumentBlueprintTreeStore',
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { DOCUMENT_TYPE_ITEM_REPOSITORY_ALIAS } from '../../repository/index.js';
|
||||
import { UmbPickerInputContext } from '@umbraco-cms/backoffice/picker-input';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UMB_DOCUMENT_TYPE_PICKER_MODAL } from '@umbraco-cms/backoffice/modal';
|
||||
import { DocumentTypeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
|
||||
export class UmbDocumentTypePickerContext extends UmbPickerInputContext<DocumentTypeItemResponseModel> {
|
||||
constructor(host: UmbControllerHostElement) {
|
||||
super(host, DOCUMENT_TYPE_ITEM_REPOSITORY_ALIAS, UMB_DOCUMENT_TYPE_PICKER_MODAL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
import { UmbDocumentTypePickerContext } from './document-type-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 type { DocumentTypeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
|
||||
@customElement('umb-document-type-input')
|
||||
export class UmbDocumentTypeInputElement 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 = idsString.split(/[ ,]+/);
|
||||
}
|
||||
|
||||
@property()
|
||||
get pickableFilter() {
|
||||
return this.#pickerContext.pickableFilter;
|
||||
}
|
||||
set pickableFilter(newVal) {
|
||||
this.#pickerContext.pickableFilter = newVal;
|
||||
}
|
||||
|
||||
@state()
|
||||
private _items?: Array<DocumentTypeItemResponseModel>;
|
||||
|
||||
#pickerContext = new UmbDocumentTypePickerContext(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: DocumentTypeItemResponseModel) {
|
||||
if (!item.id) return;
|
||||
return html`
|
||||
<uui-ref-node-document-type name=${item.name}>
|
||||
<uui-action-bar slot="actions">
|
||||
<uui-button
|
||||
@click=${() => this.#pickerContext.requestRemoveItem(item.id!)}
|
||||
label="Remove Document Type ${item.name}"
|
||||
>Remove</uui-button
|
||||
>
|
||||
</uui-action-bar>
|
||||
</uui-ref-node-document-type>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
css`
|
||||
#add-button {
|
||||
width: 100%;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
export default UmbDocumentTypeInputElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-document-type-input': UmbDocumentTypeInputElement;
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
import './input-document-type/input-document-type.element.js';
|
||||
import './document-type-input/document-type-input.element.js';
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
import {
|
||||
UmbDocumentTypeTreeStore,
|
||||
UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN,
|
||||
} from '../../repository/document-type.tree.store.js';
|
||||
import { css, html, nothing, ifDefined, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { FormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { DocumentTypeResponseModel, EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import {
|
||||
UmbModalManagerContext,
|
||||
UMB_MODAL_MANAGER_CONTEXT_TOKEN,
|
||||
UMB_CONFIRM_MODAL,
|
||||
UMB_DOCUMENT_TYPE_PICKER_MODAL,
|
||||
} from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
||||
|
||||
@customElement('umb-input-document-type')
|
||||
export class UmbInputDocumentTypeElement extends FormControlMixin(UmbLitElement) {
|
||||
// TODO: do we need both selectedIds and value? If we just use value we follow the same pattern as native form controls.
|
||||
private _selectedIds: Array<string> = [];
|
||||
@property({ type: Array })
|
||||
public get selectedIds(): Array<string> {
|
||||
return this._selectedIds;
|
||||
}
|
||||
public set selectedIds(ids: Array<string>) {
|
||||
this._selectedIds = ids ?? [];
|
||||
super.value = this._selectedIds.join(',');
|
||||
this._observePickedDocuments();
|
||||
}
|
||||
|
||||
@property()
|
||||
public set value(idsString: string) {
|
||||
if (idsString !== this._value) {
|
||||
this.selectedIds = idsString.split(/[ ,]+/);
|
||||
}
|
||||
}
|
||||
|
||||
@state()
|
||||
private _items?: Array<DocumentTypeResponseModel>;
|
||||
|
||||
private _modalContext?: UmbModalManagerContext;
|
||||
private _documentTypeStore?: UmbDocumentTypeTreeStore;
|
||||
private _pickedItemsObserver?: UmbObserverController<EntityTreeItemResponseModel[]>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.consumeContext(UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN, (instance) => {
|
||||
this._documentTypeStore = instance;
|
||||
this._observePickedDocuments();
|
||||
});
|
||||
this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => {
|
||||
this._modalContext = instance;
|
||||
});
|
||||
}
|
||||
|
||||
protected getFormElement() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _observePickedDocuments() {
|
||||
this._pickedItemsObserver?.destroy();
|
||||
|
||||
if (!this._documentTypeStore) return;
|
||||
|
||||
// TODO: consider changing this to the list data endpoint when it is available
|
||||
this._pickedItemsObserver = this.observe(this._documentTypeStore.items(this._selectedIds), (items) => {
|
||||
this._items = items;
|
||||
});
|
||||
}
|
||||
|
||||
private _openPicker() {
|
||||
// We send a shallow copy(good enough as its just an array of ids) of our this._selectedIds, as we don't want the modal to manipulate our data:
|
||||
const modalContext = this._modalContext?.open(UMB_DOCUMENT_TYPE_PICKER_MODAL, {
|
||||
multiple: true,
|
||||
selection: [...this._selectedIds],
|
||||
});
|
||||
|
||||
modalContext?.onSubmit().then(({ selection }: any) => {
|
||||
this._setSelection(selection);
|
||||
});
|
||||
}
|
||||
|
||||
private async _removeItem(item: DocumentTypeResponseModel) {
|
||||
const modalContext = this._modalContext?.open(UMB_CONFIRM_MODAL, {
|
||||
color: 'danger',
|
||||
headline: `Remove ${item.name}?`,
|
||||
content: 'Are you sure you want to remove this item',
|
||||
confirmLabel: 'Remove',
|
||||
});
|
||||
|
||||
await modalContext?.onSubmit();
|
||||
const newSelection = this._selectedIds.filter((value) => value !== item.id);
|
||||
this._setSelection(newSelection);
|
||||
}
|
||||
|
||||
private _setSelection(newSelection: Array<string>) {
|
||||
this.selectedIds = newSelection;
|
||||
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
|
||||
}
|
||||
|
||||
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._openPicker} label="open">Add</uui-button>
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderItem(item: DocumentTypeResponseModel) {
|
||||
// TODO: remove when we have a way to handle trashed items
|
||||
const tempItem = item as DocumentTypeResponseModel & { isTrashed: boolean };
|
||||
|
||||
return html`
|
||||
<uui-ref-node name=${ifDefined(item.name === null ? undefined : item.name)} detail=${ifDefined(item.id)}>
|
||||
<uui-icon slot="icon" name="${ifDefined(item.icon)}"></uui-icon>
|
||||
${tempItem.isTrashed ? html` <uui-tag size="s" slot="tag" color="danger">Trashed</uui-tag> ` : nothing}
|
||||
<uui-action-bar slot="actions">
|
||||
<uui-button @click=${() => this._removeItem(item)} label="Remove document ${item.name}">Remove</uui-button>
|
||||
</uui-action-bar>
|
||||
</uui-ref-node>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
css`
|
||||
#add-button {
|
||||
width: 100%;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
export default UmbInputDocumentTypeElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-input-document-type': UmbInputDocumentTypeElement;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { UmbDocumentTypeRepository } from '../../repository/document-type.repository.js';
|
||||
import { UmbDocumentTypeDetailRepository } from '../../repository/detail/document-type-detail.repository.js';
|
||||
import { UMB_DOCUMENT_TYPE_CREATE_OPTIONS_MODAL } from './modal/index.js';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbModalManagerContext, UMB_MODAL_MANAGER_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
export class UmbCreateDataTypeEntityAction extends UmbEntityActionBase<UmbDocumentTypeRepository> {
|
||||
export class UmbCreateDataTypeEntityAction extends UmbEntityActionBase<UmbDocumentTypeDetailRepository> {
|
||||
#modalManagerContext?: UmbModalManagerContext;
|
||||
|
||||
constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
DOCUMENT_TYPE_FOLDER_ENTITY_TYPE,
|
||||
DOCUMENT_TYPE_ROOT_ENTITY_TYPE,
|
||||
} from '../../index.js';
|
||||
import { DOCUMENT_TYPE_REPOSITORY_ALIAS } from '../../repository/manifests.js';
|
||||
import { DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS } from '../../repository/index.js';
|
||||
import { UmbCreateDataTypeEntityAction } from './create.action.js';
|
||||
import { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
@@ -17,7 +17,7 @@ const entityActions: Array<ManifestTypes> = [
|
||||
meta: {
|
||||
icon: 'icon-add',
|
||||
label: 'Create...',
|
||||
repositoryAlias: DOCUMENT_TYPE_REPOSITORY_ALIAS,
|
||||
repositoryAlias: DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS,
|
||||
entityTypes: [DOCUMENT_TYPE_ENTITY_TYPE, DOCUMENT_TYPE_ROOT_ENTITY_TYPE, DOCUMENT_TYPE_FOLDER_ENTITY_TYPE],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DOCUMENT_TYPE_REPOSITORY_ALIAS } from '../../../repository/manifests.js';
|
||||
import { DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS } from '../../../repository/index.js';
|
||||
import { UmbDocumentTypeCreateOptionsModalData } from './index.js';
|
||||
import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbTextStyles } from "@umbraco-cms/backoffice/style";
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import {
|
||||
UmbModalManagerContext,
|
||||
UmbModalContext,
|
||||
@@ -30,7 +30,7 @@ export class UmbDataTypeCreateOptionsModalElement extends UmbLitElement {
|
||||
#onClick(event: PointerEvent) {
|
||||
event.stopPropagation();
|
||||
const folderModalHandler = this.#modalContext?.open(UMB_FOLDER_MODAL, {
|
||||
repositoryAlias: DOCUMENT_TYPE_REPOSITORY_ALIAS,
|
||||
repositoryAlias: DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS,
|
||||
});
|
||||
folderModalHandler?.onSubmit().then(() => this.modalContext?.submit());
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DOCUMENT_TYPE_REPOSITORY_ALIAS } from '../repository/manifests.js';
|
||||
import { DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js';
|
||||
import { manifests as createManifests } from './create/manifests.js';
|
||||
import {
|
||||
UmbCopyEntityAction,
|
||||
@@ -20,7 +20,7 @@ const entityActions: Array<ManifestEntityAction> = [
|
||||
meta: {
|
||||
icon: 'icon-trash',
|
||||
label: 'Delete',
|
||||
repositoryAlias: DOCUMENT_TYPE_REPOSITORY_ALIAS,
|
||||
repositoryAlias: DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS,
|
||||
entityTypes: [entityType],
|
||||
},
|
||||
},
|
||||
@@ -33,7 +33,7 @@ const entityActions: Array<ManifestEntityAction> = [
|
||||
meta: {
|
||||
icon: 'icon-enter',
|
||||
label: 'Move',
|
||||
repositoryAlias: DOCUMENT_TYPE_REPOSITORY_ALIAS,
|
||||
repositoryAlias: DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS,
|
||||
entityTypes: [entityType],
|
||||
},
|
||||
},
|
||||
@@ -46,7 +46,7 @@ const entityActions: Array<ManifestEntityAction> = [
|
||||
meta: {
|
||||
icon: 'icon-documents',
|
||||
label: 'Copy',
|
||||
repositoryAlias: DOCUMENT_TYPE_REPOSITORY_ALIAS,
|
||||
repositoryAlias: DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS,
|
||||
entityTypes: [entityType],
|
||||
},
|
||||
},
|
||||
@@ -59,7 +59,7 @@ const entityActions: Array<ManifestEntityAction> = [
|
||||
meta: {
|
||||
icon: 'icon-navigation-vertical',
|
||||
label: 'Sort',
|
||||
repositoryAlias: DOCUMENT_TYPE_REPOSITORY_ALIAS,
|
||||
repositoryAlias: DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS,
|
||||
entityTypes: [entityType],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DOCUMENT_TYPE_TREE_ALIAS } from '../tree/manifests.js';
|
||||
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
const menuItem: ManifestTypes = {
|
||||
@@ -7,7 +8,7 @@ const menuItem: ManifestTypes = {
|
||||
name: 'Document Types Menu Item',
|
||||
weight: 900,
|
||||
meta: {
|
||||
treeAlias: 'Umb.Tree.DocumentTypes',
|
||||
treeAlias: DOCUMENT_TYPE_TREE_ALIAS,
|
||||
label: 'Document Types',
|
||||
icon: 'icon-folder',
|
||||
menus: ['Umb.Menu.Settings'],
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import { UmbDocumentTypeTreeServerDataSource } from './sources/document-type.tree.server.data.js';
|
||||
import { UmbDocumentTypeServerDataSource } from './sources/document-type.server.data.js';
|
||||
import { UmbDocumentTypeTreeStore, UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN } from './document-type.tree.store.js';
|
||||
import { UmbDocumentTypeStore, UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN } from './document-type.store.js';
|
||||
import { UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT_TOKEN, UmbDocumentTypeItemStore } from './document-type-item.store.js';
|
||||
import { UmbDocumentTypeItemServerDataSource } from './sources/document-type-item.server.data.js';
|
||||
import type { UmbTreeDataSource, UmbTreeRepository, UmbDetailRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT, UmbDocumentTypeTreeStore } from '../../tree/document-type.tree.store.js';
|
||||
import { UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT, UmbDocumentTypeItemStore } from '../item/document-type-item.store.js';
|
||||
import { UmbDocumentTypeServerDataSource } from './document-type.server.data.js';
|
||||
import { UmbDocumentTypeDetailStore, UMB_DOCUMENT_TYPE_DETAIL_STORE_CONTEXT } from './document-type-detail.store.js';
|
||||
import { type UmbDetailRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { UmbBaseController, type UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
||||
import {
|
||||
CreateDocumentTypeRequestModel,
|
||||
DocumentTypeResponseModel,
|
||||
EntityTreeItemResponseModel,
|
||||
FolderTreeItemResponseModel,
|
||||
UpdateDocumentTypeRequestModel,
|
||||
} from '@umbraco-cms/backoffice/backend-api';
|
||||
@@ -19,21 +15,19 @@ import { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
type ItemType = DocumentTypeResponseModel;
|
||||
|
||||
export class UmbDocumentTypeRepository extends UmbBaseController
|
||||
export class UmbDocumentTypeDetailRepository
|
||||
extends UmbBaseController
|
||||
implements
|
||||
UmbTreeRepository<EntityTreeItemResponseModel>,
|
||||
UmbDetailRepository<CreateDocumentTypeRequestModel, any, UpdateDocumentTypeRequestModel, DocumentTypeResponseModel>,
|
||||
UmbApi
|
||||
{
|
||||
#init!: Promise<unknown>;
|
||||
|
||||
#treeSource: UmbTreeDataSource;
|
||||
#treeStore?: UmbDocumentTypeTreeStore;
|
||||
|
||||
#detailDataSource: UmbDocumentTypeServerDataSource;
|
||||
#detailStore?: UmbDocumentTypeStore;
|
||||
#detailStore?: UmbDocumentTypeDetailStore;
|
||||
|
||||
#itemSource: UmbDocumentTypeItemServerDataSource;
|
||||
#itemStore?: UmbDocumentTypeItemStore;
|
||||
|
||||
#notificationContext?: UmbNotificationContext;
|
||||
@@ -42,20 +36,18 @@ export class UmbDocumentTypeRepository extends UmbBaseController
|
||||
super(host);
|
||||
|
||||
// TODO: figure out how spin up get the correct data source
|
||||
this.#treeSource = new UmbDocumentTypeTreeServerDataSource(this);
|
||||
this.#detailDataSource = new UmbDocumentTypeServerDataSource(this);
|
||||
this.#itemSource = new UmbDocumentTypeItemServerDataSource(this);
|
||||
|
||||
this.#init = Promise.all([
|
||||
this.consumeContext(UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN, (instance) => {
|
||||
this.consumeContext(UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT, (instance) => {
|
||||
this.#treeStore = instance;
|
||||
}),
|
||||
|
||||
this.consumeContext(UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN, (instance) => {
|
||||
this.consumeContext(UMB_DOCUMENT_TYPE_DETAIL_STORE_CONTEXT, (instance) => {
|
||||
this.#detailStore = instance;
|
||||
}),
|
||||
|
||||
this.consumeContext(UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT_TOKEN, (instance) => {
|
||||
this.consumeContext(UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT, (instance) => {
|
||||
this.#itemStore = instance;
|
||||
}),
|
||||
|
||||
@@ -65,86 +57,6 @@ export class UmbDocumentTypeRepository extends UmbBaseController
|
||||
]);
|
||||
}
|
||||
|
||||
// TODO: Move
|
||||
async requestTreeRoot() {
|
||||
await this.#init;
|
||||
|
||||
const data = {
|
||||
id: null,
|
||||
type: 'document-type-root',
|
||||
name: 'Document Types',
|
||||
icon: 'icon-folder',
|
||||
hasChildren: true,
|
||||
};
|
||||
|
||||
return { data };
|
||||
}
|
||||
|
||||
async requestRootTreeItems() {
|
||||
await this.#init;
|
||||
|
||||
const { data, error } = await this.#treeSource.getRootItems();
|
||||
|
||||
if (data) {
|
||||
this.#treeStore?.appendItems(data.items);
|
||||
}
|
||||
|
||||
return { data, error, asObservable: () => this.#treeStore!.rootItems };
|
||||
}
|
||||
|
||||
async requestTreeItemsOf(parentId: string | null) {
|
||||
await this.#init;
|
||||
if (parentId === undefined) throw new Error('Parent id is missing');
|
||||
|
||||
const { data, error } = await this.#treeSource.getChildrenOf(parentId);
|
||||
|
||||
if (data) {
|
||||
this.#treeStore?.appendItems(data.items);
|
||||
}
|
||||
|
||||
return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentId) };
|
||||
}
|
||||
|
||||
async requestItems(ids: Array<string>) {
|
||||
if (!ids) throw new Error('Document Type Ids are missing');
|
||||
await this.#init;
|
||||
|
||||
const { data, error } = await this.#itemSource.getItems(ids);
|
||||
|
||||
if (data) {
|
||||
this.#itemStore?.appendItems(data);
|
||||
}
|
||||
|
||||
return { data, error, asObservable: () => this.#itemStore!.items(ids) };
|
||||
}
|
||||
|
||||
async requestItemsLegacy(ids: Array<string>) {
|
||||
await this.#init;
|
||||
|
||||
if (!ids) {
|
||||
throw new Error('Ids are missing');
|
||||
}
|
||||
|
||||
const { data, error } = await this.#treeSource.getItems(ids);
|
||||
|
||||
return { data, error, asObservable: () => this.#treeStore!.items(ids) };
|
||||
}
|
||||
|
||||
async rootTreeItems() {
|
||||
await this.#init;
|
||||
return this.#treeStore!.rootItems;
|
||||
}
|
||||
|
||||
async treeItemsOf(parentId: string | null) {
|
||||
await this.#init;
|
||||
return this.#treeStore!.childrenOf(parentId);
|
||||
}
|
||||
|
||||
async itemsLegacy(ids: Array<string>) {
|
||||
await this.#init;
|
||||
return this.#treeStore!.items(ids);
|
||||
}
|
||||
|
||||
// DETAILS:
|
||||
|
||||
async createScaffold(parentId: string | null) {
|
||||
@@ -241,7 +153,7 @@ export class UmbDocumentTypeRepository extends UmbBaseController
|
||||
// Consider to look up the data before fetching from the server.
|
||||
// Consider notify a workspace if a template is deleted from the store while someone is editing it.
|
||||
// TODO: would be nice to align the stores on methods/methodNames.
|
||||
this.#detailStore?.remove([id]);
|
||||
this.#detailStore?.removeItem(id);
|
||||
this.#treeStore?.removeItem(id);
|
||||
this.#itemStore?.removeItem(id);
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api
|
||||
* @extends {UmbStoreBase}
|
||||
* @description - Data Store for Document Types
|
||||
*/
|
||||
export class UmbDocumentTypeStore extends UmbStoreBase<DocumentTypeResponseModel> {
|
||||
export class UmbDocumentTypeDetailStore extends UmbStoreBase<DocumentTypeResponseModel> {
|
||||
/**
|
||||
* Creates an instance of UmbDocumentTypeStore.
|
||||
* @param {UmbControllerHostElement} host
|
||||
@@ -19,37 +19,21 @@ export class UmbDocumentTypeStore extends UmbStoreBase<DocumentTypeResponseModel
|
||||
constructor(host: UmbControllerHostElement) {
|
||||
super(
|
||||
host,
|
||||
UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN.toString(),
|
||||
new UmbArrayState<DocumentTypeResponseModel>([], (x) => x.id)
|
||||
UMB_DOCUMENT_TYPE_DETAIL_STORE_CONTEXT.toString(),
|
||||
new UmbArrayState<DocumentTypeResponseModel>([], (x) => x.id),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a document-type to the store
|
||||
* @param {DocumentTypeModel} document
|
||||
* @memberof UmbDocumentTypeStore
|
||||
*/
|
||||
append(document: DocumentTypeResponseModel) {
|
||||
this._data.append([document]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a document-type to the store
|
||||
* @param {DocumentTypeModel} document
|
||||
* @memberof UmbDocumentTypeStore
|
||||
* @param {DocumentTypeResponseModel['id']} id
|
||||
* @return {*}
|
||||
* @memberof UmbDocumentTypeDetailStore
|
||||
*/
|
||||
byId(id: DocumentTypeResponseModel['id']) {
|
||||
return this._data.asObservablePart((x) => x.find((y) => y.id === id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes document-types in the store with the given uniques
|
||||
* @param {string[]} uniques
|
||||
* @memberof UmbDocumentTypeStore
|
||||
*/
|
||||
remove(uniques: Array<DocumentTypeResponseModel['id']>) {
|
||||
this._data.remove(uniques);
|
||||
}
|
||||
}
|
||||
|
||||
export const UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDocumentTypeStore>('UmbDocumentTypeStore');
|
||||
export const UMB_DOCUMENT_TYPE_DETAIL_STORE_CONTEXT = new UmbContextToken<UmbDocumentTypeDetailStore>(
|
||||
'UmbDocumentTypeDetailStore',
|
||||
);
|
||||
@@ -0,0 +1,3 @@
|
||||
export { UmbDocumentTypeDetailRepository } from './document-type-detail.repository.js';
|
||||
export { DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS, DOCUMENT_TYPE_DETAIL_STORE_ALIAS } from './manifests.js';
|
||||
export { UMB_DOCUMENT_TYPE_DETAIL_STORE_CONTEXT } from './document-type-detail.store.js';
|
||||
@@ -0,0 +1,22 @@
|
||||
import { UmbDocumentTypeDetailRepository } from './document-type-detail.repository.js';
|
||||
import { UmbDocumentTypeDetailStore } from './document-type-detail.store.js';
|
||||
import { ManifestRepository, ManifestStore } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS = 'Umb.Repository.DocumentType.Detail';
|
||||
export const DOCUMENT_TYPE_DETAIL_STORE_ALIAS = 'Umb.Store.DocumentType.Detail';
|
||||
|
||||
const detailRepository: ManifestRepository = {
|
||||
type: 'repository',
|
||||
alias: DOCUMENT_TYPE_DETAIL_REPOSITORY_ALIAS,
|
||||
name: 'Document Types Repository',
|
||||
api: UmbDocumentTypeDetailRepository,
|
||||
};
|
||||
|
||||
const detailStore: ManifestStore = {
|
||||
type: 'store',
|
||||
alias: DOCUMENT_TYPE_DETAIL_STORE_ALIAS,
|
||||
name: 'Document Type Store',
|
||||
api: UmbDocumentTypeDetailStore,
|
||||
};
|
||||
|
||||
export const manifests = [detailRepository, detailStore];
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from './document-type.repository.js';
|
||||
export * from './document-type.store.js';
|
||||
export * from './document-type.tree.store.js';
|
||||
export * from './item/index.js';
|
||||
export * from './detail/index.js';
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { UmbDocumentTypeItemModel } from './types.js';
|
||||
import { UmbDocumentTypeItemServerDataSource } from './document-type-item.server.data.js';
|
||||
import { UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT } from './document-type-item.store.js';
|
||||
import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbItemRepositoryBase } from '@umbraco-cms/backoffice/repository';
|
||||
|
||||
export class UmbDocumentTypeItemRepository extends UmbItemRepositoryBase<UmbDocumentTypeItemModel> {
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, UmbDocumentTypeItemServerDataSource, UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT);
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ export class UmbDocumentTypeItemStore
|
||||
constructor(host: UmbControllerHostElement) {
|
||||
super(
|
||||
host,
|
||||
UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT_TOKEN.toString(),
|
||||
UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT.toString(),
|
||||
new UmbArrayState<DocumentTypeItemResponseModel>([], (x) => x.id),
|
||||
);
|
||||
}
|
||||
@@ -33,6 +33,6 @@ export class UmbDocumentTypeItemStore
|
||||
}
|
||||
}
|
||||
|
||||
export const UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDocumentTypeItemStore>(
|
||||
export const UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT = new UmbContextToken<UmbDocumentTypeItemStore>(
|
||||
'UmbDocumentTypeItemStore',
|
||||
);
|
||||
@@ -0,0 +1,3 @@
|
||||
export { UmbDocumentTypeItemRepository } from './document-type-item.repository.js';
|
||||
export { DOCUMENT_TYPE_ITEM_REPOSITORY_ALIAS, DOCUMENT_TYPE_ITEM_STORE_ALIAS } from './manifests.js';
|
||||
export * from './types.js';
|
||||
@@ -0,0 +1,22 @@
|
||||
import { UmbDocumentTypeItemRepository } from './document-type-item.repository.js';
|
||||
import { UmbDocumentTypeItemStore } from './document-type-item.store.js';
|
||||
import { ManifestItemStore, ManifestRepository } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const DOCUMENT_TYPE_ITEM_REPOSITORY_ALIAS = 'Umb.Repository.DocumentType.Item';
|
||||
export const DOCUMENT_TYPE_ITEM_STORE_ALIAS = 'Umb.Store.DocumentType.Item';
|
||||
|
||||
const itemRepository: ManifestRepository = {
|
||||
type: 'repository',
|
||||
alias: DOCUMENT_TYPE_ITEM_REPOSITORY_ALIAS,
|
||||
name: 'Document Type Item Repository',
|
||||
api: UmbDocumentTypeItemRepository,
|
||||
};
|
||||
|
||||
const itemStore: ManifestItemStore = {
|
||||
type: 'itemStore',
|
||||
alias: DOCUMENT_TYPE_ITEM_STORE_ALIAS,
|
||||
name: 'Document Type Item Store',
|
||||
api: UmbDocumentTypeItemStore,
|
||||
};
|
||||
|
||||
export const manifests = [itemRepository, itemStore];
|
||||
@@ -0,0 +1,3 @@
|
||||
import { DocumentTypeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
|
||||
export type UmbDocumentTypeItemModel = DocumentTypeItemResponseModel;
|
||||
@@ -1,46 +1,4 @@
|
||||
import { UmbDocumentTypeItemStore } from './document-type-item.store.js';
|
||||
import { UmbDocumentTypeRepository } from './document-type.repository.js';
|
||||
import { UmbDocumentTypeStore } from './document-type.store.js';
|
||||
import { UmbDocumentTypeTreeStore } from './document-type.tree.store.js';
|
||||
import {
|
||||
ManifestItemStore,
|
||||
ManifestRepository,
|
||||
ManifestStore,
|
||||
ManifestTreeStore,
|
||||
} from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { manifests as detailManifests } from './detail/manifests.js';
|
||||
import { manifests as itemManifests } from './item/manifests.js';
|
||||
|
||||
export const DOCUMENT_TYPE_REPOSITORY_ALIAS = 'Umb.Repository.DocumentType';
|
||||
|
||||
const repository: ManifestRepository = {
|
||||
type: 'repository',
|
||||
alias: DOCUMENT_TYPE_REPOSITORY_ALIAS,
|
||||
name: 'Document Types Repository',
|
||||
api: UmbDocumentTypeRepository,
|
||||
};
|
||||
|
||||
export const DOCUMENT_TYPE_STORE_ALIAS = 'Umb.Store.DocumentType';
|
||||
export const DOCUMENT_TYPE_TREE_STORE_ALIAS = 'Umb.Store.DocumentTypeTree';
|
||||
export const DOCUMENT_TYPE_ITEM_STORE_ALIAS = 'Umb.Store.DocumentTypeItem';
|
||||
|
||||
const store: ManifestStore = {
|
||||
type: 'store',
|
||||
alias: DOCUMENT_TYPE_STORE_ALIAS,
|
||||
name: 'Document Type Store',
|
||||
api: UmbDocumentTypeStore,
|
||||
};
|
||||
|
||||
const treeStore: ManifestTreeStore = {
|
||||
type: 'treeStore',
|
||||
alias: DOCUMENT_TYPE_TREE_STORE_ALIAS,
|
||||
name: 'Document Type Tree Store',
|
||||
api: UmbDocumentTypeTreeStore,
|
||||
};
|
||||
|
||||
const itemStore: ManifestItemStore = {
|
||||
type: 'itemStore',
|
||||
alias: DOCUMENT_TYPE_ITEM_STORE_ALIAS,
|
||||
name: 'Document Type Item Store',
|
||||
api: UmbDocumentTypeItemStore,
|
||||
};
|
||||
|
||||
export const manifests = [repository, store, treeStore, itemStore];
|
||||
export const manifests = [...detailManifests, ...itemManifests];
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { DOCUMENT_TYPE_ROOT_ENTITY_TYPE } from '../index.js';
|
||||
import { UmbDocumentTypeTreeServerDataSource } from './document-type.tree.server.data-source.js';
|
||||
import { UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT } from './document-type.tree.store.js';
|
||||
import { UmbDocumentTypeTreeItemModel, UmbDocumentTypeTreeRootModel } from './types.js';
|
||||
import { UmbTreeRepositoryBase } from '@umbraco-cms/backoffice/tree';
|
||||
import { type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export class UmbDocumentTypeTreeRepository
|
||||
extends UmbTreeRepositoryBase<UmbDocumentTypeTreeItemModel, UmbDocumentTypeTreeRootModel>
|
||||
implements UmbApi
|
||||
{
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, UmbDocumentTypeTreeServerDataSource, UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT);
|
||||
}
|
||||
|
||||
async requestTreeRoot() {
|
||||
const data = {
|
||||
id: null,
|
||||
type: DOCUMENT_TYPE_ROOT_ENTITY_TYPE,
|
||||
name: 'Document Types',
|
||||
icon: 'icon-folder',
|
||||
hasChildren: true,
|
||||
};
|
||||
|
||||
return { data };
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository';
|
||||
import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import { DocumentTypeResource } from '@umbraco-cms/backoffice/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
/**
|
||||
* A data source for the Document tree that fetches data from the server
|
||||
* A data source for the Document Type tree that fetches data from the server
|
||||
* @export
|
||||
* @class UmbDocumentTypeTreeServerDataSource
|
||||
* @implements {UmbTreeDataSource}
|
||||
@@ -12,35 +12,6 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
export class UmbDocumentTypeTreeServerDataSource implements UmbTreeDataSource {
|
||||
#host: UmbControllerHost;
|
||||
|
||||
// TODO: how do we handle trashed items?
|
||||
async trashItems(ids: Array<string>) {
|
||||
// TODO: use backend cli when available.
|
||||
return tryExecuteAndNotify(
|
||||
this.#host,
|
||||
fetch('/umbraco/management/api/v1/document-type/trash', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(ids),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async moveItems(ids: Array<string>, destination: string) {
|
||||
// TODO: use backend cli when available.
|
||||
return tryExecuteAndNotify(
|
||||
this.#host,
|
||||
fetch('/umbraco/management/api/v1/document-type/move', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ ids: ids, destination }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of UmbDocumentTypeTreeServerDataSource.
|
||||
* @param {UmbControllerHost} host
|
||||
@@ -77,7 +48,7 @@ export class UmbDocumentTypeTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
DocumentTypeResource.getTreeDocumentTypeChildren({
|
||||
parentId,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -97,7 +68,7 @@ export class UmbDocumentTypeTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
DocumentTypeResource.getDocumentTypeItem({
|
||||
id: ids,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class UmbDocumentTypeTreeStore
|
||||
* @extends {UmbStoreBase}
|
||||
* @description - Tree Data Store for Document-Types
|
||||
* @description - Tree Data Store for Document Types
|
||||
*/
|
||||
// TODO: consider if tree store could be turned into a general EntityTreeStore class?
|
||||
export class UmbDocumentTypeTreeStore extends UmbEntityTreeStore {
|
||||
/**
|
||||
* Creates an instance of UmbDocumentTypeTreeStore.
|
||||
@@ -16,10 +15,10 @@ export class UmbDocumentTypeTreeStore extends UmbEntityTreeStore {
|
||||
* @memberof UmbDocumentTypeTreeStore
|
||||
*/
|
||||
constructor(host: UmbControllerHostElement) {
|
||||
super(host, UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN.toString());
|
||||
super(host, UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT.toString());
|
||||
}
|
||||
}
|
||||
|
||||
export const UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDocumentTypeTreeStore>(
|
||||
'UmbDocumentTypeTreeStore'
|
||||
export const UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT = new UmbContextToken<UmbDocumentTypeTreeStore>(
|
||||
'UmbDocumentTypeTreeStore',
|
||||
);
|
||||
@@ -1,14 +1,36 @@
|
||||
import { DOCUMENT_TYPE_REPOSITORY_ALIAS } from '../repository/manifests.js';
|
||||
import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UmbDocumentTypeTreeRepository } from './document-type-tree.repository.js';
|
||||
import { UmbDocumentTypeTreeStore } from './document-type.tree.store.js';
|
||||
import type {
|
||||
ManifestRepository,
|
||||
ManifestTree,
|
||||
ManifestTreeItem,
|
||||
ManifestTreeStore,
|
||||
} from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const DOCUMENT_TYPE_TREE_ALIAS = 'Umb.Tree.DocumentTypes';
|
||||
export const DOCUMENT_TYPE_TREE_REPOSITORY_ALIAS = 'Umb.Repository.DocumentType.Tree';
|
||||
export const DOCUMENT_TYPE_TREE_STORE_ALIAS = 'Umb.Store.DocumentType.Tree';
|
||||
export const DOCUMENT_TYPE_TREE_ALIAS = 'Umb.Tree.DocumentType';
|
||||
|
||||
const treeRepository: ManifestRepository = {
|
||||
type: 'repository',
|
||||
alias: DOCUMENT_TYPE_TREE_REPOSITORY_ALIAS,
|
||||
name: 'Document Type Tree Repository',
|
||||
api: UmbDocumentTypeTreeRepository,
|
||||
};
|
||||
|
||||
const treeStore: ManifestTreeStore = {
|
||||
type: 'treeStore',
|
||||
alias: DOCUMENT_TYPE_TREE_STORE_ALIAS,
|
||||
name: 'Document Type Tree Store',
|
||||
api: UmbDocumentTypeTreeStore,
|
||||
};
|
||||
|
||||
const tree: ManifestTree = {
|
||||
type: 'tree',
|
||||
alias: DOCUMENT_TYPE_TREE_ALIAS,
|
||||
name: 'Document Types Tree',
|
||||
name: 'Document Type Tree',
|
||||
meta: {
|
||||
repositoryAlias: DOCUMENT_TYPE_REPOSITORY_ALIAS,
|
||||
repositoryAlias: DOCUMENT_TYPE_TREE_REPOSITORY_ALIAS,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -22,4 +44,4 @@ const treeItem: ManifestTreeItem = {
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [tree, treeItem];
|
||||
export const manifests = [treeRepository, treeStore, tree, treeItem];
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { DocumentTypeTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import type { UmbEntityTreeItemModel, UmbEntityTreeRootModel } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
export type UmbDocumentTypeTreeItemModel = DocumentTypeTreeItemResponseModel & UmbEntityTreeItemModel;
|
||||
export type UmbDocumentTypeTreeRootModel = DocumentTypeTreeItemResponseModel & UmbEntityTreeRootModel;
|
||||
@@ -1,6 +1,9 @@
|
||||
import { UmbDocumentTypeRepository } from '../repository/document-type.repository.js';
|
||||
import { UmbDocumentTypeDetailRepository } from '../repository/detail/document-type-detail.repository.js';
|
||||
import { UmbContentTypePropertyStructureManager } from '@umbraco-cms/backoffice/content-type';
|
||||
import { UmbEditableWorkspaceContextBase, UmbSaveableWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';
|
||||
import {
|
||||
UmbEditableWorkspaceContextBase,
|
||||
UmbSaveableWorkspaceContextInterface,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
import type {
|
||||
ContentTypeCompositionModel,
|
||||
ContentTypeSortModel,
|
||||
@@ -12,7 +15,7 @@ import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api';
|
||||
|
||||
type EntityType = DocumentTypeResponseModel;
|
||||
export class UmbDocumentTypeWorkspaceContext
|
||||
extends UmbEditableWorkspaceContextBase<UmbDocumentTypeRepository, EntityType>
|
||||
extends UmbEditableWorkspaceContextBase<UmbDocumentTypeDetailRepository, EntityType>
|
||||
implements UmbSaveableWorkspaceContextInterface<EntityType | undefined>
|
||||
{
|
||||
// Draft is located in structure manager
|
||||
@@ -42,7 +45,7 @@ export class UmbDocumentTypeWorkspaceContext
|
||||
isSorting = this.#isSorting.asObservable();
|
||||
|
||||
constructor(host: UmbControllerHostElement) {
|
||||
super(host, 'Umb.Workspace.DocumentType', new UmbDocumentTypeRepository(host));
|
||||
super(host, 'Umb.Workspace.DocumentType', new UmbDocumentTypeDetailRepository(host));
|
||||
|
||||
this.structure = new UmbContentTypePropertyStructureManager(this.host, this.repository);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { UmbDocumentTypeWorkspaceContext } from '../../document-type-workspace.context.js';
|
||||
import type { UmbInputDocumentTypeElement } from '../../../components/input-document-type/input-document-type.element.js';
|
||||
import type { UmbDocumentTypeInputElement } from '../../../components/document-type-input/document-type-input.element.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 type { UUIToggleElement } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
|
||||
@@ -62,10 +62,10 @@ export class UmbDocumentTypeWorkspaceViewStructureElement
|
||||
</div>
|
||||
<div slot="editor">
|
||||
<!-- TODO: maybe we want to somehow display the hierarchy, but not necessary in the same way as old backoffice? -->
|
||||
<umb-input-document-type
|
||||
<umb-document-type-input
|
||||
.selectedIds=${this._allowedContentTypeIDs ?? []}
|
||||
@change="${(e: CustomEvent) => {
|
||||
const sortedContentTypesList = (e.target as UmbInputDocumentTypeElement).selectedIds.map(
|
||||
const sortedContentTypesList = (e.target as UmbDocumentTypeInputElement).selectedIds.map(
|
||||
(id, index) => ({
|
||||
id: id,
|
||||
sortOrder: index,
|
||||
@@ -73,7 +73,7 @@ export class UmbDocumentTypeWorkspaceViewStructureElement
|
||||
);
|
||||
this.#workspaceContext?.setAllowedContentTypes(sortedContentTypesList);
|
||||
}}">
|
||||
</umb-input-document-type>
|
||||
</umb-document-type-input>
|
||||
</div>
|
||||
</umb-workspace-property-layout>
|
||||
</uui-box>
|
||||
|
||||
@@ -3,12 +3,15 @@ import {
|
||||
UMB_DOCUMENT_RECYCLE_BIN_TREE_STORE_CONTEXT,
|
||||
UmbDocumentRecycleBinTreeStore,
|
||||
} from './document-recycle.bin.tree.store.js';
|
||||
import type { UmbTreeDataSource, UmbTreeRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import type { UmbTreeRepository, UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbBaseController, type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
|
||||
import { DocumentTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
|
||||
export class UmbDocumentRecycleBinRepository extends UmbBaseController implements UmbTreeRepository<DocumentTreeItemResponseModel> {
|
||||
export class UmbDocumentRecycleBinRepository
|
||||
extends UmbBaseController
|
||||
implements UmbTreeRepository<DocumentTreeItemResponseModel>
|
||||
{
|
||||
#init!: Promise<unknown>;
|
||||
|
||||
#treeSource: UmbTreeDataSource;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository';
|
||||
import { type UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import { DocumentResource } from '@umbraco-cms/backoffice/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,8 @@ import { UmbDocumentTreeStore, UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN } from './d
|
||||
import { UmbDocumentTreeServerDataSource } from './sources/document.tree.server.data.js';
|
||||
import { UMB_DOCUMENT_ITEM_STORE_CONTEXT_TOKEN, type UmbDocumentItemStore } from './document-item.store.js';
|
||||
import { UmbDocumentItemServerDataSource } from './sources/document-item.server.data.js';
|
||||
import type { UmbTreeDataSource, UmbTreeRepository, UmbDetailRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import type { UmbDetailRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import type { UmbTreeRepository, UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbBaseController, UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import {
|
||||
DocumentResponseModel,
|
||||
@@ -15,7 +16,8 @@ import {
|
||||
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
|
||||
import { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export class UmbDocumentRepository extends UmbBaseController
|
||||
export class UmbDocumentRepository
|
||||
extends UmbBaseController
|
||||
implements
|
||||
UmbTreeRepository<DocumentTreeItemResponseModel>,
|
||||
UmbDetailRepository<CreateDocumentRequestModel, any, UpdateDocumentRequestModel, DocumentResponseModel>,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository';
|
||||
import { type UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import { DocumentResource } from '@umbraco-cms/backoffice/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
/**
|
||||
@@ -23,7 +23,7 @@ export class UmbDocumentTreeServerDataSource implements UmbTreeDataSource {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ export class UmbDocumentTreeServerDataSource implements UmbTreeDataSource {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ export class UmbDocumentTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
DocumentResource.getTreeDocumentChildren({
|
||||
parentId,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@ export class UmbDocumentTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
DocumentResource.getDocumentItem({
|
||||
id: ids,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbDocumentRepository } from '../repository/document.repository.js';
|
||||
import { UmbDocumentTypeRepository } from '../../document-types/repository/document-type.repository.js';
|
||||
import { UmbDocumentTypeDetailRepository } from '../../document-types/repository/detail/document-type-detail.repository.js';
|
||||
import { UmbDocumentVariantContext } from '../variant-context/document-variant-context.js';
|
||||
import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
|
||||
import { UmbContentTypePropertyStructureManager } from '@umbraco-cms/backoffice/content-type';
|
||||
@@ -54,7 +54,10 @@ export class UmbDocumentWorkspaceContext
|
||||
// TODO: Get Workspace Alias via Manifest.
|
||||
super(host, 'Umb.Workspace.Document', new UmbDocumentRepository(host));
|
||||
|
||||
this.structure = new UmbContentTypePropertyStructureManager(this.host, new UmbDocumentTypeRepository(this.host));
|
||||
this.structure = new UmbContentTypePropertyStructureManager(
|
||||
this.host,
|
||||
new UmbDocumentTypeDetailRepository(this.host),
|
||||
);
|
||||
this.splitView = new UmbWorkspaceSplitViewManager(this.host);
|
||||
|
||||
new UmbObserverController(this.host, this.documentTypeKey, (id) => this.structure.loadType(id));
|
||||
@@ -130,7 +133,7 @@ export class UmbDocumentWorkspaceContext
|
||||
const variants = partialUpdateFrozenArray(
|
||||
oldVariants,
|
||||
{ name },
|
||||
variantId ? (x) => variantId.compare(x) : () => true
|
||||
variantId ? (x) => variantId.compare(x) : () => true,
|
||||
);
|
||||
this.#currentData.update({ variants });
|
||||
}
|
||||
@@ -142,7 +145,8 @@ export class UmbDocumentWorkspaceContext
|
||||
async propertyValueByAlias<PropertyValueType = unknown>(propertyAlias: string, variantId?: UmbVariantId) {
|
||||
return this.#currentData.asObservablePart(
|
||||
(data) =>
|
||||
data?.values?.find((x) => x?.alias === propertyAlias && (variantId ? variantId.compare(x) : true))?.value as PropertyValueType
|
||||
data?.values?.find((x) => x?.alias === propertyAlias && (variantId ? variantId.compare(x) : true))
|
||||
?.value as PropertyValueType,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -156,20 +160,24 @@ export class UmbDocumentWorkspaceContext
|
||||
const currentData = this.#currentData.value;
|
||||
if (currentData) {
|
||||
const newDataSet = currentData.values?.find(
|
||||
(x) => x.alias === alias && (variantId ? variantId.compare(x) : true)
|
||||
(x) => x.alias === alias && (variantId ? variantId.compare(x) : true),
|
||||
);
|
||||
return newDataSet?.value as ReturnType;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
async setPropertyValue<PropertyValueType = unknown>(alias: string, value: PropertyValueType, variantId?: UmbVariantId) {
|
||||
async setPropertyValue<PropertyValueType = unknown>(
|
||||
alias: string,
|
||||
value: PropertyValueType,
|
||||
variantId?: UmbVariantId,
|
||||
) {
|
||||
const entry = { ...variantId?.toObject(), alias, value };
|
||||
const currentData = this.#currentData.value;
|
||||
if (currentData) {
|
||||
const values = appendToFrozenArray(
|
||||
currentData.values || [],
|
||||
entry,
|
||||
(x) => x.alias === alias && (variantId ? variantId.compare(x) : true)
|
||||
(x) => x.alias === alias && (variantId ? variantId.compare(x) : true),
|
||||
);
|
||||
this.#currentData.update({ values });
|
||||
}
|
||||
@@ -221,9 +229,11 @@ export class UmbDocumentWorkspaceContext
|
||||
|
||||
export default UmbDocumentWorkspaceContext;
|
||||
|
||||
|
||||
export const UMB_DOCUMENT_WORKSPACE_CONTEXT = new UmbContextToken<UmbSaveableWorkspaceContextInterface, UmbDocumentWorkspaceContext>(
|
||||
export const UMB_DOCUMENT_WORKSPACE_CONTEXT = new UmbContextToken<
|
||||
UmbSaveableWorkspaceContextInterface,
|
||||
UmbDocumentWorkspaceContext
|
||||
>(
|
||||
'UmbWorkspaceContext',
|
||||
// TODO: Refactor: make a better generic way to identify workspaces, maybe workspaceType or workspaceAlias?.
|
||||
(context): context is UmbDocumentWorkspaceContext => context.getEntityType?.() === 'document'
|
||||
(context): context is UmbDocumentWorkspaceContext => context.getEntityType?.() === 'document',
|
||||
);
|
||||
|
||||
@@ -7,13 +7,12 @@ import { UmbMediaTypeItemServerDataSource } from './sources/media-type-item.serv
|
||||
import { UmbBaseController, UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
|
||||
import {
|
||||
UmbTreeRepository,
|
||||
UmbTreeDataSource,
|
||||
UmbDataSource,
|
||||
UmbItemRepository,
|
||||
UmbDetailRepository,
|
||||
UmbItemDataSource,
|
||||
} from '@umbraco-cms/backoffice/repository';
|
||||
import { UmbTreeRepository, UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import {
|
||||
CreateMediaTypeRequestModel,
|
||||
FolderTreeItemResponseModel,
|
||||
@@ -23,7 +22,8 @@ import {
|
||||
} from '@umbraco-cms/backoffice/backend-api';
|
||||
import { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export class UmbMediaTypeRepository extends UmbBaseController
|
||||
export class UmbMediaTypeRepository
|
||||
extends UmbBaseController
|
||||
implements
|
||||
UmbItemRepository<MediaTypeItemResponseModel>,
|
||||
UmbTreeRepository<FolderTreeItemResponseModel>,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/tree';
|
||||
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
/**
|
||||
@@ -20,5 +20,5 @@ export class UmbMediaTypeTreeStore extends UmbEntityTreeStore {
|
||||
}
|
||||
|
||||
export const UMB_MEDIA_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbMediaTypeTreeStore>(
|
||||
'UmbMediaTypeTreeStore'
|
||||
'UmbMediaTypeTreeStore',
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MediaTypeResource } from '@umbraco-cms/backoffice/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository';
|
||||
import { type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { type UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
/**
|
||||
@@ -48,7 +48,7 @@ export class UmbMediaTypeTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
MediaTypeResource.getTreeMediaTypeChildren({
|
||||
parentId,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ export class UmbMediaTypeTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
MediaTypeResource.getMediaTypeItem({
|
||||
id: ids,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { UmbMediaStore, UMB_MEDIA_STORE_CONTEXT_TOKEN } from './media.store.js';
|
||||
import { UmbMediaDetailServerDataSource } from './sources/media.detail.server.data.js';
|
||||
import { UmbMediaItemServerDataSource } from './sources/media-item.server.data.js';
|
||||
import { UmbMediaItemStore } from './media-item.store.js';
|
||||
import type { UmbTreeRepository, UmbTreeDataSource } from '@umbraco-cms/backoffice/repository';
|
||||
import type { UmbTreeRepository, UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbBaseController, UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import {
|
||||
CreateMediaRequestModel,
|
||||
@@ -16,7 +16,8 @@ import { UmbDetailRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
|
||||
import { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export class UmbMediaRepository extends UmbBaseController
|
||||
export class UmbMediaRepository
|
||||
extends UmbBaseController
|
||||
implements
|
||||
UmbTreeRepository<EntityTreeItemResponseModel>,
|
||||
UmbDetailRepository<CreateMediaRequestModel, any, UpdateMediaRequestModel, MediaDetails>,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
export const UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbMediaTreeStore>('UmbMediaTreeStore');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository';
|
||||
import { type UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import { MediaResource } from '@umbraco-cms/backoffice/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
/**
|
||||
@@ -23,7 +23,7 @@ export class UmbMediaTreeServerDataSource implements UmbTreeDataSource {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ export class UmbMediaTreeServerDataSource implements UmbTreeDataSource {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ export class UmbMediaTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
MediaResource.getTreeMediaChildren({
|
||||
parentId,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@ export class UmbMediaTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
MediaResource.getTreeMediaItem({
|
||||
id: ids,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,14 @@ import { UmbMemberGroupStore, UMB_MEMBER_GROUP_STORE_CONTEXT_TOKEN } from './mem
|
||||
import { UmbMemberGroupTreeServerDataSource } from './sources/member-group.tree.server.data.js';
|
||||
import { UmbBaseController, type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
|
||||
import type { UmbTreeDataSource, UmbDetailRepository, UmbTreeRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { UmbDetailRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import type { UmbTreeRepository, UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
import { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
// TODO => Update type when backend updated
|
||||
export class UmbMemberGroupRepository extends UmbBaseController
|
||||
export class UmbMemberGroupRepository
|
||||
extends UmbBaseController
|
||||
implements UmbTreeRepository<EntityTreeItemResponseModel>, UmbDetailRepository<any, any, any, any>, UmbApi
|
||||
{
|
||||
#init!: Promise<unknown>;
|
||||
@@ -24,7 +26,7 @@ export class UmbMemberGroupRepository extends UmbBaseController
|
||||
#notificationContext?: UmbNotificationContext;
|
||||
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host)
|
||||
super(host);
|
||||
// TODO: figure out how spin up get the correct data source
|
||||
this.#treeSource = new UmbMemberGroupTreeServerDataSource(this);
|
||||
this.#detailSource = new UmbMemberGroupDetailServerDataSource(this);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store';
|
||||
import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/tree';
|
||||
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
/**
|
||||
@@ -20,5 +20,5 @@ export class UmbMemberGroupTreeStore extends UmbEntityTreeStore {
|
||||
}
|
||||
|
||||
export const UMB_MEMBER_GROUP_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbMemberGroupTreeStore>(
|
||||
'UmbMemberGroupTreeStore'
|
||||
'UmbMemberGroupTreeStore',
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MemberGroupResource } from '@umbraco-cms/backoffice/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository';
|
||||
import { type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { type UmbTreeDataSource } from '@umbraco-cms/backoffice/tree';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ export class UmbMemberGroupTreeServerDataSource implements UmbTreeDataSource {
|
||||
this.#host,
|
||||
MemberGroupResource.getMemberGroupItem({
|
||||
id: ids,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user