Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
2da4550
property value preset type
nielslyngsoe Feb 20, 2025
95882f2
add version to comment
nielslyngsoe Feb 20, 2025
1a18056
move clone controller
nielslyngsoe Feb 20, 2025
16ca317
add JSDocs
nielslyngsoe Feb 20, 2025
1f0cc67
sort getByTypeAndFilter
nielslyngsoe Feb 20, 2025
19529c1
builder
nielslyngsoe Feb 20, 2025
64c7ec3
updates for extension type
nielslyngsoe Feb 20, 2025
c04d0e5
unit test
nielslyngsoe Feb 20, 2025
7073f4d
test weight
nielslyngsoe Feb 20, 2025
d366914
dynamic filter depending on situation
nielslyngsoe Feb 21, 2025
347bd91
async test
nielslyngsoe Feb 21, 2025
136c679
combine ui and schema test
nielslyngsoe Feb 21, 2025
065c937
make block creation async
nielslyngsoe Feb 21, 2025
19026fb
commit todos
nielslyngsoe Feb 21, 2025
888e19e
proper deprecation
nielslyngsoe Feb 21, 2025
841f256
value can be undefined
nielslyngsoe Feb 21, 2025
542b684
toggle preset api
nielslyngsoe Feb 21, 2025
8d9650a
ability to observe and get all languages
nielslyngsoe Feb 21, 2025
8d56256
default config field
nielslyngsoe Feb 21, 2025
14bc830
change only to expose all Cultures
nielslyngsoe Feb 21, 2025
d770877
Variant Presets
nielslyngsoe Feb 22, 2025
5c58546
fix test
nielslyngsoe Feb 22, 2025
10ebeec
implementation for blocks
nielslyngsoe Feb 22, 2025
79c6d87
TODO
nielslyngsoe Feb 22, 2025
32e100a
improve comment
nielslyngsoe Feb 22, 2025
cf3490f
implement for ContentTypes
nielslyngsoe Feb 22, 2025
4159f44
always set culture and segment for variant values
nielslyngsoe Feb 22, 2025
2666e01
only set values that got a value
nielslyngsoe Feb 22, 2025
61b03e8
todo notes
nielslyngsoe Feb 22, 2025
1d1255a
Merge branch 'v15/dev' into v15/feature/property-value-preset
nielslyngsoe Feb 24, 2025
de4ae7e
also resolve init when createScaffold
nielslyngsoe Feb 24, 2025
2c5bdc2
property-value-preset.Slider
nielslyngsoe Feb 24, 2025
9753c74
leaving some concept code for another time
nielslyngsoe Feb 24, 2025
3bf7488
enable undefined
nielslyngsoe Feb 24, 2025
4e3d635
revert
nielslyngsoe Feb 24, 2025
4b50d28
sort properties when creating
nielslyngsoe Feb 24, 2025
194a09c
refactor into setCurrentData
nielslyngsoe Feb 24, 2025
eb5e2f3
Merge branch 'v15/dev' into v15/feature/property-value-preset
nielslyngsoe Feb 24, 2025
d09f3fd
refactor to content data manager
nielslyngsoe Feb 24, 2025
af96ad4
Keep order from persisted data
nielslyngsoe Feb 24, 2025
7e42a50
refactor to also cover updateCurrent
nielslyngsoe Feb 24, 2025
3c11ec3
add type safety by making persisted partial as well
nielslyngsoe Feb 24, 2025
31b97ca
Merge branch 'v15/bugfix/18431' into v15/feature/property-value-preset
nielslyngsoe Feb 24, 2025
aceebd3
lint corrections
nielslyngsoe Feb 24, 2025
36dcb57
preset for markdown
nielslyngsoe Feb 24, 2025
c253a33
refactor to work with frozen data
nielslyngsoe Feb 24, 2025
9d620f1
Merge branch 'v15/bugfix/18431' into v15/feature/property-value-preset
nielslyngsoe Feb 24, 2025
883757e
implement for MarkDown
nielslyngsoe Feb 24, 2025
fe746e1
compare based on object properties not object as a whole
nielslyngsoe Feb 24, 2025
7b2f49d
Merge branch 'v15/bugfix/18431' into v15/feature/property-value-preset
nielslyngsoe Feb 24, 2025
6dd795d
Merge branch 'v15/dev' into v15/feature/property-value-preset
nielslyngsoe Feb 24, 2025
e177861
only update persisted data in regards to what was saved
nielslyngsoe Feb 24, 2025
313e0b1
fix tests
nielslyngsoe Feb 24, 2025
0e077d4
rename
madsrasmussen Feb 25, 2025
238bbb0
remove api from name
madsrasmussen Feb 25, 2025
06be85f
Merge branch 'v15/dev' into v15/feature/property-value-preset
madsrasmussen Feb 25, 2025
3749afd
rename class
madsrasmussen Feb 25, 2025
a4db51e
rename
madsrasmussen Feb 25, 2025
a46ff84
rename
madsrasmussen Feb 25, 2025
e0b6cad
rename
madsrasmussen Feb 25, 2025
04ff837
make linter happy
madsrasmussen Feb 25, 2025
e61e23b
align file names
madsrasmussen Feb 25, 2025
2fa3e2a
delete temp files
madsrasmussen Feb 25, 2025
a683851
fix alias
madsrasmussen Feb 25, 2025
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 @@ -177,6 +177,7 @@ export abstract class UmbBaseExtensionsInitializer<

