mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
[ACS-6252] support disabling the tags and categories feature in the applications (#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
This commit is contained in:
parent
6a326f776a
commit
2c69887e08
@ -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",
|
||||
|
@ -1495,6 +1495,9 @@
|
||||
"allowOnlyPredefinedValues": true,
|
||||
"field": "TAG"
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.areTagsEnabled"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -1509,6 +1512,9 @@
|
||||
"allowOnlyPredefinedValues": true,
|
||||
"field": "cm:categories"
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.areCategoriesEnabled"
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -2160,7 +2166,10 @@
|
||||
"type": "text",
|
||||
"sortable": false,
|
||||
"desktopOnly": true,
|
||||
"order": 60
|
||||
"order": 60,
|
||||
"rules": {
|
||||
"visible": "app.areTagsEnabled"
|
||||
}
|
||||
}
|
||||
],
|
||||
"libraries": [
|
||||
@ -2357,7 +2366,10 @@
|
||||
"type": "text",
|
||||
"sortable": false,
|
||||
"desktopOnly": true,
|
||||
"order": 80
|
||||
"order": 80,
|
||||
"rules": {
|
||||
"visible": "app.areTagsEnabled"
|
||||
}
|
||||
}
|
||||
],
|
||||
"recent": [
|
||||
@ -2422,7 +2434,10 @@
|
||||
"type": "text",
|
||||
"sortable": false,
|
||||
"desktopOnly": true,
|
||||
"order": 60
|
||||
"order": 60,
|
||||
"rules": {
|
||||
"visible": "app.areTagsEnabled"
|
||||
}
|
||||
}
|
||||
],
|
||||
"favorites": [
|
||||
@ -2497,7 +2512,10 @@
|
||||
"type": "text",
|
||||
"sortable": false,
|
||||
"desktopOnly": true,
|
||||
"order": 70
|
||||
"order": 70,
|
||||
"rules": {
|
||||
"visible": "app.areTagsEnabled"
|
||||
}
|
||||
}
|
||||
],
|
||||
"trashcan": [
|
||||
|
@ -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'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
@ -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]
|
||||
@ -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`));
|
||||
@ -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);
|
||||
@ -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);
|
||||
});
|
||||
|
||||
@ -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();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -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';
|
||||
@ -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({
|
||||
@ -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({
|
||||
@ -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);
|
||||
@ -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({
|
||||
|
@ -29,15 +29,19 @@ import { By } from '@angular/platform-browser';
|
||||
import { DebugElement } from '@angular/core';
|
||||
import { tagMock, mimeTypeMock, simpleConditionUnknownFieldMock, categoriesListMock } from '../../mock/conditions.mock';
|
||||
import { MimeType } from './rule-mime-types';
|
||||
import { CategoryService } from '@alfresco/adf-content-services';
|
||||
import { CategoryService, TagService } from '@alfresco/adf-content-services';
|
||||
import { of } from 'rxjs';
|
||||
import { RuleSimpleCondition } from '../../model/rule-simple-condition.model';
|
||||
import { delay } from 'rxjs/operators';
|
||||
import { MatOption } from '@angular/material/core';
|
||||
import { RuleConditionField, ruleConditionFields } from './rule-condition-fields';
|
||||
|
||||
describe('RuleSimpleConditionUiComponent', () => {
|
||||
let fixture: ComponentFixture<RuleSimpleConditionUiComponent>;
|
||||
let categoryService: CategoryService;
|
||||
|
||||
const fieldSelectAutomationId = 'field-select';
|
||||
|
||||
const getByDataAutomationId = (dataAutomationId: string): DebugElement =>
|
||||
fixture.debugElement.query(By.css(`[data-automation-id="${dataAutomationId}"]`));
|
||||
|
||||
@ -57,6 +61,18 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
fixture.detectChanges();
|
||||
};
|
||||
|
||||
const expectConditionFieldsDisplayedAsOptions = (conditionFields: RuleConditionField[]): void => {
|
||||
fixture.detectChanges();
|
||||
getByDataAutomationId(fieldSelectAutomationId).nativeElement.click();
|
||||
fixture.detectChanges();
|
||||
const options = fixture.debugElement.queryAll(By.directive(MatOption));
|
||||
conditionFields.forEach((field, i) => {
|
||||
const option = options[i];
|
||||
expect(field.name).toBe(option.componentInstance.value);
|
||||
expect(field.label).toBe(option.nativeElement.textContent.trim());
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreTestingModule, RuleSimpleConditionUiComponent]
|
||||
@ -69,7 +85,7 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
it('should default the field to the name, the comparator to equals and the value empty', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getByDataAutomationId('field-select').componentInstance.value).toBe('cm:name');
|
||||
expect(getByDataAutomationId(fieldSelectAutomationId).componentInstance.value).toBe('cm:name');
|
||||
expect(getByDataAutomationId('comparator-select').componentInstance.value).toBe('equals');
|
||||
expect(getByDataAutomationId('value-input').nativeElement.value).toBe('');
|
||||
});
|
||||
@ -81,7 +97,7 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
expect(fixture.componentInstance.isComparatorHidden).toBeFalsy();
|
||||
expect(getComputedStyle(comparatorFormField).display).not.toBe('none');
|
||||
|
||||
changeMatSelectValue('field-select', 'category');
|
||||
changeMatSelectValue(fieldSelectAutomationId, 'category');
|
||||
|
||||
expect(fixture.componentInstance.isComparatorHidden).toBeTruthy();
|
||||
expect(getComputedStyle(comparatorFormField).display).toBe('none');
|
||||
@ -94,7 +110,7 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
expect(fixture.componentInstance.isComparatorHidden).toBeFalsy();
|
||||
expect(getComputedStyle(comparatorFormField).display).not.toBe('none');
|
||||
|
||||
changeMatSelectValue('field-select', 'mimetype');
|
||||
changeMatSelectValue(fieldSelectAutomationId, 'mimetype');
|
||||
|
||||
expect(fixture.componentInstance.isComparatorHidden).toBeTruthy();
|
||||
expect(getComputedStyle(comparatorFormField).display).toBe('none');
|
||||
@ -108,7 +124,7 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
expect(fixture.componentInstance.isComparatorHidden).toBeFalsy();
|
||||
expect(getComputedStyle(comparatorFormField).display).not.toBe('none');
|
||||
|
||||
changeMatSelectValue('field-select', autoCompleteField);
|
||||
changeMatSelectValue(fieldSelectAutomationId, autoCompleteField);
|
||||
|
||||
expect(fixture.componentInstance.isComparatorHidden).toBeTruthy();
|
||||
expect(getComputedStyle(comparatorFormField).display).toBe('none');
|
||||
@ -120,11 +136,11 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
changeMatSelectValue('comparator-select', 'contains');
|
||||
|
||||
expect(getByDataAutomationId('comparator-select').componentInstance.value).toBe('contains');
|
||||
changeMatSelectValue('field-select', 'mimetype');
|
||||
changeMatSelectValue(fieldSelectAutomationId, 'mimetype');
|
||||
|
||||
expect(onChangeFieldSpy).toHaveBeenCalledTimes(1);
|
||||
expect(getByDataAutomationId('comparator-select').componentInstance.value).toBe('equals');
|
||||
changeMatSelectValue('field-select', 'size');
|
||||
changeMatSelectValue(fieldSelectAutomationId, 'size');
|
||||
|
||||
expect(onChangeFieldSpy).toHaveBeenCalledTimes(2);
|
||||
expect(getByDataAutomationId('comparator-select').componentInstance.value).toBe('equals');
|
||||
@ -134,8 +150,8 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
fixture.componentInstance.writeValue(simpleConditionUnknownFieldMock);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getByDataAutomationId('field-select').componentInstance.value).toBe(simpleConditionUnknownFieldMock.field);
|
||||
const matSelect = getByDataAutomationId('field-select').nativeElement;
|
||||
expect(getByDataAutomationId(fieldSelectAutomationId).componentInstance.value).toBe(simpleConditionUnknownFieldMock.field);
|
||||
const matSelect = getByDataAutomationId(fieldSelectAutomationId).nativeElement;
|
||||
matSelect.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
@ -147,8 +163,8 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
it('should remove the option for the unknown field as soon as another option is selected', () => {
|
||||
fixture.componentInstance.writeValue(simpleConditionUnknownFieldMock);
|
||||
fixture.detectChanges();
|
||||
changeMatSelectValue('field-select', 'cm:name');
|
||||
const matSelect = getByDataAutomationId('field-select').nativeElement;
|
||||
changeMatSelectValue(fieldSelectAutomationId, 'cm:name');
|
||||
const matSelect = getByDataAutomationId(fieldSelectAutomationId).nativeElement;
|
||||
matSelect.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
@ -200,7 +216,7 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
|
||||
it('should provide auto-complete option when category is selected', () => {
|
||||
fixture.detectChanges();
|
||||
changeMatSelectValue('field-select', 'category');
|
||||
changeMatSelectValue(fieldSelectAutomationId, 'category');
|
||||
|
||||
expect(getByDataAutomationId('auto-complete-input-field')).toBeTruthy();
|
||||
expect(fixture.componentInstance.form.get('parameter').value).toEqual('');
|
||||
@ -210,7 +226,7 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
spyOn(categoryService, 'searchCategories').and.returnValue(of(categoriesListMock));
|
||||
|
||||
fixture.detectChanges();
|
||||
changeMatSelectValue('field-select', 'category');
|
||||
changeMatSelectValue(fieldSelectAutomationId, 'category');
|
||||
tick(500);
|
||||
|
||||
expect(categoryService.searchCategories).toHaveBeenCalledWith('');
|
||||
@ -221,7 +237,7 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
spyOn(categoryService, 'searchCategories').and.returnValue(of(categoriesListMock));
|
||||
|
||||
fixture.detectChanges();
|
||||
changeMatSelectValue('field-select', 'category');
|
||||
changeMatSelectValue(fieldSelectAutomationId, 'category');
|
||||
tick(500);
|
||||
expect(categoryService.searchCategories).toHaveBeenCalledWith('');
|
||||
|
||||
@ -256,7 +272,7 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
it('should show loading spinner while auto-complete options are fetched, and then remove it once it is received', fakeAsync(() => {
|
||||
spyOn(categoryService, 'searchCategories').and.returnValue(of(categoriesListMock).pipe(delay(1000)));
|
||||
fixture.detectChanges();
|
||||
changeMatSelectValue('field-select', 'category');
|
||||
changeMatSelectValue(fieldSelectAutomationId, 'category');
|
||||
tick(500);
|
||||
getByDataAutomationId('auto-complete-input-field')?.nativeElement?.click();
|
||||
let loadingSpinner = getByDataAutomationId('auto-complete-loading-spinner');
|
||||
@ -271,7 +287,7 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
it('should display correct label for category when user selects a category from auto-complete dropdown', fakeAsync(() => {
|
||||
spyOn(categoryService, 'searchCategories').and.returnValue(of(categoriesListMock));
|
||||
fixture.detectChanges();
|
||||
changeMatSelectValue('field-select', 'category');
|
||||
changeMatSelectValue(fieldSelectAutomationId, 'category');
|
||||
tick(500);
|
||||
getByDataAutomationId('auto-complete-input-field')?.nativeElement?.click();
|
||||
changeMatSelectValue('folder-rule-auto-complete', categoriesListMock.list.entries[0].entry.id);
|
||||
@ -283,7 +299,7 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
it('should automatically select first category when user focuses out of parameter form field with category option selected', fakeAsync(() => {
|
||||
spyOn(categoryService, 'searchCategories').and.returnValue(of(categoriesListMock));
|
||||
fixture.detectChanges();
|
||||
changeMatSelectValue('field-select', 'category');
|
||||
changeMatSelectValue(fieldSelectAutomationId, 'category');
|
||||
tick(500);
|
||||
const autoCompleteInputField = getByDataAutomationId('auto-complete-input-field')?.nativeElement;
|
||||
autoCompleteInputField.value = 'FakeCat';
|
||||
@ -292,4 +308,38 @@ describe('RuleSimpleConditionUiComponent', () => {
|
||||
expect(parameterValue).toEqual(categoriesListMock.list.entries[0].entry.id);
|
||||
discardPeriodicTasks();
|
||||
}));
|
||||
|
||||
it('should display correct condition field options when tagService.areTagsEnabled returns true', () => {
|
||||
const tagService = TestBed.inject(TagService);
|
||||
spyOn(tagService, 'areTagsEnabled').and.returnValue(true);
|
||||
fixture = TestBed.createComponent(RuleSimpleConditionUiComponent);
|
||||
|
||||
expect(tagService.areTagsEnabled).toHaveBeenCalled();
|
||||
expectConditionFieldsDisplayedAsOptions(ruleConditionFields);
|
||||
});
|
||||
|
||||
it('should display correct condition field options when tagService.areTagsEnabled returns false', () => {
|
||||
const tagService = TestBed.inject(TagService);
|
||||
spyOn(tagService, 'areTagsEnabled').and.returnValue(false);
|
||||
fixture = TestBed.createComponent(RuleSimpleConditionUiComponent);
|
||||
|
||||
expect(tagService.areTagsEnabled).toHaveBeenCalled();
|
||||
expectConditionFieldsDisplayedAsOptions(ruleConditionFields.filter((field) => field.name !== 'tag'));
|
||||
});
|
||||
|
||||
it('should display correct condition field options when categoryService.areCategoriesEnabled returns true', () => {
|
||||
spyOn(categoryService, 'areCategoriesEnabled').and.returnValue(true);
|
||||
fixture = TestBed.createComponent(RuleSimpleConditionUiComponent);
|
||||
|
||||
expect(categoryService.areCategoriesEnabled).toHaveBeenCalled();
|
||||
expectConditionFieldsDisplayedAsOptions(ruleConditionFields);
|
||||
});
|
||||
|
||||
it('should display correct condition field options when categoryService.areCategoriesEnabled returns false', () => {
|
||||
spyOn(categoryService, 'areCategoriesEnabled').and.returnValue(false);
|
||||
fixture = TestBed.createComponent(RuleSimpleConditionUiComponent);
|
||||
|
||||
expect(categoryService.areCategoriesEnabled).toHaveBeenCalled();
|
||||
expectConditionFieldsDisplayedAsOptions(ruleConditionFields.filter((field) => field.name !== 'category'));
|
||||
});
|
||||
});
|
||||
|
@ -34,7 +34,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { CategoryService } from '@alfresco/adf-content-services';
|
||||
import { CategoryService, TagService } from '@alfresco/adf-content-services';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { debounceTime, distinctUntilChanged, first, takeUntil } from 'rxjs/operators';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
@ -77,8 +77,6 @@ const AUTOCOMPLETE_OPTIONS_DEBOUNCE_TIME = 500;
|
||||
]
|
||||
})
|
||||
export class RuleSimpleConditionUiComponent implements OnInit, ControlValueAccessor, OnDestroy {
|
||||
readonly fields = ruleConditionFields;
|
||||
|
||||
form = new FormGroup({
|
||||
field: new FormControl('cm:name'),
|
||||
comparator: new FormControl('equals'),
|
||||
@ -102,8 +100,15 @@ export class RuleSimpleConditionUiComponent implements OnInit, ControlValueAcces
|
||||
this.setDisabledState(isReadOnly);
|
||||
}
|
||||
|
||||
constructor(private config: AppConfigService, private categoryService: CategoryService) {
|
||||
this.mimeTypes = this.config.get<Array<MimeType>>('mimeTypes');
|
||||
private readonly disabledTags = !this.tagService.areTagsEnabled();
|
||||
private readonly disabledCategories = !this.categoryService.areCategoriesEnabled();
|
||||
|
||||
readonly fields = ruleConditionFields.filter(
|
||||
(condition) => !((this.disabledTags && condition.name === 'tag') || (this.disabledCategories && condition.name === 'category'))
|
||||
);
|
||||
|
||||
constructor(config: AppConfigService, private categoryService: CategoryService, private tagService: TagService) {
|
||||
this.mimeTypes = config.get<Array<MimeType>>('mimeTypes');
|
||||
}
|
||||
get isSelectedFieldKnown(): boolean {
|
||||
const selectedFieldName = this.form.get('field').value;
|
||||
|
@ -29,6 +29,8 @@ import { Rule } from '../model/rule.model';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { RuleTriggersUiComponent } from './triggers/rule-triggers.ui-component';
|
||||
import { RuleOptionsUiComponent } from './options/rule-options.ui-component';
|
||||
import { RuleActionListUiComponent } from './actions/rule-action-list.ui-component';
|
||||
import { CategoryService } from '@alfresco/adf-content-services';
|
||||
|
||||
describe('RuleDetailsUiComponent', () => {
|
||||
let fixture: ComponentFixture<RuleDetailsUiComponent>;
|
||||
@ -140,4 +142,54 @@ describe('RuleDetailsUiComponent', () => {
|
||||
|
||||
expect(getComponentInstance<RuleOptionsUiComponent>('rule-details-options-component')).toBeFalsy();
|
||||
});
|
||||
|
||||
describe('RuleActionListUiComponent', () => {
|
||||
let categoryService: CategoryService;
|
||||
|
||||
const getRuleActionsListComponent = (): RuleActionListUiComponent =>
|
||||
fixture.debugElement.query(By.directive(RuleActionListUiComponent)).componentInstance;
|
||||
|
||||
beforeEach(() => {
|
||||
categoryService = TestBed.inject(CategoryService);
|
||||
component.actionDefinitions = [
|
||||
{
|
||||
id: 'link-category',
|
||||
name: 'test name',
|
||||
description: 'some description',
|
||||
title: 'some title',
|
||||
applicableTypes: [],
|
||||
trackStatus: false,
|
||||
parameterDefinitions: []
|
||||
},
|
||||
{
|
||||
id: 'test id',
|
||||
name: 'test name 2',
|
||||
description: 'some description',
|
||||
title: 'some title',
|
||||
applicableTypes: [],
|
||||
trackStatus: false,
|
||||
parameterDefinitions: []
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
it('should have assigned not filtered out category related actions from actionDefinitions if categoryService.areCategoriesEnabled returns true', () => {
|
||||
spyOn(categoryService, 'areCategoriesEnabled').and.returnValue(true);
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(categoryService.areCategoriesEnabled).toHaveBeenCalled();
|
||||
expect(component.actionDefinitions.length).toBe(2);
|
||||
expect(getRuleActionsListComponent().actionDefinitions).toBe(component.actionDefinitions);
|
||||
});
|
||||
|
||||
it('should have assigned filter out category related actions from actionDefinitions if categoryService.areCategoriesEnabled returns false', () => {
|
||||
spyOn(categoryService, 'areCategoriesEnabled').and.returnValue(false);
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(categoryService.areCategoriesEnabled).toHaveBeenCalled();
|
||||
expect(component.actionDefinitions.length).toBe(1);
|
||||
expect(component.actionDefinitions[0].id).toBe('test id');
|
||||
expect(getRuleActionsListComponent().actionDefinitions).toBe(component.actionDefinitions);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -40,6 +40,7 @@ import { RuleTriggersUiComponent } from './triggers/rule-triggers.ui-component';
|
||||
import { RuleCompositeConditionUiComponent } from './conditions/rule-composite-condition.ui-component';
|
||||
import { RuleActionListUiComponent } from './actions/rule-action-list.ui-component';
|
||||
import { RuleOptionsUiComponent } from './options/rule-options.ui-component';
|
||||
import { CategoryService } from '@alfresco/adf-content-services';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@ -136,7 +137,11 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
|
||||
return !this.readOnly || this.value.isAsynchronous || this.value.isInheritable;
|
||||
}
|
||||
|
||||
constructor(private categoryService: CategoryService) {}
|
||||
|
||||
ngOnInit() {
|
||||
const disabledCategory = !this.categoryService.areCategoriesEnabled();
|
||||
this.actionDefinitions = this.actionDefinitions.filter((action) => !(disabledCategory && action.id === 'link-category'));
|
||||
this.form = new UntypedFormGroup({
|
||||
id: new UntypedFormControl(this.value.id),
|
||||
name: new UntypedFormControl(this.value.name || '', Validators.required),
|
||||
|
@ -244,7 +244,9 @@ export class ContentServiceExtensionModule {
|
||||
'app.isContentServiceEnabled': rules.isContentServiceEnabled,
|
||||
'app.isUploadSupported': rules.isUploadSupported,
|
||||
'app.canCreateLibrary': rules.canCreateLibrary,
|
||||
'app.isSearchSupported': rules.isSearchSupported
|
||||
'app.isSearchSupported': rules.isSearchSupported,
|
||||
'app.areTagsEnabled': rules.areTagsEnabled,
|
||||
'app.areCategoriesEnabled': rules.areCategoriesEnabled
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import { AppExtensionService, NodePermissionService } from '@alfresco/aca-shared
|
||||
import { Actions } from '@ngrx/effects';
|
||||
import { of, Subject } from 'rxjs';
|
||||
import { ContentActionType } from '@alfresco/adf-extensions';
|
||||
import { CategoryService, ContentMetadataCardComponent, TagService } from '@alfresco/adf-content-services';
|
||||
|
||||
describe('MetadataTabComponent', () => {
|
||||
let fixture: ComponentFixture<MetadataTabComponent>;
|
||||
@ -251,26 +252,70 @@ describe('MetadataTabComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('displayAspect', () => {
|
||||
describe('ContentMetadataCardComponent', () => {
|
||||
const getContentMetadataCard = (): ContentMetadataCardComponent =>
|
||||
fixture.debugElement.query(By.directive(ContentMetadataCardComponent)).componentInstance;
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MetadataTabComponent);
|
||||
store = TestBed.inject(Store);
|
||||
component = fixture.componentInstance;
|
||||
});
|
||||
|
||||
it('show pass empty when store is in initial state', () => {
|
||||
const initialState = fixture.debugElement.query(By.css('adf-content-metadata-card'));
|
||||
expect(initialState.componentInstance.displayAspect).toBeFalsy();
|
||||
describe('displayAspect', () => {
|
||||
beforeEach(() => {
|
||||
store = TestBed.inject(Store);
|
||||
});
|
||||
|
||||
it('should show pass empty when store is in initial state', () => {
|
||||
expect(getContentMetadataCard().displayAspect).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should update the exif if store got updated', () => {
|
||||
store.dispatch(new SetInfoDrawerMetadataAspectAction('EXIF'));
|
||||
component.displayAspect$.subscribe((aspect) => {
|
||||
expect(aspect).toBe('EXIF');
|
||||
});
|
||||
fixture.detectChanges();
|
||||
expect(getContentMetadataCard().displayAspect).toBe('EXIF');
|
||||
});
|
||||
});
|
||||
|
||||
it('should update the exif if store got updated', () => {
|
||||
store.dispatch(new SetInfoDrawerMetadataAspectAction('EXIF'));
|
||||
component.displayAspect$.subscribe((aspect) => {
|
||||
expect(aspect).toBe('EXIF');
|
||||
describe('Tags and categories', () => {
|
||||
it('should have assigned displayCategories to true if categoryService.areCategoriesEnabled returns true', () => {
|
||||
const categoryService = TestBed.inject(CategoryService);
|
||||
spyOn(categoryService, 'areCategoriesEnabled').and.returnValue(true);
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(categoryService.areCategoriesEnabled).toHaveBeenCalled();
|
||||
expect(getContentMetadataCard().displayCategories).toBeTrue();
|
||||
});
|
||||
|
||||
it('should have assigned displayCategories to false if categoryService.areCategoriesEnabled returns false', () => {
|
||||
const categoryService = TestBed.inject(CategoryService);
|
||||
spyOn(categoryService, 'areCategoriesEnabled').and.returnValue(false);
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(categoryService.areCategoriesEnabled).toHaveBeenCalled();
|
||||
expect(getContentMetadataCard().displayCategories).toBeFalse();
|
||||
});
|
||||
|
||||
it('should have assigned displayTags to true if tagService.areTagsEnabled returns true', () => {
|
||||
const tagService = TestBed.inject(TagService);
|
||||
spyOn(tagService, 'areTagsEnabled').and.returnValue(true);
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(tagService.areTagsEnabled).toHaveBeenCalled();
|
||||
expect(getContentMetadataCard().displayTags).toBeTrue();
|
||||
});
|
||||
|
||||
it('should have assigned displayTags to false if tagService.areTagsEnabled returns false', () => {
|
||||
const tagService = TestBed.inject(TagService);
|
||||
spyOn(tagService, 'areTagsEnabled').and.returnValue(false);
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(tagService.areTagsEnabled).toHaveBeenCalled();
|
||||
expect(getContentMetadataCard().displayTags).toBeFalse();
|
||||
});
|
||||
fixture.detectChanges();
|
||||
const initialState = fixture.debugElement.query(By.css('adf-content-metadata-card'));
|
||||
expect(initialState.componentInstance.displayAspect).toBe('EXIF');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -29,7 +29,13 @@ import { AppStore, EditOfflineAction, infoDrawerMetadataAspect, NodeActionTypes
|
||||
import { AppConfigService, NotificationService } from '@alfresco/adf-core';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { ContentMetadataModule, ContentMetadataService, ContentMetadataCustomPanel } from '@alfresco/adf-content-services';
|
||||
import {
|
||||
ContentMetadataModule,
|
||||
ContentMetadataService,
|
||||
ContentMetadataCustomPanel,
|
||||
TagService,
|
||||
CategoryService
|
||||
} from '@alfresco/adf-content-services';
|
||||
import { filter, map, takeUntil } from 'rxjs/operators';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Actions, ofType } from '@ngrx/effects';
|
||||
@ -46,6 +52,8 @@ import { Actions, ofType } from '@ngrx/effects';
|
||||
[displayAspect]="displayAspect$ | async"
|
||||
[customPanels]="customPanels | async"
|
||||
[(editable)]="editable"
|
||||
[displayCategories]="displayCategories"
|
||||
[displayTags]="displayTags"
|
||||
>
|
||||
</adf-content-metadata-card>
|
||||
`,
|
||||
@ -54,6 +62,8 @@ import { Actions, ofType } from '@ngrx/effects';
|
||||
})
|
||||
export class MetadataTabComponent implements OnInit, OnDestroy {
|
||||
protected onDestroy$ = new Subject<boolean>();
|
||||
private _displayCategories = true;
|
||||
private _displayTags = true;
|
||||
|
||||
@Input()
|
||||
node: Node;
|
||||
@ -63,6 +73,14 @@ export class MetadataTabComponent implements OnInit, OnDestroy {
|
||||
editable = false;
|
||||
customPanels: Observable<ContentMetadataCustomPanel[]>;
|
||||
|
||||
get displayCategories(): boolean {
|
||||
return this._displayCategories;
|
||||
}
|
||||
|
||||
get displayTags(): boolean {
|
||||
return this._displayTags;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private permission: NodePermissionService,
|
||||
protected extensions: AppExtensionService,
|
||||
@ -70,7 +88,9 @@ export class MetadataTabComponent implements OnInit, OnDestroy {
|
||||
private store: Store<AppStore>,
|
||||
private notificationService: NotificationService,
|
||||
private contentMetadataService: ContentMetadataService,
|
||||
private actions$: Actions
|
||||
private actions$: Actions,
|
||||
private tagService: TagService,
|
||||
private categoryService: CategoryService
|
||||
) {
|
||||
if (this.extensions.contentMetadata) {
|
||||
this.appConfig.config['content-metadata'].presets = this.extensions.contentMetadata.presets;
|
||||
@ -79,6 +99,8 @@ export class MetadataTabComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this._displayTags = this.tagService.areTagsEnabled();
|
||||
this._displayCategories = this.categoryService.areCategoriesEnabled();
|
||||
this.contentMetadataService.error.pipe(takeUntil(this.onDestroy$)).subscribe((err: { message: string }) => {
|
||||
this.notificationService.showError(err.message);
|
||||
});
|
||||
|
@ -858,6 +858,72 @@ describe('app.evaluators', () => {
|
||||
expect(app.canManagePermissions(context)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('areTagsEnabled', () => {
|
||||
it('should call context.appConfig.get with correct parameters', () => {
|
||||
const context: any = {
|
||||
appConfig: {
|
||||
get: jasmine.createSpy()
|
||||
}
|
||||
};
|
||||
|
||||
app.areTagsEnabled(context);
|
||||
expect(context.appConfig.get).toHaveBeenCalledWith('plugins.tags', true);
|
||||
});
|
||||
|
||||
it('should return true if get from appConfig returns true', () => {
|
||||
expect(
|
||||
app.areTagsEnabled({
|
||||
appConfig: {
|
||||
get: () => true
|
||||
}
|
||||
} as any)
|
||||
).toBeTrue();
|
||||
});
|
||||
|
||||
it('should return false if get from appConfig returns false', () => {
|
||||
expect(
|
||||
app.areTagsEnabled({
|
||||
appConfig: {
|
||||
get: () => false
|
||||
}
|
||||
} as any)
|
||||
).toBeFalse();
|
||||
});
|
||||
});
|
||||
|
||||
describe('areCategoriesEnabled', () => {
|
||||
it('should call context.appConfig.get with correct parameters', () => {
|
||||
const context: any = {
|
||||
appConfig: {
|
||||
get: jasmine.createSpy()
|
||||
}
|
||||
};
|
||||
|
||||
app.areCategoriesEnabled(context);
|
||||
expect(context.appConfig.get).toHaveBeenCalledWith('plugins.categories', true);
|
||||
});
|
||||
|
||||
it('should return true if get from appConfig returns true', () => {
|
||||
expect(
|
||||
app.areCategoriesEnabled({
|
||||
appConfig: {
|
||||
get: () => true
|
||||
}
|
||||
} as any)
|
||||
).toBeTrue();
|
||||
});
|
||||
|
||||
it('should return false if get from appConfig returns false', () => {
|
||||
expect(
|
||||
app.areCategoriesEnabled({
|
||||
appConfig: {
|
||||
get: () => false
|
||||
}
|
||||
} as any)
|
||||
).toBeFalse();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createTestContext(): TestRuleContext {
|
||||
|
@ -636,3 +636,7 @@ export function isSmartFolder(context: RuleContext): boolean {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export const areTagsEnabled = (context: AcaRuleContext): boolean => context.appConfig.get('plugins.tags', true);
|
||||
|
||||
export const areCategoriesEnabled = (context: AcaRuleContext): boolean => context.appConfig.get('plugins.categories', true);
|
||||
|
@ -1049,13 +1049,14 @@ describe('AppExtensionService', () => {
|
||||
});
|
||||
|
||||
describe('search', () => {
|
||||
let config: ExtensionConfig;
|
||||
|
||||
beforeEach(() => {
|
||||
extensions.setEvaluators({
|
||||
visible: () => true,
|
||||
notVisible: () => false
|
||||
});
|
||||
|
||||
applyConfig({
|
||||
config = {
|
||||
$id: 'test',
|
||||
$name: 'test',
|
||||
$version: '1.0.0',
|
||||
@ -1105,22 +1106,64 @@ describe('AppExtensionService', () => {
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
it('should load the search extension', () => {
|
||||
applyConfig(config);
|
||||
expect(service.search.length).toBe(2);
|
||||
expect(service.search[0].id).toBe('app.search');
|
||||
expect(service.search[1].id).toBe('app.search-1');
|
||||
});
|
||||
|
||||
it('should not load the disabled search extension', () => {
|
||||
applyConfig(config);
|
||||
expect(service.search.find(({ id }) => id === 'app.search-2')).toBe(undefined, 'disabled configuration shown in the result');
|
||||
});
|
||||
|
||||
it('should not load the not visible search extension', () => {
|
||||
applyConfig(config);
|
||||
expect(service.search.find(({ id }) => id === 'app.search-3')).toBe(undefined, 'not visible configuration shown in the result');
|
||||
});
|
||||
|
||||
it('should contain category if it has no rules field', () => {
|
||||
applyConfig(config);
|
||||
const search = service.search[0];
|
||||
expect(search.categories.length).toBe(1);
|
||||
expect(search.categories[0].id).toBe('size');
|
||||
});
|
||||
|
||||
it('should contain category if it has no visible field in rules', () => {
|
||||
config.features.search[0].categories[0].rules = {};
|
||||
|
||||
applyConfig(config);
|
||||
const search = service.search[0];
|
||||
expect(search.categories.length).toBe(1);
|
||||
expect(search.categories[0].id).toBe('size');
|
||||
});
|
||||
|
||||
it('should contain category if it has visible field and extensions.evaluateRule returns true', () => {
|
||||
spyOn(extensions, 'evaluateRule').and.returnValue(true);
|
||||
const visible = 'test';
|
||||
config.features.search[0].categories[0].rules = { visible };
|
||||
|
||||
applyConfig(config);
|
||||
const search = service.search[0];
|
||||
expect(extensions.evaluateRule).toHaveBeenCalledWith(visible, service);
|
||||
expect(search.categories.length).toBe(1);
|
||||
expect(search.categories[0].id).toBe('size');
|
||||
});
|
||||
|
||||
it('should not contain category if it has visible field and extensions.evaluateRule returns false', () => {
|
||||
spyOn(extensions, 'evaluateRule').and.returnValue(false);
|
||||
const visible = 'test';
|
||||
config.features.search[0].categories[0].rules = { visible };
|
||||
|
||||
applyConfig(config);
|
||||
const search = service.search[0];
|
||||
expect(extensions.evaluateRule).toHaveBeenCalledWith(visible, service);
|
||||
expect(search.categories.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('rules', () => {
|
||||
|
@ -56,6 +56,7 @@ import { ViewerRules } from '../models/viewer.rules';
|
||||
import { Badge, SettingsGroupRef } from '../models/types';
|
||||
import { NodePermissionService } from '../services/node-permission.service';
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
import { SearchCategory } from '@alfresco/adf-content-services';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@ -167,6 +168,9 @@ export class AppExtensionService implements RuleContext {
|
||||
this.sidebarTabs = this.loader.getElements<SidebarTabRef>(config, 'features.sidebar.tabs');
|
||||
this.contentMetadata = this.loadContentMetadata(config);
|
||||
this.search = this.loadSearchForms(config);
|
||||
this.search?.forEach((searchSet) => {
|
||||
searchSet.categories = searchSet.categories?.filter((category) => this.filterVisible(category));
|
||||
});
|
||||
|
||||
this.documentListPresets = {
|
||||
libraries: this.getDocumentListPreset(config, 'libraries'),
|
||||
@ -482,7 +486,7 @@ export class AppExtensionService implements RuleContext {
|
||||
};
|
||||
}
|
||||
|
||||
filterVisible(action: ContentActionRef | SettingsGroupRef | SidebarTabRef | DocumentListPresetRef): boolean {
|
||||
filterVisible(action: ContentActionRef | SettingsGroupRef | SidebarTabRef | DocumentListPresetRef | SearchCategory): boolean {
|
||||
if (action?.rules?.visible) {
|
||||
return this.extensions.evaluateRule(action.rules.visible, this);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user