Merge branch 'main' into improvement/move-dictionary-picker-token

This commit is contained in:
Mads Rasmussen
2024-03-05 12:54:10 +01:00
committed by GitHub
15 changed files with 418 additions and 84 deletions

View File

@@ -35,7 +35,7 @@ const jsModuleWithDefaultAndApiExport = {
api: UmbExtensionApiTrueTestClass,
};
describe('Extension-Api: Create Extension Api', () => {
describe('Create Extension Api Method', () => {
let hostElement: UmbTestControllerHostElement;
beforeEach(async () => {

View File

@@ -45,11 +45,10 @@ export async function createExtensionElementWithApi<
apiConstructor = await apiPromise;
}
if (manifest.elementName) {
if (!element && manifest.elementName) {
element = document.createElement(manifest.elementName) as ElementType;
}
if (fallbackElement) {
if (!element && fallbackElement) {
element = document.createElement(fallbackElement) as ElementType;
}
@@ -62,9 +61,37 @@ export async function createExtensionElementWithApi<
return { element, api };
}
console.error(
`-- Extension of alias "${manifest.alias}" did not succeed creating an element with api, missing one or two JavaScript files via the 'element' and 'api' or the 'js' property or with just 'api' and the Element Name in 'elementName' in the manifest.`,
manifest,
);
// Debug messages:
if (!element && apiConstructor) {
// If we have a elementPropValue, that means that element or js property was defined, but the element was not created.
if (elementPropValue) {
console.error(
`-- Extension of alias "${manifest.alias}" did not succeed creating an Element with Api, Api was created but the imported Element JS file did not export a 'element' or 'default'. Alternatively define the 'elementName' in the manifest.`,
manifest,
);
} else {
console.error(
`-- Extension of alias "${manifest.alias}" did not succeed creating an Element with Api, Api was created but the Element was missing a JavaScript file via the 'element' or the 'js' property. Alternatively define a Element Name in 'elementName' in the manifest.`,
manifest,
);
}
} else if (element && !apiConstructor) {
if (apiPropValue) {
console.error(
`-- Extension of alias "${manifest.alias}" did not succeed creating an Element with Api, Element was created but the imported Api JS file did not export a 'api' or 'default'.`,
manifest,
);
} else {
console.error(
`-- Extension of alias "${manifest.alias}" did not succeed creating an Element with Api, Element was created but the Api is missing a JavaScript file via the 'api' or 'js' property.`,
manifest,
);
}
} else {
console.error(
`-- Extension of alias "${manifest.alias}" did not succeed creating an Element with Api, neither an Element or Api was created, missing one or two JavaScript files via the 'element' and 'api' or the 'js' property or with just 'api' and the Element Name in 'elementName' in the manifest.`,
manifest,
);
}
return {};
}

View File

@@ -0,0 +1,199 @@
import { expect } from '@open-wc/testing';
import type { ManifestElementAndApi } from '../types/index.js';
import type { UmbApi } from '../index.js';
import { createExtensionElementWithApi } from './create-extension-element-with-api.function.js';
import { customElement } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
interface UmbExtensionApiBooleanTestElement extends UmbLitElement {
isValidElementClassInstance(): boolean;
}
@customElement('umb-extension-api-true-test-element')
class UmbExtensionApiTrueTestElement extends UmbLitElement implements UmbExtensionApiBooleanTestElement {
isValidElementClassInstance() {
return true;
}
}
@customElement('umb-extension-api-false-test-element')
class UmbExtensionApiFalseTestElement extends UmbLitElement implements UmbExtensionApiBooleanTestElement {
isValidElementClassInstance() {
return false;
}
}
const elementJsModuleWithDefaultExport = {
default: UmbExtensionApiTrueTestElement,
};
const elementJsModuleWithElementExport = {
element: UmbExtensionApiTrueTestElement,
};
const elementJsModuleWithDefaultAndElementExport = {
default: UmbExtensionApiFalseTestElement,
element: UmbExtensionApiTrueTestElement,
};
interface UmbTestApi extends UmbApi {
isValidApiClassInstance(): boolean;
}
class UmbTestApiTrue implements UmbTestApi {
isValidApiClassInstance() {
return true;
}
destroy() {}
}
class UmbTestApiFalse implements UmbTestApi {
isValidApiClassInstance() {
return true;
}
destroy() {}
}
const apiJsModuleWithDefaultExport = {
default: UmbTestApiTrue,
};
const apiJsModuleWithApiExport = {
api: UmbTestApiTrue,
};
const apiJsModuleWithDefaultAndApiExport = {
default: UmbTestApiFalse,
api: UmbTestApiTrue,
};
describe('Create Extension Element and Api Method', () => {
it('Returns `undefined` when manifest does not have any correct properties', async () => {
const manifest: ManifestElementAndApi<UmbExtensionApiBooleanTestElement, UmbTestApi> = {
type: 'my-test-type',
alias: 'Umb.Test.CreateManifestElement',
name: 'pretty name',
};
const { element, api } = await createExtensionElementWithApi(manifest);
expect(element).to.be.undefined;
expect(api).to.be.undefined;
});
it('Returns fallback element instance when manifest does not provide element', async () => {
const manifest: ManifestElementAndApi<UmbExtensionApiTrueTestElement, UmbTestApi> = {
type: 'my-test-type',
alias: 'Umb.Test.CreateManifestElement',
name: 'pretty name',
js: () => Promise.resolve(apiJsModuleWithApiExport),
};
const { element, api } = await createExtensionElementWithApi(manifest, 'umb-extension-api-true-test-element');
expect(element).to.not.be.undefined;
expect(api).to.not.be.undefined;
if (element) {
expect(element.isValidElementClassInstance()).to.be.true;
}
if (api) {
expect(api.isValidApiClassInstance()).to.be.true;
}
});
it('Still returns fallback element instance when manifest does not provide element and manifest has a js with an api', async () => {
const manifest: ManifestElementAndApi<UmbExtensionApiTrueTestElement, UmbTestApi> = {
type: 'my-test-type',
alias: 'Umb.Test.CreateManifestElement',
name: 'pretty name',
js: () => Promise.resolve(apiJsModuleWithApiExport),
};
const { element, api } = await createExtensionElementWithApi(manifest, 'umb-extension-api-true-test-element');
expect(element).to.not.be.undefined;
expect(api).to.not.be.undefined;
if (element) {
expect(element.isValidElementClassInstance()).to.be.true;
}
if (api) {
expect(api.isValidApiClassInstance()).to.be.true;
}
});
it('Handles when `api` property contains a class constructor', async () => {
const manifest: ManifestElementAndApi<UmbExtensionApiTrueTestElement, UmbTestApi> = {
type: 'my-test-type',
alias: 'Umb.Test.CreateManifestElement',
name: 'pretty name',
elementName: 'umb-extension-api-true-test-element',
api: () => Promise.resolve(apiJsModuleWithDefaultExport),
};
const { element, api } = await createExtensionElementWithApi(manifest);
expect(element).to.not.be.undefined;
expect(api).to.not.be.undefined;
if (element) {
expect(element.isValidElementClassInstance()).to.be.true;
}
if (api) {
expect(api.isValidApiClassInstance()).to.be.true;
}
});
it('Handles when `loader` has a default export', async () => {
const manifest: ManifestElementAndApi<UmbExtensionApiTrueTestElement, UmbTestApi> = {
type: 'my-test-type',
alias: 'Umb.Test.CreateManifestElement',
name: 'pretty name',
js: () => Promise.resolve(elementJsModuleWithDefaultExport),
api: () => Promise.resolve(apiJsModuleWithDefaultExport),
};
const { element, api } = await createExtensionElementWithApi(manifest);
expect(element).to.not.be.undefined;
expect(api).to.not.be.undefined;
if (element) {
expect(element.isValidElementClassInstance()).to.be.true;
}
if (api) {
expect(api.isValidApiClassInstance()).to.be.true;
}
});
it('Handles when `loader` has a element export', async () => {
const manifest: ManifestElementAndApi<UmbExtensionApiTrueTestElement, UmbTestApi> = {
type: 'my-test-type',
alias: 'Umb.Test.CreateManifestElement',
name: 'pretty name',
js: () => Promise.resolve(elementJsModuleWithElementExport),
api: () => Promise.resolve(apiJsModuleWithApiExport),
};
const { element, api } = await createExtensionElementWithApi(manifest);
expect(element).to.not.be.undefined;
expect(api).to.not.be.undefined;
if (element) {
expect(element.isValidElementClassInstance()).to.be.true;
}
if (api) {
expect(api.isValidApiClassInstance()).to.be.true;
}
});
it('Prioritizes api export from loader property', async () => {
const manifest: ManifestElementAndApi<UmbExtensionApiTrueTestElement, UmbTestApi> = {
type: 'my-test-type',
alias: 'Umb.Test.CreateManifestElement',
name: 'pretty name',
js: () => Promise.resolve(elementJsModuleWithDefaultAndElementExport),
api: () => Promise.resolve(apiJsModuleWithDefaultAndApiExport),
};
const { element, api } = await createExtensionElementWithApi(manifest);
expect(element).to.not.be.undefined;
expect(api).to.not.be.undefined;
if (element) {
expect(element.isValidElementClassInstance()).to.be.true;
}
if (api) {
expect(api.isValidApiClassInstance()).to.be.true;
}
});
});

View File

@@ -5,25 +5,15 @@ export async function createExtensionElement<ElementType extends HTMLElement>(
manifest: ManifestElement<ElementType> | ManifestElementAndApi<any>,
fallbackElement?: string,
): Promise<ElementType | undefined> {
if (manifest.element) {
const elementConstructor = await loadManifestElement<ElementType>(manifest.element);
const elementPropValue = manifest.element ?? manifest.js;
if (elementPropValue) {
const elementConstructor = await loadManifestElement<ElementType>(elementPropValue);
if (elementConstructor) {
return new elementConstructor();
} else {
console.error(
`-- Extension of alias "${manifest.alias}" did not succeed creating an element class instance via the extension manifest property 'element', using either a 'element' or 'default' export`,
manifest,
);
}
}
if (manifest.js) {
const elementConstructor2 = await loadManifestElement<ElementType>(manifest.js);
if (elementConstructor2) {
return new elementConstructor2();
} else {
console.error(
`-- Extension of alias "${manifest.alias}" did not succeed creating an element class instance via the extension manifest property 'js', using either a 'element' or 'default' export`,
`-- Extension of alias "${manifest.alias}" did not succeed creating an element class instance via the extension manifest property '${elementPropValue}'. The imported Element JS file did not export a 'element' or 'default'. Alternatively define the 'elementName' in the manifest.`,
manifest,
);
}
@@ -38,8 +28,9 @@ export async function createExtensionElement<ElementType extends HTMLElement>(
}
console.error(
`-- Extension of alias "${manifest.alias}" did not succeed creating an element, missing a JavaScript file via the 'element' or 'js' property or a Element Name in 'elementName' in the manifest.`,
`-- Extension of alias "${manifest.alias}" did not succeed creating an Element, missing a JavaScript file via the 'element' or 'js' property. Alternatively define a Element Name in 'elementName' in the manifest.`,
manifest,
);
return undefined;
}

View File

@@ -31,7 +31,7 @@ const jsModuleWithDefaultAndElementExport = {
element: UmbExtensionApiTrueTestElement,
};
describe('Extension-Api: Create Extension Element', () => {
describe('Create Extension Element Method', () => {
it('Returns `undefined` when manifest does not have any correct properties', async () => {
const manifest: ManifestElement = {
type: 'my-test-type',

View File

@@ -1,5 +1,5 @@
import { umbExtensionsRegistry } from './registry.js';
import { html, property, state } from '@umbraco-cms/backoffice/external/lit';
import { property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { ManifestElementAndApi } from '@umbraco-cms/backoffice/extension-api';
import { UmbExtensionElementAndApiInitializer } from '@umbraco-cms/backoffice/extension-api';

View File

@@ -1,5 +1,4 @@
import { UmbMediaItemRepository } from '../../repository/index.js';
import type { UmbMediaCreateOptionsModalData } from './media-create-options-modal.token.js';
import { UMB_MEDIA_CREATE_OPTIONS_MODAL } from './media-create-options-modal.token.js';
import type { UmbEntityActionArgs } from '@umbraco-cms/backoffice/entity-action';
import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
@@ -7,11 +6,8 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
export class UmbCreateMediaEntityAction extends UmbEntityActionBase<never> {
#itemRepository;
constructor(host: UmbControllerHost, args: UmbEntityActionArgs<never>) {
super(host, args);
this.#itemRepository = new UmbMediaItemRepository(host);
}
async execute() {
@@ -20,23 +16,18 @@ export class UmbCreateMediaEntityAction extends UmbEntityActionBase<never> {
if (this.args.unique) {
// get media item to get the doc type id
const { data, error } = await this.#itemRepository.requestItems([this.args.unique]);
const itemRepository = new UmbMediaItemRepository(this._host);
const { data, error } = await itemRepository.requestItems([this.args.unique]);
if (error || !data) throw new Error(`Failed to load media item`);
mediaItem = data[0];
}
if (!mediaItem) throw new Error(`Failed to load media item`);
this._openModal({
parent: { unique: this.args.unique, entityType: this.args.entityType },
mediaType: { unique: mediaItem.mediaType.unique },
});
}
private async _openModal(modalData: UmbMediaCreateOptionsModalData) {
const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
const modalContext = modalManager.open(this, UMB_MEDIA_CREATE_OPTIONS_MODAL, {
data: modalData,
data: {
parent: { unique: this.args.unique, entityType: this.args.entityType },
mediaType: mediaItem ? { unique: mediaItem.mediaType.unique } : null,
},
});
await modalContext.onSubmit();

View File

@@ -23,7 +23,7 @@ export class UmbMediaCreateOptionsModalElement extends UmbModalBaseElement<
async firstUpdated() {
const mediaUnique = this.data?.parent.unique;
const mediaTypeUnique = this.data?.mediaType.unique || null;
const mediaTypeUnique = this.data?.mediaType?.unique || null;
this.#retrieveAllowedMediaTypesOf(mediaTypeUnique);
@@ -68,7 +68,7 @@ export class UmbMediaCreateOptionsModalElement extends UmbModalBaseElement<
data-id=${ifDefined(mediaType.unique)}
href="${`section/media/workspace/media/create/parent/${this.data?.parent.entityType}/${
this.data?.parent.unique ?? 'null'
}}/${mediaType.unique}`}"
}/${mediaType.unique}`}"
label="${mediaType.name}"
@click=${this.#onNavigate}>
> ${mediaType.icon ? html`<umb-icon slot="icon" name=${mediaType.icon}></umb-icon>` : nothing}

View File

@@ -7,7 +7,7 @@ export interface UmbMediaCreateOptionsModalData {
};
mediaType: {
unique: string;
};
} | null;
}
export interface UmbMediaCreateOptionsModalValue {}

View File

@@ -76,7 +76,7 @@ export class UmbMediaServerDataSource implements UmbDetailDataSource<UmbMediaDet
const media: UmbMediaDetailModel = {
entityType: UMB_MEDIA_ENTITY_TYPE,
unique: data.id,
values: data.values,
values: data.values as UmbMediaDetailModel['values'],
variants: data.variants.map((variant) => {
return {
state: null,
@@ -87,7 +87,7 @@ export class UmbMediaServerDataSource implements UmbDetailDataSource<UmbMediaDet
updateDate: variant.updateDate,
};
}),
urls: data.urls,
urls: data.urls as UmbMediaDetailModel['urls'],
mediaType: {
unique: data.mediaType.id,
collection: data.mediaType.collection ? { unique: data.mediaType.collection.id } : null,
@@ -114,7 +114,11 @@ export class UmbMediaServerDataSource implements UmbDetailDataSource<UmbMediaDet
parent: parentUnique ? { id: parentUnique } : null,
mediaType: { id: model.mediaType.unique },
values: model.values,
variants: model.variants,
variants: model.variants.map((variant) => ({
culture: variant.culture || null,
segment: variant.segment || null,
name: variant.name,
})),
};
const { data, error } = await tryExecuteAndNotify(

View File

@@ -1,6 +1,5 @@
import type { UmbMediaEntityType } from './entity.js';
import type { UmbVariantModel, UmbVariantOptionModel } from '@umbraco-cms/backoffice/variant';
import type { MediaUrlInfoModel, MediaValueModel } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
export interface UmbMediaDetailModel {
@@ -11,9 +10,23 @@ export interface UmbMediaDetailModel {
entityType: UmbMediaEntityType;
isTrashed: boolean;
unique: string;
urls: Array<MediaUrlInfoModel>;
values: Array<MediaValueModel>;
urls: Array<UmbMediaUrlInfoModel>;
values: Array<UmbMediaValueModel>;
variants: Array<UmbVariantModel>;
}
export interface UmbMediaUrlInfoModel {
culture: string | null;
url: string;
}
export interface UmbMediaVariantModel extends UmbVariantModel {}
export interface UmbMediaValueModel<ValueType = unknown> {
culture: string | null;
segment: string | null;
alias: string;
value: ValueType;
}
export interface UmbMediaVariantOptionModel extends UmbVariantOptionModel<UmbVariantModel> {}

View File

@@ -2,8 +2,8 @@ import { UmbMediaTypeDetailRepository } from '../../media-types/repository/detai
import { UmbMediaPropertyDataContext } from '../property-dataset-context/media-property-dataset-context.js';
import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js';
import { UmbMediaDetailRepository } from '../repository/index.js';
import type { UmbMediaDetailModel, UmbMediaVariantOptionModel } from '../types.js';
import type { UmbVariantId } from '@umbraco-cms/backoffice/variant';
import type { UmbMediaDetailModel, UmbMediaVariantModel, UmbMediaVariantOptionModel } from '../types.js';
import { UMB_INVARIANT_CULTURE, UmbVariantId } from '@umbraco-cms/backoffice/variant';
import { UmbContentTypePropertyStructureManager } from '@umbraco-cms/backoffice/content-type';
import {
UmbEditableWorkspaceContextBase,
@@ -12,6 +12,7 @@ import {
} from '@umbraco-cms/backoffice/workspace';
import {
appendToFrozenArray,
jsonStringComparison,
mergeObservables,
partialUpdateFrozenArray,
UmbArrayState,
@@ -52,25 +53,59 @@ export class UmbMediaWorkspaceContext
readonly contentTypeCollection = this.#currentData.asObservablePart((data) => data?.mediaType.collection);
readonly variants = this.#currentData.asObservablePart((data) => data?.variants || []);
readonly variantOptions = mergeObservables([this.variants, this.languages], ([variants, languages]) => {
return languages.map((language) => {
return {
variant: variants.find((x) => x.culture === language.unique),
language,
// TODO: When including segments, this should be updated to include the segment as well. [NL]
unique: language.unique, // This must be a variantId string!
} as UmbMediaVariantOptionModel;
});
});
readonly urls = this.#currentData.asObservablePart((data) => data?.urls || []);
readonly structure = new UmbContentTypePropertyStructureManager(this, new UmbMediaTypeDetailRepository(this));
readonly variesByCulture = this.structure.ownerContentTypePart((x) => x?.variesByCulture);
//#variesByCulture?: boolean;
readonly variesBySegment = this.structure.ownerContentTypePart((x) => x?.variesBySegment);
//#variesBySegment?: boolean;
readonly varies = this.structure.ownerContentTypePart((x) =>
x ? x.variesByCulture || x.variesBySegment : undefined,
);
#varies?: boolean;
readonly splitView = new UmbWorkspaceSplitViewManager();
readonly variantOptions = mergeObservables(
[this.varies, this.variants, this.languages],
([varies, variants, languages]) => {
// TODO: When including segments, when be aware about the case of segment varying when not culture varying. [NL]
if (varies === true) {
return languages.map((language) => {
return {
variant: variants.find((x) => x.culture === language.unique),
language,
// TODO: When including segments, this object should be updated to include a object for the segment. [NL]
// TODO: When including segments, the unique should be updated to include the segment as well. [NL]
unique: language.unique, // This must be a variantId string!
culture: language.unique,
segment: null,
} as UmbMediaVariantOptionModel;
});
} else if (varies === false) {
return [
{
variant: variants.find((x) => x.culture === null),
language: languages.find((x) => x.isDefault),
culture: null,
segment: null,
unique: UMB_INVARIANT_CULTURE, // This must be a variantId string!
} as UmbMediaVariantOptionModel,
];
}
return [] as Array<UmbMediaVariantOptionModel>;
},
);
constructor(host: UmbControllerHost) {
super(host, 'Umb.Workspace.Media');
this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique));
this.observe(this.varies, (varies) => (this.#varies = varies));
this.loadLanguages();
}
resetState() {
@@ -80,6 +115,7 @@ export class UmbMediaWorkspaceContext
}
async loadLanguages() {
// TODO: If we don't end up having a Global Context for languages, then we should at least change this into using a asObservable which should be returned from the repository. [Nl]
const { data } = await this.#languageRepository.requestCollection({});
this.#languages.setValue(data?.items ?? []);
}
@@ -125,6 +161,11 @@ export class UmbMediaWorkspaceContext
return this.getData()?.mediaType.unique;
}
// TODO: Check if this is used:
getVaries() {
return this.#varies;
}
variantById(variantId: UmbVariantId) {
return this.#currentData.asObservablePart((data) => data?.variants?.find((x) => variantId.compare(x)));
}
@@ -144,13 +185,15 @@ export class UmbMediaWorkspaceContext
}
setName(name: string, variantId?: UmbVariantId) {
const oldVariants = this.#currentData.getValue()?.variants || [];
const variants = partialUpdateFrozenArray(
oldVariants,
{ name },
variantId ? (x) => variantId.compare(x) : () => true,
);
this.#currentData.update({ variants });
// const oldVariants = this.#currentData.getValue()?.variants || [];
// const variants = partialUpdateFrozenArray(
// oldVariants,
// { name },
// variantId ? (x) => variantId.compare(x) : () => true,
// );
// this.#currentData.update({ variants });
this.#updateVariantData(variantId ?? UmbVariantId.CreateInvariant(), { name });
}
async propertyStructureById(propertyId: string) {
@@ -197,6 +240,82 @@ export class UmbMediaWorkspaceContext
(x) => x.alias === alias && (variantId ? variantId.compare(x as any) : true),
);
this.#currentData.update({ values });
// TODO: We should move this type of logic to the act of saving [NL]
this.#updateVariantData(variantId);
}
}
/* #calculateChangedVariants() {
const persisted = this.#persistedData.getValue();
const current = this.#currentData.getValue();
if (!current) throw new Error('Current data is missing');
const changedVariants = current?.variants.map((variant) => {
const persistedVariant = persisted?.variants.find((x) => UmbVariantId.Create(variant).compare(x));
return {
culture: variant.culture,
segment: variant.segment,
equal: persistedVariant ? jsonStringComparison(variant, persistedVariant) : false,
};
});
const changedProperties = current?.values.map((value) => {
const persistedValues = persisted?.values.find((x) => UmbVariantId.Create(value).compare(x));
return {
culture: value.culture,
segment: value.segment,
equal: persistedValues ? jsonStringComparison(value, persistedValues) : false,
};
});
// calculate the variantIds of those who either have a change in properties or in variants:
return (
changedVariants
?.concat(changedProperties ?? [])
.filter((x) => x.equal === false)
.map((x) => new UmbVariantId(x.culture, x.segment)) ?? []
);
} */
#updateVariantData(variantId: UmbVariantId, update?: Partial<UmbMediaVariantModel>) {
const currentData = this.getData();
if (!currentData) throw new Error('Data is missing');
if (this.#varies === true) {
// If variant Id is invariant, we don't to have the variant appended to our data.
if (variantId.isInvariant()) return;
const variant = currentData.variants.find((x) => variantId.compare(x));
const newVariants = appendToFrozenArray(
currentData.variants,
{
name: '',
createDate: null,
updateDate: null,
...variantId.toObject(),
...variant,
...update,
},
(x) => variantId.compare(x),
);
this.#currentData.update({ variants: newVariants });
} else if (this.#varies === false) {
// TODO: Beware about segments, in this case we need to also consider segments, if its allowed to vary by segments.
const invariantVariantId = UmbVariantId.CreateInvariant();
const variant = currentData.variants.find((x) => invariantVariantId.compare(x));
// Cause we are invariant, we will just overwrite all variants with this one:
const newVariants = [
{
name: '',
createDate: null,
updateDate: null,
...invariantVariantId.toObject(),
...variant,
...update,
},
];
this.#currentData.update({ variants: newVariants });
} else {
throw new Error('Varies by culture is missing');
}
}
@@ -205,7 +324,6 @@ export class UmbMediaWorkspaceContext
if (this.getIsNew()) {
if (!this.#parent) throw new Error('Parent is not set');
await this.repository.create(this.#currentData.value, this.#parent.unique);
const value = this.#currentData.value;
if ((await this.repository.create(value, this.#parent.unique)).data !== undefined) {

View File

@@ -1,8 +1,4 @@
import {
UMB_PARTIAL_VIEW_ROOT_ENTITY_TYPE,
UMB_PARTIAL_VIEW_ENTITY_TYPE,
UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE,
} from '../../entity.js';
import { UMB_PARTIAL_VIEW_ROOT_ENTITY_TYPE, UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE } from '../../entity.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
export const manifests: Array<ManifestTypes> = [
@@ -11,10 +7,6 @@ export const manifests: Array<ManifestTypes> = [
kind: 'reloadTreeItemChildren',
alias: 'Umb.EntityAction.PartialView.Tree.ReloadChildrenOf',
name: 'Reload Partial View Tree Item Children Entity Action',
forEntityTypes: [
UMB_PARTIAL_VIEW_ROOT_ENTITY_TYPE,
UMB_PARTIAL_VIEW_ENTITY_TYPE,
UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE,
],
forEntityTypes: [UMB_PARTIAL_VIEW_ROOT_ENTITY_TYPE, UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE],
},
];

View File

@@ -1,4 +1,4 @@
import { UMB_SCRIPT_ROOT_ENTITY_TYPE, UMB_SCRIPT_ENTITY_TYPE, UMB_SCRIPT_FOLDER_ENTITY_TYPE } from '../../entity.js';
import { UMB_SCRIPT_ROOT_ENTITY_TYPE, UMB_SCRIPT_FOLDER_ENTITY_TYPE } from '../../entity.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
export const manifests: Array<ManifestTypes> = [
@@ -7,6 +7,6 @@ export const manifests: Array<ManifestTypes> = [
alias: 'Umb.EntityAction.Script.Tree.ReloadChildrenOf',
name: 'Reload Script Tree Item Children Entity Action',
kind: 'reloadTreeItemChildren',
forEntityTypes: [UMB_SCRIPT_ROOT_ENTITY_TYPE, UMB_SCRIPT_ENTITY_TYPE, UMB_SCRIPT_FOLDER_ENTITY_TYPE],
forEntityTypes: [UMB_SCRIPT_ROOT_ENTITY_TYPE, UMB_SCRIPT_FOLDER_ENTITY_TYPE],
},
];

View File

@@ -1,6 +1,5 @@
import {
UMB_STYLESHEET_ROOT_ENTITY_TYPE,
UMB_STYLESHEET_ENTITY_TYPE,
UMB_STYLESHEET_FOLDER_ENTITY_TYPE,
} from '../../entity.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
@@ -11,6 +10,6 @@ export const manifests: Array<ManifestTypes> = [
kind: 'reloadTreeItemChildren',
alias: 'Umb.EntityAction.Stylesheet.Tree.ReloadChildrenOf',
name: 'Reload Stylesheet Tree Item Children Entity Action',
forEntityTypes: [UMB_STYLESHEET_ROOT_ENTITY_TYPE, UMB_STYLESHEET_ENTITY_TYPE, UMB_STYLESHEET_FOLDER_ENTITY_TYPE],
forEntityTypes: [UMB_STYLESHEET_ROOT_ENTITY_TYPE, UMB_STYLESHEET_FOLDER_ENTITY_TYPE],
},
];