Merge branch 'v14/feature/router-404' into v14/bugfix/hide-content-workspace-view-when-no-properties
This commit is contained in:
@@ -2,7 +2,7 @@ import type { UmbBackofficeContext } from '../backoffice.context.js';
|
||||
import { UMB_BACKOFFICE_CONTEXT } from '../backoffice.context.js';
|
||||
import { css, html, customElement, state, nothing } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbSectionContext, UMB_SECTION_CONTEXT, UMB_SECTION_PATH_PATTERN } from '@umbraco-cms/backoffice/section';
|
||||
import type { UmbRoute, UmbRouterSlotChangeEvent } from '@umbraco-cms/backoffice/router';
|
||||
import type { PageComponent, UmbRoute, UmbRouterSlotChangeEvent } from '@umbraco-cms/backoffice/router';
|
||||
import type { ManifestSection, UmbSectionElement } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import type { UmbExtensionManifestInitializer } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { createExtensionElement } from '@umbraco-cms/backoffice/extension-api';
|
||||
@@ -11,7 +11,7 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
@customElement('umb-backoffice-main')
|
||||
export class UmbBackofficeMainElement extends UmbLitElement {
|
||||
@state()
|
||||
private _routes: Array<UmbRoute & { alias: string }> = [];
|
||||
private _routes: Array<UmbRoute> = [];
|
||||
|
||||
@state()
|
||||
private _sections: Array<UmbExtensionManifestInitializer<ManifestSection>> = [];
|
||||
@@ -43,28 +43,39 @@ export class UmbBackofficeMainElement extends UmbLitElement {
|
||||
|
||||
private _createRoutes() {
|
||||
if (!this._sections) return;
|
||||
const oldValue = this._routes;
|
||||
|
||||
// TODO: Refactor this for re-use across the app where the routes are re-generated at any time.
|
||||
this._routes = this._sections
|
||||
const newRoutes = this._sections
|
||||
.filter((x) => x.manifest)
|
||||
.map((section) => {
|
||||
const existingRoute = this._routes.find((r) => r.alias === section.alias);
|
||||
const existingRoute = this._routes.find((r) => r.path === UMB_SECTION_PATH_PATTERN.generateLocal({ sectionName: section.manifest!.meta.pathname }));
|
||||
if (existingRoute) {
|
||||
return existingRoute;
|
||||
} else {
|
||||
return {
|
||||
alias: section.alias,
|
||||
//alias: section.alias,
|
||||
path: UMB_SECTION_PATH_PATTERN.generateLocal({ sectionName: section.manifest!.meta.pathname }),
|
||||
component: () => createExtensionElement(section.manifest!, 'umb-section-default'),
|
||||
setup: (component) => {
|
||||
(component as UmbSectionElement).manifest = section.manifest as ManifestSection;
|
||||
setup: (component: PageComponent) => {
|
||||
(component as UmbSectionElement).manifest = section.manifest;
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
this.requestUpdate('_routes', oldValue);
|
||||
if(newRoutes.length > 0 ) {
|
||||
newRoutes.push({
|
||||
path: ``,
|
||||
redirectTo: newRoutes[0].path
|
||||
});
|
||||
}
|
||||
|
||||
newRoutes.push({
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
});
|
||||
|
||||
this._routes = newRoutes;
|
||||
}
|
||||
|
||||
private _onRouteChange = async (event: UmbRouterSlotChangeEvent) => {
|
||||
|
||||
@@ -2524,4 +2524,8 @@ export default {
|
||||
detailedLevelDescription:
|
||||
'\n We will send:\n <ul>\n <li>Anonymized site ID, Umbraco version, and packages installed.</li>\n <li>Number of: Root nodes, Content nodes, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, and Property Editors in use.</li>\n <li>System information: Webserver, server OS, server framework, server OS language, and database provider.</li>\n <li>Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, whether the delivery API is enabled, and allows public access, and if you are in debug mode.</li>\n </ul>\n <em>We might change what we send on the Detailed level in the future. If so, it will be listed above.\n <br>By choosing "Detailed" you agree to current and future anonymized information being collected.</em>\n ',
|
||||
},
|
||||
routing: {
|
||||
routeNotFoundTitle: 'Not found',
|
||||
routeNotFoundDescription: 'The requested route could not be found. Please check the URL and try again.'
|
||||
}
|
||||
} as UmbLocalizationDictionary;
|
||||
|
||||
@@ -45,6 +45,11 @@ ensureAnchorHistory();
|
||||
* @event changestate - Dispatched when the router slot state changes.
|
||||
*/
|
||||
export class RouterSlot<D = any, P = any> extends HTMLElement implements IRouterSlot<D, P> {
|
||||
/**
|
||||
* Method to cancel navigation if changed.
|
||||
*/
|
||||
private _cancelNavigation ?:() => void;
|
||||
|
||||
/**
|
||||
* Listeners on the router.
|
||||
*/
|
||||
@@ -197,8 +202,17 @@ export class RouterSlot<D = any, P = any> extends HTMLElement implements IRouter
|
||||
this._routes.push(...routes);
|
||||
|
||||
if (navigate === undefined) {
|
||||
// If navigate is not determined, then we will check if we have a route match. If not then we will re-render.
|
||||
// If navigate is not determined, then we will check if we have a route match. If not then we will re-render. [NL]
|
||||
navigate = this._routeMatch === null;
|
||||
if (navigate === false) {
|
||||
if (this.isConnected) {
|
||||
const newMatch = this.getRouteMatch();
|
||||
// Check if this match matches the current match (aka. If the path has changed), if so we should navigate. [NL]
|
||||
if(newMatch) {
|
||||
navigate = shouldNavigate(this.match, newMatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Navigate fallback:
|
||||
@@ -232,13 +246,21 @@ export class RouterSlot<D = any, P = any> extends HTMLElement implements IRouter
|
||||
|
||||
// Either choose the parent fragment or the current path if no parent exists.
|
||||
// The root router slot will always use the entire path.
|
||||
const pathFragment =
|
||||
this.parent != null && this.parent.fragments != null ? this.parent.fragments.rest : pathWithoutBasePath();
|
||||
const pathFragment = this.getPathFragment();
|
||||
|
||||
// Route to the path
|
||||
await this.renderPath(pathFragment);
|
||||
}
|
||||
|
||||
protected getPathFragment() {
|
||||
return this.parent != null && this.parent.fragments != null ? this.parent.fragments.rest : pathWithoutBasePath();
|
||||
}
|
||||
|
||||
protected getRouteMatch() {
|
||||
// Find the corresponding route.
|
||||
return matchRoutes(this._routes, this.getPathFragment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches listeners, either globally or on the parent router.
|
||||
*/
|
||||
@@ -296,6 +318,8 @@ export class RouterSlot<D = any, P = any> extends HTMLElement implements IRouter
|
||||
* Returns true if a navigation was made to a new page.
|
||||
*/
|
||||
protected async renderPath(path: string | PathFragment): Promise<boolean> {
|
||||
|
||||
// Notice: Since this is never called from any other place than one higher in this file(when writing this...), we could just retrieve the path and find a match by using this.getRouteMatch() [NL]
|
||||
// Find the corresponding route.
|
||||
const match = matchRoutes(this._routes, path);
|
||||
|
||||
@@ -312,10 +336,17 @@ export class RouterSlot<D = any, P = any> extends HTMLElement implements IRouter
|
||||
// Only change route if its a new route.
|
||||
const navigate = shouldNavigate(this.match, match);
|
||||
if (navigate) {
|
||||
|
||||
// If another navigation is still begin resolved in this very moment, then we need to cancel that so it does not end up overriding this new navigation.[NL]
|
||||
this._cancelNavigation?.();
|
||||
// Listen for another push state event. If another push state event happens
|
||||
// while we are about to navigate we have to cancel.
|
||||
let navigationInvalidated = false;
|
||||
const cancelNavigation = () => (navigationInvalidated = true);
|
||||
const cancelNavigation = () => {
|
||||
navigationInvalidated = true;
|
||||
this._cancelNavigation = undefined;
|
||||
};
|
||||
this._cancelNavigation = cancelNavigation;
|
||||
const removeChangeListener: EventListenerSubscription = addListener<Event, GlobalRouterEvent>(
|
||||
GLOBAL_ROUTER_EVENTS_TARGET,
|
||||
'changestate',
|
||||
@@ -378,16 +409,23 @@ export class RouterSlot<D = any, P = any> extends HTMLElement implements IRouter
|
||||
return cancel();
|
||||
}
|
||||
|
||||
// Remove the old page by clearing the slot
|
||||
this.clearChildren();
|
||||
// We have some routes that share the same component instance, those should not be removed and re-appended [NL]
|
||||
const isTheSameComponent = this.firstChild === page;
|
||||
|
||||
if(!isTheSameComponent) {
|
||||
// Remove the old page by clearing the slot
|
||||
this.clearChildren();
|
||||
}
|
||||
|
||||
// Store the new route match before we append the new page to the DOM.
|
||||
// We do this to ensure that we can find the match in the connectedCallback of the page.
|
||||
this._routeMatch = match;
|
||||
|
||||
if (page) {
|
||||
// Append the new page
|
||||
this.appendChild(page);
|
||||
if(!isTheSameComponent) {
|
||||
if (page) {
|
||||
// Append the new page
|
||||
this.appendChild(page);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -211,6 +211,8 @@ export abstract class UmbBaseExtensionInitializer<
|
||||
// Check if we already have a controller for this config:
|
||||
const existing = this.#conditionControllers.find((controller) => controller.config === conditionConfig);
|
||||
if (!existing) {
|
||||
|
||||
// TODO: Be aware that we might not have a host element any longer at this moment, but I did not want to make a fix for it jet, as its a good indication to if something else is terrible wrong [NL]
|
||||
const conditionController = await createExtensionApi(this, conditionManifest, [
|
||||
{
|
||||
manifest: conditionManifest,
|
||||
|
||||
@@ -5,12 +5,13 @@ export type ObserverCallback<T> = (value: T) => void;
|
||||
|
||||
export class UmbObserver<T> {
|
||||
#source!: Observable<T>;
|
||||
#callback!: ObserverCallback<T>;
|
||||
#callback?: ObserverCallback<T>;
|
||||
#subscription!: Subscription;
|
||||
|
||||
constructor(source: Observable<T>, callback?: ObserverCallback<T>) {
|
||||
this.#source = source;
|
||||
if (callback) {
|
||||
this.#callback = callback;
|
||||
this.#subscription = source.subscribe(callback);
|
||||
}
|
||||
}
|
||||
@@ -44,7 +45,7 @@ export class UmbObserver<T> {
|
||||
|
||||
hostConnected() {
|
||||
// Notice: This will not re-subscribe if this controller was destroyed. Only if the subscription was closed.
|
||||
if (this.#subscription?.closed) {
|
||||
if (this.#subscription?.closed && this.#callback) {
|
||||
this.#subscription = this.#source.subscribe(this.#callback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { UmbBlockGridAreaConfigEntryContext } from './block-grid-area-config-entry.context.js';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { html, css, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UmbBlockGridAreaConfigEntryContext } from './block-grid-area-config-entry.context.js';
|
||||
import '../block-grid-block/index.js';
|
||||
import '../block-scale-handler/index.js';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { UmbBlockGridTypeAreaType } from '../../../types.js';
|
||||
import type { UmbPropertyDatasetContext } from '@umbraco-cms/backoffice/property';
|
||||
import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
|
||||
import type {
|
||||
@@ -14,6 +13,7 @@ import { UmbArrayState, UmbObjectState, appendToFrozenArray } from '@umbraco-cms
|
||||
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';
|
||||
import type { UmbBlockGridTypeAreaType } from '../../../types.js';
|
||||
|
||||
export class UmbBlockGridAreaTypeWorkspaceContext
|
||||
extends UmbSubmittableWorkspaceContextBase<UmbBlockGridTypeAreaType>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { UMB_BLOCK_GRID_MANAGER_CONTEXT } from '../../context/block-grid-manager.context-token.js';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UMB_BLOCK_GRID_ENTRY_CONTEXT, type UmbBlockGridTypeAreaType } from '@umbraco-cms/backoffice/block-grid';
|
||||
import { css, customElement, html, repeat, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UMB_BLOCK_GRID_MANAGER_CONTEXT } from '../../context/block-grid-manager.context-token.js';
|
||||
import { UMB_BLOCK_GRID_ENTRY_CONTEXT, type UmbBlockGridTypeAreaType } from '@umbraco-cms/backoffice/block-grid';
|
||||
|
||||
import '../block-grid-entries/index.js';
|
||||
/**
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
import { closestColumnSpanOption } from '../utils/index.js';
|
||||
import { UMB_BLOCK_GRID_MANAGER_CONTEXT } from './block-grid-manager.context-token.js';
|
||||
import { UMB_BLOCK_GRID_ENTRIES_CONTEXT } from './block-grid-entries.context-token.js';
|
||||
import {
|
||||
type UmbBlockGridScalableContext,
|
||||
UmbBlockGridScaleManager,
|
||||
} from './block-grid-scale-manager/block-grid-scale-manager.controller.js';
|
||||
import { UmbBlockEntryContext } from '@umbraco-cms/backoffice/block';
|
||||
import type { UmbContentTypeModel, UmbPropertyTypeModel } from '@umbraco-cms/backoffice/content-type';
|
||||
import type { UmbBlockGridTypeModel, UmbBlockGridLayoutModel } from '@umbraco-cms/backoffice/block-grid';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import {
|
||||
UmbArrayState,
|
||||
@@ -17,6 +8,15 @@ import {
|
||||
appendToFrozenArray,
|
||||
observeMultiple,
|
||||
} from '@umbraco-cms/backoffice/observable-api';
|
||||
import { closestColumnSpanOption } from '../utils/index.js';
|
||||
import { UMB_BLOCK_GRID_MANAGER_CONTEXT } from './block-grid-manager.context-token.js';
|
||||
import { UMB_BLOCK_GRID_ENTRIES_CONTEXT } from './block-grid-entries.context-token.js';
|
||||
import {
|
||||
type UmbBlockGridScalableContext,
|
||||
UmbBlockGridScaleManager,
|
||||
} from './block-grid-scale-manager/block-grid-scale-manager.controller.js';
|
||||
import { UmbBlockEntryContext } from '@umbraco-cms/backoffice/block';
|
||||
import type { UmbBlockGridTypeModel, UmbBlockGridLayoutModel } from '@umbraco-cms/backoffice/block-grid';
|
||||
|
||||
export class UmbBlockGridEntryContext
|
||||
extends UmbBlockEntryContext<
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { closestColumnSpanOption } from '../../utils/index.js';
|
||||
import { getAccumulatedValueOfIndex, getInterpolatedIndexOfPositionInWeightMap } from '@umbraco-cms/backoffice/utils';
|
||||
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { closestColumnSpanOption } from '../../utils/index.js';
|
||||
|
||||
// This might be more generic than Block Grid, but this is where it belongs currently:
|
||||
export interface UmbBlockGridScalableContext extends UmbControllerHost {
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import type { UmbBlockGridTypeAreaType } from '../../index.js';
|
||||
import { UMB_BLOCK_GRID_DEFAULT_LAYOUT_STYLESHEET } from '../../context/block-grid-manager.context.js';
|
||||
import { UMB_BLOCK_GRID_AREA_TYPE_WORKSPACE_MODAL } from '../../components/block-grid-area-config-entry/index.js';
|
||||
import { UmbBlockGridAreaTypeEntriesContext } from './block-grid-area-type-entries.context.js';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { html, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
|
||||
@@ -13,6 +9,10 @@ import {
|
||||
import { UmbId } from '@umbraco-cms/backoffice/id';
|
||||
import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router';
|
||||
import { incrementString } from '@umbraco-cms/backoffice/utils';
|
||||
import { UMB_BLOCK_GRID_AREA_TYPE_WORKSPACE_MODAL } from '../../components/block-grid-area-config-entry/index.js';
|
||||
import { UMB_BLOCK_GRID_DEFAULT_LAYOUT_STYLESHEET } from '../../context/block-grid-manager.context.js';
|
||||
import type { UmbBlockGridTypeAreaType } from '../../index.js';
|
||||
import { UmbBlockGridAreaTypeEntriesContext } from './block-grid-area-type-entries.context.js';
|
||||
|
||||
@customElement('umb-property-editor-ui-block-grid-areas-config')
|
||||
export class UmbPropertyEditorUIBlockGridAreasConfigElement
|
||||
@@ -127,7 +127,6 @@ export class UmbPropertyEditorUIBlockGridAreasConfigElement
|
||||
//TODO: open area edit workspace
|
||||
}
|
||||
|
||||
// TODO: Needs localizations:
|
||||
override render() {
|
||||
return this._areaGridColumns
|
||||
? html`${this._styleElement}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { manifests as workspaceViewManifests } from './views/manifests.js';
|
||||
import { UMB_BLOCK_GRID_TYPE_WORKSPACE_ALIAS } from './index.js';
|
||||
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifests: Array<ManifestTypes> = [
|
||||
...workspaceViewManifests,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UMB_BLOCK_GRID_TYPE_WORKSPACE_ALIAS } from '../index.js';
|
||||
import type { ManifestTypes, ManifestWorkspaceView } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UMB_BLOCK_GRID_TYPE_WORKSPACE_ALIAS } from '../index.js';
|
||||
|
||||
export const workspaceViews: Array<ManifestWorkspaceView> = [
|
||||
{
|
||||
@@ -53,7 +53,7 @@ export const workspaceViews: Array<ManifestWorkspaceView> = [
|
||||
{
|
||||
alias: 'Umb.Condition.WorkspaceAlias',
|
||||
match: UMB_BLOCK_GRID_TYPE_WORKSPACE_ALIAS,
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
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';
|
||||
import { UmbRepositoryItemsManager } from '@umbraco-cms/backoffice/repository';
|
||||
import type { UmbDocumentTypeItemModel } from '@umbraco-cms/backoffice/document-type';
|
||||
import { UMB_DOCUMENT_TYPE_ITEM_REPOSITORY_ALIAS } from '@umbraco-cms/backoffice/document-type';
|
||||
import { UMB_BLOCK_TYPE_WORKSPACE_CONTEXT } from './block-type-workspace.context-token.js';
|
||||
|
||||
@customElement('umb-block-type-workspace-editor')
|
||||
export class UmbBlockTypeWorkspaceEditorElement extends UmbLitElement {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
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 {
|
||||
@@ -14,6 +12,8 @@ import {
|
||||
import { UmbArrayState, UmbObjectState, appendToFrozenArray } from '@umbraco-cms/backoffice/observable-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { ManifestWorkspace, PropertyEditorSettingsProperty } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import type { UmbBlockTypeBaseModel, UmbBlockTypeWithGroupKey } from '../types.js';
|
||||
import { UmbBlockTypeWorkspaceEditorElement } from './block-type-workspace-editor.element.js';
|
||||
|
||||
export class UmbBlockTypeWorkspaceContext<BlockTypeData extends UmbBlockTypeWithGroupKey = UmbBlockTypeWithGroupKey>
|
||||
extends UmbSubmittableWorkspaceContextBase<BlockTypeData>
|
||||
@@ -27,7 +27,7 @@ export class UmbBlockTypeWorkspaceContext<BlockTypeData extends UmbBlockTypeWith
|
||||
//readonly data = this.#data.asObservable();
|
||||
|
||||
// TODO: Get the name of the contentElementType..
|
||||
readonly name = this.#data.asObservablePart((data) => 'block');
|
||||
readonly name = this.#data.asObservablePart(() => 'block');
|
||||
readonly unique = this.#data.asObservablePart((data) => data?.contentElementTypeKey);
|
||||
|
||||
#properties = new UmbArrayState<PropertyEditorSettingsProperty>([], (x) => x.alias);
|
||||
|
||||
@@ -24,7 +24,7 @@ export const manifests: Array<ManifestTypes> = [
|
||||
{
|
||||
type: 'workspace',
|
||||
kind: 'routable',
|
||||
name: 'Block List Type Workspace',
|
||||
name: 'Block Workspace',
|
||||
alias: UMB_BLOCK_WORKSPACE_ALIAS,
|
||||
api: () => import('./block-workspace.context.js'),
|
||||
meta: {
|
||||
@@ -61,7 +61,7 @@ export const manifests: Array<ManifestTypes> = [
|
||||
alias: 'Umb.WorkspaceView.Block.Settings',
|
||||
name: 'Block Workspace Settings View',
|
||||
js: () => import('./views/edit/block-workspace-view-edit.element.js'),
|
||||
weight: 1000,
|
||||
weight: 900,
|
||||
meta: {
|
||||
label: '#general_settings',
|
||||
pathname: 'settings',
|
||||
@@ -75,7 +75,7 @@ export const manifests: Array<ManifestTypes> = [
|
||||
},
|
||||
{
|
||||
alias: 'Umb.Condition.BlockWorkspaceHasSettings',
|
||||
},
|
||||
}
|
||||
],
|
||||
} as any,
|
||||
];
|
||||
|
||||
@@ -116,6 +116,10 @@ export class UmbBlockWorkspaceViewEditElement extends UmbLitElement implements U
|
||||
path: '',
|
||||
redirectTo: routes[0]?.path,
|
||||
});
|
||||
routes.push({
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
});
|
||||
}
|
||||
|
||||
this._routes = routes;
|
||||
|
||||
@@ -98,6 +98,11 @@ export class UmbCollectionViewManager extends UmbControllerBase {
|
||||
});
|
||||
}
|
||||
|
||||
routes.push({
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
});
|
||||
|
||||
this.#routes.setValue(routes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,6 +226,11 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements
|
||||
}
|
||||
}
|
||||
|
||||
routes.push({
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
});
|
||||
|
||||
this._routes = routes;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,11 +108,10 @@ export class UmbContentWorkspaceViewEditElement extends UmbLitElement implements
|
||||
});
|
||||
}
|
||||
|
||||
// Find the routes who are removed:
|
||||
//const removedRoutes = this._routes.filter((route) => !routes.find((r) => r.path === route.path));
|
||||
|
||||
// Find the routes who are new:
|
||||
//const newRoutes = routes.filter((route) => !this._routes.find((r) => r.path === route.path));
|
||||
routes.push({
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
});
|
||||
|
||||
this._routes = routes;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { UMB_PROPERTY_DATASET_CONTEXT } from '../property-dataset/index.js';
|
||||
import type { UmbVariantId } from '@umbraco-cms/backoffice/variant';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
|
||||
import {
|
||||
@@ -11,6 +9,8 @@ import {
|
||||
UmbStringState,
|
||||
} from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UMB_PROPERTY_DATASET_CONTEXT } from '../property-dataset/index.js';
|
||||
import type { UmbVariantId } from '@umbraco-cms/backoffice/variant';
|
||||
import type { UmbPropertyEditorConfigProperty } from '@umbraco-cms/backoffice/property-editor';
|
||||
import { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
|
||||
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
/**
|
||||
* A fallback view to be used in Workspace Views, maybe this can be upgraded at a later point.
|
||||
*/
|
||||
// TODO: Rename and move this file to a more generic place.
|
||||
@customElement('umb-route-not-found')
|
||||
export class UmbRouteNotFoundElement extends UmbLitElement {
|
||||
|
||||
override render() {
|
||||
return html`
|
||||
<div class="uui-text">
|
||||
<h4><umb-localize key="routing_routeNotFoundTitle"></umb-localize></h4>
|
||||
<umb-localize key="routing_routeNotFoundDescription"></umb-localize>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static override styles = [
|
||||
UmbTextStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:host > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
animation: fadeIn 4s .2s forwards;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
100% {
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
export default UmbRouteNotFoundElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-route-not-found': UmbRouteNotFoundElement;
|
||||
}
|
||||
}
|
||||
@@ -9,3 +9,4 @@ export * from './path-pattern.class.js';
|
||||
export * from './modal-registration/modal-route-registration.interface.js';
|
||||
export * from './modal-registration/modal-route-registration.controller.js';
|
||||
export * from './types.js';
|
||||
export * from './components/not-found/route-not-found.element.js';
|
||||
|
||||
@@ -28,7 +28,8 @@ export class UmbRouterSlotElement extends UmbLitElement {
|
||||
value ??= [];
|
||||
const oldValue = this.#router.routes;
|
||||
if (
|
||||
value.filter((route) => (oldValue ? oldValue.findIndex((r) => r.path === route.path) === -1 : true)).length > 0
|
||||
value.length !== oldValue?.length ||
|
||||
value.filter((route) => (oldValue?.findIndex((r) => r.path === route.path) === -1)).length > 0
|
||||
) {
|
||||
this.#router.routes = value;
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ import type { IRoute, IRoutingInfo, PageComponent, UmbRoute } from '@umbraco-cms
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import type { UmbExtensionElementInitializer } from '@umbraco-cms/backoffice/extension-api';
|
||||
import {
|
||||
UmbExtensionsApiInitializer,
|
||||
UmbExtensionsElementInitializer,
|
||||
UmbExtensionsManifestInitializer,
|
||||
createExtensionApi,
|
||||
createExtensionElement,
|
||||
} from '@umbraco-cms/backoffice/extension-api';
|
||||
import { aliasToPath, debounce } from '@umbraco-cms/backoffice/utils';
|
||||
import { aliasToPath } from '@umbraco-cms/backoffice/utils';
|
||||
|
||||
/**
|
||||
* @export
|
||||
@@ -86,15 +86,12 @@ export class UmbSectionDefaultElement extends UmbLitElement implements UmbSectio
|
||||
const api = await createExtensionApi(this, extensionController.manifest);
|
||||
|
||||
return {
|
||||
path:
|
||||
path: (
|
||||
api?.getPath?.() ||
|
||||
extensionController.manifest.meta?.path ||
|
||||
aliasToPath(extensionController.manifest.alias),
|
||||
// TODO: look into removing the "as PageComponent" type hack
|
||||
// be aware that this is kind of a hack to pass the manifest element to the router. But as the two resolve components
|
||||
// in a similar way. I currently find it more safe to let the router do the component resolving instead
|
||||
// of replicating it as a custom resolver here.
|
||||
component: extensionController.manifest.element as PageComponent | PromiseLike<PageComponent>,
|
||||
aliasToPath(extensionController.manifest.alias)
|
||||
),
|
||||
component: () => createExtensionElement(extensionController.manifest),
|
||||
setup: (element: PageComponent, info: IRoutingInfo) => {
|
||||
api?.setup?.(element, info);
|
||||
},
|
||||
@@ -102,14 +99,12 @@ export class UmbSectionDefaultElement extends UmbLitElement implements UmbSectio
|
||||
}),
|
||||
);
|
||||
|
||||
this.#debouncedCreateRoutes(routes);
|
||||
this.#createRoutes(routes);
|
||||
},
|
||||
'umbRouteExtensionApisInitializer',
|
||||
);
|
||||
}
|
||||
|
||||
#debouncedCreateRoutes = debounce(this.#createRoutes, 50);
|
||||
|
||||
#createRoutes(routes: Array<IRoute>) {
|
||||
this._routes = [
|
||||
...routes,
|
||||
|
||||
@@ -71,17 +71,18 @@ export class UmbWorkspaceEditorElement extends UmbLitElement {
|
||||
} as UmbRoute;
|
||||
});
|
||||
|
||||
// If we have a post fix then we need to add a direct from the empty url of the split-view-index:
|
||||
// TODO: This is problematic, cause if a workspaceView appears later, then this takes over. And it is also a problem if it does not use redirect, but just a view defined with and empty path.
|
||||
const firstRoute = newRoutes[0];
|
||||
if (firstRoute) {
|
||||
newRoutes.push({
|
||||
path: ``,
|
||||
redirectTo: firstRoute.path,
|
||||
});
|
||||
}
|
||||
newRoutes.push({
|
||||
path: '',
|
||||
redirectTo: newRoutes[0]?.path,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
newRoutes.push({
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
});
|
||||
|
||||
this._routes = newRoutes;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import type { ActiveVariant } from '../../controllers/index.js';
|
||||
import { UMB_WORKSPACE_SPLIT_VIEW_CONTEXT } from './workspace-split-view.context.js';
|
||||
import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
|
||||
import { UMB_PROPERTY_DATASET_CONTEXT, isNameablePropertyDatasetContext } from '@umbraco-cms/backoffice/property';
|
||||
import {
|
||||
type UUIInputElement,
|
||||
UUIInputEvent,
|
||||
type UUIPopoverContainerElement,
|
||||
} from '@umbraco-cms/backoffice/external/uui';
|
||||
import { css, html, nothing, customElement, state, query } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import type { UmbDocumentWorkspaceContext } from '@umbraco-cms/backoffice/document';
|
||||
import type { ActiveVariant } from '../../controllers/index.js';
|
||||
import { UMB_WORKSPACE_SPLIT_VIEW_CONTEXT } from './workspace-split-view.context.js';
|
||||
import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
|
||||
import { UMB_PROPERTY_DATASET_CONTEXT, isNameablePropertyDatasetContext } from '@umbraco-cms/backoffice/property';
|
||||
import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
|
||||
type UmbDocumentVariantOption = {
|
||||
culture: string | null;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { UMB_VARIANT_WORKSPACE_CONTEXT } from '../../contexts/index.js';
|
||||
import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
|
||||
import { UmbNumberState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UMB_VARIANT_WORKSPACE_CONTEXT } from '../../contexts/index.js';
|
||||
import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
|
||||
import type { UmbPropertyDatasetContext } from '@umbraco-cms/backoffice/property';
|
||||
|
||||
export class UmbWorkspaceSplitViewContext extends UmbContextBase<UmbWorkspaceSplitViewContext> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { css, html, customElement, property, ifDefined } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbWorkspaceSplitViewContext } from './workspace-split-view.context.js';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { css, html, customElement, property, ifDefined } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
// import local components
|
||||
@@ -34,6 +34,7 @@ export class UmbWorkspaceSplitViewElement extends UmbLitElement {
|
||||
splitViewContext = new UmbWorkspaceSplitViewContext(this);
|
||||
|
||||
override render() {
|
||||
|
||||
return html`
|
||||
<umb-workspace-editor
|
||||
alias=${this.alias}
|
||||
|
||||
@@ -8,6 +8,14 @@ export class UmbWorkspaceRouteManager extends UmbControllerBase {
|
||||
public readonly routes = this.#routes.asObservable();
|
||||
|
||||
setRoutes(routes: Array<UmbRoute>) {
|
||||
this.#routes.setValue(routes);
|
||||
this.#routes.setValue(
|
||||
[
|
||||
...routes,
|
||||
{
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
|
||||
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
|
||||
|
||||
export type ActiveVariant = {
|
||||
index: number;
|
||||
@@ -13,7 +13,7 @@ export type ActiveVariant = {
|
||||
* @description - Class managing the split view state for a workspace context.
|
||||
*/
|
||||
export class UmbWorkspaceSplitViewManager {
|
||||
#activeVariantsInfo = new UmbArrayState<ActiveVariant>([], (x) => x.index);
|
||||
#activeVariantsInfo = new UmbArrayState<ActiveVariant>([], (x) => x.index).sortBy((a, b) => (a.index || 0) - (b.index || 0));
|
||||
public readonly activeVariantsInfo = this.#activeVariantsInfo.asObservable();
|
||||
|
||||
private _routeBase?: string;
|
||||
@@ -25,7 +25,7 @@ export class UmbWorkspaceSplitViewManager {
|
||||
}
|
||||
|
||||
setActiveVariant(index: number, culture: string | null, segment: string | null) {
|
||||
this.#activeVariantsInfo.appendOne({ index, culture: culture || null, segment: segment || null });
|
||||
this.#activeVariantsInfo.appendOneAt({ index, culture: culture ?? null, segment: segment ?? null }, index);
|
||||
}
|
||||
|
||||
getActiveVariants() {
|
||||
@@ -39,7 +39,7 @@ export class UmbWorkspaceSplitViewManager {
|
||||
}
|
||||
|
||||
public activeVariantByIndex(index: number) {
|
||||
return this.#activeVariantsInfo.asObservablePart((data) => data[index] || undefined);
|
||||
return this.#activeVariantsInfo.asObservablePart((data) => data.find(x => x.index === index) || undefined);
|
||||
}
|
||||
|
||||
public switchVariant(index: number, variantId: UmbVariantId) {
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import type { UmbSubmittableWorkspaceContext } from '../../contexts/tokens/submittable-workspace-context.interface.js';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { html, customElement, state, css } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import type { UmbRoute } from '@umbraco-cms/backoffice/router';
|
||||
import { UmbExtensionsApiInitializer } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
@customElement('umb-editable-workspace')
|
||||
export class UmbEditableWorkspaceElement extends UmbLitElement {
|
||||
@state()
|
||||
_routes: UmbRoute[] = [];
|
||||
|
||||
public set api(api: UmbSubmittableWorkspaceContext) {
|
||||
this.observe(api.routes.routes, (routes) => (this._routes = routes));
|
||||
|
||||
new UmbExtensionsApiInitializer(this, umbExtensionsRegistry, 'workspaceContext', [api]);
|
||||
}
|
||||
|
||||
override render() {
|
||||
return html` <umb-router-slot .routes="${this._routes}"></umb-router-slot>`;
|
||||
}
|
||||
|
||||
static override styles = [
|
||||
css`
|
||||
form {
|
||||
display: contents;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
export default UmbEditableWorkspaceElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-editable-workspace': UmbEditableWorkspaceElement;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import type { UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifest: UmbBackofficeManifestKind = {
|
||||
type: 'kind',
|
||||
alias: 'Umb.Kind.Workspace.Editable',
|
||||
matchKind: 'editable',
|
||||
matchType: 'workspace',
|
||||
manifest: {
|
||||
type: 'workspace',
|
||||
kind: 'editable',
|
||||
element: () => import('./editable-workspace.element.js'),
|
||||
},
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
import { expect, fixture, html } from '@open-wc/testing';
|
||||
import { UmbEditableWorkspaceElement } from './editable-workspace.element.js';
|
||||
import { type UmbTestRunnerWindow, defaultA11yConfig } from '@umbraco-cms/internal/test-utils';
|
||||
|
||||
describe('UmbEditableWorkspaceElement', () => {
|
||||
let element: UmbEditableWorkspaceElement;
|
||||
|
||||
beforeEach(async () => {
|
||||
element = await fixture(html`<umb-editable-workspace></umb-editable-workspace>`);
|
||||
});
|
||||
|
||||
it('is defined with its own instance', () => {
|
||||
expect(element).to.be.instanceOf(UmbEditableWorkspaceElement);
|
||||
});
|
||||
|
||||
if ((window as UmbTestRunnerWindow).__UMBRACO_TEST_RUN_A11Y_TEST) {
|
||||
it('passes the a11y audit', async () => {
|
||||
// TODO: should we use shadowDom here?
|
||||
await expect(element).to.be.accessible(defaultA11yConfig);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,5 +1,4 @@
|
||||
import { manifest as editableKindManifest } from './editable/editable-workspace.kind.js';
|
||||
import { manifest as routableKindManifest } from './routable/routable-workspace.kind.js';
|
||||
import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifests: Array<ManifestTypes | UmbBackofficeManifestKind> = [routableKindManifest, editableKindManifest];
|
||||
export const manifests: Array<ManifestTypes | UmbBackofficeManifestKind> = [routableKindManifest];
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import { UmbDataTypeDetailRepository } from '../repository/detail/data-type-detail.repository.js';
|
||||
import type { UmbDataTypeDetailModel, UmbDataTypePropertyModel } from '../types.js';
|
||||
import { UmbDataTypeWorkspaceEditorElement } from './data-type-workspace-editor.element.js';
|
||||
import type { UmbPropertyDatasetContext } from '@umbraco-cms/backoffice/property';
|
||||
import type {
|
||||
UmbInvariantDatasetWorkspaceContext,
|
||||
@@ -10,7 +7,6 @@ import {
|
||||
UmbSubmittableWorkspaceContextBase,
|
||||
UmbInvariantWorkspacePropertyDatasetContext,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
UmbWorkspaceRouteManager,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
import {
|
||||
appendToFrozenArray,
|
||||
@@ -29,7 +25,9 @@ import {
|
||||
UmbRequestReloadChildrenOfEntityEvent,
|
||||
UmbRequestReloadStructureForEntityEvent,
|
||||
} from '@umbraco-cms/backoffice/entity-action';
|
||||
import { UMB_PROPERTY_EDITOR_SCHEMA_ALIAS_DEFAULT } from '@umbraco-cms/backoffice/property-editor';
|
||||
import type { UmbDataTypeDetailModel, UmbDataTypePropertyModel } from '../types.js';
|
||||
import { UmbDataTypeDetailRepository } from '../repository/detail/data-type-detail.repository.js';
|
||||
import { UmbDataTypeWorkspaceEditorElement } from './data-type-workspace-editor.element.js';
|
||||
|
||||
type EntityType = UmbDataTypeDetailModel;
|
||||
export class UmbDataTypeWorkspaceContext
|
||||
|
||||
@@ -10,7 +10,7 @@ const DATA_TYPE_WORKSPACE_ALIAS = 'Umb.Workspace.DataType';
|
||||
|
||||
const workspace: ManifestWorkspaces = {
|
||||
type: 'workspace',
|
||||
kind: 'editable',
|
||||
kind: 'routable',
|
||||
alias: DATA_TYPE_WORKSPACE_ALIAS,
|
||||
name: 'Data Type Workspace',
|
||||
api: () => import('./data-type-workspace.context.js'),
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import { UmbDictionaryDetailRepository } from '../repository/index.js';
|
||||
import type { UmbDictionaryDetailModel } from '../types.js';
|
||||
import { UmbDictionaryWorkspaceEditorElement } from './dictionary-workspace-editor.element.js';
|
||||
import {
|
||||
type UmbSubmittableWorkspaceContext,
|
||||
UmbSubmittableWorkspaceContextBase,
|
||||
UmbWorkspaceRouteManager,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
type UmbRoutableWorkspaceContext,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
@@ -15,6 +11,9 @@ import {
|
||||
UmbRequestReloadChildrenOfEntityEvent,
|
||||
UmbRequestReloadStructureForEntityEvent,
|
||||
} from '@umbraco-cms/backoffice/entity-action';
|
||||
import type { UmbDictionaryDetailModel } from '../types.js';
|
||||
import { UmbDictionaryDetailRepository } from '../repository/index.js';
|
||||
import { UmbDictionaryWorkspaceEditorElement } from './dictionary-workspace-editor.element.js';
|
||||
|
||||
export class UmbDictionaryWorkspaceContext
|
||||
extends UmbSubmittableWorkspaceContextBase<UmbDictionaryDetailModel>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { UmbDocumentBlueprintVariantOptionModel } from '../types.js';
|
||||
import { UmbDocumentBlueprintWorkspaceSplitViewElement } from './document-blueprint-workspace-split-view.element.js';
|
||||
import { UMB_DOCUMENT_BLUEPRINT_WORKSPACE_CONTEXT } from './document-blueprint-workspace.context-token.js';
|
||||
import { customElement, state, css, html } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import type { UmbRoute, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router';
|
||||
import type { UmbDocumentBlueprintVariantOptionModel } from '../types.js';
|
||||
import { UMB_DOCUMENT_BLUEPRINT_WORKSPACE_CONTEXT } from './document-blueprint-workspace.context-token.js';
|
||||
import { UmbDocumentBlueprintWorkspaceSplitViewElement } from './document-blueprint-workspace-split-view.element.js';
|
||||
|
||||
@customElement('umb-document-blueprint-workspace-editor')
|
||||
export class UmbDocumentBlueprintWorkspaceEditorElement extends UmbLitElement {
|
||||
@@ -83,17 +83,12 @@ export class UmbDocumentBlueprintWorkspaceEditorElement extends UmbLitElement {
|
||||
});
|
||||
}
|
||||
|
||||
const oldValue = this._routes;
|
||||
routes.push({
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
});
|
||||
|
||||
// is there any differences in the amount ot the paths? [NL]
|
||||
// TODO: if we make a memorization function as the observer, we can avoid this check and avoid the whole build of routes. [NL]
|
||||
if (oldValue && oldValue.length === routes.length) {
|
||||
// is there any differences in the paths? [NL]
|
||||
const hasDifferences = oldValue.some((route, index) => route.path !== routes[index].path);
|
||||
if (!hasDifferences) return;
|
||||
}
|
||||
this._routes = routes;
|
||||
this.requestUpdate('_routes', oldValue);
|
||||
}
|
||||
|
||||
private _gotWorkspaceRoute = (e: UmbRouterSlotInitEvent) => {
|
||||
@@ -101,7 +96,7 @@ export class UmbDocumentBlueprintWorkspaceEditorElement extends UmbLitElement {
|
||||
};
|
||||
|
||||
override render() {
|
||||
return this._routes && this._routes.length > 0
|
||||
return this._routes
|
||||
? html`<umb-router-slot .routes=${this._routes} @init=${this._gotWorkspaceRoute}></umb-router-slot>`
|
||||
: '';
|
||||
}
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
import { UmbDocumentTypeDetailRepository } from '../repository/detail/document-type-detail.repository.js';
|
||||
import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../entity.js';
|
||||
import type { UmbDocumentTypeDetailModel } from '../types.js';
|
||||
import {
|
||||
UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN,
|
||||
UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_ELEMENT,
|
||||
UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_TEMPLATE,
|
||||
UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN,
|
||||
type UmbCreateDocumentTypeWorkspacePresetType,
|
||||
} from '../paths.js';
|
||||
import { UmbDocumentTypeWorkspaceEditorElement } from './document-type-workspace-editor.element.js';
|
||||
import { UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type';
|
||||
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import {
|
||||
@@ -18,7 +7,6 @@ import {
|
||||
import {
|
||||
UmbSubmittableWorkspaceContextBase,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
UmbWorkspaceRouteManager,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
import { UmbTemplateDetailRepository } from '@umbraco-cms/backoffice/template';
|
||||
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
|
||||
@@ -31,6 +19,17 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
|
||||
import type { UmbRoutableWorkspaceContext } from '@umbraco-cms/backoffice/workspace';
|
||||
import type { UmbPathPatternTypeAsEncodedParamsType } from '@umbraco-cms/backoffice/router';
|
||||
import {
|
||||
UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN,
|
||||
UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_ELEMENT,
|
||||
UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_TEMPLATE,
|
||||
UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN,
|
||||
type UmbCreateDocumentTypeWorkspacePresetType,
|
||||
} from '../paths.js';
|
||||
import type { UmbDocumentTypeDetailModel } from '../types.js';
|
||||
import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../entity.js';
|
||||
import { UmbDocumentTypeDetailRepository } from '../repository/detail/document-type-detail.repository.js';
|
||||
import { UmbDocumentTypeWorkspaceEditorElement } from './document-type-workspace-editor.element.js';
|
||||
|
||||
type EntityType = UmbDocumentTypeDetailModel;
|
||||
export class UmbDocumentTypeWorkspaceContext
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { isDocumentUserPermission } from '../utils.js';
|
||||
import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user';
|
||||
import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity';
|
||||
import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
|
||||
@@ -10,6 +9,7 @@ import type {
|
||||
} from '@umbraco-cms/backoffice/extension-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { DocumentPermissionPresentationModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import { isDocumentUserPermission } from '../utils.js';
|
||||
|
||||
export class UmbDocumentUserPermissionCondition
|
||||
extends UmbConditionBase<UmbDocumentUserPermissionConditionConfig>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { UmbDocumentVariantOptionModel } from '../types.js';
|
||||
import { UmbDocumentWorkspaceSplitViewElement } from './document-workspace-split-view.element.js';
|
||||
import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from './document-workspace.context-token.js';
|
||||
import { customElement, state, css, html } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import type { UmbRoute, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router';
|
||||
import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language';
|
||||
import type { UmbDocumentVariantOptionModel } from '../types.js';
|
||||
import { UmbDocumentWorkspaceSplitViewElement } from './document-workspace-split-view.element.js';
|
||||
import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from './document-workspace.context-token.js';
|
||||
|
||||
// TODO: This seem fully identical with Media Workspace Editor, so we can refactor this to a generic component. [NL]
|
||||
@customElement('umb-document-workspace-editor')
|
||||
@@ -101,7 +101,8 @@ export class UmbDocumentWorkspaceEditorElement extends UmbLitElement {
|
||||
const route = routes.find((route) => route.path === this.#appCulture);
|
||||
|
||||
if (!route) {
|
||||
history.pushState({}, '', `${this.#workspaceRoute}/${routes[routes.length - 2].path}`);
|
||||
// TODO: Notice: here is a specific index used for fallback, this could be made more solid [NL]
|
||||
history.pushState({}, '', `${this.#workspaceRoute}/${routes[routes.length - 3].path}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -110,16 +111,12 @@ export class UmbDocumentWorkspaceEditorElement extends UmbLitElement {
|
||||
});
|
||||
}
|
||||
|
||||
const oldValue = this._routes;
|
||||
routes.push({
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
});
|
||||
|
||||
// is there any differences in the amount ot the paths? [NL]
|
||||
if (oldValue && oldValue.length === routes.length) {
|
||||
// is there any differences in the paths? [NL]
|
||||
const hasDifferences = oldValue.some((route, index) => route.path !== routes[index].path);
|
||||
if (!hasDifferences) return;
|
||||
}
|
||||
this._routes = routes;
|
||||
this.requestUpdate('_routes', oldValue);
|
||||
}
|
||||
|
||||
private _gotWorkspaceRoute = (e: UmbRouterSlotInitEvent) => {
|
||||
@@ -128,7 +125,7 @@ export class UmbDocumentWorkspaceEditorElement extends UmbLitElement {
|
||||
};
|
||||
|
||||
override render() {
|
||||
return this._routes && this._routes.length > 0
|
||||
return this._routes
|
||||
? html`<umb-router-slot .routes=${this._routes} @init=${this._gotWorkspaceRoute}></umb-router-slot>`
|
||||
: '';
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from './document-workspace.context-token.js';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { css, html, nothing, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { ActiveVariant } from '@umbraco-cms/backoffice/workspace';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from './document-workspace.context-token.js';
|
||||
|
||||
@customElement('umb-document-workspace-split-view')
|
||||
export class UmbDocumentWorkspaceSplitViewElement extends UmbLitElement {
|
||||
|
||||
@@ -24,7 +24,10 @@ export class UmbDashboardHealthCheckElement extends UmbLitElement {
|
||||
{
|
||||
path: ``,
|
||||
component: () => import('./views/health-check-overview.element.js'),
|
||||
},
|
||||
},{
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
}
|
||||
];
|
||||
|
||||
private _healthCheckDashboardContext = new UmbHealthCheckDashboardContext(this);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
type UmbSubmittableWorkspaceContext,
|
||||
UmbSubmittableWorkspaceContextBase,
|
||||
UmbWorkspaceRouteManager,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
type UmbRoutableWorkspaceContext,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
UmbSubmittableWorkspaceContextBase,
|
||||
type UmbRoutableWorkspaceContext,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
UmbWorkspaceRouteManager,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
import { UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type';
|
||||
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||
|
||||
@@ -52,6 +52,10 @@ export class UmbMediaSectionViewElement extends UmbLitElement {
|
||||
path: '',
|
||||
redirectTo: 'collection',
|
||||
},
|
||||
{
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
}
|
||||
];
|
||||
},
|
||||
'_observeConfigDataType',
|
||||
|
||||
@@ -83,17 +83,12 @@ export class UmbMediaWorkspaceEditorElement extends UmbLitElement {
|
||||
});
|
||||
}
|
||||
|
||||
const oldValue = this._routes;
|
||||
routes.push({
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
});
|
||||
|
||||
// is there any differences in the amount ot the paths? [NL]
|
||||
// TODO: if we make a memorization function as the observer, we can avoid this check and avoid the whole build of routes. [NL]
|
||||
if (oldValue && oldValue.length === routes.length) {
|
||||
// is there any differences in the paths? [NL]
|
||||
const hasDifferences = oldValue.some((route, index) => route.path !== routes[index].path);
|
||||
if (!hasDifferences) return;
|
||||
}
|
||||
this._routes = routes;
|
||||
this.requestUpdate('_routes', oldValue);
|
||||
}
|
||||
|
||||
private _gotWorkspaceRoute = (e: UmbRouterSlotInitEvent) => {
|
||||
|
||||
@@ -28,6 +28,10 @@ export class UmbMemberGroupSectionViewElement extends UmbLitElement {
|
||||
path: '',
|
||||
redirectTo: 'collection',
|
||||
},
|
||||
{
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
}
|
||||
];
|
||||
|
||||
override render() {
|
||||
|
||||
@@ -5,7 +5,6 @@ import { UmbMemberGroupWorkspaceEditorElement } from './member-group-workspace-e
|
||||
import {
|
||||
type UmbSubmittableWorkspaceContext,
|
||||
UmbSubmittableWorkspaceContextBase,
|
||||
UmbWorkspaceRouteManager,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
type UmbRoutableWorkspaceContext,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
|
||||
@@ -5,7 +5,6 @@ import { UmbMemberTypeWorkspaceEditorElement } from './member-type-workspace-edi
|
||||
import {
|
||||
UmbSubmittableWorkspaceContextBase,
|
||||
type UmbRoutableWorkspaceContext,
|
||||
UmbWorkspaceRouteManager,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
@@ -28,6 +28,10 @@ export class UmbMemberSectionViewElement extends UmbLitElement {
|
||||
path: '',
|
||||
redirectTo: 'collection',
|
||||
},
|
||||
{
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
}
|
||||
];
|
||||
|
||||
override render() {
|
||||
|
||||
@@ -85,17 +85,12 @@ export class UmbMemberWorkspaceEditorElement extends UmbLitElement {
|
||||
});
|
||||
}
|
||||
|
||||
const oldValue = this._routes;
|
||||
routes.push({
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
});
|
||||
|
||||
// is there any differences in the amount ot the paths? [NL]
|
||||
// TODO: if we make a memorization function as the observer, we can avoid this check and avoid the whole build of routes. [NL]
|
||||
if (oldValue && oldValue.length === routes.length) {
|
||||
// is there any differences in the paths? [NL]
|
||||
const hasDifferences = oldValue.some((route, index) => route.path !== routes[index].path);
|
||||
if (!hasDifferences) return;
|
||||
}
|
||||
this._routes = routes;
|
||||
this.requestUpdate('_routes', oldValue);
|
||||
}
|
||||
|
||||
private _gotWorkspaceRoute = (e: UmbRouterSlotInitEvent) => {
|
||||
|
||||
@@ -61,6 +61,10 @@ export class UmbCreatedPackagesSectionViewElement extends UmbLitElement implemen
|
||||
path: '',
|
||||
redirectTo: 'overview',
|
||||
});
|
||||
routes.push({
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
});
|
||||
this._routes = routes;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,10 @@ export class UmbDashboardExamineManagementElement extends UmbLitElement {
|
||||
{
|
||||
path: ``,
|
||||
component: () => import('./views/section-view-examine-overview.js'),
|
||||
},
|
||||
},{
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
}
|
||||
];
|
||||
|
||||
@state()
|
||||
|
||||
@@ -8,7 +8,6 @@ import type { UmbRoutableWorkspaceContext, UmbSubmittableWorkspaceContext } from
|
||||
import {
|
||||
UmbSubmittableWorkspaceContextBase,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
UmbWorkspaceRouteManager,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
import { loadCodeEditor } from '@umbraco-cms/backoffice/code-editor';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
@@ -44,6 +44,10 @@ export class UmbPartialViewWorkspaceElement extends UmbLitElement {
|
||||
this.#workspaceContext.load(unique);
|
||||
},
|
||||
},
|
||||
{
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
}
|
||||
];
|
||||
|
||||
constructor() {
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
type UmbRoutableWorkspaceContext,
|
||||
type UmbSubmittableWorkspaceContext,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
UmbWorkspaceRouteManager,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
import { loadCodeEditor } from '@umbraco-cms/backoffice/code-editor';
|
||||
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
|
||||
|
||||
@@ -6,7 +6,6 @@ import { UmbStylesheetWorkspaceEditorElement } from './stylesheet-workspace-edit
|
||||
import {
|
||||
type UmbSubmittableWorkspaceContext,
|
||||
UmbSubmittableWorkspaceContextBase,
|
||||
UmbWorkspaceRouteManager,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
type UmbRoutableWorkspaceContext,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
|
||||
@@ -8,7 +8,6 @@ import type { UmbRoutableWorkspaceContext, UmbSubmittableWorkspaceContext } from
|
||||
import {
|
||||
UmbSubmittableWorkspaceContextBase,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
UmbWorkspaceRouteManager,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
import { UmbBooleanState, UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
@@ -30,6 +30,10 @@ export class UmbUserGroupSectionViewElement extends UmbLitElement {
|
||||
path: '',
|
||||
redirectTo: 'collection',
|
||||
},
|
||||
{
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
}
|
||||
];
|
||||
|
||||
override render() {
|
||||
|
||||
@@ -6,7 +6,6 @@ import type { UmbRoutableWorkspaceContext, UmbSubmittableWorkspaceContext } from
|
||||
import {
|
||||
UmbSubmittableWorkspaceContextBase,
|
||||
UmbWorkspaceIsNewRedirectController,
|
||||
UmbWorkspaceRouteManager,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
@@ -34,6 +34,10 @@ export class UmbSectionViewUsersElement extends UmbLitElement {
|
||||
path: '',
|
||||
redirectTo: 'collection',
|
||||
},
|
||||
{
|
||||
path: `**`,
|
||||
component: async () => (await import('@umbraco-cms/backoffice/router')).UmbRouteNotFoundElement,
|
||||
}
|
||||
];
|
||||
|
||||
override render() {
|
||||
|
||||
Reference in New Issue
Block a user