Skip to content

Commit

Permalink
[ACS-6252] support disabling the tags and categories feature in the a…
Browse files Browse the repository at this point in the history
…pplications (#3533)

* ACS-6252 Allow to hide tags and categories from metadata panel and to hide tags column from personal files

* ACS-6252 Allow to hide tags column from all other lists

* ACS-6252 Allow to hide tags and categories from search filters

* ACS-6252 Set type for search field

* ACS-6252 Hide displaying tags and categories related operators, properties and aspects in folder rules when that feature is disabled

* ACS-6252 Get from service information if tags and categories are disabled

* ACS-6252 Handled case when tags and categories configuration is missing in app.config.json

* ACS-6252 Unit tests for changes for RuleActionUiComponent

* ACS-6252 Unit tests for changes for RuleSimpleConditionUiComponent

* ACS-6252 Unit tests for changes for MetadataTabComponent

* ACS-6252 Unit tests for changes for app rules

* ACS-6252 Unit tests for changes for AppExtensionService

* ACS-6252 Removed redundant private from constructor parameter and corrected unit test title

* ACS-6252 Hide link to category action if categories feature is disabled

* ACS-6252 Move to beforeEach
  • Loading branch information
AleksanderSklorz authored Nov 28, 2023
1 parent 6a326f7 commit 2c69887
Show file tree
Hide file tree
Showing 16 changed files with 535 additions and 64 deletions.
4 changes: 3 additions & 1 deletion app/src/app.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
"plugins": {
"aosPlugin": true,
"contentService": true,
"folderRules": true
"folderRules": true,
"tags": true,
"categories": true
},
"oauth2": {
"host": "{protocol}//{hostname}{:port}/auth/realms/alfresco",
Expand Down
26 changes: 22 additions & 4 deletions projects/aca-content/assets/app.extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,9 @@
"allowOnlyPredefinedValues": true,
"field": "TAG"
}
},
"rules": {
"visible": "app.areTagsEnabled"
}
},
{
Expand All @@ -1509,6 +1512,9 @@
"allowOnlyPredefinedValues": true,
"field": "cm:categories"
}
},
"rules": {
"visible": "app.areCategoriesEnabled"
}
}
]
Expand Down Expand Up @@ -2160,7 +2166,10 @@
"type": "text",
"sortable": false,
"desktopOnly": true,
"order": 60
"order": 60,
"rules": {
"visible": "app.areTagsEnabled"
}
}
],
"libraries": [
Expand Down Expand Up @@ -2357,7 +2366,10 @@
"type": "text",
"sortable": false,
"desktopOnly": true,
"order": 80
"order": 80,
"rules": {
"visible": "app.areTagsEnabled"
}
}
],
"recent": [
Expand Down Expand Up @@ -2422,7 +2434,10 @@
"type": "text",
"sortable": false,
"desktopOnly": true,
"order": 60
"order": 60,
"rules": {
"visible": "app.areTagsEnabled"
}
}
],
"favorites": [
Expand Down Expand Up @@ -2497,7 +2512,10 @@
"type": "text",
"sortable": false,
"desktopOnly": true,
"order": 70
"order": 70,
"rules": {
"visible": "app.areTagsEnabled"
}
}
],
"trashcan": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,47 @@ export const rawConstraints = {
constraintName: 'ac-aspects'
}
};

export const dummyTagsConstraints: ActionParameterConstraint[] = [
{
name: 'aspect-name',
constraints: [
{
value: 'cm:tagscope',
label: 'Label 1'
},
{
value: 'cm:tagScopeCache',
label: 'Label 2'
},
{
value: 'cm:notTagRelated',
label: 'Label 3'
},
{
value: 'cm:taggable',
label: 'Label 4'
}
]
}
];

