extension workspace as collection
This commit is contained in:
@@ -114,6 +114,10 @@ export class UmbExtensionRegistry<
|
||||
this._extensions.setValue([...this._extensions.getValue(), manifest as ManifestTypes]);
|
||||
}
|
||||
|
||||
getExtensions(): Array<ManifestTypes> {
|
||||
return this._extensions.getValue();
|
||||
}
|
||||
|
||||
registerMany(manifests: Array<ManifestTypes | ManifestKind<ManifestTypes>>): void {
|
||||
// we have to register extensions individually, so we ensure a manifest is valid before continuing to the next one
|
||||
manifests.forEach((manifest) => this.register(manifest));
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { UMB_EXTENSION_COLLECTION_REPOSITORY_ALIAS } from './repository/index.js';
|
||||
import { manifests as collectionRepositoryManifests } from './repository/manifests.js';
|
||||
import { manifests as collectionViewManifests } from './views/manifests.js';
|
||||
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const UMB_EXTENSION_COLLECTION_ALIAS = 'Umb.Collection.Extension';
|
||||
|
||||
const collectionManifest: ManifestTypes = {
|
||||
type: 'collection',
|
||||
kind: 'default',
|
||||
alias: UMB_EXTENSION_COLLECTION_ALIAS,
|
||||
name: 'Extension Collection',
|
||||
meta: {
|
||||
repositoryAlias: UMB_EXTENSION_COLLECTION_REPOSITORY_ALIAS,
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [collectionManifest, ...collectionRepositoryManifests, ...collectionViewManifests];
|
||||
@@ -0,0 +1,21 @@
|
||||
import { umbExtensionsRegistry } from '../../registry.js';
|
||||
import { UmbRepositoryBase, type UmbCollectionRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
export class UmbExtensionCollectionRepository extends UmbRepositoryBase implements UmbCollectionRepository {
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host);
|
||||
}
|
||||
|
||||
async requestCollection(filter: any) {
|
||||
const extensions = umbExtensionsRegistry.getExtensions();
|
||||
const total = extensions.length;
|
||||
const items = extensions.slice(filter.skip, filter.skip + filter.take);
|
||||
const data = { items, total };
|
||||
return { data };
|
||||
}
|
||||
|
||||
destroy(): void {}
|
||||
}
|
||||
|
||||
export default UmbExtensionCollectionRepository;
|
||||
@@ -0,0 +1,2 @@
|
||||
export { UMB_EXTENSION_COLLECTION_REPOSITORY_ALIAS } from './manifests.js';
|
||||
export { UmbExtensionCollectionRepository } from './extension-collection.repository.js';
|
||||
@@ -0,0 +1,13 @@
|
||||
import { UmbExtensionCollectionRepository } from './extension-collection.repository.js';
|
||||
import type { ManifestRepository } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const UMB_EXTENSION_COLLECTION_REPOSITORY_ALIAS = 'Umb.Repository.ExtensionCollection';
|
||||
|
||||
const repository: ManifestRepository = {
|
||||
type: 'repository',
|
||||
alias: UMB_EXTENSION_COLLECTION_REPOSITORY_ALIAS,
|
||||
name: 'Extension Collection Repository',
|
||||
api: UmbExtensionCollectionRepository,
|
||||
};
|
||||
|
||||
export const manifests = [repository];
|
||||
@@ -0,0 +1,50 @@
|
||||
import { umbExtensionsRegistry, type ManifestTypes } from '../../index.js';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import { UMB_CONFIRM_MODAL, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
@customElement('umb-extension-table-action-column-layout')
|
||||
export class UmbExtensionTableActionColumnLayoutElement extends UmbLitElement {
|
||||
@property({ attribute: false })
|
||||
value!: ManifestTypes;
|
||||
|
||||
#modalContext?: UmbModalManagerContext;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (instance) => {
|
||||
this.#modalContext = instance;
|
||||
});
|
||||
}
|
||||
|
||||
async #removeExtension() {
|
||||
const modalContext = this.#modalContext?.open(UMB_CONFIRM_MODAL, {
|
||||
data: {
|
||||
headline: 'Unload extension',
|
||||
confirmLabel: 'Unload',
|
||||
content: html`<p>Are you sure you want to unload the extension <strong>${this.value.alias}</strong>?</p>`,
|
||||
color: 'danger',
|
||||
},
|
||||
});
|
||||
|
||||
await modalContext?.onSubmit();
|
||||
umbExtensionsRegistry.unregister(this.value.alias);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<uui-button label="Unload" color="danger" look="primary" @click=${this.#removeExtension}>
|
||||
<uui-icon name="icon-trash"></uui-icon>
|
||||
</uui-button>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = [UmbTextStyles];
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-extension-table-action-column-layout': UmbExtensionTableActionColumnLayoutElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection';
|
||||
import type { ManifestCollectionView } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const UMB_EXTENSION_TABLE_COLLECTION_VIEW_ALIAS = 'Umb.CollectionView.Extension.Table';
|
||||
|
||||
const tableCollectionView: ManifestCollectionView = {
|
||||
type: 'collectionView',
|
||||
alias: UMB_EXTENSION_TABLE_COLLECTION_VIEW_ALIAS,
|
||||
name: 'Extension Table Collection View',
|
||||
js: () => import('./table/extension-table-collection-view.element.js'),
|
||||
meta: {
|
||||
label: 'Table',
|
||||
icon: 'icon-list',
|
||||
pathName: 'table',
|
||||
},
|
||||
conditions: [
|
||||
{
|
||||
alias: UMB_COLLECTION_ALIAS_CONDITION,
|
||||
match: 'Umb.Collection.Extension',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const manifests = [tableCollectionView];
|
||||
@@ -0,0 +1,115 @@
|
||||
import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection';
|
||||
import { UMB_DEFAULT_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection';
|
||||
import type { UmbTableColumn, UmbTableConfig, UmbTableItem } from '@umbraco-cms/backoffice/components';
|
||||
import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import type { ManifestBase } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
import '../extension-table-action-column-layout.element.js';
|
||||
|
||||
@customElement('umb-extension-table-collection-view')
|
||||
export class UmbExtensionTableCollectionViewElement extends UmbLitElement {
|
||||
@state()
|
||||
private _tableConfig: UmbTableConfig = {
|
||||
allowSelection: false,
|
||||
};
|
||||
|
||||
@state()
|
||||
private _tableColumns: Array<UmbTableColumn> = [
|
||||
{
|
||||
name: 'Type',
|
||||
alias: 'extensionType',
|
||||
},
|
||||
{
|
||||
name: 'Name',
|
||||
alias: 'extensionName',
|
||||
},
|
||||
{
|
||||
name: 'Alias',
|
||||
alias: 'extensionAlias',
|
||||
},
|
||||
{
|
||||
name: 'Weight',
|
||||
alias: 'extensionWeight',
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
alias: 'extensionAction',
|
||||
elementName: 'umb-extension-table-action-column-layout',
|
||||
},
|
||||
];
|
||||
|
||||
@state()
|
||||
private _tableItems: Array<UmbTableItem> = [];
|
||||
|
||||
#collectionContext?: UmbDefaultCollectionContext<ManifestBase>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext(UMB_DEFAULT_COLLECTION_CONTEXT, (instance) => {
|
||||
this.#collectionContext = instance;
|
||||
this.#observeCollectionItems();
|
||||
});
|
||||
}
|
||||
|
||||
#observeCollectionItems() {
|
||||
if (!this.#collectionContext) return;
|
||||
this.observe(this.#collectionContext.items, (items) => this.#createTableItems(items), 'umbCollectionItemsObserver');
|
||||
}
|
||||
|
||||
#createTableItems(extensions: Array<ManifestBase>) {
|
||||
this._tableItems = extensions.map((extension) => {
|
||||
return {
|
||||
id: extension.alias,
|
||||
data: [
|
||||
{
|
||||
columnAlias: 'extensionType',
|
||||
value: extension.type,
|
||||
},
|
||||
{
|
||||
columnAlias: 'extensionName',
|
||||
value: extension.name,
|
||||
},
|
||||
{
|
||||
columnAlias: 'extensionAlias',
|
||||
value: extension.alias,
|
||||
},
|
||||
{
|
||||
columnAlias: 'extensionWeight',
|
||||
value: extension.weight,
|
||||
},
|
||||
{
|
||||
columnAlias: 'extensionAction',
|
||||
value: extension,
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<umb-table .config=${this._tableConfig} .columns=${this._tableColumns} .items=${this._tableItems}></umb-table>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
UmbTextStyles,
|
||||
css`
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
export default UmbExtensionTableCollectionViewElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-extension-table-collection-view': UmbExtensionTableCollectionViewElement;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { manifests as conditionManifests } from './conditions/manifests.js';
|
||||
import { manifests as menuItemManifests } from './menu-item/manifests.js';
|
||||
import { manifests as workspaceManifests } from './workspace/manifests.js';
|
||||
import { manifests as collectionManifests } from './collection/manifests.js';
|
||||
|
||||
export const manifests = [...conditionManifests, ...menuItemManifests, ...workspaceManifests];
|
||||
export const manifests = [...conditionManifests, ...menuItemManifests, ...workspaceManifests, ...collectionManifests];
|
||||
|
||||
@@ -1,107 +1,17 @@
|
||||
import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { map } from '@umbraco-cms/backoffice/external/rxjs';
|
||||
import type { ManifestTypes} from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UMB_EXTENSION_COLLECTION_ALIAS } from '../collection/manifests.js';
|
||||
import { UMB_EXTENSION_ROOT_WORKSPACE_ALIAS } from './manifests.js';
|
||||
import { html, customElement } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import type { UmbModalManagerContext} from '@umbraco-cms/backoffice/modal';
|
||||
import { UMB_MODAL_MANAGER_CONTEXT, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
@customElement('umb-extension-root-workspace')
|
||||
export class UmbExtensionRootWorkspaceElement extends UmbLitElement {
|
||||
@state()
|
||||
private _extensions?: Array<ManifestTypes> = undefined;
|
||||
|
||||
private _modalContext?: UmbModalManagerContext;
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this._observeExtensions();
|
||||
|
||||
this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (instance) => {
|
||||
this._modalContext = instance;
|
||||
});
|
||||
}
|
||||
|
||||
private _observeExtensions() {
|
||||
this.observe(
|
||||
umbExtensionsRegistry.extensions.pipe(
|
||||
map((exts) =>
|
||||
exts.sort((a, b) => {
|
||||
// If type is the same, sort by weight
|
||||
if (a.type === b.type) {
|
||||
return (b.weight || 0) - (a.weight || 0);
|
||||
}
|
||||
// Otherwise sort by type
|
||||
return a.type.localeCompare(b.type);
|
||||
}),
|
||||
),
|
||||
),
|
||||
(extensions) => {
|
||||
this._extensions = extensions || undefined;
|
||||
},
|
||||
'_observeExtensionRegistry',
|
||||
);
|
||||
}
|
||||
|
||||
async #removeExtension(extension: ManifestTypes) {
|
||||
const modalContext = this._modalContext?.open(UMB_CONFIRM_MODAL, {
|
||||
data: {
|
||||
headline: 'Unload extension',
|
||||
confirmLabel: 'Unload',
|
||||
content: html`<p>Are you sure you want to unload the extension <strong>${extension.alias}</strong>?</p>`,
|
||||
color: 'danger',
|
||||
},
|
||||
});
|
||||
|
||||
await modalContext?.onSubmit();
|
||||
umbExtensionsRegistry.unregister(extension.alias);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<umb-workspace-editor headline="Extensions" alias="Umb.Workspace.ExtensionRoot" .enforceNoFooter=${true}>
|
||||
<uui-box>
|
||||
<uui-table>
|
||||
<uui-table-head>
|
||||
<uui-table-head-cell>Type</uui-table-head-cell>
|
||||
<uui-table-head-cell>Name</uui-table-head-cell>
|
||||
<uui-table-head-cell>Alias</uui-table-head-cell>
|
||||
<uui-table-head-cell>Weight</uui-table-head-cell>
|
||||
<uui-table-head-cell>Actions</uui-table-head-cell>
|
||||
</uui-table-head>
|
||||
|
||||
${this._extensions?.map(
|
||||
(extension) => html`
|
||||
<uui-table-row>
|
||||
<uui-table-cell>${extension.type}</uui-table-cell>
|
||||
<uui-table-cell> ${extension.name} </uui-table-cell>
|
||||
<uui-table-cell>${extension.alias}</uui-table-cell>
|
||||
<uui-table-cell>${extension.weight ? extension.weight : ''} </uui-table-cell>
|
||||
<uui-table-cell>
|
||||
<uui-button
|
||||
label="Unload"
|
||||
color="danger"
|
||||
look="primary"
|
||||
@click=${() => this.#removeExtension(extension)}>
|
||||
<uui-icon name="icon-trash"></uui-icon>
|
||||
</uui-button>
|
||||
</uui-table-cell>
|
||||
</uui-table-row>
|
||||
`,
|
||||
)}
|
||||
</uui-table>
|
||||
</uui-box>
|
||||
<umb-workspace-editor headline="Extensions" alias=${UMB_EXTENSION_ROOT_WORKSPACE_ALIAS} .enforceNoFooter=${true}>
|
||||
<umb-collection alias=${UMB_EXTENSION_COLLECTION_ALIAS}></umb-collection>
|
||||
</umb-workspace-editor>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
css`
|
||||
uui-box {
|
||||
margin: var(--uui-size-layout-1);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
export default UmbExtensionRootWorkspaceElement;
|
||||
|
||||
@@ -4,6 +4,8 @@ import type {
|
||||
ManifestWorkspaceView,
|
||||
} from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const UMB_EXTENSION_ROOT_WORKSPACE_ALIAS = 'Umb.Workspace.ExtensionRoot';
|
||||
|
||||
const workspace: ManifestWorkspace = {
|
||||
type: 'workspace',
|
||||
alias: 'Umb.Workspace.ExtensionRoot',
|
||||
|
||||
Reference in New Issue
Block a user