Merge branch 'main' into feature/templates-scaffold
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import { createExtensionElement } from './create-extension-element.function';
|
||||
import { isManifestElementableType } from './is-manifest-elementable-type.function';
|
||||
|
||||
export async function createExtensionElementOrFallback(manifest: any, fallbackElementName: string): Promise<HTMLElement | undefined> {
|
||||
if (isManifestElementableType(manifest)) {
|
||||
return createExtensionElement(manifest);
|
||||
}
|
||||
|
||||
return Promise.resolve(document.createElement(fallbackElementName));
|
||||
}
|
||||
@@ -8,5 +8,6 @@ export * from './is-manifest-elementable-type.function';
|
||||
export * from './is-manifest-js-type.function';
|
||||
export * from './is-manifest-loader-type.function';
|
||||
export * from './load-extension.function';
|
||||
export * from './create-extension-element-or-fallback.function';
|
||||
|
||||
export const umbExtensionsRegistry = new UmbExtensionRegistry();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { BehaviorSubject, map, Observable } from 'rxjs';
|
||||
import type { ManifestTypes, ManifestTypeMap, ManifestBase } from '../../models';
|
||||
import type { ManifestTypes, ManifestTypeMap, ManifestBase, ManifestWithLoader, ManifestEntrypoint } from '../../models';
|
||||
import { hasDefaultExport } from '../has-default-export.function';
|
||||
import { loadExtension } from '../load-extension.function';
|
||||
|
||||
@@ -13,7 +13,7 @@ export class UmbExtensionRegistry {
|
||||
private _extensions = new BehaviorSubject<Array<ManifestBase>>([]);
|
||||
public readonly extensions = this._extensions.asObservable();
|
||||
|
||||
register(manifest: ManifestTypes & { loader?: () => Promise<object | HTMLElement> }): void {
|
||||
register(manifest: ManifestTypes): void {
|
||||
const extensionsValues = this._extensions.getValue();
|
||||
const extension = extensionsValues.find((extension) => extension.alias === manifest.alias);
|
||||
|
||||
@@ -26,7 +26,7 @@ export class UmbExtensionRegistry {
|
||||
|
||||
// If entrypoint extension, we should load and run it immediately
|
||||
if (manifest.type === 'entrypoint') {
|
||||
loadExtension(manifest).then((js) => {
|
||||
loadExtension(manifest as ManifestEntrypoint).then((js) => {
|
||||
if (hasDefaultExport(js)) {
|
||||
new js.default();
|
||||
} else {
|
||||
|
||||
@@ -18,6 +18,7 @@ import type { ManifestCollectionBulkAction } from './collection-bulk-action.mode
|
||||
import type { ManifestCollectionView } from './collection-view.models';
|
||||
import type { ManifestHealthCheck } from './health-check.models';
|
||||
import type { ManifestSidebarMenuItem } from './sidebar-menu-item.models';
|
||||
import type { ManifestTheme } from './theme.models';
|
||||
|
||||
export * from './header-app.models';
|
||||
export * from './section.models';
|
||||
@@ -39,6 +40,7 @@ export * from './collection-bulk-action.models';
|
||||
export * from './collection-view.models';
|
||||
export * from './health-check.models';
|
||||
export * from './sidebar-menu-item.models';
|
||||
export * from './theme.models';
|
||||
|
||||
export type ManifestTypes =
|
||||
| ManifestCustom
|
||||
@@ -63,7 +65,8 @@ export type ManifestTypes =
|
||||
| ManifestCollectionBulkAction
|
||||
| ManifestCollectionView
|
||||
| ManifestHealthCheck
|
||||
| ManifestSidebarMenuItem;
|
||||
| ManifestSidebarMenuItem
|
||||
| ManifestTheme;
|
||||
|
||||
export type ManifestStandardTypes = ManifestTypes['type'];
|
||||
|
||||
@@ -78,14 +81,29 @@ export interface ManifestBase {
|
||||
weight?: number;
|
||||
}
|
||||
|
||||
export interface ManifestElement extends ManifestBase {
|
||||
export interface ManifestWithLoader<LoaderReturnType> extends ManifestBase {
|
||||
loader?: () => Promise<LoaderReturnType>;
|
||||
}
|
||||
|
||||
export interface ManifestElement extends ManifestWithLoader<object | HTMLElement> {
|
||||
type: ManifestStandardTypes;
|
||||
js?: string;
|
||||
elementName?: string;
|
||||
loader?: () => Promise<object | HTMLElement>;
|
||||
//loader?: () => Promise<object | HTMLElement>;
|
||||
meta?: any;
|
||||
}
|
||||
|
||||
export interface ManifestWithView extends ManifestElement {
|
||||
meta: MetaManifestWithView;
|
||||
}
|
||||
|
||||
export interface MetaManifestWithView {
|
||||
pathname: string;
|
||||
label: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
|
||||
export interface ManifestElementWithElementName extends ManifestElement {
|
||||
elementName: string;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { ManifestWithLoader } from "./models";
|
||||
|
||||
|
||||
// TODO: make or find type for JS Module with default export: Would be nice to support css file directly.
|
||||
export interface ManifestTheme extends ManifestWithLoader<string> {
|
||||
type: 'theme';
|
||||
css?: string;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ManifestElement } from './models';
|
||||
import type { ManifestWithView } from './models';
|
||||
|
||||
export interface ManifestWorkspaceView extends ManifestElement {
|
||||
export interface ManifestWorkspaceView extends ManifestWithView {
|
||||
type: 'workspaceView';
|
||||
meta: MetaEditorView;
|
||||
}
|
||||
|
||||
3
src/Umbraco.Web.UI.Client/libs/router/index.ts
Normal file
3
src/Umbraco.Web.UI.Client/libs/router/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './router-slot.element';
|
||||
export * from './router-slot-change.event';
|
||||
export * from './router-slot-init.event';
|
||||
4
src/Umbraco.Web.UI.Client/libs/router/rollup.config.js
Normal file
4
src/Umbraco.Web.UI.Client/libs/router/rollup.config.js
Normal file
@@ -0,0 +1,4 @@
|
||||
import config from '../../utils/rollup.config.js';
|
||||
export default {
|
||||
...config,
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
import { UUIEvent } from '@umbraco-ui/uui-base/lib/events';
|
||||
import type { UmbRouterSlotElement } from './router-slot.element';
|
||||
export class UmbRouterSlotChangeEvent extends UUIEvent<never, UmbRouterSlotElement> {
|
||||
constructor() {
|
||||
super('change');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { UUIEvent } from '@umbraco-ui/uui-base/lib/events';
|
||||
import type { UmbRouterSlotElement } from './router-slot.element';
|
||||
export class UmbRouterSlotInitEvent extends UUIEvent<never, UmbRouterSlotElement> {
|
||||
constructor() {
|
||||
super('init');
|
||||
}
|
||||
}
|
||||
79
src/Umbraco.Web.UI.Client/libs/router/router-slot.element.ts
Normal file
79
src/Umbraco.Web.UI.Client/libs/router/router-slot.element.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { LitElement, PropertyValueMap } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { IRoute, RouterSlot } from 'router-slot';
|
||||
import { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/router';
|
||||
|
||||
/**
|
||||
* @element umb-router-slot-element
|
||||
* @description - Component for wrapping Router Slot element, providing some local events for implementation.
|
||||
* @extends UmbRouterSlotElement
|
||||
*/
|
||||
@customElement('umb-router-slot')
|
||||
export class UmbRouterSlotElement extends LitElement {
|
||||
#router: RouterSlot;
|
||||
#listening = false;
|
||||
|
||||
@property()
|
||||
public get routes(): IRoute[] | undefined {
|
||||
return (this.#router as any).routes;
|
||||
}
|
||||
public set routes(value: IRoute[] | undefined) {
|
||||
(this.#router as any).routes = value;
|
||||
}
|
||||
|
||||
private _routerPath?: string;
|
||||
public get absoluteRouterPath() {
|
||||
return this._routerPath;
|
||||
}
|
||||
|
||||
private _activeLocalPath?: string;
|
||||
public get localActiveViewPath() {
|
||||
return this._activeLocalPath;
|
||||
}
|
||||
|
||||
public get absoluteActiveViewPath() {
|
||||
return this._routerPath + '/' + this._activeLocalPath;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#router = document.createElement('router-slot');
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
if (this.#listening === false) {
|
||||
window.addEventListener('navigationsuccess', this._onNavigationChanged);
|
||||
this.#listening = true;
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
window.removeEventListener('navigationsuccess', this._onNavigationChanged);
|
||||
this.#listening = false;
|
||||
}
|
||||
|
||||
protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
|
||||
super.firstUpdated(_changedProperties);
|
||||
this._routerPath = this.#router.constructAbsolutePath('') || '';
|
||||
this.dispatchEvent(new UmbRouterSlotInitEvent());
|
||||
}
|
||||
|
||||
private _onNavigationChanged = (event?: any) => {
|
||||
if (event.detail.slot === this.#router) {
|
||||
this._activeLocalPath = event.detail.match.route.path;
|
||||
this.dispatchEvent(new UmbRouterSlotChangeEvent());
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return this.#router;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-router-slot': UmbRouterSlotElement;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { Path } from 'msw';
|
||||
export function umbracoPath(path: string): Path {
|
||||
export function umbracoPath(path: string) {
|
||||
return `/umbraco/management/api/v1${path}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user