Merge branch 'feature/entity-actions' of https://github.com/umbraco/Umbraco.CMS.Backoffice into feature/entity-actions
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import type { ClassConstructor, ManifestClass } from '../models';
|
||||
import { hasDefaultExport } from './has-default-export.function';
|
||||
import { isManifestClassConstructorType } from './is-manifest-class-instance-type.function';
|
||||
import { loadExtension } from './load-extension.function';
|
||||
|
||||
//TODO: Write tests for this method:
|
||||
export async function createExtensionClass<T = unknown>(manifest: ManifestClass, constructorArguments: unknown[]): Promise<T | undefined> {
|
||||
|
||||
const js = await loadExtension(manifest);
|
||||
|
||||
if (isManifestClassConstructorType(manifest)) {
|
||||
return new manifest.class(...constructorArguments) as T;
|
||||
}
|
||||
|
||||
if (js) {
|
||||
if (hasDefaultExport<ClassConstructor<T>>(js)) {
|
||||
return new js.default(...constructorArguments);
|
||||
}
|
||||
|
||||
console.error('-- Extension did not succeed creating an class instance, missing a default export of the served JavaScript file', manifest);
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
console.error('-- Extension did not succeed creating an class instance, missing a default export or `class` in the manifest.', manifest);
|
||||
return undefined;
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { ManifestElement } from '../models';
|
||||
import type { HTMLElementConstructor, ManifestElement } from '../models';
|
||||
import { hasDefaultExport } from './has-default-export.function';
|
||||
import { isManifestElementNameType } from './is-manifest-element-name-type.function';
|
||||
import { loadExtension } from './load-extension.function';
|
||||
|
||||
export async function createExtensionElement(manifest: ManifestElement): Promise<HTMLElement | undefined> {
|
||||
|
||||
|
||||
//TODO: Write tests for these extension options:
|
||||
const js = await loadExtension(manifest);
|
||||
|
||||
@@ -15,7 +15,7 @@ export async function createExtensionElement(manifest: ManifestElement): Promise
|
||||
|
||||
// TODO: Do we need this except for the default() loader?
|
||||
if (js) {
|
||||
if (hasDefaultExport(js)) {
|
||||
if (hasDefaultExport<HTMLElementConstructor>(js)) {
|
||||
// created by default class
|
||||
return new js.default();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import type { HTMLElementConstructor } from '../models';
|
||||
|
||||
export function hasDefaultExport(object: unknown): object is { default: HTMLElementConstructor } {
|
||||
export function hasDefaultExport<ConstructorType>(object: unknown): object is { default: ConstructorType } {
|
||||
return typeof object === 'object' && object !== null && 'default' in object;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { ManifestClass, ManifestClassWithClassConstructor } from '../models';
|
||||
|
||||
export function isManifestClassConstructorType(manifest: unknown): manifest is ManifestClassWithClassConstructor {
|
||||
return (
|
||||
typeof manifest === 'object' && manifest !== null && (manifest as ManifestClass).class !== undefined
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { isManifestJSType } from './is-manifest-js-type.function';
|
||||
import { isManifestLoaderType } from './is-manifest-loader-type.function';
|
||||
import { isManifestClassConstructorType } from './is-manifest-class-instance-type.function';
|
||||
import type { ManifestBase, ManifestClass } from '@umbraco-cms/extensions-registry';
|
||||
|
||||
export function isManifestClassableType(manifest: ManifestBase): manifest is ManifestClass {
|
||||
return isManifestClassConstructorType(manifest) || isManifestLoaderType(manifest) || isManifestJSType(manifest);
|
||||
}
|
||||
@@ -1,75 +1,78 @@
|
||||
import type { ManifestCollectionBulkAction } from './collection-bulk-action.models';
|
||||
import type { ManifestCollectionView } from './collection-view.models';
|
||||
import type { ManifestDashboard } from './dashboard.models';
|
||||
import type { ManifestDashboardCollection } from './dashboard-collection.models';
|
||||
import type { ManifestEntityAction } from './entity-action.models';
|
||||
import type { ManifestExternalLoginProvider } from './external-login-provider.models';
|
||||
import type { ManifestHeaderApp } from './header-app.models';
|
||||
import type { ManifestHealthCheck } from './health-check.models';
|
||||
import type { ManifestPackageView } from './package-view.models';
|
||||
import type { ManifestPropertyAction } from './property-action.models';
|
||||
import type { ManifestPropertyEditorUI, ManifestPropertyEditorModel } from './property-editor.models';
|
||||
import type { ManifestSection } from './section.models';
|
||||
import type { ManifestSectionView } from './section-view.models';
|
||||
import type { ManifestSidebarMenuItem } from './sidebar-menu-item.models';
|
||||
import type { ManifestTheme } from './theme.models';
|
||||
import type { ManifestTree } from './tree.models';
|
||||
import type { ManifestTreeItemAction } from './tree-item-action.models';
|
||||
import type { ManifestUserDashboard } from './user-dashboard.models';
|
||||
import type { ManifestWorkspace } from './workspace.models';
|
||||
import type { ManifestWorkspaceAction } from './workspace-action.models';
|
||||
import type { ManifestWorkspaceView } from './workspace-view.models';
|
||||
import type { ManifestWorkspaceViewCollection } from './workspace-view-collection.models';
|
||||
import type { ManifestPropertyEditorUI, ManifestPropertyEditorModel } from './property-editor.models';
|
||||
import type { ManifestDashboard } from './dashboard.models';
|
||||
import type { ManifestDashboardCollection } from './dashboard-collection.models';
|
||||
import type { ManifestUserDashboard } from './user-dashboard.models';
|
||||
import type { ManifestPropertyAction } from './property-action.models';
|
||||
import type { ManifestPackageView } from './package-view.models';
|
||||
import type { ManifestExternalLoginProvider } from './external-login-provider.models';
|
||||
import type { ManifestCollectionBulkAction } from './collection-bulk-action.models';
|
||||
import type { ManifestCollectionView } from './collection-view.models';
|
||||
import type { ManifestHealthCheck } from './health-check.models';
|
||||
import type { ManifestSidebarMenuItem } from './sidebar-menu-item.models';
|
||||
import type { ManifestTheme } from './theme.models';
|
||||
import type { ManifestEntityAction } from './entity-action.models';
|
||||
import { ManifestRepository } from './repository.models';
|
||||
import type { ClassConstructor } from '@umbraco-cms/models';
|
||||
|
||||
export * from './header-app.models';
|
||||
export * from './section.models';
|
||||
export * from './section-view.models';
|
||||
export * from './tree.models';
|
||||
export * from './tree-item-action.models';
|
||||
export * from './workspace.models';
|
||||
export * from './workspace-action.models';
|
||||
export * from './workspace-view.models';
|
||||
export * from './workspace-view-collection.models';
|
||||
export * from './property-editor.models';
|
||||
export * from './dashboard.models';
|
||||
export * from './dashboard-collection.models';
|
||||
export * from './user-dashboard.models';
|
||||
export * from './property-action.models';
|
||||
export * from './package-view.models';
|
||||
export * from './external-login-provider.models';
|
||||
export * from './collection-bulk-action.models';
|
||||
export * from './collection-view.models';
|
||||
export * from './dashboard-collection.models';
|
||||
export * from './dashboard.models';
|
||||
export * from './entity-action.models';
|
||||
export * from './external-login-provider.models';
|
||||
export * from './header-app.models';
|
||||
export * from './health-check.models';
|
||||
export * from './package-view.models';
|
||||
export * from './property-action.models';
|
||||
export * from './property-editor.models';
|
||||
export * from './section-view.models';
|
||||
export * from './section.models';
|
||||
export * from './sidebar-menu-item.models';
|
||||
export * from './theme.models';
|
||||
export * from './entity-action.models';
|
||||
export * from './tree-item-action.models';
|
||||
export * from './tree.models';
|
||||
export * from './user-dashboard.models';
|
||||
export * from './workspace-action.models';
|
||||
export * from './workspace-view-collection.models';
|
||||
export * from './workspace-view.models';
|
||||
export * from './workspace.models';
|
||||
|
||||
export type ManifestTypes =
|
||||
| ManifestCollectionBulkAction
|
||||
| ManifestCollectionView
|
||||
| ManifestCustom
|
||||
| ManifestDashboard
|
||||
| ManifestDashboardCollection
|
||||
| ManifestEntityAction
|
||||
| ManifestEntrypoint
|
||||
| ManifestExternalLoginProvider
|
||||
| ManifestHeaderApp
|
||||
| ManifestHealthCheck
|
||||
| ManifestPackageView
|
||||
| ManifestPropertyAction
|
||||
| ManifestPropertyEditorModel
|
||||
| ManifestPropertyEditorUI
|
||||
| ManifestRepository
|
||||
| ManifestSection
|
||||
| ManifestSectionView
|
||||
| ManifestSidebarMenuItem
|
||||
| ManifestTheme
|
||||
| ManifestTree
|
||||
| ManifestTreeItemAction
|
||||
| ManifestUserDashboard
|
||||
| ManifestWorkspace
|
||||
| ManifestWorkspaceAction
|
||||
| ManifestWorkspaceView
|
||||
| ManifestWorkspaceViewCollection
|
||||
| ManifestTreeItemAction
|
||||
| ManifestPropertyEditorUI
|
||||
| ManifestPropertyEditorModel
|
||||
| ManifestDashboard
|
||||
| ManifestDashboardCollection
|
||||
| ManifestUserDashboard
|
||||
| ManifestPropertyAction
|
||||
| ManifestPackageView
|
||||
| ManifestExternalLoginProvider
|
||||
| ManifestEntrypoint
|
||||
| ManifestCollectionBulkAction
|
||||
| ManifestCollectionView
|
||||
| ManifestHealthCheck
|
||||
| ManifestSidebarMenuItem
|
||||
| ManifestTheme
|
||||
| ManifestEntityAction;
|
||||
| ManifestWorkspaceViewCollection;
|
||||
|
||||
export type ManifestStandardTypes = ManifestTypes['type'];
|
||||
|
||||
@@ -88,6 +91,18 @@ export interface ManifestWithLoader<LoaderReturnType> extends ManifestBase {
|
||||
loader?: () => Promise<LoaderReturnType>;
|
||||
}
|
||||
|
||||
export interface ManifestClass extends ManifestWithLoader<object> {
|
||||
type: ManifestStandardTypes;
|
||||
js?: string;
|
||||
className?: string;
|
||||
class?: ClassConstructor<unknown>;
|
||||
//loader?: () => Promise<object | HTMLElement>;
|
||||
}
|
||||
|
||||
export interface ManifestClassWithClassConstructor extends ManifestClass {
|
||||
class: ClassConstructor<unknown>;
|
||||
}
|
||||
|
||||
export interface ManifestElement extends ManifestWithLoader<object | HTMLElement> {
|
||||
type: ManifestStandardTypes;
|
||||
js?: string;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { ManifestClass } from './models';
|
||||
|
||||
export interface ManifestRepository extends ManifestClass {
|
||||
type: 'repository';
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ManifestBase } from './models';
|
||||
import type { UmbRepositoryFactory } from '@umbraco-cms/models';
|
||||
import type { ClassConstructor } from '@umbraco-cms/models';
|
||||
|
||||
export interface ManifestTree extends ManifestBase {
|
||||
type: 'tree';
|
||||
@@ -8,5 +8,5 @@ export interface ManifestTree extends ManifestBase {
|
||||
|
||||
export interface MetaTree {
|
||||
storeAlias?: string;
|
||||
repository?: UmbRepositoryFactory<any>;
|
||||
repository?: ClassConstructor<unknown>;
|
||||
}
|
||||
|
||||
@@ -5,11 +5,13 @@ export interface ManifestWorkspaceViewCollection extends ManifestBase {
|
||||
meta: MetaEditorViewCollection;
|
||||
}
|
||||
|
||||
// TODO: Get rid of store alias, when we are done migrating to repositories(remember to enforce repositoryAlias):
|
||||
export interface MetaEditorViewCollection {
|
||||
workspaces: string[];
|
||||
pathname: string;
|
||||
label: string;
|
||||
icon: string;
|
||||
entityType: string;
|
||||
storeAlias: string;
|
||||
storeAlias?: string;
|
||||
repositoryAlias?: string;
|
||||
}
|
||||
|
||||
@@ -4,12 +4,8 @@ import {
|
||||
DocumentTypeTreeItem,
|
||||
EntityTreeItem,
|
||||
FolderTreeItem,
|
||||
PagedEntityTreeItem,
|
||||
ProblemDetails,
|
||||
} from '@umbraco-cms/backend-api';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { UmbTreeRepository } from 'libs/repository/tree-repository.interface';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
// Extension Manifests
|
||||
export * from '@umbraco-cms/extensions-registry';
|
||||
@@ -17,6 +13,8 @@ export * from '@umbraco-cms/extensions-registry';
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type HTMLElementConstructor<T = HTMLElement> = new (...args: any[]) => T;
|
||||
|
||||
export type ClassConstructor<T> = new (...args: any[]) => T;
|
||||
|
||||
// Users
|
||||
// TODO: would the right name be Node? as entity is just something with a Key. But node is something in a content structure, aka. with hasChildren and parentKey.
|
||||
export interface Entity {
|
||||
@@ -159,6 +157,3 @@ export interface DataSourceResponse<T = undefined> {
|
||||
data?: T;
|
||||
error?: ProblemDetails;
|
||||
}
|
||||
export interface UmbRepositoryFactory<T> {
|
||||
new (host: UmbControllerHostInterface): T;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { manifests as sidebarMenuItemManifests } from './sidebar-menu-item/manifests';
|
||||
import { manifests as repositoryManifests } from './repository/manifests';
|
||||
import { manifests as treeManifests } from './tree/manifests';
|
||||
import { manifests as workspaceManifests } from './workspace/manifests';
|
||||
import { manifests as entityActionManifests } from './entity-actions/manifests';
|
||||
@@ -6,6 +7,7 @@ import { manifests as entityActionManifests } from './entity-actions/manifests';
|
||||
export const manifests = [
|
||||
...sidebarMenuItemManifests,
|
||||
...treeManifests,
|
||||
...repositoryManifests,
|
||||
...workspaceManifests,
|
||||
...entityActionManifests,
|
||||
];
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { UmbDocumentRepository } from '../repository/document.repository';
|
||||
import { ManifestRepository } from 'libs/extensions-registry/repository.models';
|
||||
|
||||
export const DOCUMENT_REPOSITORY_ALIAS = 'Umb.Repository.Documents';
|
||||
|
||||
const repository: ManifestRepository = {
|
||||
type: 'repository',
|
||||
alias: DOCUMENT_REPOSITORY_ALIAS,
|
||||
name: 'Documents Repository',
|
||||
class: UmbDocumentRepository,
|
||||
};
|
||||
|
||||
export const manifests = [repository];
|
||||
@@ -1,6 +1,6 @@
|
||||
import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context';
|
||||
import { UmbDocumentRepository } from '../repository/document.repository';
|
||||
import { UmbWorkspaceContextInterface } from '../../../shared/components/workspace/workspace-context/workspace-context.interface';
|
||||
import type { UmbWorkspaceEntityContextInterface } from '../../../shared/components/workspace/workspace-context/workspace-entity-context.interface';
|
||||
import type { DocumentDetails } from '@umbraco-cms/models';
|
||||
import { appendToFrozenArray, ObjectState } from '@umbraco-cms/observable-api';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
@@ -8,7 +8,7 @@ import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
// TODO: should this contex be called DocumentDraft instead of workspace? or should the draft be part of this?
|
||||
|
||||
type EntityType = DocumentDetails;
|
||||
export class UmbDocumentWorkspaceContext extends UmbWorkspaceContext implements UmbWorkspaceContextInterface<EntityType | undefined> {
|
||||
export class UmbDocumentWorkspaceContext extends UmbWorkspaceContext implements UmbWorkspaceEntityContextInterface<EntityType | undefined> {
|
||||
|
||||
#host: UmbControllerHostInterface;
|
||||
#templateDetailRepo: UmbDocumentRepository;
|
||||
@@ -33,6 +33,10 @@ export class UmbDocumentWorkspaceContext extends UmbWorkspaceContext implements
|
||||
}
|
||||
*/
|
||||
|
||||
getEntityKey() {
|
||||
return this.getData()?.key || '';
|
||||
}
|
||||
|
||||
getEntityType() {
|
||||
return 'document';
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { css, html, nothing } from 'lit';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import type { UmbWorkspaceEntityElement } from '../../../shared/components/workspace/workspace-entity-element.interface';
|
||||
import { UmbDocumentWorkspaceContext } from './document-workspace.context';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models';
|
||||
import { DOCUMENT_REPOSITORY_ALIAS } from '../repository/manifests';
|
||||
import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView, ManifestWorkspaceViewCollection } from '@umbraco-cms/models';
|
||||
|
||||
const workspace: ManifestWorkspace = {
|
||||
type: 'workspace',
|
||||
@@ -41,6 +42,23 @@ const workspaceViews: Array<ManifestWorkspaceView> = [
|
||||
},
|
||||
];
|
||||
|
||||
const workspaceViewCollections: Array<ManifestWorkspaceViewCollection> = [
|
||||
{
|
||||
type: 'workspaceViewCollection',
|
||||
alias: 'Umb.WorkspaceView.Document.Collection',
|
||||
name: 'Document Workspace Collection View',
|
||||
weight: 300,
|
||||
meta: {
|
||||
workspaces: ['Umb.Workspace.Document'],
|
||||
label: 'Documents',
|
||||
pathname: 'collection',
|
||||
icon: 'umb:grid',
|
||||
entityType: 'document',
|
||||
repositoryAlias: DOCUMENT_REPOSITORY_ALIAS
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const workspaceActions: Array<ManifestWorkspaceAction> = [
|
||||
{
|
||||
type: 'workspaceAction',
|
||||
@@ -77,4 +95,4 @@ const workspaceActions: Array<ManifestWorkspaceAction> = [
|
||||
},
|
||||
];
|
||||
|
||||
export const manifests = [workspace, ...workspaceViews, ...workspaceActions];
|
||||
export const manifests = [workspace, ...workspaceViews, ...workspaceViewCollections, ...workspaceActions];
|
||||
|
||||
@@ -3,6 +3,9 @@ import { UmbTreeStore } from '@umbraco-cms/store';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { UmbContextToken, UmbContextConsumerController } from '@umbraco-cms/context-api';
|
||||
import { ArrayState, UmbObserverController } from '@umbraco-cms/observable-api';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api';
|
||||
import { createExtensionClass } from 'libs/extensions-api/create-extension-class.function';
|
||||
import { UmbTreeRepository } from '@umbraco-cms/repository';
|
||||
export class UmbCollectionContext<
|
||||
DataType extends ContentTreeItem,
|
||||
StoreType extends UmbTreeStore<DataType> = UmbTreeStore<DataType>
|
||||
@@ -11,6 +14,8 @@ export class UmbCollectionContext<
|
||||
private _host: UmbControllerHostInterface;
|
||||
private _entityKey: string | null;
|
||||
|
||||
#repository?: UmbTreeRepository;
|
||||
|
||||
private _store?: StoreType;
|
||||
protected _dataObserver?: UmbObserverController<DataType[]>;
|
||||
|
||||
@@ -26,18 +31,35 @@ export class UmbCollectionContext<
|
||||
public readonly search = this._search.asObservable();
|
||||
*/
|
||||
|
||||
constructor(host: UmbControllerHostInterface, entityKey: string | null, storeAlias: string) {
|
||||
constructor(host: UmbControllerHostInterface, entityKey: string | null, storeAlias?: string, repositoryAlias?: string) {
|
||||
this._host = host;
|
||||
this._entityKey = entityKey;
|
||||
|
||||
new UmbContextConsumerController(this._host, storeAlias, (_instance: StoreType) => {
|
||||
this._store = _instance;
|
||||
if (!this._store) {
|
||||
// TODO: if we keep the type assumption of _store existing, then we should here make sure to break the application in a good way.
|
||||
return;
|
||||
}
|
||||
this._onStoreSubscription();
|
||||
});
|
||||
if(storeAlias) {
|
||||
new UmbContextConsumerController(this._host, storeAlias, (_instance: StoreType) => {
|
||||
this._store = _instance;
|
||||
if (!this._store) {
|
||||
// TODO: if we keep the type assumption of _store existing, then we should here make sure to break the application in a good way.
|
||||
return;
|
||||
}
|
||||
this._onStoreSubscription();
|
||||
});
|
||||
} else if (repositoryAlias) {
|
||||
console.log("has repo alias:", repositoryAlias);
|
||||
new UmbObserverController(this._host,
|
||||
umbExtensionsRegistry.getByTypeAndAlias('repository', repositoryAlias),
|
||||
async (repositoryManifest) => {
|
||||
// Do something..
|
||||
if(repositoryManifest) {
|
||||
// TODO: use the right interface here, we might need a collection repository interface.
|
||||
const result = await createExtensionClass<UmbTreeRepository>(repositoryManifest, [this._host]);
|
||||
this.#repository = result;
|
||||
console.log("this.#repository", this.#repository)
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import { css, html } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { UmbCollectionContext, UMB_COLLECTION_CONTEXT_TOKEN } from '../collection.context';
|
||||
import {
|
||||
UmbTableColumn,
|
||||
UmbTableConfig,
|
||||
UmbTableDeselectedEvent,
|
||||
UmbTableElement,
|
||||
UmbTableItem,
|
||||
UmbTableOrderedEvent,
|
||||
UmbTableSelectedEvent,
|
||||
} from '../../components/table';
|
||||
import type { DocumentDetails } from '@umbraco-cms/models';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
type EntityType = DocumentDetails;
|
||||
|
||||
@customElement('umb-collection-view-document-table')
|
||||
export class UmbCollectionViewDocumentTableElement extends UmbLitElement {
|
||||
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: var(--uui-size-space-3) var(--uui-size-space-6);
|
||||
}
|
||||
|
||||
/* TODO: Should we have embedded padding in the table component? */
|
||||
umb-table {
|
||||
padding: 0; /* To fix the embedded padding in the table component. */
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@state()
|
||||
private _items?: Array<EntityType>;
|
||||
|
||||
@state()
|
||||
private _tableConfig: UmbTableConfig = {
|
||||
allowSelection: true,
|
||||
};
|
||||
|
||||
@state()
|
||||
private _tableColumns: Array<UmbTableColumn> = [
|
||||
{
|
||||
name: 'Name',
|
||||
alias: 'entityName',
|
||||
},
|
||||
];
|
||||
|
||||
@state()
|
||||
private _tableItems: Array<UmbTableItem> = [];
|
||||
|
||||
@state()
|
||||
private _selection: Array<string> = [];
|
||||
|
||||
private _collectionContext?: UmbCollectionContext<EntityType>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.consumeContext(UMB_COLLECTION_CONTEXT_TOKEN, (instance) => {
|
||||
this._collectionContext = instance;
|
||||
this._observeCollectionContext();
|
||||
});
|
||||
}
|
||||
|
||||
private _observeCollectionContext() {
|
||||
if (!this._collectionContext) return;
|
||||
|
||||
this.observe(this._collectionContext.data, (items) => {
|
||||
this._items = items;
|
||||
this._createTableItems(this._items);
|
||||
});
|
||||
|
||||
this.observe(this._collectionContext.selection, (selection) => {
|
||||
this._selection = selection;
|
||||
});
|
||||
}
|
||||
|
||||
private _createTableItems(items: Array<any>) {
|
||||
this._tableItems = items.map((item) => {
|
||||
return {
|
||||
key: item.key,
|
||||
icon: item.icon,
|
||||
data: [
|
||||
{
|
||||
columnAlias: 'entityName',
|
||||
value: item.name || 'Untitled',
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private _handleSelect(event: UmbTableSelectedEvent) {
|
||||
event.stopPropagation();
|
||||
const table = event.target as UmbTableElement;
|
||||
const selection = table.selection;
|
||||
this._collectionContext?.setSelection(selection);
|
||||
}
|
||||
|
||||
private _handleDeselect(event: UmbTableDeselectedEvent) {
|
||||
event.stopPropagation();
|
||||
const table = event.target as UmbTableElement;
|
||||
const selection = table.selection;
|
||||
this._collectionContext?.setSelection(selection);
|
||||
}
|
||||
|
||||
private _handleOrdering(event: UmbTableOrderedEvent) {
|
||||
const table = event.target as UmbTableElement;
|
||||
const orderingColumn = table.orderingColumn;
|
||||
const orderingDesc = table.orderingDesc;
|
||||
console.log(`fetch media items, order column: ${orderingColumn}, desc: ${orderingDesc}`);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<umb-table
|
||||
.config=${this._tableConfig}
|
||||
.columns=${this._tableColumns}
|
||||
.items=${this._tableItems}
|
||||
.selection=${this._selection}
|
||||
@selected="${this._handleSelect}"
|
||||
@deselected="${this._handleDeselect}"
|
||||
@ordered="${this._handleOrdering}"></umb-table>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-collection-view-document-table': UmbCollectionViewDocumentTableElement;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,24 @@
|
||||
import type { ManifestCollectionView } from '@umbraco-cms/models';
|
||||
|
||||
export const manifests: Array<ManifestCollectionView> = [
|
||||
|
||||
{
|
||||
type: 'collectionView',
|
||||
alias: 'Umb.CollectionView.Table',
|
||||
name: 'Table',
|
||||
elementName: 'umb-collection-view-document-table',
|
||||
loader: () => import('./collection-view-document-table.element'),
|
||||
weight: 200,
|
||||
meta: {
|
||||
label: 'Table',
|
||||
icon: 'umb:box',
|
||||
entityType: 'document',
|
||||
pathName: 'table',
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
type: 'collectionView',
|
||||
alias: 'Umb.CollectionView.Grid',
|
||||
|
||||
@@ -52,7 +52,8 @@ export class UmbWorkspaceViewCollectionElement extends UmbLitElement {
|
||||
this._collectionContext = new UmbCollectionContext(
|
||||
this,
|
||||
entityKey,
|
||||
manifestMeta.storeAlias
|
||||
manifestMeta.storeAlias,
|
||||
manifestMeta.repositoryAlias
|
||||
);
|
||||
this.provideContext(UMB_COLLECTION_CONTEXT_TOKEN, this._collectionContext);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user