Hello
I am wanting to see if its possible to have a condition with the existing contexts available to do the following.
Goal
A condition to check the currently viewed document has a specific Data Type Editor Alias.
For example only load this extension for an entity action when we have a property on the content node that uses Umbraco.BlockGrid
Things tried
I have tried to look at the UMB_PROPERTY_STRUCTURE_WORKSPACE_CONTEXT to see if I can find information about the datatypes for the properties that build up the content node.
I can see in there I can only get the property’s datatype as a unique and nothing more.
I have built a custom condition that calls a custom C# API controller I wrote that sends the document/content node GUID/unique. Which I then use C# APIs to look up the content node and then filter and try to find if the document/node does have any properties with a given content editor alias.
How would you solve it?
Is there some existing context and observable property to use that has the info I need ?
Or is the current approach I have the best way - to me I am not 100% convinced hence I am asking here
I would have thought this information should be available to me already without my approach above
One of the things that worked really well for me, is get the Umbraco source code in Visual Studio and use Github Copilot with a reasoning model like Claude and ask it questions on how to do this. Not only can it see the entire source code, but it can also see examples as done by the Umbraco developers themselves. It helped me find a way to attach a condition to an existing entity (in my case the delete button) by looking at the source.
Claude says this. Maybe it’s not perfect, but it might be a good direction:
import { UMB_PROPERTY_STRUCTURE_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type';
export class YourExtensionCondition {
#dataTypeRepository = new UmbDataTypeDetailRepository(this);
#hasTargetDataType = false;
constructor() {
this.consumeContext(UMB_PROPERTY_STRUCTURE_WORKSPACE_CONTEXT, (context) => {
this.observe(context?.structure.contentTypeProperties, (contentTypeProperties) => {
this.#checkForBlockGridDataType(contentTypeProperties);
});
});
}
async #checkForBlockGridDataType(contentTypeProperties) {
if (!contentTypeProperties?.length) {
this.#hasTargetDataType = false;
return;
}
// Use Promise.all for better performance when checking multiple data types
const dataTypeChecks = contentTypeProperties.map(async (property) => {
if (!property.dataType?.unique) return false;
try {
await this.#dataTypeRepository.requestByUnique(property.dataType.unique);
const dataTypeObservable = await this.#dataTypeRepository.byUnique(property.dataType.unique);
const dataType = dataTypeObservable?.getValue();
return dataType?.editorAlias === 'Umbraco.BlockGrid';
} catch {
return false;
}
});
const results = await Promise.allSettled(dataTypeChecks);
this.#hasTargetDataType = results.some(result =>
result.status === 'fulfilled' && result.value === true
);
// Trigger your condition logic here
this.#updateConditionState();
}
#updateConditionState() {
// Update your extension's visibility/availability based on this.#hasTargetDataType
console.log('Has BlockGrid property:', this.#hasTargetDataType);
}
}
Well, clearly not great as it would result in requesting all data-type begin requested over again for every change to the document type.
Instead, you could borrow something we do:
#dataTypeItemManager = new UmbDataTypeItemRepositoryManager(this);
...
this.consumeContext(UMB_PROPERTY_STRUCTURE_WORKSPACE_CONTEXT, (context) => {
this.observe(
context.contentTypeDataTypeUniques,
(dataTypeUniques: Array<string>) => {
this.#dataTypeItemManager.setUniques(dataTypeUniques);
}
);
});
...
this.observe(
this.#dataTypeItemManager.items,
(dataTypes) => {
// Here you have all the data-types:
console.log(dataTypes)
}
);
But again requesting all data-types is not really ideal, so it would be better if you just checked the Data Type ID?
Also we could make this available for you, but we currently do not do that, so there is room for a PR?