Merge branch 'release/15.1.1' into v15/dev

# Conflicts:
#	src/Umbraco.Core/Extensions/PublishedContentExtensions.cs
#	src/Umbraco.Web.UI.Client/package-lock.json
#	src/Umbraco.Web.UI.Client/package.json
#	version.json
This commit is contained in:
Sven Geusens
2024-12-12 16:36:45 +01:00
105 changed files with 2812 additions and 615 deletions

View File

@@ -1,14 +1,14 @@
import type { ManifestDashboard } from '@umbraco-cms/backoffice/dashboard';
import type { ManifestModal } from '@umbraco-cms/backoffice/modal';
const demoModal : ManifestModal = {
const demoModal: ManifestModal = {
type: 'modal',
name: 'Example Custom Modal Element',
alias: 'example.modal.custom.element',
js: () => import('./example-modal-view.element.js'),
}
};
const demoModalsDashboard : ManifestDashboard = {
const demoModalsDashboard: ManifestDashboard = {
type: 'dashboard',
name: 'Example Custom Modal Dashboard',
alias: 'example.dashboard.custom.modal.element',
@@ -18,12 +18,12 @@ const demoModalsDashboard : ManifestDashboard = {
label: 'Custom Modal',
pathname: 'custom-modal',
},
conditions : [
conditions: [
{
alias: 'Umb.Condition.SectionAlias',
match: 'Umb.Section.Content'
}
]
}
match: 'Umb.Section.Content',
},
],
};
export default [demoModal,demoModalsDashboard];
export default [demoModal, demoModalsDashboard];

View File

@@ -1,23 +1,21 @@
import type { ManifestDashboard } from '@umbraco-cms/backoffice/dashboard';
const dashboard : ManifestDashboard = {
const dashboard: ManifestDashboard = {
type: 'dashboard',
alias: 'Demo.Dashboard',
name: 'Demo Dashboard Validation Context',
weight: 1000,
element: () => import('./validation-context-dashboard.js'),
meta: {
label: 'Validation Context Demo',
pathname: 'demo'
label: 'Validation Context Demo',
pathname: 'demo',
},
conditions : [
{
alias : "Umb.Condition.SectionAlias",
match : "Umb.Section.Content"
}
]
}
conditions: [
{
alias: 'Umb.Condition.SectionAlias',
match: 'Umb.Section.Content',
},
],
};
export const manifests = [
dashboard
];
export const manifests = [dashboard];

View File

@@ -11,6 +11,7 @@ import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property';
import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router';
import { incrementString } from '@umbraco-cms/backoffice/utils';
import '../../components/block-grid-area-config-entry/index.js';
@customElement('umb-property-editor-ui-block-grid-areas-config')
export class UmbPropertyEditorUIBlockGridAreasConfigElement
extends UmbLitElement

View File

