mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-02 17:53:30 +00:00
[MNT-25612] ADW Metadata Drawer ignores read‑only presets (readOnlyAspects / readOnlyProperties) (#12129)
This commit is contained in:
+1
-1
@@ -869,7 +869,7 @@ describe('ContentMetadataComponent', () => {
|
||||
|
||||
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
||||
|
||||
expect(contentMetadataService.getContentTypeProperty).toHaveBeenCalledWith(expectedNode);
|
||||
expect(contentMetadataService.getContentTypeProperty).toHaveBeenCalledWith(expectedNode, preset);
|
||||
expect(contentMetadataService.getBasicProperties).toHaveBeenCalledWith(expectedNode, preset);
|
||||
});
|
||||
|
||||
|
||||
+1
-1
@@ -474,7 +474,7 @@ export class ContentMetadataComponent implements OnChanges, OnInit {
|
||||
|
||||
private getProperties(node: Node) {
|
||||
const properties$ = this.contentMetadataService.getBasicProperties(node, this.preset);
|
||||
const contentTypeProperty$ = this.contentMetadataService.getContentTypeProperty(node);
|
||||
const contentTypeProperty$ = this.contentMetadataService.getContentTypeProperty(node, this.preset);
|
||||
return zip(properties$, contentTypeProperty$).pipe(
|
||||
map(([properties, contentTypeProperty]) => {
|
||||
const filteredProperties = contentTypeProperty.filter(
|
||||
|
||||
+52
@@ -249,6 +249,15 @@ describe('ContentMetaDataService', () => {
|
||||
expect(authorProperty.editable).toBeTrue();
|
||||
});
|
||||
|
||||
it('should hide basic properties from general info when they are excluded', async () => {
|
||||
setConfig('custom', [{ includeAll: true, exclude: ['cm:title'] }]);
|
||||
|
||||
const res = await firstValueFrom(service.getBasicProperties(fakeNode, 'custom'));
|
||||
|
||||
expect(res.find((property) => property.key === 'properties.cm:title')).toBeUndefined();
|
||||
expect(res.find((property) => property.key === 'properties.cm:name')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should return the content type property', () => {
|
||||
spyOn(contentPropertyService, 'getContentTypeCardItem').and.returnValue(of([{ label: 'hello i am a weird content type' } as CardViewItem]));
|
||||
|
||||
@@ -257,6 +266,49 @@ describe('ContentMetaDataService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should hide a single content type property in general info when that property is excluded', async () => {
|
||||
setConfig('custom', [{ includeAll: true, exclude: ['fn:thema'] }]);
|
||||
spyOn(contentPropertyService, 'getContentTypeCardItem').and.returnValue(
|
||||
of([
|
||||
{ label: 'Content Type', key: 'nodeType' } as CardViewItem,
|
||||
{ label: 'System', key: 'properties.fn:system' } as CardViewItem,
|
||||
{ label: 'Thema', key: 'properties.fn:thema' } as CardViewItem
|
||||
])
|
||||
);
|
||||
|
||||
const res = await firstValueFrom(service.getContentTypeProperty(fakeNode, 'custom'));
|
||||
|
||||
expect(res.map((item) => item.key)).toEqual(['nodeType', 'properties.fn:system']);
|
||||
});
|
||||
|
||||
it('should hide content type specific properties in general info when the node type is excluded', async () => {
|
||||
setConfig('custom', [{ includeAll: true, exclude: ['fn:fakenode'] }]);
|
||||
spyOn(contentPropertyService, 'getContentTypeCardItem').and.returnValue(
|
||||
of([
|
||||
{ label: 'Content Type', key: 'nodeType' } as CardViewItem,
|
||||
{ label: 'System', key: 'properties.fn:system' } as CardViewItem,
|
||||
{ label: 'Thema', key: 'properties.fn:thema' } as CardViewItem
|
||||
])
|
||||
);
|
||||
|
||||
const res = await firstValueFrom(service.getContentTypeProperty(fakeNode, 'custom'));
|
||||
|
||||
expect(res.length).toBe(1);
|
||||
expect(res[0].key).toBe('nodeType');
|
||||
});
|
||||
|
||||
it('should keep content type specific properties in general info when the node type is not excluded', async () => {
|
||||
setConfig('custom', [{ includeAll: true, exclude: ['cm:versionable'] }]);
|
||||
spyOn(contentPropertyService, 'getContentTypeCardItem').and.returnValue(
|
||||
of([{ label: 'Content Type', key: 'nodeType' } as CardViewItem, { label: 'System', key: 'properties.fn:system' } as CardViewItem])
|
||||
);
|
||||
|
||||
const res = await firstValueFrom(service.getContentTypeProperty(fakeNode, 'custom'));
|
||||
|
||||
expect(res.length).toBe(2);
|
||||
expect(res.map((item) => item.key)).toEqual(['nodeType', 'properties.fn:system']);
|
||||
});
|
||||
|
||||
it('should trigger the opening of the content type dialog', () => {
|
||||
spyOn(contentPropertyService, 'openContentTypeDialogConfirm').and.returnValue(of(true));
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import { Property } from '../interfaces/property.interface';
|
||||
|
||||
interface LayoutBlockWithReadOnly extends LayoutOrientedConfigLayoutBlock {
|
||||
readOnlyProperties?: string | string[];
|
||||
exclude?: string | string[];
|
||||
}
|
||||
|
||||
const CONTENT_METADATA_CONFIG_KEY = 'content-metadata';
|
||||
@@ -50,8 +51,13 @@ export class ContentMetadataService {
|
||||
error = new Subject<{ statusCode: number; message: string }>();
|
||||
|
||||
getBasicProperties(node: Node, preset: string | PresetConfig = 'default'): Observable<CardViewItem[]> {
|
||||
const properties = this.basicPropertiesService.getProperties(node);
|
||||
const readOnlyProperties = this.getReadOnlyPropertyNames(preset);
|
||||
const excludedNames = this.getExcludedNames(preset);
|
||||
|
||||
const properties = this.basicPropertiesService.getProperties(node).filter((property) => {
|
||||
const propertyName = this.getBasicPropertyName(property.key);
|
||||
return !propertyName || !excludedNames.includes(propertyName);
|
||||
});
|
||||
|
||||
if (readOnlyProperties.length) {
|
||||
properties.forEach((property) => {
|
||||
@@ -70,7 +76,7 @@ export class ContentMetadataService {
|
||||
}
|
||||
|
||||
private getReadOnlyPropertyNames(preset: string | PresetConfig): string[] {
|
||||
const presetConfig = typeof preset === 'string' ? this.appConfig.config[CONTENT_METADATA_CONFIG_KEY]?.presets?.[preset] : preset;
|
||||
const presetConfig = this.getPresetConfig(preset);
|
||||
|
||||
if (this.isLayoutConfig(presetConfig)) {
|
||||
return presetConfig.reduce((readOnly, block) => readOnly.concat(this.getLayoutBlockReadOnlyNames(block)), [] as string[]);
|
||||
@@ -83,6 +89,10 @@ export class ContentMetadataService {
|
||||
return [];
|
||||
}
|
||||
|
||||
private getPresetConfig(preset: string | PresetConfig): PresetConfig {
|
||||
return typeof preset === 'string' ? this.appConfig.config[CONTENT_METADATA_CONFIG_KEY]?.presets?.[preset] : preset;
|
||||
}
|
||||
|
||||
private isLayoutConfig(config: unknown): config is LayoutOrientedConfig {
|
||||
return Array.isArray(config);
|
||||
}
|
||||
@@ -96,15 +106,45 @@ export class ContentMetadataService {
|
||||
return blockReadOnly.concat(nonEditableItems);
|
||||
}
|
||||
|
||||
private normaliseToArray(value: string | string[] | Property[] | undefined): string[] {
|
||||
private normaliseToArray(value: string | string[] | Property[] | boolean | undefined): string[] {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => (typeof item === 'string' ? item : item?.name)).filter((name): name is string => typeof name === 'string');
|
||||
}
|
||||
return typeof value === 'string' ? [value] : [];
|
||||
}
|
||||
|
||||
getContentTypeProperty(node: Node): Observable<CardViewItem[]> {
|
||||
return this.contentTypePropertyService.getContentTypeCardItem(node);
|
||||
getContentTypeProperty(node: Node, preset: string | PresetConfig = 'default'): Observable<CardViewItem[]> {
|
||||
const excludedNames = this.getExcludedNames(preset);
|
||||
const isTypeExcluded = excludedNames.includes(node.nodeType);
|
||||
|
||||
return this.contentTypePropertyService.getContentTypeCardItem(node).pipe(
|
||||
map((items) =>
|
||||
items.filter((item) => {
|
||||
const propertyName = this.getBasicPropertyName(item.key);
|
||||
if (!propertyName) {
|
||||
return true;
|
||||
}
|
||||
return !isTypeExcluded && !excludedNames.includes(propertyName);
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private getExcludedNames(preset: string | PresetConfig): string[] {
|
||||
const presetConfig = this.getPresetConfig(preset);
|
||||
|
||||
if (this.isLayoutConfig(presetConfig)) {
|
||||
return presetConfig.reduce(
|
||||
(excluded, block) => excluded.concat(this.normaliseToArray((block as LayoutBlockWithReadOnly)?.exclude)),
|
||||
[] as string[]
|
||||
);
|
||||
}
|
||||
|
||||
if (presetConfig != null && typeof presetConfig === 'object') {
|
||||
return this.normaliseToArray(presetConfig.exclude);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
openConfirmDialog(changedProperties): Observable<any> {
|
||||
|
||||
Reference in New Issue
Block a user