this.#exposedPermittedExts = approvedExtensions;

// TODO: Option to first resolve once all have responded are completed. [NL]
if (this.#exposedPermittedExts.length > 0) {
this.#promiseResolvers.forEach((x) => x());
this.#promiseResolvers = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import type { UmbApiConstructorArgumentsMethodType } from './types.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';

/**
*
* @param host
* @param manifest
* @param constructorArgs
* @param {UmbControllerHost} host - The controller host for this controller to be appended to
* @param {ManifestApi} manifest - The manifest of the extension
* @param {Array | UmbApiConstructorArgumentsMethodType} constructorArgs - The constructor arguments to pass to the API class
* @returns {Promise<UmbApi | undefined>} - The API class instance
*/
export async function createExtensionApi<ApiType extends UmbApi = UmbApi>(
host: UmbControllerHost,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,9 @@ export class UmbExtensionRegistry<
return [];
}
const kinds = this._kinds.getValue();
return exts.map((ext) => (ext?.kind ? (this.#mergeExtensionWithKinds([ext, kinds]) ?? ext) : ext));
return exts
.map((ext) => (ext?.kind ? (this.#mergeExtensionWithKinds([ext, kinds]) ?? ext) : ext))
.sort(sortExtensions);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ export class UmbBlockGridEntriesContext
originData?: UmbBlockGridWorkspaceOriginData,
) {
await this._retrieveManager;
return this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData);
return await this._manager?.createWithPresets(contentElementTypeKey, partialLayoutEntry, originData);
}

// insert Block?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import { transformServerPathToClientPath } from '@umbraco-cms/backoffice/utils';
import { UmbBlockManagerContext } from '@umbraco-cms/backoffice/block';
import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app';
import type { UmbBlockDataModel } from '@umbraco-cms/backoffice/block';
import type { UmbBlockDataModel, UmbBlockDataObjectModel } from '@umbraco-cms/backoffice/block';
import type { UmbBlockTypeGroup } from '@umbraco-cms/backoffice/block-type';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbNumberRangeValueType } from '@umbraco-cms/backoffice/models';
Expand Down Expand Up @@ -91,15 +91,30 @@ export class UmbBlockGridManagerContext<
this.#serverUrl = appContext.getServerUrl();
});
}

/**
* @deprecated Use createWithPresets instead. Will be removed in v.17.
*/
create(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
contentElementTypeKey: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
partialLayoutEntry?: Omit<BlockLayoutType, 'contentKey'>,
// This property is used by some implementations, but not used in this. Do not remove. [NL]
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_originData?: UmbBlockGridWorkspaceOriginData,
) {
throw new Error('Method deparecated use createWithPresets');
return {} as UmbBlockDataObjectModel<BlockLayoutType>;
}

async createWithPresets(
contentElementTypeKey: string,
partialLayoutEntry?: Omit<BlockLayoutType, 'contentKey'>,
// This property is used by some implementations, but not used in this.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
originData?: UmbBlockGridWorkspaceOriginData,
) {
return super._createBlockData(contentElementTypeKey, partialLayoutEntry);
return await super._createBlockData(contentElementTypeKey, partialLayoutEntry);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export class UmbBlockListEntriesContext extends UmbBlockEntriesContext<
originData?: UmbBlockListWorkspaceOriginData,
) {
await this._retrieveManager;
return this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData);
return await this._manager?.createWithPresets(contentElementTypeKey, partialLayoutEntry, originData);
}

