Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

workspace routable kind #1455

Merged
merged 29 commits into from Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8b371fa
workspace routable kind
nielslyngsoe Mar 19, 2024
f7ea74d
Merge remote-tracking branch 'origin/main' into feature/workspace-kin…
nielslyngsoe Mar 19, 2024
9beee77
append condition types
nielslyngsoe Mar 19, 2024
1d127d9
init workspace context as part of the kind
nielslyngsoe Mar 20, 2024
47165df
member workspace
nielslyngsoe Mar 20, 2024
47f8cca
media
nielslyngsoe Mar 20, 2024
897c174
simplify route component
nielslyngsoe Mar 20, 2024
4abf26d
media type
nielslyngsoe Mar 20, 2024
d72ec35
member type
nielslyngsoe Mar 20, 2024
97beb57
template + member group
nielslyngsoe Mar 20, 2024
0846a16
stylesheet
nielslyngsoe Mar 20, 2024
40e87bb
script
nielslyngsoe Mar 20, 2024
3e6c241
partial views
nielslyngsoe Mar 20, 2024
d2e5e54
user workspace
nielslyngsoe Mar 20, 2024
10bf2a3
user group
nielslyngsoe Mar 20, 2024
5ed3f5d
language
nielslyngsoe Mar 20, 2024
15803ff
dictionary
nielslyngsoe Mar 20, 2024
9d1e7f3
block + block type
nielslyngsoe Mar 20, 2024
90e6d29
block
nielslyngsoe Mar 20, 2024
0651c39
fix block workspace
nielslyngsoe Mar 20, 2024
051b879
out comment broken conditions
nielslyngsoe Mar 20, 2024
8feb680
use argument manifest for block type
nielslyngsoe Mar 20, 2024
2d11b1d
correct kind to routable
nielslyngsoe Mar 20, 2024
9061745
implement UmbDefaultWorkspaceContext
nielslyngsoe Mar 20, 2024
00cfcf3
fix import
nielslyngsoe Mar 20, 2024
7bdc47d
default api feature for extension with api slot+initializer
nielslyngsoe Mar 20, 2024
c517f02
revert implementation of default api
nielslyngsoe Mar 20, 2024
066ca95
fix log viewer
nielslyngsoe Mar 21, 2024
df70cae
fix import path
nielslyngsoe Mar 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Expand Up @@ -14,6 +14,7 @@
"pickable",
"popovertarget",
"Registrator",
"Routable",
"stylesheet",
"svgs",
"templating",
Expand Down
Expand Up @@ -5,9 +5,8 @@ import { EXAMPLE_COUNTER_CONTEXT } from './counter-workspace-context';
export class ExampleIncrementorWorkspaceAction extends UmbWorkspaceActionBase implements UmbWorkspaceAction {
// This method is executed
async execute() {
await this.consumeContext(EXAMPLE_COUNTER_CONTEXT, (context) => {
context.increment();
}).asPromise();
const context = await this.getContext(EXAMPLE_COUNTER_CONTEXT);
context.increment();
}
}

