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 @@ -20,6 +20,7 @@ import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import { UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-api';
import { umbExtensionsRegistry, type ManifestRepository } from '@umbraco-cms/backoffice/extension-registry';
import {
UmbVariantPropertyReadOnlyStateManager,
UmbVariantPropertyViewStateManager,
UmbVariantPropertyWriteStateManager,
} from '@umbraco-cms/backoffice/property';
Expand Down Expand Up @@ -104,6 +105,7 @@ export class UmbContentTypeStructureManager<

public readonly propertyViewState = new UmbVariantPropertyViewStateManager(this);
public readonly propertyWriteState = new UmbVariantPropertyWriteStateManager(this);
public readonly propertyReadOnlyState = new UmbVariantPropertyReadOnlyStateManager(this);

#containers: UmbArrayState<UmbPropertyTypeContainerModel> = new UmbArrayState<UmbPropertyTypeContainerModel>(
[],
Expand Down Expand Up @@ -818,6 +820,7 @@ export class UmbContentTypeStructureManager<
this.#containers.destroy();
this.propertyViewState.destroy();
this.propertyWriteState.destroy();
this.propertyReadOnlyState.destroy();
super.destroy();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export class UmbContentWorkspaceViewEditPropertiesElement extends UmbLitElement
@state()
_propertyWriteStates: Array<UmbVariantPropertyWriteState> = [];

@state()
_propertyReadOnlyStates: Array<UmbVariantPropertyReadState> = [];

constructor() {
super();

Expand Down Expand Up @@ -77,6 +80,12 @@ export class UmbContentWorkspaceViewEditPropertiesElement extends UmbLitElement
},
'umbObservePropertyWriteStates',
);

this.observe(
workspaceContext.structure.propertyReadOnlyState.states,
(states) => (this._propertyReadOnlyStates = states),
'umbObservePropertyWriteStates',
);
});

this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (datasetContext) => {
Expand Down Expand Up @@ -129,9 +138,20 @@ export class UmbContentWorkspaceViewEditPropertiesElement extends UmbLitElement
}

const propertyVariantId = this.#getPropertyVariantId(property);
return this._propertyWriteStates.some(

// Check if the property is writable
const isWriteAllowed = this._propertyWriteStates.some(
(state) => state.propertyType.unique === property.unique && state.propertyType.variantId.equal(propertyVariantId),
);

// Check if the property is read only
const isReadOnly = this._propertyReadOnlyStates.some(
(state) => state.propertyType.unique === property.unique && state.propertyType.variantId.equal(propertyVariantId),
);

// If the property has a read only state it will override the write state
// and the property will always be read only
return isWriteAllowed && !isReadOnly;
}

#getPropertyVariantId(property: UmbPropertyTypeModel) {
Expand Down
4 changes: 2 additions & 2 deletions src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export * from './components/index.js';
export * from './conditions/index.js';
export * from './property-dataset/index.js';
export * from './property-read-only-state.manager.js';
export * from './property-value-cloner/property-value-clone.controller.js';
export * from './property-value-preset/index.js';
export * from './property-view-state.manager.js';
export * from './property-write-state.manager.js';
export * from './property-view-state.manager.js';
export * from './property-write-state.manager.js';
export * from './variant-property-read-only-state.manager.js';
export * from './variant-property-view-state.manager.js';
export * from './variant-property-write-state.manager.js';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
import { UmbReadOnlyStateManager, type UmbState } from '@umbraco-cms/backoffice/utils';

export interface UmbPropertyReadOnlyState extends UmbState {
propertyType: UmbReferenceByUnique;
}

export class UmbPropertyReadOnlyStateManager<
ReadOnlyStateType extends UmbPropertyReadOnlyState = UmbPropertyReadOnlyState,
> extends UmbReadOnlyStateManager<ReadOnlyStateType> {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { UmbPropertyReadOnlyStateManager, type UmbPropertyReadOnlyState } from './property-read-only-state.manager.js';
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
import type { UmbReferenceByVariantId } from '@umbraco-cms/backoffice/variant';

export interface UmbVariantPropertyReadOnlyState extends UmbPropertyReadOnlyState {
propertyType: UmbReferenceByUnique & UmbReferenceByVariantId;
}

export class UmbVariantPropertyReadOnlyStateManager extends UmbPropertyReadOnlyStateManager<UmbVariantPropertyReadOnlyState> {}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './variant-id.class.js';
export * from './variant-object-compare.function.js';

export type * from './types.js';
Original file line number Diff line number Diff line change
@@ -1,9 +1,65 @@
import type { UmbDocumentDetailModel, UmbDocumentVariantModel } from '../types.js';
import type { UmbDocumentDetailModel, UmbDocumentVariantModel, UmbDocumentWorkspaceContext } from '../types.js';
import { UMB_DOCUMENT_CONFIGURATION_CONTEXT } from '../global-contexts/index.js';
import { UmbContentPropertyDatasetContext } from '@umbraco-cms/backoffice/content';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbDocumentTypeDetailModel } from '@umbraco-cms/backoffice/document-type';
import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
import { UmbVariantId, type UmbVariantPropertyReadOnlyState } from '@umbraco-cms/backoffice/variant';
import type { DocumentConfigurationResponseModel } from '@umbraco-cms/backoffice/external/backend-api';

export class UmbDocumentPropertyDatasetContext extends UmbContentPropertyDatasetContext<
UmbDocumentDetailModel,
UmbDocumentTypeDetailModel,
UmbDocumentVariantModel
> {}
> {
#dataSetVariantId?: UmbVariantId;
#documentConfiguration?: DocumentConfigurationResponseModel;

constructor(host: UmbControllerHost, dataOwner: UmbDocumentWorkspaceContext, variantId?: UmbVariantId) {
super(host, dataOwner, variantId);

this.#dataSetVariantId = variantId;

this.consumeContext(UMB_DOCUMENT_CONFIGURATION_CONTEXT, async (context) => {
this.#documentConfiguration = (await context?.getDocumentConfiguration()) ?? undefined;

if (this.#documentConfiguration?.allowEditInvariantFromNonDefault !== true) {
this.#preventEditInvariantFromNonDefault();
}
});
}

#preventEditInvariantFromNonDefault() {
this.observe(
observeMultiple([this._dataOwner.structure.contentTypeProperties, this._dataOwner.variantOptions]),
([properties, variantOptions]) => {
if (properties.length === 0) return;
if (variantOptions.length === 0) return;

const currentVariantOption = variantOptions.find(
(option) => option.culture === this.#dataSetVariantId?.culture,
);
const isDefaultLanguage = currentVariantOption?.language.isDefault;

properties.forEach((property) => {
const unique = 'UMB_PREVENT_EDIT_INVARIANT_FROM_NON_DEFAULT_' + property.unique;

this._dataOwner.structure.propertyReadOnlyState.removeState(unique);

if (!property.variesByCulture && !isDefaultLanguage) {
const state: UmbVariantPropertyReadOnlyState = {
unique,
message: 'Shared properties can only be edited in the default language',
propertyType: {
unique: property.unique,
variantId: new UmbVariantId(),
},
};

this._dataOwner.structure.propertyReadOnlyState.addState(state);
}
});
},
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ export class UmbDocumentWorkspaceContext
this.#isTrashedContext.setIsTrashed(false);
this.structure.propertyViewState.clear();
this.structure.propertyWriteState.clear();
this.structure.propertyReadOnlyState.clear();
}

override async load(unique: string) {
Expand Down