@@ -38,12 +38,9 @@ export class UmbPropertyEditorUIBlockGridElement
#settingsDataPathTranslator?: UmbBlockElementDataValidationPathTranslator;
#managerContext = new UmbBlockGridManagerContext(this);
//
private _value: UmbBlockGridValueModel = {
layout: {},
contentData: [],
settingsData: [],
expose: [],
};
private _value: UmbBlockGridValueModel | undefined = undefined;
#lastValue: UmbBlockGridValueModel | undefined = undefined;
public set config(config: UmbPropertyEditorConfigCollection | undefined) {
if (!config) return;
@@ -68,6 +65,13 @@ export class UmbPropertyEditorUIBlockGridElement
@property({ attribute: false })
public override set value(value: UmbBlockGridValueModel | undefined) {
this.#lastValue = value;
if (!value) {
this._value = undefined;
return;
}
const buildUpValue: Partial<UmbBlockGridValueModel> = value ? { ...value } : {};
buildUpValue.layout ??= {};
buildUpValue.contentData ??= [];
@@ -80,7 +84,7 @@ export class UmbPropertyEditorUIBlockGridElement
this.#managerContext.setSettings(this._value.settingsData);
this.#managerContext.setExposes(this._value.expose);
}
public override get value(): UmbBlockGridValueModel {
public override get value(): UmbBlockGridValueModel | undefined {
return this._value;
}
@@ -116,13 +120,24 @@ export class UmbPropertyEditorUIBlockGridElement
this.#managerContext.exposes,
]).pipe(debounceTime(20)),
([layouts, contents, settings, exposes]) => {
this._value = {
...this._value,
layout: { [UMB_BLOCK_GRID_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts },
contentData: contents,
settingsData: settings,
expose: exposes,
};
if (layouts.length === 0) {
this._value = undefined;
} else {
this._value = {
...this._value,
layout: { [UMB_BLOCK_GRID_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts },
contentData: contents,
settingsData: settings,
expose: exposes,
};
}
// If we don't have a value set from the outside or an internal value, we don't want to set the value.
// This is added to prevent the block grid from setting an empty value on startup.
if (this.#lastValue === undefined && this._value === undefined) {
return;
}
propertyContext.setValue(this._value);
},
'motherObserver',

View File

@@ -56,15 +56,19 @@ export class UmbPropertyEditorUIBlockListElement
//#catalogueModal: UmbModalRouteRegistrationController<typeof UMB_BLOCK_CATALOGUE_MODAL.DATA, undefined>;
private _value: UmbBlockListValueModel = {
layout: {},
contentData: [],
settingsData: [],
expose: [],
};
private _value: UmbBlockListValueModel | undefined = undefined;
#lastValue: UmbBlockListValueModel | undefined = undefined;
@property({ attribute: false })
public override set value(value: UmbBlockListValueModel | undefined) {
this.#lastValue = value;
if (!value) {
this._value = undefined;
return;
}
const buildUpValue: Partial<UmbBlockListValueModel> = value ? { ...value } : {};
buildUpValue.layout ??= {};
buildUpValue.contentData ??= [];
@@ -188,13 +192,24 @@ export class UmbPropertyEditorUIBlockListElement
this.#managerContext.exposes,
]).pipe(debounceTime(20)),
([layouts, contents, settings, exposes]) => {
this._value = {
...this._value,
layout: { [UMB_BLOCK_LIST_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts },
contentData: contents,
settingsData: settings,
expose: exposes,
};
if (layouts.length === 0) {
this._value = undefined;
} else {
this._value = {
...this._value,
layout: { [UMB_BLOCK_LIST_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts },
contentData: contents,
settingsData: settings,
expose: exposes,
};
}
// If we don't have a value set from the outside or an internal value, we don't want to set the value.
// This is added to prevent the block list from setting an empty value on startup.
if (this.#lastValue === undefined && this._value === undefined) {
return;
}
context.setValue(this._value);
},
'motherObserver',

View File

@@ -300,9 +300,9 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert
? html`<uui-button
@click=${this.#expose}
label=${this.localize.term('blockEditor_createThisFor', this._contentTypeName)}
look="secondary"
><uui-icon name="icon-add"></uui-icon
></uui-button>`
look="secondary">
<uui-icon name="icon-add"></uui-icon>
</uui-button>`
: nothing;
}

View File

@@ -625,10 +625,18 @@ export abstract class UmbBlockEntryContext<
//activate
public edit() {
window.location.href = this.#generateWorkspaceEditContentPath(this.#workspacePath.value, this.getContentKey());
window.history.pushState(
{},
'',
this.#generateWorkspaceEditContentPath(this.#workspacePath.value, this.getContentKey()),
);
}
public editSettings() {
window.location.href = this.#generateWorkspaceEditSettingsPath(this.#workspacePath.value, this.getContentKey());
window.history.pushState(
{},
'',
this.#generateWorkspaceEditSettingsPath(this.#workspacePath.value, this.getContentKey()),
);
}
async requestDelete() {

View File

@@ -5,6 +5,5 @@ export * from './auth.context.token.js';
export * from './modals/index.js';
export type * from './models/openApiConfiguration.js';
export * from './components/index.js';
export type * from './auth-provider.extension.js';
export type * from './types.js';

View File

@@ -1,5 +1,7 @@
import type { ManifestAuthProvider } from './auth-provider.extension.js';
export type * from './auth-provider.extension.js';
/**
* User login state that can be used to determine the current state of the user.
* @example 'loggedIn'

View File

@@ -1,4 +1,4 @@
import type { ManifestCollectionAction } from '../../extensions/index.js';
import type { ManifestCollectionAction } from '../../extensions/types.js';
export interface ManifestCollectionActionCreateKind extends ManifestCollectionAction {
type: 'collectionAction';

View File

@@ -1,4 +1,4 @@
import type { ManifestCollectionView } from './extensions/index.js';
import type { ManifestCollectionView } from './extensions/types.js';
import { umbExtensionsRegistry } from '../extension-registry/index.js';
import { UmbCollectionViewManager } from './collection-view.manager.js';
import { expect } from '@open-wc/testing';

View File

@@ -1,4 +1,4 @@
import type { ManifestCollectionView } from './extensions/index.js';
import type { ManifestCollectionView } from './extensions/types.js';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import { UmbExtensionsManifestInitializer, createExtensionElement } from '@umbraco-cms/backoffice/extension-api';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

View File

@@ -1,5 +1,5 @@
import type { UmbCollectionConfiguration } from './types.js';
import type { ManifestCollection } from './extensions/index.js';
import type { ManifestCollection } from './extensions/types.js';
import { customElement, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbExtensionElementAndApiSlotElementBase } from '@umbraco-cms/backoffice/extension-registry';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';

View File

@@ -1,5 +1,5 @@
import { UMB_COLLECTION_CONTEXT } from '../default/index.js';
import type { ManifestCollectionView } from '../extensions/index.js';
import type { ManifestCollectionView } from '../extensions/types.js';
import type { UmbCollectionLayoutConfiguration } from '../types.js';
import { UMB_ROUTE_CONTEXT } from '../../router/route.context.js';
import { css, customElement, html, nothing, query, repeat, state } from '@umbraco-cms/backoffice/external/lit';

View File

@@ -8,7 +8,7 @@ import type {
} from '../types.js';
import type { UmbCollectionFilterModel } from '../collection-filter-model.interface.js';
import type { UmbCollectionRepository } from '../repository/collection-repository.interface.js';
import type { ManifestCollection } from '../extensions/index.js';
import type { ManifestCollection } from '../extensions/types.js';
import { UMB_COLLECTION_CONTEXT } from './collection-default.context-token.js';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { UmbArrayState, UmbBasicState, UmbNumberState, UmbObjectState } from '@umbraco-cms/backoffice/observable-api';

View File

@@ -1,9 +1,11 @@
import type { ManifestCollection } from './extensions/index.js';
import type { ManifestCollection } from './extensions/types.js';
import type { Observable } from '@umbraco-cms/backoffice/external/rxjs';
import type { UmbPaginationManager } from '@umbraco-cms/backoffice/utils';
export type * from './extensions/index.js';
export type * from './action/create/types.js';
export type * from './extensions/types.js';
export type * from './conditions/types.js';
export type * from './workspace-view/types.js';
/** @deprecated No longer used internally. This will be removed in Umbraco 17. [LK] */
export interface UmbCollectionBulkActionPermissions {
@@ -50,5 +52,3 @@ export interface UmbCollectionContext {
items: Observable<any[]>;
totalItems: Observable<number>;
}
export type * from './extensions/index.js';

View File

@@ -269,9 +269,8 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements
#deleteTab(tabId?: string) {
if (!tabId) return;
this.#workspaceContext?.structure.removeContainer(null, tabId);
// TODO: We should only navigate away if it was the last tab and if it was the active one... [NL]
if (this.#tabsStructureHelper?.isOwnerChildContainer(tabId)) {
window.history.replaceState(null, '', this._routerPath + (this._routes[0]?.path ?? '/root'));
if (this._activeTabId === tabId) {
this._activeTabId = undefined;
}
}
async #addTab() {

View File

@@ -1,6 +1,8 @@
import type { UmbPropertyValueData } from '@umbraco-cms/backoffice/property';
import type { UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant';
export type * from './collection/types.js';
export interface UmbElementDetailModel {
values: Array<UmbElementValueModel>;
}

View File

@@ -1,5 +1,4 @@
import type { MetaEntityActionDefaultKind } from '../../default/index.js';
import type { ManifestEntityAction } from '../../entity-action.extension.js';
import type { ManifestEntityAction, MetaEntityActionDefaultKind } from '../../types.js';
export interface ManifestEntityActionCreateKind extends ManifestEntityAction<MetaEntityActionCreateKind> {
type: 'entityAction';

View File

@@ -1,5 +1,4 @@
import type { MetaEntityActionDefaultKind } from '../../default/index.js';
import type { ManifestEntityAction } from '../../entity-action.extension.js';
import type { ManifestEntityAction, MetaEntityActionDefaultKind } from '../../types.js';
export interface ManifestEntityActionDeleteKind extends ManifestEntityAction<MetaEntityActionDeleteKind> {
type: 'entityAction';

View File

@@ -1 +0,0 @@
export type * from './types.js';

View File

@@ -5,10 +5,6 @@ export * from './constants.js';
export * from './entity-action-base.js';
export * from './entity-action-list.element.js';
export * from './entity-action.event.js';
export type * from './default/index.js';
export type * from './entity-action-element.interface.js';
export type * from './entity-action.extension.js';
export type * from './entity-action.interface.js';
export type * from './types.js';
export { UmbRequestReloadStructureForEntityEvent } from './request-reload-structure-for-entity.event.js';

View File

@@ -1,5 +1,10 @@
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
export type * from './default/types.js';
export type * from './entity-action-element.interface.js';
export type * from './entity-action.extension.js';
export type * from './entity-action.interface.js';
export interface UmbEntityActionArgs<MetaArgsType> extends UmbEntityModel {
meta: MetaArgsType;
}

View File

@@ -1,5 +1,3 @@
export * from './constants.js';
export * from './entity-create-option-action-base.js';
export type * from './entity-create-option-action.extension.js';
export type * from './entity-create-option-action.interface.js';
export type * from './types.js';

View File

@@ -1,5 +1,8 @@
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
export type * from './entity-create-option-action.extension.js';
export type * from './entity-create-option-action.interface.js';
export interface UmbEntityCreateOptionActionArgs<MetaArgsType> extends UmbEntityModel {
meta: MetaArgsType;
}

View File

@@ -1,4 +1,4 @@
import type { ManifestExternalLoginProvider } from '../extensions/index.js';
import type { ManifestExternalLoginProvider } from './types.js';
export interface UmbExternalLoginProviderElement extends HTMLElement {
manifest?: ManifestExternalLoginProvider;

View File

@@ -2,7 +2,7 @@ export * from './conditions/index.js';
export * from './initializers/index.js';
export * from './registry.js';
export * from './utils/index.js';
export type * from './models/index.js';
export type * from './extensions/index.js';
export type * from './models/types.js';
export type * from './extensions/types.js';
export { UmbExtensionElementAndApiSlotElementBase } from './extension-element-and-api-slot-element-base.js';

View File

@@ -3,4 +3,3 @@ export * from './icon-registry.context-token.js';
export * from './icon-registry.context.js';
export * from './icon.registry.js';
export type * from './types.js';
export type * from './extensions/icons.extension.js';

View File

@@ -1,5 +1,7 @@
import type { JsLoaderProperty } from '@umbraco-cms/backoffice/extension-api';
export type * from './extensions/icons.extension.js';
export interface UmbIconDefinition<JsType = any> {
name: string;
path: JsLoaderProperty<JsType>;

View File

@@ -1,2 +1 @@
export * from './menu-item-default.element.js';
export type * from './link/index.js';

View File

@@ -1 +0,0 @@
export type * from './types.js';

View File

@@ -0,0 +1 @@
export type * from './link/types.js';

View File

@@ -0,0 +1 @@
export type * from './menu-item/types.js';

View File

@@ -1,9 +1,7 @@
export * from './components/index.js';
export * from './menu-tree-structure-workspace-context-base.js';
export * from './menu-variant-tree-structure-workspace-context-base.js';
export type * from './menu-item-element.interface.js';
export type * from './menu-item.extension.js';
export type * from './menu.extension.js';
export type * from './types.js';
export type { UmbMenuStructureWorkspaceContext } from './menu-structure-workspace-context.interface.js';

View File

@@ -1,5 +1,10 @@
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
export type * from './components/types.js';
export type * from './conditions/types.js';
export type * from './menu-item-element.interface.js';
export type * from './menu-item.extension.js';
export type * from './menu.extension.js';
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface UmbStructureItemModelBase extends UmbEntityModel {}

View File

@@ -1,7 +1,7 @@
import type { UUIModalElement, UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui';
import type { ElementLoaderProperty } from '@umbraco-cms/backoffice/extension-api';
export type * from './extensions/index.js';
export type * from './extensions/types.js';
export interface UmbPickerModalData<ItemType> {
multiple?: boolean;

View File

@@ -1,4 +1,3 @@
export * from './manager/index.js';
export * from './picker-search-field.element.js';
export * from './picker-search-result.element.js';
export type * from './result-item/index.js';

View File

@@ -0,0 +1 @@
export type * from './result-item/types.js';

View File

@@ -4,3 +4,5 @@ export interface UmbPickerContextConfig {
queryParams?: object;
};
}
export type * from './search/types.js';

View File

@@ -2,5 +2,5 @@ export * from './components/index.js';
export * from './config/index.js';
export * from './constants.js';
export * from './events/index.js';
export type * from './extensions/index.js';
export * from './ui-picker-modal/index.js';
export type * from './extensions/types.js';

View File

@@ -1,2 +1 @@
export type * from './types.js';
export * from './empty-recycle-bin.action.js';

View File

@@ -2,7 +2,7 @@ import type { UmbTreeItemModel, UmbTreeRootModel, UmbTreeStartNode } from '../ty
import type { UmbTreeRepository } from '../data/tree-repository.interface.js';
import type { UmbTreeContext } from '../tree-context.interface.js';
import type { UmbTreeRootItemsRequestArgs } from '../data/types.js';
import type { ManifestTree } from '../extensions/index.js';
import type { ManifestTree } from '../extensions/types.js';
import { UMB_TREE_CONTEXT } from './default-tree.context-token.js';
import { type UmbActionEventContext, UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
import { type ManifestRepository, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

View File

@@ -1,3 +1 @@
export type { UmbMoveDataSource } from './move-data-source.interface.js';
export type { UmbMoveRepository } from './move-repository.interface.js';
export type * from './types.js';
export { UmbMoveToEntityAction } from './move-to.action.js';

View File

@@ -1,5 +1,7 @@
import type { ManifestEntityAction, MetaEntityActionDefaultKind } from '@umbraco-cms/backoffice/entity-action';
export type { UmbMoveDataSource } from './move-data-source.interface.js';
export type { UmbMoveRepository } from './move-repository.interface.js';
export interface UmbMoveToRequestArgs {
unique: string;
destination: {

View File

@@ -1,4 +1 @@
export { UmbSortChildrenOfEntityAction } from './sort-children-of.action.js';
export type { UmbSortChildrenOfRepository } from './sort-children-of-repository.interface.js';
export type { UmbSortChildrenOfDataSource } from './sort-children-of-data-source.interface.js';
export type * from './types.js';

View File

@@ -1,5 +1,8 @@
import type { ManifestEntityAction, MetaEntityActionDefaultKind } from '@umbraco-cms/backoffice/entity-action';
export type { UmbSortChildrenOfRepository } from './sort-children-of-repository.interface.js';
export type { UmbSortChildrenOfDataSource } from './sort-children-of-data-source.interface.js';
export interface UmbSortChildrenOfArgs {
unique: string | null;
sorting: Array<{ unique: string; sortOrder: number }>;

View File

@@ -0,0 +1,4 @@
export type * from './duplicate-to/types.js';
export type * from './move/types.js';
export type * from './reload-tree-item-children/types.js';
export type * from './sort-children-of/types.js';

View File

@@ -1,2 +1 @@
export * from './create-folder.action.js';
export type * from './types.js';

View File

@@ -1,2 +1 @@
export * from './delete-folder.action.js';
export type * from './types.js';

View File

@@ -0,0 +1,3 @@
export type * from './create-folder/types.js';
export type * from './delete-folder/types.js';
export type * from './update-folder/types.js';

View File

@@ -1,2 +1 @@
export type * from './types.js';
export * from './update-folder.action.js';

View File

@@ -1,3 +1,2 @@
export type * from './types.js';
export * from './modal/index.js';
export * from './entity-action/index.js';

View File

@@ -1,6 +1,8 @@
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
import type { MetaEntityActionDefaultKind } from '@umbraco-cms/backoffice/entity-action';
export type * from './entity-action/types.js';
export interface UmbFolderModel extends UmbEntityModel {
name: string;
}

View File

@@ -8,8 +8,6 @@ export * from './folder/index.js';
export * from './tree-item/index.js';
export * from './tree-menu-item-default/index.js';
export * from './tree.element.js';
export type * from './entity-actions/move/index.js';
export type * from './extensions/index.js';
export type * from './types.js';
export type { UmbTreePickerModalData, UmbTreePickerModalValue } from './tree-picker-modal/index.js';

View File

@@ -2,7 +2,7 @@ import type { UmbTreeItemContext } from '../tree-item-context.interface.js';
import { UMB_TREE_CONTEXT, type UmbDefaultTreeContext } from '../../default/index.js';
import type { UmbTreeItemModel, UmbTreeRootModel } from '../../types.js';
import { UmbRequestReloadTreeItemChildrenEvent } from '../../entity-actions/reload-tree-item-children/index.js';
import type { ManifestTreeItem } from '../../extensions/index.js';
import type { ManifestTreeItem } from '../../extensions/types.js';
import { map } from '@umbraco-cms/backoffice/external/rxjs';
import { UmbArrayState, UmbBooleanState, UmbObjectState, UmbStringState } from '@umbraco-cms/backoffice/observable-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';

View File

@@ -1,4 +1,4 @@
import type { ManifestTreeItem } from '../extensions/index.js';
import type { ManifestTreeItem } from '../extensions/types.js';
import { customElement, property } from '@umbraco-cms/backoffice/external/lit';
import {
UmbExtensionElementAndApiSlotElementBase,

View File

@@ -1,2 +1 @@
export * from './tree-menu-item-default.element.js';
export type * from './types.js';

View File

@@ -1,4 +1,4 @@
import type { ManifestTree } from './extensions/index.js';
import type { ManifestTree } from './extensions/types.js';
import { customElement } from '@umbraco-cms/backoffice/external/lit';
import { UmbExtensionElementAndApiSlotElementBase } from '@umbraco-cms/backoffice/extension-registry';

View File

@@ -1,5 +1,9 @@
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
export type * from './extensions/index.js';
export type * from './entity-actions/types.js';
export type * from './extensions/types.js';
export type * from './folder/types.js';
export type * from './tree-menu-item-default/types.js';
export interface UmbTreeItemModelBase extends UmbEntityModel {
name: string;

View File

@@ -1 +0,0 @@
export type * from './types.js';

View File

@@ -34,7 +34,7 @@ export class UmbWorkspaceIsNewRedirectController extends UmbControllerBase {
id: unique,
});
this.destroy();
window.history.pushState({}, '', newPath);
window.history.replaceState({}, '', newPath);
}
}
}

View File

@@ -15,7 +15,4 @@ export * from './utils/object-to-property-value-array.function.js';
export * from './workspace-property-dataset/index.js';
export * from './workspace.context-token.js';
export * from './workspace.element.js';
export type * from './conditions/index.js';
export type * from './data-manager/index.js';
export type * from './types.js';
export type * from './workspace-context.interface.js';

View File

@@ -0,0 +1 @@
export type * from './default/types.js';

View File

@@ -1,6 +1,11 @@
import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity';
export type * from './extensions/types.js';
export type * from './kinds/types.js';
export type * from './conditions/types.js';
export type * from './data-manager/types.js';
export type * from './workspace-context.interface.js';
/**
* @deprecated Use `UmbEntityUnique`instead.
*/

View File

@@ -1,7 +1,7 @@
import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api';
import type { PublicAccessRequestModel } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
import { tryExecute, tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
/**
* A data source for the Document Public Access that fetches data from the server
@@ -41,7 +41,9 @@ export class UmbDocumentPublicAccessServerDataSource {
*/
async read(unique: string) {
if (!unique) throw new Error('unique is missing');
return tryExecuteAndNotify(this.#host, DocumentService.getDocumentByIdPublicAccess({ id: unique }));
// NOTE: The entity will not be present, when fetching Public Access for a descendant of a protected Document.
// This is a perfectly valid scenario, which is handled in the view. In other words, just use tryExecute here.
return tryExecute(DocumentService.getDocumentByIdPublicAccess({ id: unique }));
}
/**

View File

@@ -102,11 +102,11 @@ export class UmbDocumentWorkspaceEditorElement extends UmbLitElement {
if (!route) {
// 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}`);
history.replaceState({}, '', `${this.#workspaceRoute}/${routes[routes.length - 3].path}`);
return;
}
history.pushState({}, '', `${this.#workspaceRoute}/${route?.path}`);
history.replaceState({}, '', `${this.#workspaceRoute}/${route?.path}`);
},
});
}

