Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { UMB_BLOCK_GRID_PROPERTY_EDITOR_SCHEMA_ALIAS } from '../../../property-e
import type { UmbBlockGridValueModel } from '../../../types.js';
import { UmbBlockToBlockGridClipboardPastePropertyValueTranslator } from './block-to-block-grid-paste-translator.js';
import type { UmbBlockClipboardEntryValueModel } from '@umbraco-cms/backoffice/block';
import type { UmbBlockGridPropertyEditorConfig } from '../../../property-editors/block-grid-editor/types.js';

@customElement('test-controller-host')
class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
Expand Down Expand Up @@ -55,22 +56,26 @@ describe('UmbBlockToBlockGridClipboardPastePropertyValueTranslator', () => {
settingsData: blockGridPropertyValue.settingsData,
};

const config1: Array<{ alias: string; value: [{ contentElementTypeKey: string }] }> = [
const config1: UmbBlockGridPropertyEditorConfig = [
{
alias: 'blocks',
value: [
{
allowAtRoot: true,
allowInAreas: true,
contentElementTypeKey: 'contentTypeKey',
},
],
},
];

const config2: Array<{ alias: string; value: [{ contentElementTypeKey: string }] }> = [
const config2: UmbBlockGridPropertyEditorConfig = [
{
alias: 'blocks',
value: [
{
allowAtRoot: true,
allowInAreas: true,
contentElementTypeKey: 'contentTypeKey2',
},
],
Expand Down Expand Up @@ -101,12 +106,12 @@ describe('UmbBlockToBlockGridClipboardPastePropertyValueTranslator', () => {

describe('isCompatibleValue', () => {
it('returns true if the value is compatible', async () => {
const result = await copyTranslator.isCompatibleValue(blockClipboardEntryValue, config1);
const result = await copyTranslator.isCompatibleValue(blockGridPropertyValue, config1);
expect(result).to.be.true;
});

it('returns false if the value is not compatible', async () => {
const result = await copyTranslator.isCompatibleValue(blockClipboardEntryValue, config2);
const result = await copyTranslator.isCompatibleValue(blockGridPropertyValue, config2);
expect(result).to.be.false;
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { UmbBlockGridLayoutModel, UmbBlockGridValueModel } from '../../../types.js';
import { UMB_BLOCK_GRID_PROPERTY_EDITOR_SCHEMA_ALIAS } from '../../../constants.js';
import type { UmbBlockGridPropertyEditorConfig } from '../../../property-editors/block-grid-editor/types.js';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbClipboardPastePropertyValueTranslator } from '@umbraco-cms/backoffice/clipboard';
import type { UmbBlockClipboardEntryValueModel, UmbBlockLayoutBaseModel } from '@umbraco-cms/backoffice/block';
Expand Down Expand Up @@ -44,19 +45,18 @@ export class UmbBlockToBlockGridClipboardPastePropertyValueTranslator

/**
* Determines if a block clipboard entry value is compatible with the Block Grid property editor.
* @param {UmbBlockClipboardEntryValueModel} value The block clipboard entry value.
* @param {*} config The Block Grid property editor configuration.
* @param {UmbBlockClipboardEntryValueModel} propertyValue The block clipboard entry value.
* @param {UmbBlockGridPropertyEditorConfig} config The Block Grid property editor configuration.
* @returns {Promise<boolean>} A promise that resolves with a boolean indicating if the value is compatible.
* @memberof UmbBlockToBlockGridClipboardPastePropertyValueTranslator
*/
async isCompatibleValue(
value: UmbBlockClipboardEntryValueModel,
// TODO: Replace any with the correct type.
config: Array<{ alias: string; value: [{ contentElementTypeKey: string }] }>,
propertyValue: UmbBlockGridValueModel,
config: UmbBlockGridPropertyEditorConfig,
): Promise<boolean> {
const allowedBlockContentTypes =
config.find((c) => c.alias === 'blocks')?.value.map((b) => b.contentElementTypeKey) ?? [];
const blockContentTypes = value.contentData.map((c) => c.contentTypeKey);
const blockContentTypes = propertyValue.contentData.map((c) => c.contentTypeKey);
return blockContentTypes?.every((b) => allowedBlockContentTypes.includes(b)) ?? false;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { UmbBlockGridPropertyEditorConfig } from '../../../property-editors/block-grid-editor/types.js';
import { UMB_BLOCK_GRID_PROPERTY_EDITOR_SCHEMA_ALIAS } from '../../../property-editors/constants.js';
import type { UmbBlockGridValueModel } from '../../../types.js';
import type { UmbGridBlockClipboardEntryValueModel } from '../../types.js';
Expand Down Expand Up @@ -35,20 +36,22 @@ export class UmbGridBlockToBlockGridClipboardPastePropertyValueTranslator

/**
* Checks if the clipboard entry value is compatible with the config.
* @param {UmbGridBlockClipboardEntryValueModel} value - The grid block clipboard entry value.
* @param {UmbGridBlockClipboardEntryValueModel} propertyValue - The grid block clipboard entry value.
* @param {*} config - The Property Editor config.
* @param {(value, config) => Promise<boolean>} filter - The filter function.
* @returns {Promise<boolean>} {Promise<boolean>}
* @memberof UmbGridBlockToBlockGridClipboardPastePropertyValueTranslator
*/
async isCompatibleValue(
value: UmbGridBlockClipboardEntryValueModel,
// TODO: Replace any with the correct type.
config: Array<{ alias: string; value: [{ contentElementTypeKey: string }] }>,
propertyValue: UmbBlockGridValueModel,
config: UmbBlockGridPropertyEditorConfig,
filter?: (propertyValue: UmbBlockGridValueModel, config: UmbBlockGridPropertyEditorConfig) => Promise<boolean>,
): Promise<boolean> {
const allowedBlockContentTypes =
config.find((c) => c.alias === 'blocks')?.value.map((b) => b.contentElementTypeKey) ?? [];
const blockContentTypes = value.contentData.map((c) => c.contentTypeKey);
return blockContentTypes?.every((b) => allowedBlockContentTypes.includes(b)) ?? false;
const blocksConfig = config.find((c) => c.alias === 'blocks');
const allowedBlockContentTypes = blocksConfig?.value.map((b) => b.contentElementTypeKey) ?? [];
const blockContentTypes = propertyValue.contentData.map((c) => c.contentTypeKey);
const allContentTypesAllowed = blockContentTypes?.every((b) => allowedBlockContentTypes.includes(b)) ?? false;
return allContentTypesAllowed && (!filter || (await filter(propertyValue, config)));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { UMB_BLOCK_GRID_PROPERTY_EDITOR_UI_ALIAS } from '../property-editors/constants.js';
import { manifests as blockManifests } from './block/manifests.js';
import { manifests as gridBlockManifests } from './grid-block/manifests.js';
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
import {
UMB_PROPERTY_HAS_VALUE_CONDITION_ALIAS,
UMB_WRITABLE_PROPERTY_CONDITION_ALIAS,
} from '@umbraco-cms/backoffice/property';

const forPropertyEditorUis = [UMB_BLOCK_GRID_PROPERTY_EDITOR_UI_ALIAS];

export const manifests: Array<UmbExtensionManifest> = [
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
{
type: 'propertyContext',
kind: 'clipboard',
Expand All @@ -31,18 +32,6 @@ export const manifests: Array<UmbExtensionManifest> = [
},
],
},
{
type: 'propertyAction',
kind: 'pasteFromClipboard',
alias: 'Umb.PropertyAction.BlockGrid.Clipboard.Paste',
name: 'Block Grid Paste From Clipboard Property Action',
forPropertyEditorUis,
conditions: [
{
alias: UMB_WRITABLE_PROPERTY_CONDITION_ALIAS,
},
],
},
...blockManifests,
...gridBlockManifests,
];
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { UmbBlockDataModel } from '../../block/index.js';

Check notice on line 1 in src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (v15/dev)

✅ Getting better: Overall Code Complexity

The mean cyclomatic complexity decreases from 4.42 to 4.35, threshold = 4. This file has many conditional statements (e.g. if, for, while) across its implementation, leading to lower code health. Avoid adding more conditionals.
import { UMB_BLOCK_CATALOGUE_MODAL, UmbBlockEntriesContext } from '../../block/index.js';
import {
UMB_BLOCK_GRID_ENTRY_CONTEXT,
Expand All @@ -14,6 +14,7 @@
UmbBlockGridValueModel,
} from '../types.js';
import { forEachBlockLayoutEntryOf } from '../utils/index.js';
import type { UmbBlockGridPropertyEditorConfig } from '../property-editors/block-grid-editor/types.js';
import { UMB_BLOCK_GRID_MANAGER_CONTEXT } from './block-grid-manager.context-token.js';
import type { UmbBlockGridScalableContainerContext } from './block-grid-scale-manager/block-grid-scale-manager.controller.js';
import {
Expand Down Expand Up @@ -170,7 +171,7 @@

// TODO: consider moving some of this logic to the clipboard property context
const propertyContext = await this.getContext(UMB_PROPERTY_CONTEXT);
const config = propertyContext.getConfig();
const config = propertyContext.getConfig() as UmbBlockGridPropertyEditorConfig;
const valueResolver = new UmbClipboardPastePropertyValueTranslatorValueResolver(this);

return {
Expand Down Expand Up @@ -198,7 +199,8 @@
clipboardEntryDetail.values,
UMB_BLOCK_GRID_PROPERTY_EDITOR_UI_ALIAS,
);
return pasteTranslator.isCompatibleValue(value, config);

return pasteTranslator.isCompatibleValue(value, config, (value) => this.#clipboardEntriesFilter(value));
}

return true;
Expand Down Expand Up @@ -269,6 +271,21 @@
});
}

async #clipboardEntriesFilter(propertyValue: UmbBlockGridValueModel) {
const allowedElementTypeKeys = this.#retrieveAllowedElementTypes().map((x) => x.contentElementTypeKey);

const rootContentKeys = propertyValue.layout['Umbraco.BlockGrid']?.map((block) => block.contentKey) ?? [];
const rootContentTypeKeys = propertyValue.contentData
.filter((content) => rootContentKeys.includes(content.key))
.map((content) => content.contentTypeKey);

const allContentTypesAllowed = rootContentTypeKeys.every((contentKey) =>
allowedElementTypeKeys.includes(contentKey),
);

return allContentTypesAllowed;
}

protected _gotBlockManager() {
if (!this._manager) return;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { manifests as componentManifests } from './components/manifests.js';
import { manifests as propertyEditorManifests } from './property-editors/manifests.js';
import { manifests as propertyValueClonerManifests } from './property-value-cloner/manifests.js';
import { manifests as workspaceManifests } from './workspace/manifests.js';
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';

export const manifests: Array<UmbExtensionManifest> = [
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
...clipboardManifests,
...componentManifests,
...propertyEditorManifests,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { manifest as blockGridSchemaManifest } from './Umbraco.BlockGrid.js';
import { UMB_BLOCK_GRID_PROPERTY_EDITOR_SCHEMA_ALIAS, UMB_BLOCK_GRID_PROPERTY_EDITOR_UI_ALIAS } from './constants.js';
import { manifests as propertyActionManifests } from './property-actions/manifests.js';
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
import { UmbStandardBlockValueResolver } from '@umbraco-cms/backoffice/block';

export const manifests: Array<UmbExtensionManifest> = [
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
{
type: 'propertyEditorUi',
alias: UMB_BLOCK_GRID_PROPERTY_EDITOR_UI_ALIAS,
Expand Down Expand Up @@ -66,7 +68,6 @@ export const manifests: Array<UmbExtensionManifest> = [
},
},
},
blockGridSchemaManifest,
{
type: 'propertyValueResolver',
alias: 'Umb.PropertyValueResolver.BlockGrid',
Expand All @@ -76,4 +77,6 @@ export const manifests: Array<UmbExtensionManifest> = [
editorAlias: UMB_BLOCK_GRID_PROPERTY_EDITOR_SCHEMA_ALIAS,
},
},
blockGridSchemaManifest,
...propertyActionManifests,
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { UmbBlockGridValueModel } from '../../../types.js';
import type { UmbBlockGridPropertyEditorConfig } from '../types.js';
import { UmbPasteFromClipboardPropertyAction } from '@umbraco-cms/backoffice/clipboard';

/**
* The Block Grid Paste From Clipboard Property Action.
* @exports
* @class UmbBlockGridPasteFromClipboardPropertyAction
* @augments UmbPasteFromClipboardPropertyAction
*/
export class UmbBlockGridPasteFromClipboardPropertyAction extends UmbPasteFromClipboardPropertyAction {
/**
* Filters the picker based on the block grid property editor config.
* @param {UmbBlockGridValueModel} propertyValue The property editor value.
* @param {UmbBlockGridPropertyEditorConfig} config The property editor config.
* @override
* @protected
* @memberof UmbBlockGridPasteFromClipboardPropertyAction
*/
protected override async _pickerFilter(
propertyValue: UmbBlockGridValueModel,
config: UmbBlockGridPropertyEditorConfig,
) {
// The property action always paste in the root of the grid so
// we need to check if the content types are allowed at the root
const blocksConfig = config.find((configValue) => configValue.alias === 'blocks');

const allowedRootContentTypeKeys =
blocksConfig?.value
.map((blockConfig) => {
if (blockConfig.allowAtRoot) {
return blockConfig.contentElementTypeKey;
} else {
return undefined;
}
})
.filter((contentTypeKey) => contentTypeKey !== undefined) ?? [];

const rootContentKeys = propertyValue.layout['Umbraco.BlockGrid']?.map((block) => block.contentKey) ?? [];
const rootContentTypeKeys = propertyValue.contentData
.filter((content) => rootContentKeys.includes(content.key))
.map((content) => content.contentTypeKey);

// ensure all content types in the paste value are allowed in the grid root
const allContentTypesAllowedAtRoot = rootContentTypeKeys.every((contentKey) =>
allowedRootContentTypeKeys.includes(contentKey),
);

return allContentTypesAllowedAtRoot;
}
}
export { UmbBlockGridPasteFromClipboardPropertyAction as api };
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { UMB_BLOCK_GRID_PROPERTY_EDITOR_UI_ALIAS } from '../constants.js';
import { UMB_WRITABLE_PROPERTY_CONDITION_ALIAS } from '@umbraco-cms/backoffice/property';
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
import { UMB_PROPERTY_ACTION_PASTE_FROM_CLIPBOARD_KIND_MANIFEST } from '@umbraco-cms/backoffice/clipboard';

export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
{
...UMB_PROPERTY_ACTION_PASTE_FROM_CLIPBOARD_KIND_MANIFEST.manifest,
type: 'propertyAction',
alias: 'Umb.PropertyAction.BlockGrid.Clipboard.Paste',
name: 'Block Grid Paste From Clipboard Property Action',
api: () => import('./block-grid-paste-from-clipboard.js'),
forPropertyEditorUis: [UMB_BLOCK_GRID_PROPERTY_EDITOR_UI_ALIAS],
conditions: [
{
alias: UMB_WRITABLE_PROPERTY_CONDITION_ALIAS,
},
],
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// TODO: add the missing fields to the type
export type UmbBlockGridPropertyEditorConfig = Array<{
alias: 'blocks';
value: Array<{
allowAtRoot: boolean;
allowInAreas: boolean;
contentElementTypeKey: string;
}>;
}>;
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { manifests as blockGridEditorManifests } from './block-grid-editor/manif
import { manifest as blockGridGroupConfiguration } from './block-grid-group-configuration/manifests.js';
import { manifest as blockGridLayoutStylesheet } from './block-grid-layout-stylesheet/manifests.js';
import { manifest as blockGridTypeConfiguration } from './block-grid-type-configuration/manifests.js';
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';

export const manifests: Array<UmbExtensionManifest> = [
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
blockGridAreaTypePermission,
blockGridAreasConfigEditor,
blockGridColumnSpan,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@ describe('UmbBlockToBlockListClipboardPastePropertyValueTranslator', () => {

describe('isCompatibleValue', () => {
it('should return true if the content types are allowed', async () => {
const result = await pasteTranslator.isCompatibleValue(blockClipboardEntryValue, config);
const result = await pasteTranslator.isCompatibleValue(blockListPropertyValue, config);
expect(result).to.be.true;
});

it('should return false if the content types are not allowed', async () => {
const result = await pasteTranslator.isCompatibleValue(blockClipboardEntryValue, config2);
const result = await pasteTranslator.isCompatibleValue(blockListPropertyValue, config2);
expect(result).to.be.false;
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ export class UmbBlockToBlockListClipboardPastePropertyValueTranslator

/**
* Checks if the clipboard entry value is compatible with the config.
* @param {UmbBlockClipboardEntryValueModel} value - The block clipboard entry value.
* @param {UmbBlockListValueModel} propertyValue - The property value
* @param {*} config - The Property Editor config.
* @returns {Promise<boolean>} - Whether the clipboard entry value is compatible with the config.
* @memberof UmbBlockToBlockListClipboardPastePropertyValueTranslator
*/
async isCompatibleValue(
value: UmbBlockClipboardEntryValueModel,
propertyValue: UmbBlockListValueModel,
// TODO: Replace any with the correct type.
config: Array<{ alias: string; value: [{ contentElementTypeKey: string }] }>,
): Promise<boolean> {
const allowedBlockContentTypes =
config.find((c) => c.alias === 'blocks')?.value.map((b) => b.contentElementTypeKey) ?? [];
const blockContentTypes = value.contentData.map((c) => c.contentTypeKey);
const blockContentTypes = propertyValue.contentData.map((c) => c.contentTypeKey);
return blockContentTypes?.every((b) => allowedBlockContentTypes.includes(b)) ?? false;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './clipboard-entry/constants.js';
export * from './clipboard-root/constants.js';
export * from './collection/constants.js';
export * from './property/context/constants.js';
export * from './property/constants.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './paste/constants.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './paste/index.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { UMB_PROPERTY_ACTION_PASTE_FROM_CLIPBOARD_KIND_MANIFEST } from './manifests.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { UmbPasteFromClipboardPropertyAction } from './paste-from-clipboard.property-action.js';
Loading
Loading