export const dummyCategoriesConstraints: ActionParameterConstraint[] = [
{
name: 'aspect-name',
constraints: [
{
value: 'cm:categories',
label: 'Label 1'
},
{
value: 'cm:notCategoryRelated',
label: 'Label 2'
},
{
value: 'cm:generalclassifiable',
label: 'Label 3'
}
]
}
];
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,27 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CardViewBoolItemModel, CardViewComponent, CardViewSelectItemModel, CardViewTextItemModel, CoreTestingModule } from '@alfresco/adf-core';
import { RuleActionUiComponent } from './rule-action.ui-component';
import { actionLinkToCategoryTransformedMock, actionsTransformedListMock } from '../../mock/actions.mock';
import { DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
import { dummyConstraints } from '../../mock/action-parameter-constraints.mock';
import { dummyCategoriesConstraints, dummyConstraints, dummyTagsConstraints } from '../../mock/action-parameter-constraints.mock';
import { CategoryService, TagService } from '@alfresco/adf-content-services';
import { MatSelect } from '@angular/material/select';

describe('RuleActionUiComponent', () => {
let fixture: ComponentFixture<RuleActionUiComponent>;
let component: RuleActionUiComponent;

const getByDataAutomationId = (dataAutomationId: string): DebugElement =>
fixture.debugElement.query(By.css(`[data-automation-id="${dataAutomationId}"]`));
const getSelectElement = (): HTMLElement => fixture.debugElement.query(By.directive(MatSelect)).nativeElement;

const changeMatSelectValue = (dataAutomationId: string, value: string) => {
const matSelect = getByDataAutomationId(dataAutomationId).nativeElement;
matSelect.click();
const changeMatSelectValue = (value: string) => {
getSelectElement().click();
fixture.detectChanges();
const matOption = fixture.debugElement.query(By.css(`.mat-option[ng-reflect-value="${value}"]`)).nativeElement;
matOption.click();
fixture.detectChanges();
};

const getPropertiesCardView = (): CardViewComponent => fixture.debugElement.query(By.directive(CardViewComponent)).componentInstance;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [CoreTestingModule, RuleActionUiComponent]
Expand All @@ -59,8 +60,7 @@ describe('RuleActionUiComponent', () => {
component.actionDefinitions = actionsTransformedListMock;
fixture.detectChanges();

const matSelect = getByDataAutomationId('rule-action-select').nativeElement;
matSelect.click();
getSelectElement().click();
fixture.detectChanges();

const matOptions = fixture.debugElement.queryAll(By.css(`mat-option`));
Expand All @@ -74,10 +74,10 @@ describe('RuleActionUiComponent', () => {
component.parameterConstraints = dummyConstraints;
fixture.detectChanges();

const cardView = getByDataAutomationId('rule-action-card-view').componentInstance as CardViewComponent;
const cardView = getPropertiesCardView();
expect(cardView.properties.length).toBe(0);

changeMatSelectValue('rule-action-select', 'mock-action-1-definition');
changeMatSelectValue('mock-action-1-definition');

expect(cardView.properties.length).toBe(5);
expect(cardView.properties[0]).toBeInstanceOf(CardViewTextItemModel);
Expand All @@ -86,7 +86,7 @@ describe('RuleActionUiComponent', () => {
expect(cardView.properties[3]).toBeInstanceOf(CardViewTextItemModel);
expect(cardView.properties[4]).toBeInstanceOf(CardViewSelectItemModel);

changeMatSelectValue('rule-action-select', 'mock-action-2-definition');
changeMatSelectValue('mock-action-2-definition');
expect(cardView.properties.length).toBe(0);
});

Expand All @@ -95,13 +95,95 @@ describe('RuleActionUiComponent', () => {
component.parameterConstraints = dummyConstraints;
fixture.detectChanges();

const cardView = getByDataAutomationId('rule-action-card-view').componentInstance as CardViewComponent;
const cardView = getPropertiesCardView();
expect(cardView.properties.length).toBe(0);

changeMatSelectValue('rule-action-select', 'mock-action-3-definition');
changeMatSelectValue('mock-action-3-definition');

expect(cardView.properties[0].icon).toBeFalsy();
expect(cardView.properties[0].value).toBeFalsy();
expect(cardView.properties[0]).toBeInstanceOf(CardViewTextItemModel);
});

describe('Select options', () => {
beforeEach(() => {
component.actionDefinitions = actionsTransformedListMock;
});

it('should not filter out tags related options if tagService.areTagsEnabled returns true', (done) => {
component.parameterConstraints = dummyTagsConstraints;
const tagService = TestBed.inject(TagService);
spyOn(tagService, 'areTagsEnabled').and.returnValue(true);
fixture.detectChanges();

changeMatSelectValue('mock-action-1-definition');
expect(tagService.areTagsEnabled).toHaveBeenCalled();
(getPropertiesCardView().properties[2] as CardViewSelectItemModel<string>).options$.subscribe((options) => {
expect(options).toEqual(
dummyTagsConstraints[0].constraints.map((constraint) => ({
key: constraint.value,
label: `${constraint.label} [${constraint.value}]`
}))
);
done();
});
});

it('should filter out tags related options if tagService.areTagsEnabled returns false', (done) => {
component.parameterConstraints = dummyTagsConstraints;
const tagService = TestBed.inject(TagService);
spyOn(tagService, 'areTagsEnabled').and.returnValue(false);
fixture.detectChanges();

changeMatSelectValue('mock-action-1-definition');
expect(tagService.areTagsEnabled).toHaveBeenCalled();
(getPropertiesCardView().properties[2] as CardViewSelectItemModel<string>).options$.subscribe((options) => {
expect(options).toEqual([
{
key: 'cm:notTagRelated',
label: 'Label 3 [cm:notTagRelated]'
}
]);
done();
});
});

it('should not filter out categories related options if categoryService.areCategoriesEnabled returns true', (done) => {
component.parameterConstraints = dummyCategoriesConstraints;
const categoriesService = TestBed.inject(CategoryService);
spyOn(categoriesService, 'areCategoriesEnabled').and.returnValue(true);
fixture.detectChanges();

changeMatSelectValue('mock-action-1-definition');
expect(categoriesService.areCategoriesEnabled).toHaveBeenCalled();
(getPropertiesCardView().properties[2] as CardViewSelectItemModel<string>).options$.subscribe((options) => {
expect(options).toEqual(
dummyCategoriesConstraints[0].constraints.map((constraint) => ({
key: constraint.value,
label: `${constraint.label} [${constraint.value}]`
}))
);
done();
});
});

it('should filter out categories related options if categoryService.areCategoriesEnabled returns false', (done) => {
component.parameterConstraints = dummyCategoriesConstraints;
const categoryService = TestBed.inject(CategoryService);
spyOn(categoryService, 'areCategoriesEnabled').and.returnValue(false);
fixture.detectChanges();

changeMatSelectValue('mock-action-1-definition');
expect(categoryService.areCategoriesEnabled).toHaveBeenCalled();
(getPropertiesCardView().properties[2] as CardViewSelectItemModel<string>).options$.subscribe((options) => {
expect(options).toEqual([
{
key: 'cm:notCategoryRelated',
label: 'Label 2 [cm:notCategoryRelated]'
}
]);
done();
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,15 @@ import {
} from '@alfresco/adf-core';
import { ActionParameterDefinition, Node } from '@alfresco/js-api';
import { of, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { map, takeUntil } from 'rxjs/operators';
import { ActionParameterConstraint, ConstraintValue } from '../../model/action-parameter-constraint.model';
import { ContentNodeSelectorComponent, ContentNodeSelectorComponentData, NodeAction } from '@alfresco/adf-content-services';
import {
CategoryService,
ContentNodeSelectorComponent,
ContentNodeSelectorComponentData,
NodeAction,
TagService
} from '@alfresco/adf-content-services';
import { MatDialog } from '@angular/material/dialog';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { CommonModule } from '@angular/common';
Expand Down Expand Up @@ -82,6 +88,9 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
this._parameterConstraints = value.map((obj) => ({ ...obj, constraints: this.parseConstraintsToSelectOptions(obj.constraints) }));
}

private readonly tagsRelatedPropertiesAndAspects = ['cm:tagscope', 'cm:tagScopeCache', 'cm:taggable'];
private readonly categoriesRelatedPropertiesAndAspects = ['cm:categories', 'cm:generalclassifiable'];

isFullWidth = false;

form = new FormGroup({
Expand All @@ -107,7 +116,13 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
onChange: (action: RuleAction) => void = () => undefined;
onTouch: () => void = () => undefined;

constructor(private cardViewUpdateService: CardViewUpdateService, private dialog: MatDialog, private translate: TranslateService) {}
constructor(
private cardViewUpdateService: CardViewUpdateService,
private dialog: MatDialog,
private translate: TranslateService,
private tagService: TagService,
private categoryService: CategoryService
) {}

writeValue(action: RuleAction) {
this.form.setValue({
Expand Down Expand Up @@ -170,6 +185,8 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
}

setCardViewProperties() {
const disabledTags = !this.tagService.areTagsEnabled();
const disabledCategories = !this.categoryService.areCategoriesEnabled();
this.cardViewItems = (this.selectedActionDefinition?.parameterDefinitions ?? []).map((paramDef) => {
this.isFullWidth = false;
const constraintsForDropdownBox = this._parameterConstraints.find((obj) => obj.name === paramDef.name);
Expand Down Expand Up @@ -212,7 +229,17 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
return new CardViewSelectItemModel({
...cardViewPropertiesModel,
value: (this.parameters[paramDef.name] as string) ?? '',
options$: of(constraintsForDropdownBox.constraints)
options$: of(constraintsForDropdownBox.constraints).pipe(
map((options) => {
return options.filter(
(option) =>
!(
(disabledTags && this.tagsRelatedPropertiesAndAspects.includes(option.key)) ||
(disabledCategories && this.categoriesRelatedPropertiesAndAspects.includes(option.key))
)
);
})
)
});
}
return new CardViewTextItemModel({
Expand Down
Loading

0 comments on commit 2c69887

Please sign in to comment.