refactor manifest types, part 1

This commit is contained in:
Niels Lyngsø
2023-11-13 21:45:28 +01:00
parent 6ac8abada9
commit 6ac23654a5
154 changed files with 660 additions and 555 deletions

View File

@@ -115,7 +115,7 @@ To declare the Published Cache Status Dashboard as a new manifest, we need to ad
alias: 'Umb.Dashboard.PublishedStatus',
name: 'Published Status Dashboard',
elementName: 'umb-dashboard-published-status',
loader: () => import('./published-status/dashboard-published-status.element.js'),
element: () => import('./published-status/dashboard-published-status.element.js'),
weight: 200,
meta: {
label: 'Published Status',

View File

@@ -7,7 +7,7 @@ export const manifests: Array<ManifestExternalLoginProvider> = [
alias: 'Umb.ExternalLoginProvider.Test',
name: 'Test External Login Provider',
elementName: 'umb-external-login-provider-test',
loader: () => import('./external-login-provider-test.element.js'),
element: () => import('./external-login-provider-test.element.js'),
weight: 2,
meta: {
label: 'Test External Login Provider',
@@ -19,7 +19,7 @@ export const manifests: Array<ManifestExternalLoginProvider> = [
alias: 'Umb.ExternalLoginProvider.Test2',
name: 'Test External Login Provider 2',
elementName: 'umb-external-login-provider-test2',
loader: () => import('./external-login-provider-test2.element.js'),
element: () => import('./external-login-provider-test2.element.js'),
weight: 1,
meta: {
label: 'Test External Login Provider 2',

View File

@@ -1,32 +1,23 @@
import { hasApiExport, hasDefaultExport, isManifestApiConstructorType } from '../type-guards/index.js';
import type { ManifestApi, ClassConstructor, ManifestElementAndApi, UmbApi } from '../types.js';
import { loadExtensionApi } from '../functions/load-extension-api.function.js';
import { UmbApi } from '../models/api.interface.js';
import type { ManifestApi } from '../types/index.js';
import { loadManifestApiProperty } from './manifest-api-loader.function.js';
//TODO: Write tests for this method:
export async function createExtensionApi<ApiType extends UmbApi = UmbApi>(
manifest: ManifestApi<ApiType> | ManifestElementAndApi<any, ApiType>,
manifest: ManifestApi<ApiType>,
constructorArguments: unknown[] = []
): Promise<ApiType | undefined> {
const js = await loadExtensionApi(manifest);
if (isManifestApiConstructorType<ApiType>(manifest)) {
return new manifest.api(...constructorArguments);
}
if (js) {
if (hasApiExport<ClassConstructor<ApiType>>(js)) {
return new js.api(...constructorArguments);
if(manifest.api) {
const api = await loadManifestApiProperty(manifest.api, constructorArguments);
if(api) {
return api;
}
if (hasDefaultExport<ClassConstructor<ApiType>>(js)) {
return new js.default(...constructorArguments);
} else if (manifest.js) {
const js = await loadManifestApiProperty(manifest.js, constructorArguments);
if(js) {
return js;
}
console.error(
`-- Extension of alias "${manifest.alias}" did not succeed creating an api class instance, missing a 'api' or 'default' export of the served JavaScript file`,
manifest
);
return undefined;
}
console.error(

View File

@@ -1,8 +1,11 @@
import { UmbApi } from '../models/api.interface.js';
import { isManifestApiJSType, isManifestJSType, isManifestLoaderType } from '../type-guards/index.js';
import type { ManifestWithLoader } from '../types.js';
import type { ManifestApi } from '../types/index.js';
export async function loadExtensionApi<T = unknown>(manifest: ManifestWithLoader<T>): Promise<T | null> {
export async function loadExtensionApi<T extends UmbApi = UmbApi>(manifest: ManifestApi<T>): Promise<T | null> {
try {
// TODO: Get rid of this, instead make apiJs support loader.
if (isManifestLoaderType<T>(manifest)) {
return manifest.loader();
}

View File

@@ -3,6 +3,8 @@ import type { ManifestWithLoader } from '../types.js';
export async function loadExtensionElement<T = unknown>(manifest: ManifestWithLoader<T>): Promise<T | null> {
try {
// TODO: Get rid of this, instead make elementJs support loader.
if (isManifestLoaderType<T>(manifest)) {
return manifest.loader();
}

View File

@@ -3,6 +3,8 @@ import type { ManifestWithLoader } from '../types.js';
export async function loadExtension<T = unknown>(manifest: ManifestWithLoader<T>): Promise<T | null> {
try {
// TODO: Get rid of this, instead make js support loader.
if (isManifestLoaderType<T>(manifest)) {
return await manifest.loader();
}

View File

@@ -0,0 +1,31 @@
import type { UmbApi } from "../models/api.interface.js";
import type { ApiLoaderExports, ApiLoaderProperty, ClassConstructor } from "../types/utils.js";
export async function loadManifestApiProperty<ApiType extends UmbApi>(property: ApiLoaderProperty<ApiType>, constructorArguments: unknown[] = []): Promise<ApiType | undefined> {
const propType = typeof property
if(propType === 'function') {
if(typeof property.constructor === 'function') {
// Class Constructor
return new (property as ClassConstructor<ApiType>)(constructorArguments);
} else {
// Promise function
const result = await (property as (Exclude<Exclude<ApiLoaderProperty<ApiType>, string>, ClassConstructor<ApiType>>))();
if(typeof result === 'object' && result != null) {
const exportValue = 'api' in result ? result.api : undefined || 'default' in result ? result.default : undefined;
if(exportValue && typeof exportValue === 'function') {
return new exportValue(constructorArguments);
}
}
}
} else if(propType === 'string') {
// Import string
const result = await (import(/* @vite-ignore */ property as string) as unknown as ApiLoaderExports<ApiType>);
if(typeof result === 'object' && result != null) {
const exportValue = 'api' in result ? result.api : undefined || 'default' in result ? result.default : undefined;
if(exportValue && typeof exportValue === 'function') {
return new exportValue(constructorArguments);
}
}
}
return undefined;
}

View File

@@ -0,0 +1,31 @@
import type { ClassConstructor, ElementLoaderExports, ElementLoaderProperty } from "../types/utils.js";
export async function loadManifestElementProperty<ElementType extends HTMLElement>(property: ElementLoaderProperty<ElementType>): Promise<ElementType | undefined> {
const propType = typeof property
if(propType === 'function') {
if(typeof property.constructor === 'function') {
// Class Constructor
return new (property as ClassConstructor<ElementType>)();
} else {
// Promise function
const result = await (property as (Exclude<Exclude<typeof property, string>, ClassConstructor<ElementType>>))();
if(typeof result === 'object' && result !== null) {
const exportValue = 'element' in result ? result.element : undefined || 'default' in result ? result.default : undefined;
if(exportValue && typeof exportValue === 'function') {
return new exportValue();
}
}
}
} else if(propType === 'string') {
// Import string
const result = await (import(/* @vite-ignore */ property as string) as unknown as ElementLoaderExports<ElementType>);
if(typeof result === 'object' && result != null) {
const exportValue = 'element' in result ? result.element : undefined || 'default' in result ? result.default : undefined;
if(exportValue && typeof exportValue === 'function') {
return new exportValue();
}
}
}
return undefined;
}

View File

@@ -1,8 +1,8 @@
export * from './initializers/index.js';
export * from './condition/index.js';
export * from './controller/index.js';
export * from './functions/index.js';
export * from './initializers/index.js';
export * from './models/index.js';
export * from './registry/extension.registry.js';
export * from './type-guards/index.js';
export * from './types.js';
export * from './types/index.js';

View File

@@ -0,0 +1,3 @@
export interface UmbApi {
destroy?(): void;
}

View File

@@ -1 +1,2 @@
export * from './entry-point.interface.js'
export * from './api.interface.js'

View File

@@ -1,10 +1,14 @@
import { expect } from '@open-wc/testing';
import type { ManifestElementWithElementName, ManifestKind, ManifestWithMeta } from '../types.js';
import type { ManifestElementWithElementName, ManifestKind, ManifestBase } from '../types/index.js';
import { UmbExtensionRegistry } from './extension.registry.js';
interface TestManifestWithMeta extends ManifestBase {
meta: unknown;
}
describe('UmbExtensionRegistry', () => {
let extensionRegistry: UmbExtensionRegistry<ManifestWithMeta>;
let manifests: Array<ManifestWithMeta>;
let extensionRegistry: UmbExtensionRegistry<TestManifestWithMeta>;
let manifests: Array<TestManifestWithMeta>;
beforeEach(() => {
extensionRegistry = new UmbExtensionRegistry();
@@ -170,7 +174,7 @@ describe('UmbExtensionRegistry', () => {
describe('UmbExtensionRegistry with kinds', () => {
let extensionRegistry: UmbExtensionRegistry<any>;
let manifests: Array<
ManifestElementWithElementName | ManifestWithMeta | ManifestKind<ManifestElementWithElementName>
ManifestElementWithElementName | TestManifestWithMeta | ManifestKind<ManifestElementWithElementName>
>;
beforeEach(() => {

View File

@@ -8,4 +8,4 @@ export * from './is-manifest-api-js-type.function.js';
export * from './is-manifest-loader-type.function.js';
export * from './has-default-export.function.js';
export * from './has-element-export.function.js';
export * from './has-api-export.function.js';
export * from './has-api-export.function.js';

View File

@@ -1,4 +1,4 @@
import type { ManifestElement, ManifestElementWithElementName } from '../types.js';
import type { ManifestElement, ManifestElementWithElementName } from '../types/index.js';
export function isManifestElementNameType(manifest: unknown): manifest is ManifestElementWithElementName {
return typeof manifest === 'object' && manifest !== null && (manifest as ManifestElement).elementName !== undefined;

View File

@@ -1,299 +0,0 @@
import type { UmbExtensionCondition } from './condition/index.js';
import type { UmbEntryPointModule } from './models/index.js';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type HTMLElementConstructor<T = HTMLElement> = new (...args: any[]) => T;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ClassConstructor<T = object> = new (...args: any[]) => T;
export type ManifestTypeMap<ManifestTypes extends ManifestBase> = {
[Manifest in ManifestTypes as Manifest['type']]: Manifest;
} & {
[key: string]: ManifestBase;
};
export type SpecificManifestTypeOrManifestBase<
ManifestTypes extends ManifestBase,
T extends keyof ManifestTypeMap<ManifestTypes> | string
> = T extends keyof ManifestTypeMap<ManifestTypes> ? ManifestTypeMap<ManifestTypes>[T] : ManifestBase;
export interface ManifestBase {
/**
* The type of extension such as dashboard etc...
*/
type: string;
/**
* The alias of the extension, ensure it is unique
*/
alias: string;
/**
* The kind of the extension, used to group extensions together
*
* @examples ["button"]
*/
kind?: unknown; // I had to add the optional kind property set to undefined. To make the ManifestTypes recognize the Manifest Kind types. Notice that Kinds has to Omit the kind property when extending.
/**
* The friendly name of the extension
*/
name: string;
/**
* Extensions such as dashboards are ordered by weight with lower numbers being first in the list
*/
weight?: number;
}
export interface ManifestKind<ManifestTypes> {
type: 'kind';
alias: string;
matchType: string;
matchKind: string;
manifest: Partial<ManifestTypes>;
}
// TODO: Get rid of this type and implements ManifestWithDynamicConditions instead.
export interface ManifestWithConditions<ConditionType> {
/**
* Set the conditions for when the extension should be loaded
*/
conditions: ConditionType;
}
export interface UmbConditionConfigBase<AliasType extends string = string> {
alias: AliasType;
}
export type ConditionTypeMap<ConditionTypes extends UmbConditionConfigBase> = {
[Condition in ConditionTypes as Condition['alias']]: Condition;
} & {
[key: string]: UmbConditionConfigBase;
};
export type SpecificConditionTypeOrUmbConditionConfigBase<
ConditionTypes extends UmbConditionConfigBase,
T extends keyof ConditionTypeMap<ConditionTypes> | string
> = T extends keyof ConditionTypeMap<ConditionTypes> ? ConditionTypeMap<ConditionTypes>[T] : UmbConditionConfigBase;
export interface ManifestWithDynamicConditions<ConditionTypes extends UmbConditionConfigBase = UmbConditionConfigBase>
extends ManifestBase {
/**
* Set the conditions for when the extension should be loaded
*/
conditions?: Array<ConditionTypes>;
/**
* Define one or more extension aliases that this extension should overwrite.
*/
overwrites?: string | Array<string>;
}
export interface ManifestWithLoader<LoaderReturnType> extends ManifestBase {
/**
* @TJS-ignore
*/
loader?(): Promise<LoaderReturnType>;
}
// TODO: Rename this to something more descriptive:
export interface UmbApi {
destroy?(): void;
}
/**
* The type of extension such as dashboard etc...
*/
export interface ManifestApi<ApiType extends UmbApi = UmbApi>
extends ManifestWithLoader<{ default: ClassConstructor<ApiType> } | { api: ClassConstructor<ApiType> }> {
/**
* @TJS-ignore
*/
readonly API_TYPE?: ApiType;
/**
* The file location of the javascript file to load
* @TJS-required
*/
js?: string;
/**
* @TJS-ignore
*/
apiName?: string;
/**
* @TJS-ignore
*/
api?: ClassConstructor<ApiType>;
}
export interface ManifestWithLoaderIncludingDefaultExport<T = unknown>
extends ManifestWithLoader<{ default: T } | { element: T } | Omit<object, 'default'>> {
/**
* The file location of the javascript file to load
*/
js?: string;
}
export interface ManifestWithLoaderIncludingApiExport<ApiType extends UmbApi = UmbApi>
extends ManifestWithLoader<{ api: ApiType } | Omit<object, 'api'>> {
/**
* The file location of the javascript file to load
*/
js?: string;
/**
* The file location of the API javascript file to load
*/
apiJs?: string;
}
export interface ManifestWithLoaderIncludingElementExport<ElementType extends HTMLElement = HTMLElement>
extends ManifestWithLoader<{ element: ElementType } | Omit<object, 'element'>> {
/**
* The file location of the javascript file to load
*/
js?: string;
/**
* The file location of the element javascript file to load
*/
elementJs?: string;
}
export interface ManifestWithLoaderOptionalApiOrElementExport<
ElementType extends HTMLElement = HTMLElement,
ApiType extends UmbApi = UmbApi,
ClassType = { element: ElementType } | { api: ApiType } | { element: ElementType, api: ApiType } | Omit<Omit<object, 'element'>, 'api'>
>
extends ManifestWithLoader<ClassType> {
/**
* The file location of the javascript file to load
*/
js?: string;
/**
* The file location of the element javascript file to load
*/
elementJs?: string;
/**
* The file location of the API javascript file to load
*/
apiJs?: string;
}
export interface ManifestElement<ElementType extends HTMLElement = HTMLElement>
extends ManifestWithLoader<{ default: ClassConstructor<ElementType> } | Omit<object, 'default'>> {
/**
* @TJS-ignore
*/
readonly ELEMENT_TYPE?: ElementType;
/**
* The file location of the javascript file to load
*
* @TJS-require
*/
js?: string;
/**
* The HTML web component name to use such as 'my-dashboard'
* Note it is NOT <my-dashboard></my-dashboard>, just the element name.
*/
elementName?: string;
/**
* This contains properties specific to the type of extension
*/
meta?: unknown;
}
export interface ManifestElementAndApi<ElementType extends HTMLElement = HTMLElement, ApiType extends UmbApi = UmbApi>
extends ManifestWithLoaderOptionalApiOrElementExport<ElementType, ApiType> {
/**
* @TJS-ignore
*/
readonly API_TYPE?: ApiType;
/**
* @TJS-ignore
*/
readonly ELEMENT_TYPE?: ElementType;
/**
* @TJS-ignore
*/
apiName?: string;
/**
* @TJS-ignore
*/
api?: ClassConstructor<ApiType>;
/**
* The HTML web component name to use such as 'my-dashboard'
* Note it is NOT <my-dashboard></my-dashboard>, just the element name.
*/
elementName?: string;
}
export interface ManifestWithView<ElementType extends HTMLElement = HTMLElement> extends ManifestElement<ElementType> {
meta: MetaManifestWithView;
}
export interface MetaManifestWithView {
pathname: string;
label: string;
icon: string;
}
export interface ManifestElementWithElementName extends ManifestElement {
/**
* The HTML web component name to use such as 'my-dashboard'
* Note it is NOT <my-dashboard></my-dashboard> but just the name
*/
elementName: string;
}
export interface ManifestWithMeta extends ManifestBase {
/**
* This contains properties specific to the type of extension
*/
meta: unknown;
}
/**
* This type of extension gives full control and will simply load the specified JS file
* You could have custom logic to decide which extensions to load/register by using extensionRegistry
*/
export interface ManifestEntryPoint extends ManifestWithLoader<UmbEntryPointModule> {
type: 'entryPoint';
/**
* The file location of the javascript file to load in the backoffice
*/
js?: string;
}
/**
* This type of extension takes a JS module and registers all exported manifests from the pointed JS file.
*/
export interface ManifestBundle<UmbManifestTypes extends ManifestBase = ManifestBase>
extends ManifestWithLoader<{ [key: string]: Array<UmbManifestTypes> }> {
type: 'bundle';
/**
* The file location of the javascript file to load in the backoffice
*/
js?: string;
}
/**
* This type of extension takes a JS module and registers all exported manifests from the pointed JS file.
*/
export interface ManifestCondition extends ManifestApi<UmbExtensionCondition> {
type: 'condition';
/**
* The file location of the javascript file to load in the backoffice
*/
js?: string;
}

View File

@@ -0,0 +1,125 @@
import type { UmbApi } from "../models/index.js";
import type { ManifestBase } from "./manifest-base.interface.js";
import type { ApiLoaderProperty, ClassConstructor, ElementAndApiLoaderProperty, ElementLoaderProperty } from "./utils.js";
export interface ManifestWithView<ElementType extends HTMLElement = HTMLElement> extends ManifestElement<ElementType> {
meta: MetaManifestWithView;
}
export interface MetaManifestWithView {
pathname: string;
label: string;
icon: string;
}
export interface ManifestElementWithElementName extends ManifestElement {
/**
* The HTML web component name to use such as 'my-dashboard'
* Note it is NOT <my-dashboard></my-dashboard> but just the name
*/
elementName: string;
}
export interface ManifestPlainJs<JsType = unknown> extends ManifestBase {
/**
* The file location of the javascript file to load
* @TJS-type string
*/
js?: string | Promise<{ default: ClassConstructor<JsType> }> | ClassConstructor<JsType>;
}
/**
* The type of extension such as dashboard etc...
*/
export interface ManifestApi<ApiType extends UmbApi = UmbApi> extends ManifestBase {
/**
* @TJS-ignore
*/
readonly API_TYPE?: ApiType;
/**
* The file location of the javascript file to load
* @TJS-type string
*/
js?: ApiLoaderProperty<ApiType>;
/**
* @TJS-ignore
*/
api?: ApiLoaderProperty<ApiType>;
}
export interface ManifestElement<ElementType extends HTMLElement = HTMLElement> extends ManifestBase {
/**
* @TJS-ignore
*/
readonly ELEMENT_TYPE?: ElementType;
/**
* The file location of the javascript file to load
* @TJS-type string
*/
js?: ElementLoaderProperty<ElementType>;
/**
* The file location of the element javascript file to load
* @TJS-type string
*/
element?: ElementLoaderProperty<ElementType>;
/**
* The HTML web component name to use such as 'my-dashboard'
* Note it is NOT <my-dashboard></my-dashboard>, just the element name.
*/
elementName?: string;
/**
* This contains properties specific to the type of extension
*/
meta?: unknown;
}
export interface ManifestElementAndApi<ElementType extends HTMLElement = HTMLElement, ApiType extends UmbApi = UmbApi> extends ManifestBase {
/**
* @TJS-ignore
*/
readonly API_TYPE?: ApiType;
/**
* @TJS-ignore
*/
readonly ELEMENT_TYPE?: ElementType;
/**
* The file location of the javascript file to load
* @TJS-type string
*/
js?: ElementAndApiLoaderProperty<ElementType, ApiType>;
/**
* The file location of the api javascript file to load
* @TJS-type string
*/
api?: ApiLoaderProperty<ApiType>;
/**
* The file location of the element javascript file to load
* @TJS-type string
*/
element?: ElementLoaderProperty<ElementType>;
/**
* The HTML web component name to use such as 'my-dashboard'
* Note it is NOT <my-dashboard></my-dashboard>, just the element name.
*/
elementName?: string;
}

View File

@@ -0,0 +1,28 @@
import type { ManifestBase } from "./manifest-base.interface.js";
export interface UmbConditionConfigBase<AliasType extends string = string> {
alias: AliasType;
}
export type ConditionTypeMap<ConditionTypes extends UmbConditionConfigBase> = {
[Condition in ConditionTypes as Condition['alias']]: Condition;
} & {
[key: string]: UmbConditionConfigBase;
};
export type SpecificConditionTypeOrUmbConditionConfigBase<
ConditionTypes extends UmbConditionConfigBase,
T extends keyof ConditionTypeMap<ConditionTypes> | string
> = T extends keyof ConditionTypeMap<ConditionTypes> ? ConditionTypeMap<ConditionTypes>[T] : UmbConditionConfigBase;
export interface ManifestWithDynamicConditions<ConditionTypes extends UmbConditionConfigBase = UmbConditionConfigBase>
extends ManifestBase {
/**
* Set the conditions for when the extension should be loaded
*/
conditions?: Array<ConditionTypes>;
/**
* Define one or more extension aliases that this extension should overwrite.
*/
overwrites?: string | Array<string>;
}

View File

@@ -0,0 +1,8 @@
export * from './base.types.js';
export * from './condition.types.js';
export * from './manifest-base.interface.js';
export * from './manifest-bundle.interface.js';
export * from './manifest-condition.interface.js';
export * from './manifest-entrypoint.interface.js';
export * from './manifest-kind.interface.js';
export * from './utils.js';

View File

@@ -0,0 +1,29 @@
export interface ManifestBase {
/**
* The type of extension such as dashboard etc...
*/
type: string;
/**
* The alias of the extension, ensure it is unique
*/
alias: string;
/**
* The kind of the extension, used to group extensions together
*
* @examples ["button"]
*/
kind?: unknown; // I had to add the optional kind property set to undefined. To make the ManifestTypes recognize the Manifest Kind types. Notice that Kinds has to Omit the kind property when extending.
/**
* The friendly name of the extension
*/
name: string;
/**
* Extensions such as dashboards are ordered by weight with lower numbers being first in the list
*/
weight?: number;
}

View File

@@ -0,0 +1,11 @@
import type { ManifestPlainJs } from "./base.types.js";
import type { ManifestBase } from "./manifest-base.interface.js";
/**
* This type of extension takes a JS module and registers all exported manifests from the pointed JS file.
*/
export interface ManifestBundle<UmbManifestTypes extends ManifestBase = ManifestBase>
extends ManifestPlainJs<{ [key: string]: Array<UmbManifestTypes> }> {
type: 'bundle';
}

View File

@@ -0,0 +1,9 @@
import type { UmbExtensionCondition } from "../condition/index.js";
import type { ManifestPlainJs } from "./base.types.js";
/**
* This type of extension takes a JS module and registers all exported manifests from the pointed JS file.
*/
export interface ManifestCondition extends ManifestPlainJs<UmbExtensionCondition> {
type: 'condition';
}

View File

@@ -0,0 +1,10 @@
import type { UmbEntryPointModule } from "../models/index.js";
import type { ManifestPlainJs } from "./base.types.js";
/**
* This type of extension gives full control and will simply load the specified JS file
* You could have custom logic to decide which extensions to load/register by using extensionRegistry
*/
export interface ManifestEntryPoint extends ManifestPlainJs<UmbEntryPointModule> {
type: 'entryPoint';
}

View File

@@ -0,0 +1,8 @@
export interface ManifestKind<ManifestTypes> {
type: 'kind';
alias: string;
matchType: string;
matchKind: string;
manifest: Partial<ManifestTypes>;
}

View File

@@ -0,0 +1,12 @@
import type { ManifestBase } from "./manifest-base.interface.js";
export type ManifestTypeMap<ManifestTypes extends ManifestBase> = {
[Manifest in ManifestTypes as Manifest['type']]: Manifest;
} & {
[key: string]: ManifestBase;
};
export type SpecificManifestTypeOrManifestBase<
ManifestTypes extends ManifestBase,
T extends keyof ManifestTypeMap<ManifestTypes> | string
> = T extends keyof ManifestTypeMap<ManifestTypes> ? ManifestTypeMap<ManifestTypes>[T] : ManifestBase;

View File

@@ -0,0 +1,71 @@
import type { UmbApi } from "../models/index.js";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type HTMLElementConstructor<T = HTMLElement> = new (...args: any[]) => T;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ClassConstructor<T = object> = new (...args: any[]) => T;
// Module Export Types:
export type ElementLoaderExports<
ElementType extends HTMLElement = HTMLElement
> = ({default: ClassConstructor<ElementType>} | {element: ClassConstructor<ElementType>})// | Omit<Omit<object, 'element'>, 'default'>
export type ApiLoaderExports<
ApiType extends UmbApi = UmbApi
> = ({default: ClassConstructor<ApiType>} | {api: ClassConstructor<ApiType>})//| Omit<Omit<object, 'api'>, 'default'>
export type ElementAndJsLoaderExports<
ElementType extends HTMLElement = HTMLElement,
ApiType extends UmbApi = UmbApi
> = ({api: ClassConstructor<ApiType>} | {element: ClassConstructor<ElementType>} | {api: ClassConstructor<ApiType>, element: ClassConstructor<ElementType>})// | Omit<Omit<Omit<object, 'element'>, 'api'>, 'default'>
// Promise Types:
export type ElementLoaderPromise<
ElementType extends HTMLElement = HTMLElement
> = (() => Promise<ElementLoaderExports<ElementType>>)
export type ApiLoaderPromise<
ApiType extends UmbApi = UmbApi
> = (() => Promise<ApiLoaderExports<ApiType>>)
export type ElementAndJsLoaderPromise<
ElementType extends HTMLElement = HTMLElement,
ApiType extends UmbApi = UmbApi
> = (() => Promise<ElementAndJsLoaderExports<ElementType, ApiType>>)
// Property Types:
export type JsLoaderProperty<JsType = unknown> = (
string
|
(() => Promise<{default: JsType}>)// | Omit<object, 'default'>
|
JsType
);
export type ElementLoaderProperty<ElementType extends HTMLElement = HTMLElement> = (
string
|
ElementLoaderPromise<ElementType>
|
ClassConstructor<ElementType>
);
export type ApiLoaderProperty<ApiType extends UmbApi = UmbApi> = (
string
|
ApiLoaderPromise<ApiType>
|
ClassConstructor<ApiType>
);
export type ElementAndApiLoaderProperty<ElementType extends HTMLElement = HTMLElement, ApiType extends UmbApi = UmbApi> = (
string
|
ElementAndJsLoaderPromise<ElementType, ApiType>
);

View File

@@ -5,7 +5,7 @@ const modals: Array<ManifestModal> = [
type: 'modal',
alias: 'Umb.Modal.ContextDebugger',
name: 'Context Debugger Modal',
loader: () => import('./modals/debug/debug-modal.element.js'),
js: () => import('./modals/debug/debug-modal.element.js'),
},
];

View File

@@ -1,6 +1,7 @@
import type { ManifestElement, ManifestWithConditions } from '@umbraco-cms/backoffice/extension-api';
import type { ConditionTypes } from '../conditions/types.js';
import type { ManifestElement, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api';
export interface ManifestCollectionView extends ManifestElement, ManifestWithConditions<ConditionsCollectionView> {
export interface ManifestCollectionView extends ManifestElement, ManifestWithDynamicConditions<ConditionTypes> {
type: 'collectionView';
meta: MetaCollectionView;
}

View File

@@ -1,7 +1,7 @@
import type { ManifestWithLoaderIncludingDefaultExport } from '@umbraco-cms/backoffice/extension-api';
import type { ManifestPlainJs } from '@umbraco-cms/backoffice/extension-api';
import type { UmbLocalizationDictionary } from '@umbraco-cms/backoffice/localization-api';
export interface ManifestLocalization extends ManifestWithLoaderIncludingDefaultExport<UmbLocalizationDictionary> {
export interface ManifestLocalization extends ManifestPlainJs<UmbLocalizationDictionary> {
type: 'localization';
meta: MetaLocalization;
}

View File

@@ -1,10 +1,11 @@
import type { ManifestElementAndApi, UmbApi } from '@umbraco-cms/backoffice/extension-api';
// TODO: Missing Extension API Interface:
export interface ManifestWorkspace extends ManifestElementAndApi<HTMLElement, UmbApi> {
type: 'workspace';
meta: MetaEditor;
meta: MetaWorkspace;
}
export interface MetaEditor {
export interface MetaWorkspace {
entityType: string;
}

View File

@@ -10,7 +10,7 @@ const localizationManifests: Array<ManifestLocalization> = [
meta: {
culture: 'en-us',
},
loader: () => import('../../../assets/lang/en-us.js'),
js: () => import('../../../assets/lang/en-us.js'),
},
{
type: 'localization',
@@ -20,7 +20,7 @@ const localizationManifests: Array<ManifestLocalization> = [
meta: {
culture: 'da-dk',
},
loader: () => import('../../../assets/lang/da-dk.js'),
js: () => import('../../../assets/lang/da-dk.js'),
},
];

View File

@@ -5,61 +5,61 @@ const modals: Array<ManifestModal> = [
type: 'modal',
alias: 'Umb.Modal.Confirm',
name: 'Confirm Modal',
loader: () => import('./confirm/confirm-modal.element.js'),
js: () => import('./confirm/confirm-modal.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.Folder',
name: 'Folder Modal',
loader: () => import('./folder/folder-modal.element.js'),
js: () => import('./folder/folder-modal.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.IconPicker',
name: 'Icon Picker Modal',
loader: () => import('./icon-picker/icon-picker-modal.element.js'),
js: () => import('./icon-picker/icon-picker-modal.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.LinkPicker',
name: 'Link Picker Modal',
loader: () => import('./link-picker/link-picker-modal.element.js'),
js: () => import('./link-picker/link-picker-modal.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.PropertySettings',
name: 'Property Settings Modal',
loader: () => import('./property-settings/property-settings-modal.element.js'),
js: () => import('./property-settings/property-settings-modal.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.SectionPicker',
name: 'Section Picker Modal',
loader: () => import('./section-picker/section-picker-modal.element.js'),
js: () => import('./section-picker/section-picker-modal.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.Template',
name: 'Template Modal',
loader: () => import('./template/template-modal.element.js'),
js: () => import('./template/template-modal.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.CodeEditor',
name: 'Code Editor Modal',
loader: () => import('./code-editor/code-editor-modal.element.js'),
js: () => import('./code-editor/code-editor-modal.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.EmbeddedMedia',
name: 'Embedded Media Modal',
loader: () => import('./embedded-media/embedded-media-modal.element.js'),
js: () => import('./embedded-media/embedded-media-modal.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.TreePicker',
name: 'Tree Picker Modal',
loader: () => import('./tree-picker/tree-picker-modal.element.js'),
js: () => import('./tree-picker/tree-picker-modal.element.js'),
},
];

View File

@@ -5,7 +5,7 @@ export const manifests: Array<ManifestPropertyAction> = [
type: 'propertyAction',
alias: 'Umb.PropertyAction.Copy',
name: 'Copy Property Action',
loader: () => import('./common/copy/property-action-copy.element.js'),
js: () => import('./common/copy/property-action-copy.element.js'),
meta: {
propertyEditors: ['Umb.PropertyEditorUi.TextBox'],
},
@@ -14,7 +14,7 @@ export const manifests: Array<ManifestPropertyAction> = [
type: 'propertyAction',
alias: 'Umb.PropertyAction.Clear',
name: 'Clear Property Action',
loader: () => import('./common/clear/property-action-clear.element.js'),
js: () => import('./common/clear/property-action-clear.element.js'),
meta: {
propertyEditors: ['Umb.PropertyEditorUi.TextBox'],
},

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.BlockGrid.BlockConfiguration',
name: 'Block Grid Block Configuration Property Editor UI',
loader: () => import('./property-editor-ui-block-grid-block-configuration.element.js'),
js: () => import('./property-editor-ui-block-grid-block-configuration.element.js'),
meta: {
label: 'Block Grid Block Configuration',
propertyEditorSchemaAlias: 'Umbraco.BlockGrid.BlockConfiguration',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.BlockGrid.GroupConfiguration',
name: 'Block Grid Group Configuration Property Editor UI',
loader: () => import('./property-editor-ui-block-grid-group-configuration.element.js'),
js: () => import('./property-editor-ui-block-grid-group-configuration.element.js'),
meta: {
label: 'Block Grid Group Configuration',
propertyEditorSchemaAlias: 'Umbraco.BlockGrid.GroupConfiguration',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.BlockGrid.StylesheetPicker',
name: 'Block Grid Stylesheet Picker Property Editor UI',
loader: () => import('./property-editor-ui-block-grid-stylesheet-picker.element.js'),
js: () => import('./property-editor-ui-block-grid-stylesheet-picker.element.js'),
meta: {
label: 'Block Grid Stylesheet Picker',
propertyEditorSchemaAlias: '',

View File

@@ -7,7 +7,7 @@ const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.BlockGrid',
name: 'Block Grid Property Editor UI',
loader: () => import('./property-editor-ui-block-grid.element.js'),
js: () => import('./property-editor-ui-block-grid.element.js'),
meta: {
label: 'Block Grid',
propertyEditorSchemaAlias: 'Umbraco.BlockGrid',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.BlockList.BlockConfiguration',
name: 'Block List Block Configuration Property Editor UI',
loader: () => import('./property-editor-ui-block-list-block-configuration.element.js'),
js: () => import('./property-editor-ui-block-list-block-configuration.element.js'),
meta: {
label: 'Block List Block Configuration',
propertyEditorSchemaAlias: '',

View File

@@ -5,7 +5,7 @@ const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.BlockList',
name: 'Block List Property Editor UI',
loader: () => import('./property-editor-ui-block-list.element.js'),
js: () => import('./property-editor-ui-block-list.element.js'),
meta: {
label: 'Block List',
propertyEditorSchemaAlias: 'Umbraco.BlockList',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.CheckboxList',
name: 'Checkbox List Property Editor UI',
loader: () => import('./property-editor-ui-checkbox-list.element.js'),
js: () => import('./property-editor-ui-checkbox-list.element.js'),
meta: {
label: 'Checkbox List',
propertyEditorSchemaAlias: 'Umbraco.CheckboxList',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.CollectionView.BulkActionPermissions',
name: 'Collection View Bulk Action Permissions Property Editor UI',
loader: () => import('./property-editor-ui-collection-view-bulk-action-permissions.element.js'),
js: () => import('./property-editor-ui-collection-view-bulk-action-permissions.element.js'),
meta: {
label: 'Collection View Bulk Action Permissions',
propertyEditorSchemaAlias: '',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.CollectionView.ColumnConfiguration',
name: 'Collection View Column Configuration Property Editor UI',
loader: () => import('./property-editor-ui-collection-view-column-configuration.element.js'),
js: () => import('./property-editor-ui-collection-view-column-configuration.element.js'),
meta: {
label: 'Collection View Column Configuration',
propertyEditorSchemaAlias: '',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.CollectionView.LayoutConfiguration',
name: 'Collection View Column Configuration Property Editor UI',
loader: () => import('./property-editor-ui-collection-view-layout-configuration.element.js'),
js: () => import('./property-editor-ui-collection-view-layout-configuration.element.js'),
meta: {
label: 'Collection View Layout Configuration',
propertyEditorSchemaAlias: '',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.CollectionView.OrderBy',
name: 'Collection View Column Configuration Property Editor UI',
loader: () => import('./property-editor-ui-collection-view-order-by.element.js'),
js: () => import('./property-editor-ui-collection-view-order-by.element.js'),
meta: {
label: 'Collection View Order By',
propertyEditorSchemaAlias: '',

View File

@@ -8,7 +8,7 @@ const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.CollectionView',
name: 'Collection View Property Editor UI',
loader: () => import('./property-editor-ui-collection-view.element.js'),
js: () => import('./property-editor-ui-collection-view.element.js'),
meta: {
label: 'Collection View',
propertyEditorSchemaAlias: 'Umbraco.ListView',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.ColorPicker',
name: 'Color Picker Property Editor UI',
loader: () => import('./property-editor-ui-color-picker.element.js'),
js: () => import('./property-editor-ui-color-picker.element.js'),
meta: {
label: 'Color Picker',
propertyEditorSchemaAlias: 'Umbraco.ColorPicker',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.DatePicker',
name: 'Date Picker Property Editor UI',
loader: () => import('./property-editor-ui-date-picker.element.js'),
js: () => import('./property-editor-ui-date-picker.element.js'),
meta: {
label: 'Date Picker',
propertyEditorSchemaAlias: 'Umbraco.DateTime',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.Dropdown',
name: 'Dropdown Property Editor UI',
loader: () => import('./property-editor-ui-dropdown.element.js'),
js: () => import('./property-editor-ui-dropdown.element.js'),
meta: {
label: 'Dropdown',
propertyEditorSchemaAlias: 'Umbraco.Dropdown',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.EyeDropper',
name: 'Eye Dropper Color Picker Property Editor UI',
loader: () => import('./property-editor-ui-eye-dropper.element.js'),
js: () => import('./property-editor-ui-eye-dropper.element.js'),
meta: {
label: 'Eye Dropper Color Picker',
icon: 'icon-colorpicker',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.IconPicker',
name: 'Icon Picker Property Editor UI',
loader: () => import('./property-editor-ui-icon-picker.element.js'),
js: () => import('./property-editor-ui-icon-picker.element.js'),
meta: {
label: 'Icon Picker',
propertyEditorSchemaAlias: 'Umbraco.IconPicker',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.ImageCropper',
name: 'Image Cropper Property Editor UI',
loader: () => import('./property-editor-ui-image-cropper.element.js'),
js: () => import('./property-editor-ui-image-cropper.element.js'),
meta: {
label: 'Image Cropper',
icon: 'icon-colorpicker',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.ImageCropsConfiguration',
name: 'Image Crops Configuration Property Editor UI',
loader: () => import('./property-editor-ui-image-crops-configuration.element.js'),
js: () => import('./property-editor-ui-image-crops-configuration.element.js'),
meta: {
label: 'Image Crops Configuration',
icon: 'icon-autofill',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.Label',
name: 'Label Property Editor UI',
loader: () => import('./property-editor-ui-label.element.js'),
js: () => import('./property-editor-ui-label.element.js'),
meta: {
label: 'Label',
icon: 'icon-readonly',

View File

@@ -69,7 +69,7 @@ export const manifests: Array<ManifestPropertyEditorUi> = [
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.Number',
name: 'Number Property Editor UI',
loader: () => import('./number/property-editor-ui-number.element.js'),
js: () => import('./number/property-editor-ui-number.element.js'),
meta: {
label: 'Number',
icon: 'icon-autofill',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.MarkdownEditor',
name: 'Markdown Editor Property Editor UI',
loader: () => import('./property-editor-ui-markdown-editor.element.js'),
js: () => import('./property-editor-ui-markdown-editor.element.js'),
meta: {
label: 'Markdown Editor',
propertyEditorSchemaAlias: 'Umbraco.MarkdownEditor',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.MediaPicker',
name: 'Markdown Editor Property Editor UI',
loader: () => import('./property-editor-ui-media-picker.element.js'),
js: () => import('./property-editor-ui-media-picker.element.js'),
meta: {
label: 'Media Picker',
propertyEditorSchemaAlias: 'Umbraco.MediaPicker3',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.MemberGroupPicker',
name: 'Member Group Picker Property Editor UI',
loader: () => import('./property-editor-ui-member-group-picker.element.js'),
js: () => import('./property-editor-ui-member-group-picker.element.js'),
meta: {
label: 'Member Group Picker',
propertyEditorSchemaAlias: 'Umbraco.MemberGroupPicker',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.MemberPicker',
name: 'Member Picker Property Editor UI',
loader: () => import('./property-editor-ui-member-picker.element.js'),
js: () => import('./property-editor-ui-member-picker.element.js'),
meta: {
label: 'Member Picker',
propertyEditorSchemaAlias: 'Umbraco.MemberPicker',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.MultiUrlPicker',
name: 'Multi URL Picker Property Editor UI',
loader: () => import('./property-editor-ui-multi-url-picker.element.js'),
js: () => import('./property-editor-ui-multi-url-picker.element.js'),
meta: {
label: 'Multi URL Picker',
propertyEditorSchemaAlias: 'Umbraco.MultiUrlPicker',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.MultipleTextString',
name: 'Multiple Text String Property Editor UI',
loader: () => import('./property-editor-ui-multiple-text-string.element.js'),
js: () => import('./property-editor-ui-multiple-text-string.element.js'),
meta: {
label: 'Multiple Text String',
propertyEditorSchemaAlias: 'Umbraco.MultipleTextString',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.NumberRange',
name: 'Number Range Property Editor UI',
loader: () => import('./property-editor-ui-number-range.element.js'),
js: () => import('./property-editor-ui-number-range.element.js'),
meta: {
label: 'Number Range',
propertyEditorSchemaAlias: '',

View File

@@ -12,7 +12,7 @@ export const manifests: Array<ManifestPropertyEditorUi> = [
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.Integer',
name: 'Integer Property Editor UI',
loader: () => import('./property-editor-ui-number.element.js'),
js: () => import('./property-editor-ui-number.element.js'),
meta: {
label: 'Integer',
propertyEditorSchemaAlias: 'Umbraco.Integer',
@@ -33,7 +33,7 @@ export const manifests: Array<ManifestPropertyEditorUi> = [
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.Decimal',
name: 'Decimal Property Editor UI',
loader: () => import('./property-editor-ui-number.element.js'),
js: () => import('./property-editor-ui-number.element.js'),
meta: {
label: 'Decimal',
propertyEditorSchemaAlias: 'Umbraco.Decimal',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.OrderDirection',
name: 'Order Direction Property Editor UI',
loader: () => import('./property-editor-ui-order-direction.element.js'),
js: () => import('./property-editor-ui-order-direction.element.js'),
meta: {
label: 'Order Direction',
propertyEditorSchemaAlias: '',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.OverlaySize',
name: 'Overlay Size Property Editor UI',
loader: () => import('./property-editor-ui-overlay-size.element.js'),
js: () => import('./property-editor-ui-overlay-size.element.js'),
meta: {
label: 'Overlay Size',
propertyEditorSchemaAlias: '',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.RadioButtonList',
name: 'Radio Button List Property Editor UI',
loader: () => import('./property-editor-ui-radio-button-list.element.js'),
js: () => import('./property-editor-ui-radio-button-list.element.js'),
meta: {
label: 'Radio Button List',
propertyEditorSchemaAlias: 'Umbraco.RadioButtonList',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.Slider',
name: 'Slider Property Editor UI',
loader: () => import('./property-editor-ui-slider.element.js'),
js: () => import('./property-editor-ui-slider.element.js'),
meta: {
label: 'Slider',
propertyEditorSchemaAlias: 'Umbraco.Slider',

View File

@@ -13,7 +13,7 @@ export const manifests: Array<ManifestPropertyEditorUi> = [
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.TextBox',
name: 'Text Box Property Editor UI',
loader: () => import('./property-editor-ui-text-box.element.js'),
js: () => import('./property-editor-ui-text-box.element.js'),
meta: {
label: 'Text Box',
propertyEditorSchemaAlias: 'Umbraco.TextBox',
@@ -34,7 +34,7 @@ export const manifests: Array<ManifestPropertyEditorUi> = [
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.Email',
name: 'Email Property Editor UI',
loader: () => import('./property-editor-ui-text-box.element.js'),
js: () => import('./property-editor-ui-text-box.element.js'),
meta: {
label: 'Email',
propertyEditorSchemaAlias: 'Umbraco.EmailAddress',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.TextArea',
name: 'Text Area Property Editor UI',
loader: () => import('./property-editor-ui-textarea.element.js'),
js: () => import('./property-editor-ui-textarea.element.js'),
meta: {
label: 'Text Area',
propertyEditorSchemaAlias: 'Umbraco.TextArea',

View File

@@ -5,7 +5,7 @@ const configurationManifests: Array<ManifestPropertyEditorUi> = [
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUI.TinyMCE.ToolbarConfiguration',
name: 'TinyMCE Toolbar Property Editor UI',
loader: () => import('./toolbar/property-editor-ui-tiny-mce-toolbar-configuration.element.js'),
js: () => import('./toolbar/property-editor-ui-tiny-mce-toolbar-configuration.element.js'),
meta: {
label: 'TinyMCE Toolbar Configuration',
propertyEditorSchemaAlias: 'Umbraco.RichText.Configuration',
@@ -17,7 +17,7 @@ const configurationManifests: Array<ManifestPropertyEditorUi> = [
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUI.TinyMCE.StylesheetsConfiguration',
name: 'TinyMCE Stylesheets Property Editor UI',
loader: () => import('./stylesheets/property-editor-ui-tiny-mce-stylesheets-configuration.element.js'),
js: () => import('./stylesheets/property-editor-ui-tiny-mce-stylesheets-configuration.element.js'),
meta: {
label: 'TinyMCE Stylesheets Configuration',
propertyEditorSchemaAlias: 'Umbraco.RichText.Configuration',
@@ -29,7 +29,7 @@ const configurationManifests: Array<ManifestPropertyEditorUi> = [
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUI.TinyMCE.DimensionsConfiguration',
name: 'TinyMCE Dimensions Property Editor UI',
loader: () => import('./dimensions/property-editor-ui-tiny-mce-dimensions-configuration.element.js'),
js: () => import('./dimensions/property-editor-ui-tiny-mce-dimensions-configuration.element.js'),
meta: {
label: 'TinyMCE Dimensions Configuration',
propertyEditorSchemaAlias: 'Umbraco.RichText.Configuration',
@@ -41,7 +41,7 @@ const configurationManifests: Array<ManifestPropertyEditorUi> = [
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUI.TinyMCE.MaxImageSizeConfiguration',
name: 'TinyMCE Max Image Size Property Editor UI',
loader: () => import('./max-image-size/property-editor-ui-tiny-mce-maximagesize-configuration.element.js'),
js: () => import('./max-image-size/property-editor-ui-tiny-mce-maximagesize-configuration.element.js'),
meta: {
label: 'TinyMCE Max Image Size Configuration',
propertyEditorSchemaAlias: 'Umbraco.RichText.Configuration',

View File

@@ -5,7 +5,7 @@ const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.TinyMCE',
name: 'Rich Text Editor Property Editor UI',
loader: () => import('./property-editor-ui-tiny-mce.element.js'),
js: () => import('./property-editor-ui-tiny-mce.element.js'),
meta: {
label: 'Rich Text Editor',
propertyEditorSchemaAlias: 'Umbraco.RichText',

View File

@@ -5,7 +5,7 @@ const pluginManifests: Array<ManifestTinyMcePlugin> = [
type: 'tinyMcePlugin',
alias: 'Umb.TinyMcePlugin.CodeEditor',
name: 'Code Editor TinyMCE Plugin',
loader: () => import('./tiny-mce-code-editor.plugin.js'),
js: () => import('./tiny-mce-code-editor.plugin.js'),
meta: {
toolbar: [
{
@@ -20,7 +20,7 @@ const pluginManifests: Array<ManifestTinyMcePlugin> = [
type: 'tinyMcePlugin',
alias: 'Umb.TinyMcePlugin.LinkPicker',
name: 'Link Picker TinyMCE Plugin',
loader: () => import('./tiny-mce-linkpicker.plugin.js'),
js: () => import('./tiny-mce-linkpicker.plugin.js'),
meta: {
toolbar: [
{
@@ -40,7 +40,7 @@ const pluginManifests: Array<ManifestTinyMcePlugin> = [
type: 'tinyMcePlugin',
alias: 'Umb.TinyMcePlugin.MediaPicker',
name: 'Media Picker TinyMCE Plugin',
loader: () => import('./tiny-mce-mediapicker.plugin.js'),
js: () => import('./tiny-mce-mediapicker.plugin.js'),
meta: {
toolbar: [
{
@@ -55,7 +55,7 @@ const pluginManifests: Array<ManifestTinyMcePlugin> = [
type: 'tinyMcePlugin',
alias: 'Umb.TinyMcePlugin.EmbeddedMedia',
name: 'Embedded Media TinyMCE Plugin',
loader: () => import('./tiny-mce-embeddedmedia.plugin.js'),
js: () => import('./tiny-mce-embeddedmedia.plugin.js'),
meta: {
toolbar: [
{
@@ -70,7 +70,7 @@ const pluginManifests: Array<ManifestTinyMcePlugin> = [
type: 'tinyMcePlugin',
alias: 'Umb.TinyMcePlugin.MacroPicker',
name: 'Macro Picker TinyMCE Plugin',
loader: () => import('./tiny-mce-macropicker.plugin.js'),
js: () => import('./tiny-mce-macropicker.plugin.js'),
meta: {
toolbar: [
{

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.Toggle',
name: 'Toggle Property Editor UI',
loader: () => import('./property-editor-ui-toggle.element.js'),
js: () => import('./property-editor-ui-toggle.element.js'),
meta: {
label: 'Toggle',
propertyEditorSchemaAlias: 'Umbraco.TrueFalse',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.TreePicker.StartNode',
name: 'Tree Picker Start Node Property Editor UI',
loader: () => import('./property-editor-ui-tree-picker-start-node.element.js'),
js: () => import('./property-editor-ui-tree-picker-start-node.element.js'),
meta: {
label: 'Tree Picker Start Node',
icon: 'icon-page-add',

View File

@@ -5,7 +5,7 @@ const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.TreePicker',
name: 'Tree Picker Property Editor UI',
loader: () => import('./property-editor-ui-tree-picker.element.js'),
js: () => import('./property-editor-ui-tree-picker.element.js'),
meta: {
label: 'Tree Picker',
icon: 'icon-page-add',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.UploadField',
name: 'Upload Field Property Editor UI',
loader: () => import('./property-editor-ui-upload-field.element.js'),
js: () => import('./property-editor-ui-upload-field.element.js'),
meta: {
label: 'Upload Field',
propertyEditorSchemaAlias: 'Umbraco.UploadField',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.UserPicker',
name: 'User Picker Property Editor UI',
loader: () => import('./property-editor-ui-user-picker.element.js'),
js: () => import('./property-editor-ui-user-picker.element.js'),
meta: {
label: 'User Picker',
propertyEditorSchemaAlias: 'Umbraco.UserPicker',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.ValueType',
name: 'Value Type Property Editor UI',
loader: () => import('./property-editor-ui-value-type.element.js'),
js: () => import('./property-editor-ui-value-type.element.js'),
meta: {
label: 'Value Type',
icon: 'icon-autofill',

View File

@@ -5,7 +5,7 @@ export const themes: Array<ManifestTypes> = [
type: 'globalContext',
alias: 'Umb.GlobalContext.Theme',
name: 'Theme Context',
loader: () => import('./theme.context.js'),
js: () => import('./theme.context.js'),
},
{
type: 'theme',

View File

@@ -7,6 +7,6 @@ export const extensions: Array<ManifestTypes> = [
name: 'Core Entry Point',
alias: 'Umb.EntryPoint.Core',
type: 'entryPoint',
loader: () => import('./index.js'),
js: () => import('./index.js'),
},
];

View File

@@ -4,7 +4,7 @@ const workspaceModal: ManifestModal = {
type: 'modal',
alias: 'Umb.Modal.Workspace',
name: 'Workspace Modal',
loader: () => import('./workspace-modal.element.js'),
js: () => import('./workspace-modal.element.js'),
};
export const manifests = [workspaceModal];

View File

@@ -95,19 +95,19 @@ const modals: Array<ManifestModal> = [
type: 'modal',
alias: 'Umb.Modal.CreateDictionary',
name: 'Create Dictionary Modal',
loader: () => import('./create/create-dictionary-modal.element.js'),
js: () => import('./create/create-dictionary-modal.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.ExportDictionary',
name: 'Export Dictionary Modal',
loader: () => import('./export/export-dictionary-modal.element.js'),
js: () => import('./export/export-dictionary-modal.element.js'),
},
{
type: 'modal',
alias: 'Umb.Modal.ImportDictionary',
name: 'Import Dictionary Modal',
loader: () => import('./import/import-dictionary-modal.element.js'),
js: () => import('./import/import-dictionary-modal.element.js'),
},
];

View File

@@ -5,7 +5,7 @@ const menuItem: ManifestMenuItem = {
alias: 'Umb.MenuItem.Dictionary',
name: 'Dictionary Menu Item',
weight: 400,
loader: () => import('./dictionary-menu-item.element.js'),
js: () => import('./dictionary-menu-item.element.js'),
meta: {
label: 'Dictionary',
icon: 'icon-book-alt',

View File

@@ -9,7 +9,7 @@ const workspace: ManifestWorkspace = {
type: 'workspace',
alias: 'Umb.Workspace.Dictionary',
name: 'Dictionary Workspace',
loader: () => import('./dictionary-workspace.element.js'),
js: () => import('./dictionary-workspace.element.js'),
meta: {
entityType: 'dictionary-item',
},
@@ -20,7 +20,7 @@ const workspaceViews: Array<ManifestWorkspaceEditorView> = [
type: 'workspaceEditorView',
alias: 'Umb.WorkspaceView.Dictionary.Edit',
name: 'Dictionary Workspace Edit View',
loader: () => import('./views/editor/workspace-view-dictionary-editor.element.js'),
js: () => import('./views/editor/workspace-view-dictionary-editor.element.js'),
weight: 100,
meta: {
label: 'Edit',

View File

@@ -37,7 +37,7 @@ const dashboards: Array<ManifestDashboard> = [
alias: 'Umb.Dashboard.LocalizationDictionary',
name: 'Dictionary localization Dashboard',
elementName: 'umb-dashboard-translation-dictionary',
loader: () => import('./dashboards/dictionary/dashboard-localization-dictionary.element.js'),
js: () => import('./dashboards/dictionary/dashboard-localization-dictionary.element.js'),
meta: {
label: 'Dictionary overview',
pathname: '',

View File

@@ -4,6 +4,6 @@ export const extensions = [
name: 'Dictionary Management Bundle',
alias: 'Umb.Dictionary.TranslationManagement',
type: 'bundle',
loader: () => import('./manifests.js'),
js: () => import('./manifests.js'),
},
];

View File

@@ -5,7 +5,7 @@ const dashboards: Array<ManifestDashboard> = [
type: 'dashboard',
alias: 'Umb.Dashboard.RedirectManagement',
name: 'Redirect Management Dashboard',
loader: () => import('./redirect-management/dashboard-redirect-management.element.js'),
js: () => import('./redirect-management/dashboard-redirect-management.element.js'),
weight: 10,
meta: {
label: 'Redirect Management',

View File

@@ -8,7 +8,7 @@ const workspace: ManifestWorkspace = {
type: 'workspace',
alias: 'Umb.Workspace.DocumentBlueprint.Root',
name: 'Document Blueprint Root Workspace',
loader: () => import('./document-blueprint-root-workspace.element.js'),
js: () => import('./document-blueprint-root-workspace.element.js'),
meta: {
entityType: 'document-blueprint-root',
},

View File

@@ -25,7 +25,7 @@ const entityActions: Array<ManifestTypes> = [
type: 'modal',
alias: 'Umb.Modal.DocumentTypeCreateOptions',
name: 'Document Type Create Options Modal',
loader: () => import('./modal/document-type-create-options-modal.element.js'),
js: () => import('./modal/document-type-create-options-modal.element.js'),
},
];

View File

@@ -9,7 +9,7 @@ const workspace: ManifestWorkspace = {
type: 'workspace',
alias: 'Umb.Workspace.DocumentType',
name: 'Document Type Workspace',
loader: () => import('./document-type-workspace.element.js'),
js: () => import('./document-type-workspace.element.js'),
meta: {
entityType: 'document-type',
},
@@ -20,7 +20,7 @@ const workspaceEditorViews: Array<ManifestWorkspaceEditorView> = [
type: 'workspaceEditorView',
alias: 'Umb.WorkspaceView.DocumentType.Design',
name: 'Document Type Workspace Design View',
loader: () => import('./views/design/document-type-workspace-view-edit.element.js'),
js: () => import('./views/design/document-type-workspace-view-edit.element.js'),
weight: 1000,
meta: {
label: 'Design',
@@ -38,7 +38,7 @@ const workspaceEditorViews: Array<ManifestWorkspaceEditorView> = [
type: 'workspaceEditorView',
alias: 'Umb.WorkspaceView.DocumentType.Structure',
name: 'Document Type Workspace Structure View',
loader: () => import('./views/structure/document-type-workspace-view-structure.element.js'),
js: () => import('./views/structure/document-type-workspace-view-structure.element.js'),
weight: 800,
meta: {
label: 'Structure',
@@ -56,7 +56,7 @@ const workspaceEditorViews: Array<ManifestWorkspaceEditorView> = [
type: 'workspaceEditorView',
alias: 'Umb.WorkspaceView.DocumentType.Settings',
name: 'Document Type Workspace Settings View',
loader: () => import('./views/settings/document-type-workspace-view-settings.element.js'),
js: () => import('./views/settings/document-type-workspace-view-settings.element.js'),
weight: 600,
meta: {
label: 'Settings',
@@ -74,7 +74,7 @@ const workspaceEditorViews: Array<ManifestWorkspaceEditorView> = [
type: 'workspaceEditorView',
alias: 'Umb.WorkspaceView.DocumentType.Templates',
name: 'Document Type Workspace Templates View',
loader: () => import('./views/templates/document-type-workspace-view-templates.element.js'),
js: () => import('./views/templates/document-type-workspace-view-templates.element.js'),
weight: 400,
meta: {
label: 'Templates',

View File

@@ -5,11 +5,12 @@ export const manifests: Array<ManifestCollectionView> = [
type: 'collectionView',
alias: 'Umb.CollectionView.Document.Table',
name: 'Document Table Collection View',
loader: () => import('./views/table/document-table-collection-view.element.js'),
js: () => import('./views/table/document-table-collection-view.element.js'),
weight: 200,
conditions: {
entityType: 'document',
},
conditions: [{
alias: 'Umb.Condition.WorkspaceEntityType',
match: 'document',
}],
meta: {
label: 'Table',
icon: 'icon-box',

View File

@@ -35,7 +35,7 @@ const modals: Array<ManifestModal> = [
type: 'modal',
alias: 'Umb.Modal.CreateDocument',
name: 'Create Document Modal',
loader: () => import('./create-document-modal.element.js'),
js: () => import('./create-document-modal.element.js'),
},
];

View File

@@ -23,7 +23,7 @@ const modals: Array<ManifestModal> = [
type: 'modal',
alias: 'Umb.Modal.Permissions',
name: 'Permissions Modal',
loader: () => import('./permissions-modal.element.js'),
js: () => import('./permissions-modal.element.js'),
},
];

View File

@@ -5,7 +5,7 @@ const menuItem: ManifestMenuItem = {
alias: 'Umb.MenuItem.Documents',
name: 'Documents Menu Item',
weight: 200,
loader: () => import('./document-menu-item.element.js'),
js: () => import('./document-menu-item.element.js'),
meta: {
label: 'Documents',
icon: 'icon-folder',

View File

@@ -4,7 +4,7 @@ export const manifest: ManifestPropertyEditorUi = {
type: 'propertyEditorUi',
alias: 'Umb.PropertyEditorUi.DocumentPicker',
name: 'Document Picker Property Editor UI',
loader: () => import('./property-editor-ui-document-picker.element.js'),
js: () => import('./property-editor-ui-document-picker.element.js'),
meta: {
label: 'Document Picker',
propertyEditorSchemaAlias: 'Umbraco.ContentPicker',

View File

@@ -16,7 +16,7 @@ const treeItem: ManifestTreeItem = {
type: 'treeItem',
alias: 'Umb.TreeItem.Document',
name: 'Document Tree Item',
loader: () => import('./tree-item/document-tree-item.element.js'),
js: () => import('./tree-item/document-tree-item.element.js'),
meta: {
entityTypes: ['document-root', 'document'],
},

View File

@@ -21,9 +21,10 @@ export class UmbDocumentWorkspaceElement extends UmbLitElement {
public set manifest(manifest: ManifestWorkspace) {
console.log("got manifest", manifest)
console.log("got manifest", manifest.alias)
// TODO: Make context declaration.
createExtensionApi(this.manifest, [this]).then( (context) => {
createExtensionApi(manifest, [this]).then( (context) => {
if(context) {
this.#gotWorkspaceContext(context);
}

View File

@@ -1,10 +1,12 @@
import { UmbDocumentSaveAndPublishWorkspaceAction } from './actions/save-and-publish.action.js';
import { UmbDocumentSaveAndPreviewWorkspaceAction } from './actions/save-and-preview.action.js';
import { UmbSaveAndScheduleDocumentWorkspaceAction } from './actions/save-and-schedule.action.js';
import { UmbDocumentWorkspaceContext } from './document-workspace.context.js'; // JUST FOR TEST
import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace';
import type {
ManifestWorkspace,
ManifestWorkspaceAction,
ManifestWorkspaceContext,
ManifestWorkspaceEditorView,
ManifestWorkspaceViewCollection,
} from '@umbraco-cms/backoffice/extension-registry';
@@ -13,18 +15,32 @@ const workspace: ManifestWorkspace = {
type: 'workspace',
alias: 'Umb.Workspace.Document',
name: 'Document Workspace',
loader: () => import('./document-workspace.element.js'),
js: () => import('./document-workspace.element.js'),
api: UmbDocumentWorkspaceContext,
meta: {
entityType: 'document',
},
};
const workspaceContext: ManifestWorkspaceContext = {
type: 'workspaceContext',
alias: 'Umb.WorkspaceContext.Document',
name: 'Document Workspace Context',
js: './bla-test.js',
conditions: [
{
alias: 'Umb.Condition.WorkspaceAlias',
match: workspace.alias,
},
],
};
const workspaceEditorViews: Array<ManifestWorkspaceEditorView> = [
{
type: 'workspaceEditorView',
alias: 'Umb.WorkspaceView.Document.Edit',
name: 'Document Workspace Edit View',
loader: () => import('./views/edit/document-workspace-view-edit.element.js'),
js: () => import('./views/edit/document-workspace-view-edit.element.js'),
weight: 200,
meta: {
label: 'Content',
@@ -42,7 +58,7 @@ const workspaceEditorViews: Array<ManifestWorkspaceEditorView> = [
type: 'workspaceEditorView',
alias: 'Umb.WorkspaceView.Document.Info',
name: 'Document Workspace Info View',
loader: () => import('./views/info/document-info-workspace-view.element.js'),
js: () => import('./views/info/document-info-workspace-view.element.js'),
weight: 100,
meta: {
label: 'Info',
@@ -152,4 +168,4 @@ const workspaceActions: Array<ManifestWorkspaceAction> = [
*/
];
export const manifests = [workspace, ...workspaceEditorViews, ...workspaceViewCollections, ...workspaceActions];
export const manifests = [workspace, workspaceContext, ...workspaceEditorViews, ...workspaceViewCollections, ...workspaceActions];

View File

@@ -4,6 +4,6 @@ export const extensions = [
name: 'Document Management Bundle',
alias: 'Umb.Bundle.DocumentManagement',
type: 'bundle',
loader: () => import('./manifests.js'),
js: () => import('./manifests.js'),
},
];

View File

@@ -4,7 +4,7 @@ export const manifests = [
alias: 'Umb.Dashboard.HealthCheck',
name: 'Health Check',
elementName: 'umb-dashboard-health-check',
loader: () => import('./dashboard-health-check.element.js'),
js: () => import('./dashboard-health-check.element.js'),
weight: 102,
meta: {
label: 'Health Check',

View File

@@ -4,6 +4,6 @@ export const extensions = [
name: 'Health Check Bundle',
alias: 'Umb.Bundle.HealthCheck',
type: 'bundle',
loader: () => import('./manifests.js'),
js: () => import('./manifests.js'),
},
];

View File

@@ -4,6 +4,6 @@ export const extensions = [
name: 'Log Viewer Bundle',
alias: 'Umb.Bundle.LogViewer',
type: 'bundle',
loader: () => import('./manifests.js'),
js: () => import('./manifests.js'),
},
];

Some files were not shown because too many files have changed in this diff Show More