View File

@@ -1,3 +1,3 @@
export * from './constants.js';
export * from './repository/index.js';
export type * from './extensions/index.js';
export type * from './extensions/types.js';

View File

@@ -10,11 +10,10 @@ import type {
import {
UmbBlockRteEntriesContext,
UmbBlockRteManagerContext,
type UmbBlockRteLayoutModel,
type UmbBlockRteTypeModel,
} from '@umbraco-cms/backoffice/block-rte';
import { UMB_PROPERTY_CONTEXT, UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property';
import type { UmbBlockValueType } from '@umbraco-cms/backoffice/block';
import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
// eslint-disable-next-line local-rules/enforce-element-suffix-on-element-class-name
export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement implements UmbPropertyEditorUiElement {
@@ -39,7 +38,7 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im
public set value(value: UmbPropertyEditorUiValueType | undefined) {
if (!value) {
this._value = undefined;
this._markup = '';
this._markup = this._latestMarkup = '';
this.#managerContext.setLayouts([]);
this.#managerContext.setContents([]);
this.#managerContext.setSettings([]);
@@ -134,30 +133,38 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im
this.#managerContext.setLayouts(layouts);
});
// Observe the value of the property and update the editor value.
this.observe(this.#managerContext.layouts, (layouts) => {
const blocksValue =
this._value && layouts?.length > 0
? { ...this._value.blocks, layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts } }
: undefined;
this.observe(
observeMultiple([
this.#managerContext.layouts,
this.#managerContext.contents,
this.#managerContext.settings,
this.#managerContext.exposes,
]),
([layouts, contents, settings, exposes]) => {
if (layouts.length === 0) {
this._value = undefined;
} else {
this._value = {
markup: this._latestMarkup,
blocks: {
layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts },
contentData: contents,
settingsData: settings,
expose: exposes,
},
};
}
this.#setBlocksValue(blocksValue);
});
// If we don't have a value set from the outside or an internal value, we don't want to set the value.
// This is added to prevent the block list from setting an empty value on startup.
if (!this._latestMarkup && !this._value?.markup) {
return;
}
this.observe(this.#managerContext.contents, (contents) => {
const blocksValue = this._value ? { ...this._value.blocks, contentData: contents } : undefined;
this.#setBlocksValue(blocksValue);
});
this.observe(this.#managerContext.settings, (settings) => {
const blocksValue = this._value ? { ...this._value.blocks, settingsData: settings } : undefined;
this.#setBlocksValue(blocksValue);
});
this.observe(this.#managerContext.exposes, (exposes) => {
const blocksValue = this._value ? { ...this._value.blocks, expose: exposes } : undefined;
this.#setBlocksValue(blocksValue);
});
context.setValue(this._value);
},
'motherObserver',
);
});
this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (context) => {
@@ -181,19 +188,6 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im
});
}
#setBlocksValue(blocksValue?: UmbBlockValueType<UmbBlockRteLayoutModel>) {
if (!blocksValue || !this._value) {
return;
}
this._value = {
...this._value,
blocks: blocksValue,
};
this._fireChangeEvent();
}
protected _fireChangeEvent() {
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}