// insert Block?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { UmbBlockListLayoutModel, UmbBlockListTypeModel } from '../types.js
import type { UmbBlockListWorkspaceOriginData } from '../index.js';
import type { UmbBlockDataModel } from '../../block/types.js';
import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api';
import { UmbBlockManagerContext } from '@umbraco-cms/backoffice/block';
import { UmbBlockManagerContext, type UmbBlockDataObjectModel } from '@umbraco-cms/backoffice/block';

/**
* A implementation of the Block Manager specifically for the Block List Editor.
Expand All @@ -21,14 +21,29 @@ export class UmbBlockListManagerContext<
return this.#inlineEditingMode.getValue();
}

/**
* @deprecated Use createWithPresets instead. Will be removed in v.17.
*/
create(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
contentElementTypeKey: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
partialLayoutEntry?: Omit<BlockLayoutType, 'contentKey'>,
// This property is used by some implementations, but not used in this. Do not remove. [NL]
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_originData?: UmbBlockListWorkspaceOriginData,
) {
throw new Error('Method deparecated use createWithPresets');
return {} as UmbBlockDataObjectModel<BlockLayoutType>;
}
async createWithPresets(
contentElementTypeKey: string,
partialLayoutEntry?: Omit<BlockLayoutType, 'contentKey'>,
// This property is used by some implementations, but not used in this. Do not remove. [NL]
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_originData?: UmbBlockListWorkspaceOriginData,
) {
return super._createBlockData(contentElementTypeKey, partialLayoutEntry);
return await super._createBlockData(contentElementTypeKey, partialLayoutEntry);
}

insert(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export class UmbBlockRteEntriesContext extends UmbBlockEntriesContext<
originData?: UmbBlockRteWorkspaceOriginData,
) {
await this._retrieveManager;
return this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData);
return await this._manager?.createWithPresets(contentElementTypeKey, partialLayoutEntry, originData);
}

// insert Block?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { UmbBlockRteWorkspaceOriginData } from '../workspace/block-rte-workspace.modal-token.js';
import type { UmbBlockRteLayoutModel, UmbBlockRteTypeModel } from '../types.js';
import type { UmbBlockDataModel } from '../../block/types.js';
import { UmbBlockManagerContext } from '@umbraco-cms/backoffice/block';
import { UmbBlockManagerContext, type UmbBlockDataObjectModel } from '@umbraco-cms/backoffice/block';

import '../components/block-rte-entry/index.js';

Expand All @@ -18,14 +18,29 @@ export class UmbBlockRteManagerContext<
this._layouts.remove(contentKeys);
}