Expand Down
1 change: 1 addition & 0 deletions examples/workspace-context-counter/index.ts
Expand Up @@ -15,6 +15,7 @@ export const manifests: Array<ManifestTypes> = [
},
{
type: 'workspaceAction',
kind: 'default',
name: 'Example Count Incerementor Workspace Action',
alias: 'example.workspaceAction.incrementor',
weight: 1000,
Expand Down
Expand Up @@ -2,7 +2,12 @@ import { createExtensionElementWithApi } from '../functions/create-extension-ele
import type { UmbApiConstructorArgumentsMethodType } from '../index.js';
import type { UmbApi } from '../models/api.interface.js';
import type { UmbExtensionRegistry } from '../registry/extension.registry.js';
import type { ManifestElementAndApi, ManifestCondition, ManifestWithDynamicConditions } from '../types/index.js';
import type {
ManifestElementAndApi,
ManifestCondition,
ManifestWithDynamicConditions,
ApiLoaderProperty,
} from '../types/index.js';
import { UmbBaseExtensionInitializer } from './base-extension-initializer.controller.js';
import type { UmbControllerHost, UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';

Expand All @@ -25,6 +30,7 @@ export class UmbExtensionElementAndApiInitializer<
ExtensionApiInterface extends UmbApi = NonNullable<ExtensionInterface['API_TYPE']>,
> extends UmbBaseExtensionInitializer<ManifestType, ControllerType> {
#defaultElement?: string;
#defaultApi?: ApiLoaderProperty<ExtensionApiInterface>;
#component?: ExtensionElementInterface;
#api?: ExtensionApiInterface;
#constructorArguments?: Array<unknown> | UmbApiConstructorArgumentsMethodType<ManifestType>;
Expand Down Expand Up @@ -102,10 +108,12 @@ export class UmbExtensionElementAndApiInitializer<
constructorArguments: Array<unknown> | UmbApiConstructorArgumentsMethodType<ManifestType> | undefined,
onPermissionChanged: (isPermitted: boolean, controller: ControllerType) => void,
defaultElement?: string,
defaultApi?: ApiLoaderProperty<ExtensionApiInterface>,
) {
super(host, extensionRegistry, 'extApiAndElement_', alias, onPermissionChanged);
this.#constructorArguments = constructorArguments;
this.#defaultElement = defaultElement;
this.#defaultApi = defaultApi;
this._init();
}

Expand All @@ -132,7 +140,7 @@ export class UmbExtensionElementAndApiInitializer<
const { element: newComponent, api: newApi } = await createExtensionElementWithApi<
ExtensionElementInterface,
ExtensionApiInterface
>(manifest, this.#defaultElement, this.#constructorArguments as any);
>(manifest, this.#constructorArguments as any, this.#defaultElement, this.#defaultApi);

if (!this._isConditionsPositive) {
newApi?.destroy?.();
Expand Down
@@ -1,4 +1,4 @@
import type { ManifestBase } from '../types/index.js';
import type { ApiLoaderProperty, ManifestBase } from '../types/index.js';
import type { UmbExtensionRegistry } from '../registry/extension.registry.js';
import type { SpecificManifestTypeOrManifestBase } from '../types/map.types.js';
import type { UmbApiConstructorArgumentsMethodType } from '../index.js';
Expand Down Expand Up @@ -28,6 +28,7 @@ export class UmbExtensionsElementAndApiInitializer<
//
#extensionRegistry;
#defaultElement?: string;
#defaultApi?: ApiLoaderProperty;
#constructorArgs: Array<unknown> | UmbApiConstructorArgumentsMethodType<ManifestType> | undefined;
#elProps?: Record<string, unknown>;
#apiProps?: Record<string, unknown>;
Expand Down Expand Up @@ -61,11 +62,13 @@ export class UmbExtensionsElementAndApiInitializer<
onChange: (permittedManifests: Array<MyPermittedControllerType>) => void,
controllerAlias?: string,
defaultElement?: string,
defaultApi?: ApiLoaderProperty,
) {
super(host, extensionRegistry, type, filter, onChange, controllerAlias);
this.#extensionRegistry = extensionRegistry;
this.#constructorArgs = constructorArguments;
this.#defaultElement = defaultElement;
this.#defaultApi = defaultApi;
this._init();
}

Expand All @@ -77,6 +80,7 @@ export class UmbExtensionsElementAndApiInitializer<
this.#constructorArgs,
this._extensionChanged,
this.#defaultElement,
this.#defaultApi as any,
) as ControllerType;

extController.elementProps = this.#elProps;
Expand Down
@@ -1,6 +1,6 @@
import type { UmbApi } from '../models/api.interface.js';
import type { ManifestElementAndApi } from '../types/base.types.js';
import type { ClassConstructor } from '../types/utils.js';
import type { ApiLoaderProperty, ClassConstructor } from '../types/utils.js';
import { loadManifestApi } from './load-manifest-api.function.js';
import { loadManifestElement } from './load-manifest-element.function.js';
import type { UmbApiConstructorArgumentsMethodType } from './types.js';
Expand All @@ -11,10 +11,11 @@ export async function createExtensionElementWithApi<
ApiType extends UmbApi = UmbApi,
>(
manifest: ManifestElementAndApi<ElementType, ApiType>,
fallbackElement?: string,
constructorArgs?: unknown[] | UmbApiConstructorArgumentsMethodType<ManifestElementAndApi<ElementType, ApiType>>,
fallbackElement?: string,
fallbackApi?: ApiLoaderProperty<ApiType>,
): Promise<{ element?: ElementType; api?: ApiType }> {
const apiPropValue = manifest.api ?? manifest.js;
const apiPropValue = manifest.api ?? manifest.js ?? fallbackApi;
if (!apiPropValue) {
console.error(
`-- Extension of alias "${manifest.alias}" did not succeed creating an api class instance, missing a JavaScript file via the 'api' or 'js' property, using either a 'api' or 'default'(not supported on the JS property) export`,
Expand Down
Expand Up @@ -87,7 +87,7 @@ describe('Create Extension Element and Api Method', () => {
js: () => Promise.resolve(apiJsModuleWithApiExport),
};

const { element, api } = await createExtensionElementWithApi(manifest, 'umb-extension-api-true-test-element');
const { element, api } = await createExtensionElementWithApi(manifest, [], 'umb-extension-api-true-test-element');
expect(element).to.not.be.undefined;
expect(api).to.not.be.undefined;
if (element) {
Expand All @@ -106,7 +106,7 @@ describe('Create Extension Element and Api Method', () => {
js: () => Promise.resolve(apiJsModuleWithApiExport),
};

const { element, api } = await createExtensionElementWithApi(manifest, 'umb-extension-api-true-test-element');
const { element, api } = await createExtensionElementWithApi(manifest, [], 'umb-extension-api-true-test-element');
expect(element).to.not.be.undefined;
expect(api).to.not.be.undefined;
if (element) {
Expand Down
3 changes: 1 addition & 2 deletions src/packages/block/block-grid/workspace/manifests.ts
Expand Up @@ -6,11 +6,10 @@ export const manifests: Array<ManifestTypes> = [
...workspaceViewManifests,
{
type: 'workspace',
kind: 'routable',
name: 'Block Grid Type Workspace',
alias: UMB_BLOCK_GRID_TYPE_WORKSPACE_ALIAS,
element: () => import('../../block-type/workspace/block-type-workspace.element.js'),
api: () => import('../../block-type/workspace/block-type-workspace.context.js'),
weight: 900,
meta: {
entityType: 'block-grid-type',
},
Expand Down
3 changes: 1 addition & 2 deletions src/packages/block/block-list/workspace/manifests.ts
Expand Up @@ -6,11 +6,10 @@ export const manifests: Array<ManifestTypes> = [
...workspaceViewManifests,
{
type: 'workspace',
kind: 'routable',
name: 'Block List Type Workspace',
alias: UMB_BLOCK_LIST_TYPE_WORKSPACE_ALIAS,
element: () => import('../../block-type/workspace/block-type-workspace.element.js'),
api: () => import('../../block-type/workspace/block-type-workspace.context.js'),
weight: 900,
meta: {
entityType: 'block-list-type',
},
Expand Down
3 changes: 1 addition & 2 deletions src/packages/block/block-rte/workspace/manifests.ts
Expand Up @@ -6,11 +6,10 @@ export const manifests: Array<ManifestTypes> = [
...workspaceViewManifests,
{
type: 'workspace',
kind: 'routable',
name: 'Block Rte Type Workspace',
alias: UMB_BLOCK_RTE_TYPE_WORKSPACE_ALIAS,
element: () => import('../../block-type/workspace/block-type-workspace.element.js'),
api: () => import('../../block-type/workspace/block-type-workspace.context.js'),
weight: 900,
meta: {
entityType: 'block-rte-type',
},
Expand Down
@@ -1,4 +1,4 @@
import { UMB_BLOCK_TYPE_WORKSPACE_CONTEXT } from './block-type-workspace.context.js';
import { UMB_BLOCK_TYPE_WORKSPACE_CONTEXT } from './block-type-workspace.context-token.js';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { customElement, css, html, state, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
Expand Down Expand Up @@ -51,7 +51,7 @@ export class UmbBlockTypeWorkspaceEditorElement extends UmbLitElement {
alias=${this.workspaceAlias}
headline=${this.localize.term('blockEditor_blockConfigurationOverlayTitle', [this._name])}>
</umb-workspace-editor>
`
`
: '';
}

Expand Down
@@ -0,0 +1,12 @@
import type { UmbBlockTypeWorkspaceContext } from './block-type-workspace.context.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import type { UmbWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace';

export const UMB_BLOCK_TYPE_WORKSPACE_CONTEXT = new UmbContextToken<
UmbWorkspaceContextInterface,
UmbBlockTypeWorkspaceContext
>(
'UmbWorkspaceContext',
undefined,
(context): context is UmbBlockTypeWorkspaceContext => (context as any).IS_BLOCK_TYPE_WORKSPACE_CONTEXT,
);
@@ -1,22 +1,24 @@
import type { UmbBlockTypeBaseModel, UmbBlockTypeWithGroupKey } from '../types.js';
import { UmbBlockTypeWorkspaceEditorElement } from './block-type-workspace-editor.element.js';
import type { UmbPropertyDatasetContext } from '@umbraco-cms/backoffice/property';
import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
import type {
UmbInvariantableWorkspaceContextInterface,
UmbWorkspaceContextInterface,
UmbRoutableWorkspaceContext,
} from '@umbraco-cms/backoffice/workspace';
import {
UmbEditableWorkspaceContextBase,
UmbInvariantWorkspacePropertyDatasetContext,
UmbWorkspaceIsNewRedirectController,
UmbWorkspaceRouteManager,
} from '@umbraco-cms/backoffice/workspace';
import { UmbArrayState, UmbObjectState, appendToFrozenArray } from '@umbraco-cms/backoffice/observable-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import type { ManifestWorkspace, PropertyEditorSettingsProperty } from '@umbraco-cms/backoffice/extension-registry';

export class UmbBlockTypeWorkspaceContext<BlockTypeData extends UmbBlockTypeWithGroupKey = UmbBlockTypeWithGroupKey>
extends UmbEditableWorkspaceContextBase<BlockTypeData>
implements UmbInvariantableWorkspaceContextInterface
implements UmbInvariantableWorkspaceContextInterface, UmbRoutableWorkspaceContext
{
// Just for context token safety:
public readonly IS_BLOCK_TYPE_WORKSPACE_CONTEXT = true;
Expand All @@ -32,9 +34,43 @@ export class UmbBlockTypeWorkspaceContext<BlockTypeData extends UmbBlockTypeWith
#properties = new UmbArrayState<PropertyEditorSettingsProperty>([], (x) => x.alias);
readonly properties = this.#properties.asObservable();

constructor(host: UmbControllerHost, workspaceArgs: { manifest: ManifestWorkspace }) {
super(host, workspaceArgs.manifest.alias);
this.#entityType = workspaceArgs.manifest.meta?.entityType;
readonly routes = new UmbWorkspaceRouteManager(this);

constructor(host: UmbControllerHost, args: { manifest: ManifestWorkspace }) {
super(host, args.manifest.alias);
const manifest = args.manifest;
this.#entityType = manifest.meta?.entityType;

this.routes.setRoutes([
{
// Would it make more sense to have groupKey before elementTypeKey?
path: 'create/:elementTypeKey/:groupKey',
component: UmbBlockTypeWorkspaceEditorElement,
setup: async (component, info) => {
(component as UmbBlockTypeWorkspaceEditorElement).workspaceAlias = manifest.alias;

const elementTypeKey = info.match.params.elementTypeKey;
const groupKey = info.match.params.groupKey === 'null' ? null : info.match.params.groupKey;
this.create(elementTypeKey, groupKey);

new UmbWorkspaceIsNewRedirectController(
this,
this,
this.getHostElement().shadowRoot!.querySelector('umb-router-slot')!,
);
},
},
{
path: 'edit/:id',
component: UmbBlockTypeWorkspaceEditorElement,
setup: (component, info) => {
(component as UmbBlockTypeWorkspaceEditorElement).workspaceAlias = manifest.alias;

const id = info.match.params.id;
this.load(id);
},
},
]);
}

protected resetState() {
Expand Down Expand Up @@ -131,13 +167,4 @@ export class UmbBlockTypeWorkspaceContext<BlockTypeData extends UmbBlockTypeWith
}
}

export default UmbBlockTypeWorkspaceContext;

export const UMB_BLOCK_TYPE_WORKSPACE_CONTEXT = new UmbContextToken<
UmbWorkspaceContextInterface,
UmbBlockTypeWorkspaceContext
>(
'UmbWorkspaceContext',
undefined,
(context): context is UmbBlockTypeWorkspaceContext => (context as any).IS_BLOCK_TYPE_WORKSPACE_CONTEXT,
);
export { UmbBlockTypeWorkspaceContext as api };

This file was deleted.