View File

@@ -16,7 +16,7 @@ import { UmbExtensionsManifestInitializer, createExtensionApi } from '@umbraco-c
import '../search-result/search-result-item.element.js';
import type { UmbModalContext } from '@umbraco-cms/backoffice/modal';
import type { ManifestSearchResultItem } from '../extensions/index.js';
import type { ManifestSearchResultItem } from '../extensions/types.js';
type SearchProvider = {
name: string;

View File

@@ -2,6 +2,11 @@ import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
import type { UmbPagedModel, UmbRepositoryResponse } from '@umbraco-cms/backoffice/repository';
export type { UmbSearchDataSource } from './search-data-source.interface.js';
export type { UmbSearchRepository } from './search-repository.interface.js';
export type * from './extensions/types.js';
// TODO: lower requirement for search provider item type
export type UmbSearchResultItemModel = {
entityType: string;
@@ -22,8 +27,3 @@ export interface UmbSearchProvider<
> extends UmbApi {
search(args: SearchRequestArgsType): Promise<UmbRepositoryResponse<UmbPagedModel<SearchResultItemType>>>;
}
export type { UmbSearchDataSource } from './search-data-source.interface.js';
export type { UmbSearchRepository } from './search-repository.interface.js';
export type * from './extensions/index.js';

View File

@@ -76,31 +76,31 @@ export const defaultFallbackConfig: RawEditorOptions = {
// If we try to open link in a new tab, then we want to skip skip:
//if ((isWindows && e.ctrlKey) || (!isWindows && e.metaKey)) return;
const composedPaths = 'composedPath' in e ? e.composedPath() : null;
// Find the target by using the composed path to get the element through the shadow boundaries.
// Notice the difference here compared to RouterSlots implementation [NL]
const $anchor: HTMLAnchorElement = (('composedPath' in e) as any)
? (e
.composedPath()
.find(($elem) => $elem instanceof HTMLAnchorElement || ($elem as any).tagName === 'A') as HTMLAnchorElement)
: (e.target as HTMLAnchorElement);
const $anchor: HTMLAnchorElement =
(composedPaths?.find(
($elem) => $elem instanceof HTMLAnchorElement || ($elem as any).tagName === 'A',
) as HTMLAnchorElement) ?? (e.target as HTMLAnchorElement);
// Abort if the event is not about the anchor tag
if ($anchor == null || !($anchor instanceof HTMLAnchorElement || ($anchor as any).tagName === 'A')) {
// Abort if the event is not about the anchor tag or the anchor tag has the attribute [data-router-slot]="disabled"
if (
$anchor == null ||
!($anchor instanceof HTMLAnchorElement || ($anchor as any).tagName === 'A') ||
$anchor.dataset['routerSlot'] === 'disabled'
) {
return;
}
// Get the HREF value from the anchor tag
const href = $anchor.href;
// Abort if the anchor tag is not inside a block element
const isInsideBlockElement =
composedPaths?.some(
($elem) => ($elem as any).tagName === 'UMB-RTE-BLOCK' || ($elem as any).tagName === 'UMB-RTE-BLOCK-INLINE',
) ?? false;
// Only handle the anchor tag if the follow holds true:
// - The HREF is relative to the origin of the current location.
// - The target is targeting the current frame.
// - The anchor doesn't have the attribute [data-router-slot]="disabled"
if (
!href.startsWith(location.origin) ||
($anchor.target !== '' && $anchor.target !== '_self') ||
$anchor.dataset['routerSlot'] === 'disabled'
) {
if (!isInsideBlockElement) {
return;
}

View File

@@ -1,3 +1,3 @@
export * from './constants.js';
export * from './components/index.js';
export type * from './plugins/index.js';
export type * from './plugins/types.js';

View File

@@ -4,5 +4,3 @@ export * from './controllers/ufm-virtual-render.controller.js';
export * from './filters/base.filter.js';
export * from './plugins/index.js';
export type * from './types.js';
export type * from './ufm-component.extension.js';
export type * from './ufm-filter.extension.js';

View File

@@ -1 +1,2 @@
export type * from './ufm-filter.extension.js';
export type * from './ufm-component.extension.js';

View File

@@ -1,2 +1 @@
export type * from './is-admin/is-admin.condition-config.js';
export type * from './is-admin/types.js';

View File

@@ -1,6 +1,4 @@
export * from './components/index.js';
export * from './modals/index.js';
export type * from './user-granular-permission.extension.js';
export type * from './entity-user-permission.extension.js';
export type * from './types.js';

View File

@@ -1,3 +1,5 @@
export type * from './user-granular-permission.extension.js';
export type * from './entity-user-permission.extension.js';
export interface UmbUserPermissionModel {
$type: string;
verbs: Array<string>;