/**
* @deprecated Use createWithPresets instead. Will be removed in v.17.
*/
create(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
contentElementTypeKey: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
partialLayoutEntry?: Omit<BlockLayoutType, 'contentKey'>,
// This property is used by some implementations, but not used in this. Do not remove. [NL]
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_originData?: UmbBlockRteWorkspaceOriginData,
) {
throw new Error('Method deparecated use createWithPresets');
return {} as UmbBlockDataObjectModel<BlockLayoutType>;
}
async createWithPresets(
contentElementTypeKey: string,
partialLayoutEntry?: Omit<BlockLayoutType, 'contentKey'>,
// This property is used by some implementations, but not used in this, do not remove. [NL]
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_originData?: UmbBlockRteWorkspaceOriginData,
) {
const data = super._createBlockData(contentElementTypeKey, partialLayoutEntry);
const data = await super._createBlockData(contentElementTypeKey, partialLayoutEntry);

// Find block type.
const blockType = this.getBlockTypes().find((x) => x.contentElementTypeKey === contentElementTypeKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,11 +398,11 @@ export abstract class UmbBlockEntryContext<

this.observe(
observeMultiple([this.settingsKey, this.blockType]),
([settingsKey, blockType]) => {
async ([settingsKey, blockType]) => {
if (!this.#contentKey || settingsKey === undefined || !blockType) return;
if (settingsKey == null && blockType.settingsElementTypeKey) {
// We have a settings ElementType in config but not in data, so lets create the scaffold for that: [NL]
const settingsData = this._manager!.createBlockSettingsData(blockType.contentElementTypeKey); // Yes its on purpose we use the contentElementTypeKey here, as this is our identifier for a BlockType. [NL]
const settingsData = await this._manager!.createBlockSettingsData(blockType.contentElementTypeKey); // Yes its on purpose we use the contentElementTypeKey here, as this is our identifier for a BlockType. [NL]
this._manager?.setOneSettings(settingsData);
this._layout.update({ settingsKey: settingsData.key } as Partial<BlockLayoutType>);
} else if (settingsKey && blockType.settingsElementTypeKey === undefined) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@
import type { UmbVariantId } from '@umbraco-cms/backoffice/variant';
import type { UmbBlockTypeBaseModel } from '@umbraco-cms/backoffice/block-type';
import { UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils';
import {
UmbPropertyValuePresetVariantBuilderController,
type UmbPropertyTypePresetModel,
type UmbPropertyTypePresetModelTypeModel,
} from '@umbraco-cms/backoffice/property';
import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language';
import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type';

export type UmbBlockDataObjectModel<LayoutEntryType extends UmbBlockLayoutBaseModel> = {
layout: LayoutEntryType;
Expand Down Expand Up @@ -317,13 +324,25 @@
);
}

/**
* @deprecated Use `createWithPresets` instead. Which is Async. Will be removed in v.17
* @param contentElementTypeKey
* @param partialLayoutEntry
* @param originData
*/
abstract create(
contentElementTypeKey: string,
partialLayoutEntry?: Omit<BlockLayoutType, 'contentKey'>,
originData?: BlockOriginDataType,
): UmbBlockDataObjectModel<BlockLayoutType> | undefined;

public createBlockSettingsData(contentElementTypeKey: string) {
abstract createWithPresets(
contentElementTypeKey: string,
partialLayoutEntry?: Omit<BlockLayoutType, 'contentKey'>,
originData?: BlockOriginDataType,
): Promise<UmbBlockDataObjectModel<BlockLayoutType> | undefined>;

public async createBlockSettingsData(contentElementTypeKey: string) {
const blockType = this.#blockTypes.value.find((x) => x.contentElementTypeKey === contentElementTypeKey);
if (!blockType) {
throw new Error(`Cannot create block settings, missing block type for ${contentElementTypeKey}`);
Expand All @@ -332,22 +351,80 @@
throw new Error(`Cannot create block settings, missing settings element type for ${contentElementTypeKey}`);
}

// TODO: Handle presets here [NL]

return {
key: UmbId.new(),
contentTypeKey: blockType.settingsElementTypeKey,
values: [],
};
}

protected _createBlockElementData(key: string, elementTypeKey: string) {
protected async _createBlockElementData(key: string, contentTypeKey: string) {
//
const appLanguage = await this.getContext(UMB_APP_LANGUAGE_CONTEXT);

const contentStructure = this.getStructure(contentTypeKey);
if (!contentStructure) {
throw new Error(`Cannot create Preset for Block, missing content structure for ${contentTypeKey}`);
}

// Set culture and segment for all values:
const cutlures = contentStructure.variesByCulture ? await appLanguage.getCultures() : [];
if (cutlures.length === 0) {
throw new Error('Could not retrieve app cultures.');
}
// TODO: Receive the segments from somewhere. [NL]
const segments: Array<string> | undefined = contentStructure.variesBySegment ? [] : undefined;

const repo = new UmbDataTypeDetailRepository(this);

const propertyTypes = await contentStructure.getContentTypeProperties();
const valueDefinitions = await Promise.all(
propertyTypes.map(async (property) => {
// TODO: Implement caching for data-type requests. [NL]
const dataType = (await repo.requestByUnique(property.dataType.unique)).data;
// This means if its not loaded this will never resolve and the error below will never happen.
if (!dataType) {
throw new Error(`DataType of "${property.dataType.unique}" not found.`);
}
if (!dataType.editorUiAlias) {
throw new Error(`DataType of "${property.dataType.unique}" did not have a editorUiAlias.`);
}

return {
alias: property.alias,
propertyEditorUiAlias: dataType.editorUiAlias,
propertyEditorSchemaAlias: dataType.editorAlias,
config: dataType.values,
typeArgs: {
variesByCulture: property.variesByCulture,
variesBySegment: property.variesBySegment,
} as UmbPropertyTypePresetModelTypeModel,
} as UmbPropertyTypePresetModel;
}),
);

const controller = new UmbPropertyValuePresetVariantBuilderController(this);
controller.setCultures(cutlures);
if (segments) {
controller.setSegments(segments);
}
const values = await controller.create(valueDefinitions);

// Set culture and segment for all values:

return {
key: key,
contentTypeKey: elementTypeKey,
values: [],
key,
contentTypeKey,
values,

Check warning on line 420 in src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts

View check run for this annotation

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

❌ New issue: Complex Method

UmbBlockManagerContext._createBlockElementData has a cyclomatic complexity of 12, threshold = 9. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.
};
}

protected _createBlockData(contentElementTypeKey: string, partialLayoutEntry?: Omit<BlockLayoutType, 'contentKey'>) {
protected async _createBlockData(
contentElementTypeKey: string,
partialLayoutEntry?: Omit<BlockLayoutType, 'contentKey'>,
) {
// Find block type.
const blockType = this.#blockTypes.value.find((x) => x.contentElementTypeKey === contentElementTypeKey);
if (!blockType) {
Expand All @@ -360,12 +437,12 @@
...(partialLayoutEntry as Partial<BlockLayoutType>),
} as BlockLayoutType;

const content = this._createBlockElementData(layout.contentKey, contentElementTypeKey);
const content = await this._createBlockElementData(layout.contentKey, contentElementTypeKey);
let settings: UmbBlockDataModel | undefined = undefined;

if (blockType.settingsElementTypeKey) {
layout.settingsKey = UmbId.new();
settings = this._createBlockElementData(layout.settingsKey, blockType.settingsElementTypeKey);
settings = await this._createBlockElementData(layout.settingsKey, blockType.settingsElementTypeKey);
}

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,7 @@ export class UmbBlockElementManager<LayoutDataType extends UmbBlockLayoutBaseMod
}

#createPropertyVariantId(property: UmbPropertyTypeModel, variantId: UmbVariantId) {
return UmbVariantId.Create({
culture: property.variesByCulture ? variantId.culture : null,
segment: property.variesBySegment ? variantId.segment : null,
});
return variantId.toVariant(property.variesByCulture, property.variesBySegment);
}

// We will implement propertyAlias in the future, when implementing Varying Blocks. [NL]
Expand Down Expand Up @@ -192,6 +189,7 @@ export class UmbBlockElementManager<LayoutDataType extends UmbBlockLayoutBaseMod
throw new Error(`Property alias "${alias}" not found.`);
}

// TODO: I think we should await this in the same way as we do for Content Detail Workspace Context. [NL]
const editorAlias = this.#dataTypeSchemaAliasMap.get(property.dataType.unique);
if (!editorAlias) {
throw new Error(`Editor Alias of "${property.dataType.unique}" not found.`);
Expand Down
Loading
Loading