[ACS-5645]Implemented changes as per the review comments

This commit is contained in:
Yasa-Nataliya
2023-10-09 20:21:31 +05:30
parent 225d487c34
commit f3d41056d6
7 changed files with 182 additions and 243 deletions
@@ -0,0 +1,24 @@
/*!
* @license
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// eslint-disable-next-line no-shadow
export enum ButtonType {
GeneralInfo = 'generalInfo',
Tags = 'tags',
Categories = 'categories',
Group = 'group'
}
@@ -16,7 +16,7 @@
{{ 'CORE.METADATA.BASIC.HEADER' | translate }} {{ 'CORE.METADATA.BASIC.HEADER' | translate }}
</mat-panel-title> </mat-panel-title>
</div> </div>
<button *ngIf="!editable && !readOnly && hasAllowableOperations()" <button *ngIf="!editable && !readOnly && hasAllowableOperations"
mat-icon-button mat-icon-button
(click)="toggleGeneralEdit($event)" (click)="toggleGeneralEdit($event)"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate" [attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
@@ -28,12 +28,12 @@
<div *ngIf="editable" <div *ngIf="editable"
class="adf-metadata-action-buttons"> class="adf-metadata-action-buttons">
<button mat-icon-button <button mat-icon-button
(click)="cancelEditChanges('generalInfo', $event)" (click)="cancelChanges(buttonType.GeneralInfo, $event)"
data-automation-id="reset-metadata"> data-automation-id="reset-metadata">
<mat-icon>clear</mat-icon> <mat-icon>clear</mat-icon>
</button> </button>
<button mat-icon-button <button mat-icon-button
(click)="saveEditChanges('generalInfo', $event)" (click)="saveChanges(buttonType.GeneralInfo, $event, group)"
color="primary" color="primary"
data-automation-id="save-general-info-metadata" data-automation-id="save-general-info-metadata"
[disabled]="!hasMetadataChanged"> [disabled]="!hasMetadataChanged">
@@ -68,7 +68,7 @@
</mat-panel-title> </mat-panel-title>
</div> </div>
<div class="adf-tags-buttons"> <div class="adf-tags-buttons">
<button *ngIf="!editableTags" <button *ngIf="!editableTags && !readOnly && hasAllowableOperations"
mat-icon-button mat-icon-button
(click)="toggleTagsEdit($event)" (click)="toggleTagsEdit($event)"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate" [attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
@@ -80,12 +80,12 @@
</div> </div>
<div *ngIf="editableTags" class="adf-metadata-action-buttons"> <div *ngIf="editableTags" class="adf-metadata-action-buttons">
<button mat-icon-button <button mat-icon-button
(click)="cancelEditChanges('tags', $event)" (click)="cancelChanges(buttonType.Tags, $event)"
data-automation-id="reset-tags-metadata"> data-automation-id="reset-tags-metadata">
<mat-icon>clear</mat-icon> <mat-icon>clear</mat-icon>
</button> </button>
<button mat-icon-button <button mat-icon-button
(click)="saveEditChanges('tags', $event)" (click)="saveChanges(buttonType.Tags, $event, group)"
color="primary" color="primary"
data-automation-id="save-tags-metadata" data-automation-id="save-tags-metadata"
[disabled]="!hasMetadataChanged"> [disabled]="!hasMetadataChanged">
@@ -128,7 +128,7 @@
</mat-panel-title> </mat-panel-title>
</div> </div>
<div class="adf-metadata-categories-title"> <div class="adf-metadata-categories-title">
<button *ngIf="!editableCategories" <button *ngIf="!editableCategories && !readOnly && hasAllowableOperations"
mat-icon-button mat-icon-button
(click)="toggleCategoriesEdit($event)" (click)="toggleCategoriesEdit($event)"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate" [attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
@@ -140,12 +140,12 @@
</div> </div>
<div *ngIf="editableCategories" class="adf-metadata-action-buttons"> <div *ngIf="editableCategories" class="adf-metadata-action-buttons">
<button mat-icon-button <button mat-icon-button
(click)="cancelEditChanges('categories', $event)" (click)="cancelChanges(buttonType.Categories, $event)"
data-automation-id="reset-metadata"> data-automation-id="reset-metadata">
<mat-icon>clear</mat-icon> <mat-icon>clear</mat-icon>
</button> </button>
<button mat-icon-button <button mat-icon-button
(click)="saveEditChanges('categories', $event)" (click)="saveChanges(buttonType.Categories, $event, group)"
color="primary" color="primary"
data-automation-id="save-categories-metadata" data-automation-id="save-categories-metadata"
[disabled]="!hasMetadataChanged"> [disabled]="!hasMetadataChanged">
@@ -157,7 +157,7 @@
<div *ngIf="!editableCategories"> <div *ngIf="!editableCategories">
<p *ngFor="let category of categories" class="adf-metadata-categories">{{ category.name }}</p> <p *ngFor="let category of categories" class="adf-metadata-categories">{{ category.name }}</p>
</div> </div>
<div *ngIf="!categories.length && !editableCategories" class="adf-metadata-no-catagories-added"> <div *ngIf="!categories.length && !editableCategories" class="adf-metadata-no-categories-added">
{{ 'CATEGORIES_MANAGEMENT.NO_CATEGORIES_ADDED' | translate }} {{ 'CATEGORIES_MANAGEMENT.NO_CATEGORIES_ADDED' | translate }}
</div> </div>
<div *ngIf="editableCategories" class="adf-metadata-categories-header"> <div *ngIf="editableCategories" class="adf-metadata-categories-header">
@@ -197,22 +197,23 @@
{{ group.title | translate }} {{ group.title | translate }}
</mat-panel-title> </mat-panel-title>
</div> </div>
<button *ngIf="!group.editable && !readOnly && hasAllowableOperations()" <button *ngIf="!group.editable && !readOnly && hasAllowableOperations"
mat-icon-button mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate" [attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate" [attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
data-automation-id="meta-data-card-toggle-edit" class="adf-edit-icon-buttons" data-automation-id="meta-data-card-toggle-edit"
(click)="toggleEdit(group, $event)"> class="adf-edit-icon-buttons"
(click)="toggleEdit($event, group)">
<mat-icon>mode_edit</mat-icon> <mat-icon>mode_edit</mat-icon>
</button> </button>
<div class="adf-metadata-action-buttons" *ngIf="group.editable"> <div class="adf-metadata-action-buttons" *ngIf="group.editable">
<button mat-icon-button <button mat-icon-button
(click)="cancelEditChanges('group', $event, group)" (click)="cancelChanges(buttonType.Group, $event)"
data-automation-id="reset-metadata"> data-automation-id="reset-metadata">
<mat-icon>clear</mat-icon> <mat-icon>clear</mat-icon>
</button> </button>
<button mat-icon-button <button mat-icon-button
(click)="saveEditChanges('group', $event, group)" (click)="saveChanges(buttonType.Group, $event, group)"
color="primary" color="primary"
data-automation-id="save-metadata" data-automation-id="save-metadata"
[disabled]="!hasMetadataChanged"> [disabled]="!hasMetadataChanged">
@@ -221,6 +222,9 @@
</div> </div>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<mat-divider class="adf-mat-divider"></mat-divider> <mat-divider class="adf-mat-divider"></mat-divider>
<div *ngIf="!showGroup(group) && !group.editable" class="adf-metadata-no-tags-added">
{{ 'METADATA.BASIC.NO_ITEMS_MESSAGE' | translate: { groupTitle: group.title } }}
</div>
<adf-card-view <adf-card-view
(keydown)="keyDown($event)" (keydown)="keyDown($event)"
[properties]="group.properties" [properties]="group.properties"
@@ -31,6 +31,7 @@ import { CardViewContentUpdateService } from '../../../common/services/card-view
import { PropertyGroup } from '../../interfaces/property-group.interface'; import { PropertyGroup } from '../../interfaces/property-group.interface';
import { PropertyDescriptorsService } from '../../services/property-descriptors.service'; import { PropertyDescriptorsService } from '../../services/property-descriptors.service';
import { import {
CardViewGroup,
CategoriesManagementComponent, CategoriesManagementComponent,
CategoriesManagementMode, CategoriesManagementMode,
CategoryService, CategoryService,
@@ -38,6 +39,7 @@ import {
TagsCreatorMode, TagsCreatorMode,
TagService TagService
} from '@alfresco/adf-content-services'; } from '@alfresco/adf-content-services';
import { ButtonType } from './button-type.enum';
describe('ContentMetadataComponent', () => { describe('ContentMetadataComponent', () => {
let component: ContentMetadataComponent; let component: ContentMetadataComponent;
@@ -49,7 +51,6 @@ describe('ContentMetadataComponent', () => {
let folderNode: Node; let folderNode: Node;
let tagService: TagService; let tagService: TagService;
let categoryService: CategoryService; let categoryService: CategoryService;
let classesApi: ClassesApi;
let getClassSpy: jasmine.Spy; let getClassSpy: jasmine.Spy;
const preset = 'custom-preset'; const preset = 'custom-preset';
@@ -90,12 +91,12 @@ describe('ContentMetadataComponent', () => {
const clickOnGeneralInfoSave = () => { const clickOnGeneralInfoSave = () => {
findSaveGeneralInfoButton().click(); findSaveGeneralInfoButton().click();
fixture.detectChanges(); fixture.detectChanges();
} };
const clickOnTagsSave = () => { const clickOnTagsSave = () => {
findSaveTagsButton().click(); findSaveTagsButton().click();
fixture.detectChanges(); fixture.detectChanges();
} };
const findTagsCreator = (): TagsCreatorComponent => fixture.debugElement.query(By.directive(TagsCreatorComponent))?.componentInstance; const findTagsCreator = (): TagsCreatorComponent => fixture.debugElement.query(By.directive(TagsCreatorComponent))?.componentInstance;
@@ -144,9 +145,8 @@ describe('ContentMetadataComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
await fixture.whenStable(); await fixture.whenStable();
const buttonType = 'group';
const event = new MouseEvent('click'); const event = new MouseEvent('click');
component.saveGroupChanges(buttonType, event); component.saveChanges(ButtonType.Group, event);
await fixture.whenStable(); await fixture.whenStable();
} }
@@ -186,7 +186,7 @@ describe('ContentMetadataComponent', () => {
tagService = TestBed.inject(TagService); tagService = TestBed.inject(TagService);
categoryService = TestBed.inject(CategoryService); categoryService = TestBed.inject(CategoryService);
const propertyDescriptorsService = TestBed.inject(PropertyDescriptorsService); const propertyDescriptorsService = TestBed.inject(PropertyDescriptorsService);
classesApi = propertyDescriptorsService['classesApi']; const classesApi = propertyDescriptorsService['classesApi'];
node = { node = {
id: 'node-id', id: 'node-id',
@@ -285,7 +285,7 @@ describe('ContentMetadataComponent', () => {
})); }));
it('should call removeTag and assignTagsToNode on TagService on save click', fakeAsync(() => { it('should call removeTag and assignTagsToNode on TagService on save click', fakeAsync(() => {
component.editable = true; component.editableTags = true;
component.displayTags = true; component.displayTags = true;
const property = { key: 'properties.property-key', value: 'original-value' } as CardViewBaseItemModel; const property = { key: 'properties.property-key', value: 'original-value' } as CardViewBaseItemModel;
const expectedNode = { ...node, name: 'some-modified-value' }; const expectedNode = { ...node, name: 'some-modified-value' };
@@ -297,21 +297,20 @@ describe('ContentMetadataComponent', () => {
spyOn(tagService, 'assignTagsToNode').and.returnValue(EMPTY); spyOn(tagService, 'assignTagsToNode').and.returnValue(EMPTY);
const tagName1 = tagPaging.list.entries[0].entry.tag; const tagName1 = tagPaging.list.entries[0].entry.tag;
const tagName2 = 'New tag 3'; const tagName2 = 'New tag 3';
updateService.update(property, 'updated-value'); updateService.update(property, 'updated-value');
fixture.detectChanges(); fixture.detectChanges();
findTagsCreator().tagsChange.emit([tagName1, tagName2]); findTagsCreator().tagsChange.emit([tagName1, tagName2]);
const mockEvent = new Event('click'); fixture.detectChanges();
component.saveChanges(mockEvent); tick(600);
clickOnTagsSave();
tick(100);
const tag1 = new TagBody(); const tag1 = new TagBody();
tag1.tag = tagName1; tag1.tag = tagName1;
const tag2 = new TagBody(); const tag2 = new TagBody();
tag2.tag = tagName2; tag2.tag = tagName2;
expect(tagService.removeTag).toHaveBeenCalledWith(node.id, tagPaging.list.entries[1].entry.id); expect(tagService.removeTag).toHaveBeenCalledWith(node.id, tagPaging.list.entries[1].entry.id);
expect(tagService.assignTagsToNode).toHaveBeenCalledWith(node.id, [tag1, tag2]); expect(tagService.assignTagsToNode).toHaveBeenCalledWith(node.id, [tag1, tag2]);
})); }));
it('should call getTagsByNodeId on TagService on save click', () => { it('should call getTagsByNodeId on TagService on save click', () => {
component.editableTags = true; component.editableTags = true;
@@ -330,8 +329,8 @@ describe('ContentMetadataComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
findTagsCreator().tagsChange.emit([tagPaging.list.entries[0].entry.tag, 'New tag 3']); findTagsCreator().tagsChange.emit([tagPaging.list.entries[0].entry.tag, 'New tag 3']);
getTagsByNodeIdSpy.calls.reset(); getTagsByNodeIdSpy.calls.reset();
const mockEvent = new Event('click'); const mockEvent = new MouseEvent('click');
component.saveChanges(mockEvent); component.saveChanges(ButtonType.Tags, mockEvent);
expect(tagService.getTagsByNodeId).toHaveBeenCalledWith(node.id); expect(tagService.getTagsByNodeId).toHaveBeenCalledWith(node.id);
}); });
@@ -433,171 +432,86 @@ describe('ContentMetadataComponent', () => {
})); }));
}); });
describe('saveEditChanges', () => { describe('editable', () => {
it('should save general info changes and toggle editable flag', () => { it('should toggle general editable', () => {
const event = new Event('click'); const eventMock = new MouseEvent('click');
const buttonType = 'generalInfo'; component.editable = false;
component.editable = true; component.toggleGeneralEdit(eventMock);
expect(component.editable).toBe(true);
spyOn(component, 'saveChanges');
component.saveEditChanges(buttonType, event);
expect(component.saveChanges).toHaveBeenCalledWith(event);
expect(component.editable).toBe(false);
});
it('should save tags changes and toggle editableTags flag', () => {
const event = new Event('click');
const buttonType = 'tags';
component.editableTags = true;
spyOn(component, 'saveChanges');
component.saveEditChanges(buttonType, event);
expect(component.saveChanges).toHaveBeenCalledWith(event);
expect(component.editableTags).toBe(false); expect(component.editableTags).toBe(false);
});
it('should save categories changes and toggle editableCategories flag', () => {
const event = new Event('click');
const buttonType = 'categories';
component.editableCategories = true;
spyOn(component, 'saveChanges');
component.saveEditChanges(buttonType, event);
expect(component.saveChanges).toHaveBeenCalledWith(event);
expect(component.editableCategories).toBe(false); expect(component.editableCategories).toBe(false);
}); });
it('should save group changes and toggle editable flag', () => { it('should toggle tags editable', () => {
const group = { editable: true }; const eventMock = new MouseEvent('click');
const event = new Event('click'); component.editableTags = false;
const buttonType = 'group'; component.toggleTagsEdit(eventMock);
expect(component.editableTags).toBe(true);
spyOn(component, 'saveChanges'); expect(component.tagNameControlVisible).toBe(true);
component.saveEditChanges(buttonType, event, group); expect(component.tagsPanelState).toBe(true);
expect(component.saveChanges).toHaveBeenCalledWith(event);
expect(group.editable).toBe(false);
});
});
describe('cancelChanges', () => {
it('should cancel group changes and set group editable to false', () => {
const group = { editable: true };
const event = new Event('click');
const buttonType = 'group';
spyOn(component, 'cancelChanges');
component.cancelEditChanges(buttonType, event, group);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(group.editable).toBe(false);
});
it('should cancel general info changes and toggle editable flag', () => {
const event = new Event('click');
const buttonType = 'generalInfo';
component.editable = true;
spyOn(component, 'cancelChanges');
component.cancelEditChanges(buttonType, event);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(component.editable).toBe(false); expect(component.editable).toBe(false);
});
it('should cancel tags changes and toggle editableTags flag', () => {
const event = new Event('click');
const buttonType = 'tags';
component.editableTags = true;
spyOn(component, 'cancelChanges');
component.cancelEditChanges(buttonType, event);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(component.editableTags).toBe(false);
});
it('should cancel categories changes and toggle editableCategories flag', () => {
const event = new Event('click');
const buttonType = 'categories';
component.editableCategories = true;
spyOn(component, 'cancelChanges');
component.cancelEditChanges(buttonType, event);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(component.editableCategories).toBe(false); expect(component.editableCategories).toBe(false);
}); });
});
describe('editing', () => { it('should toggle categories editable', () => {
it('should toggle categories edit and set categoriesPanelState accordingly', () => { const eventMock = new MouseEvent('click');
const event = new Event('click');
spyOn(event, 'stopPropagation');
component.editableCategories = false; component.editableCategories = false;
component.categoriesPanelState = false; component.toggleCategoriesEdit(eventMock);
component.toggleCategoriesEdit(event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(component.editableCategories).toBe(true); expect(component.editableCategories).toBe(true);
expect(component.categoryControlVisible).toBe(true);
expect(component.categoriesPanelState).toBe(true); expect(component.categoriesPanelState).toBe(true);
component.toggleCategoriesEdit(event); expect(component.editable).toBe(false);
expect(component.editableCategories).toBe(false); expect(component.editableTags).toBe(false);
expect(component.categoriesPanelState).toBe(false); });
});
it('should toggle group edit and expand the panel if editable', () => { it('should toggle group editable', () => {
const event = new Event('click'); const eventMock = new MouseEvent('click');
spyOn(event, 'stopPropagation'); const group: CardViewGroup = {
const group = { editable: false, expanded: false }; editable: false, expanded: false,
component.toggleEdit(group, event); title: '',
expect(event.stopPropagation).toHaveBeenCalled(); properties: []
};
component.editableGroup = null;
component.toggleEdit(eventMock, group);
expect(group.editable).toBe(true); expect(group.editable).toBe(true);
expect(group.expanded).toBe(true); expect(group.expanded).toBe(true);
}); expect(component.editableGroup).toBe(group);
it('should toggle group edit but not expand the panel if not editable', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
const group = { editable: true, expanded: true };
component.toggleEdit(group, event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(group.editable).toBe(false);
expect(group.expanded).toBe(true);
});
it('should toggle general info edit and set generalInfoPanelState accordingly', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
component.generalInfoPanelState = true;
component.editable = false;
component.toggleGeneralEdit(event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(component.editable).toBe(true);
expect(component.generalInfoPanelState).toBe(true);
component.toggleGeneralEdit(event);
expect(component.editable).toBe(false); expect(component.editable).toBe(false);
expect(component.generalInfoPanelState).toBe(true); expect(component.editableTags).toBe(false);
expect(component.editableCategories).toBe(false);
});
});
describe('toggleEditMode', () => {
it('should toggle general editable', () => {
component.editable = false;
component.toggleEditMode(ButtonType.GeneralInfo);
expect(component.editable).toBe(true);
});
it('should toggle tags editable', () => {
component.editableTags = false;
component.toggleEditMode(ButtonType.Tags);
expect(component.editableTags).toBe(true);
}); });
it('should toggle tags edit and set tagsPanelState accordingly', () => { it('should toggle categories editable', () => {
const event = new Event('click'); component.editableCategories = false;
spyOn(event, 'stopPropagation'); component.toggleEditMode(ButtonType.Categories);
component.editableTags = false; expect(component.editableCategories).toBe(true);
component.tagsPanelState = false;
component.toggleTagsEdit(event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(component.editableTags).toBe(true);
expect(component.tagsPanelState).toBe(true);
component.toggleTagsEdit(event);
expect(component.editableTags).toBe(false);
expect(component.tagsPanelState).toBe(false);
}); });
})
it('should toggle group editable', () => {
const group: CardViewGroup = {
editable: false, expanded: false,
title: '',
properties: []
};
component.editableGroup = null;
component.toggleEditMode(ButtonType.Group, group);
expect(group.editable).toBe(true);
});
});
describe('Reseting', () => { describe('Reseting', () => {
it('should reset properties on reset click', async () => { it('should reset properties on reset click', async () => {
@@ -791,6 +705,7 @@ describe('ContentMetadataComponent', () => {
describe('Display properties with aspect oriented config', () => { describe('Display properties with aspect oriented config', () => {
let appConfig: AppConfigService; let appConfig: AppConfigService;
let classesApi: ClassesApi;
let expectedNode: Node; let expectedNode: Node;
const verResponse: PropertyGroup = { const verResponse: PropertyGroup = {
@@ -1285,14 +1200,6 @@ describe('ContentMetadataComponent', () => {
expect(tagsCreator.disabledTagsRemoving).toBeFalse(); expect(tagsCreator.disabledTagsRemoving).toBeFalse();
}); });
it('should have assigned true to disabledTagsRemoving after clicking on update button', () => {
tagsCreator.tagsChange.emit([]);
fixture.detectChanges();
clickOnTagsSave();
expect(tagsCreator.disabledTagsRemoving).toBeTrue();
});
it('should have assigned false to disabledTagsRemoving if forkJoin fails', () => { it('should have assigned false to disabledTagsRemoving if forkJoin fails', () => {
const property = { key: 'properties.property-key', value: 'original-value' } as CardViewBaseItemModel; const property = { key: 'properties.property-key', value: 'original-value' } as CardViewBaseItemModel;
const expectedNode = { ...node, name: 'some-modified-value' }; const expectedNode = { ...node, name: 'some-modified-value' };
@@ -1314,15 +1221,6 @@ describe('ContentMetadataComponent', () => {
expect(tagsCreator.disabledTagsRemoving).toBeFalse(); expect(tagsCreator.disabledTagsRemoving).toBeFalse();
}); });
it('should have assigned false to tagNameControlVisible after clicking on update button', () => {
tagsCreator.tagNameControlVisibleChange.emit(true);
tagsCreator.tagsChange.emit([]);
fixture.detectChanges();
clickOnTagsSave();
expect(tagsCreator.tagNameControlVisible).toBeFalse();
});
describe('Setting tags', () => { describe('Setting tags', () => {
let tagPaging: TagPaging; let tagPaging: TagPaging;
@@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core'; import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
import { import {
Category, Category,
CategoryEntry, CategoryEntry,
@@ -46,6 +46,7 @@ import { CategoryService } from '../../../category/services/category.service';
import { CategoriesManagementMode } from '../../../category/categories-management/categories-management-mode'; import { CategoriesManagementMode } from '../../../category/categories-management/categories-management-mode';
import { MatExpansionPanel } from '@angular/material/expansion'; import { MatExpansionPanel } from '@angular/material/expansion';
import { AllowableOperationsEnum, ContentService } from '../../../common'; import { AllowableOperationsEnum, ContentService } from '../../../common';
import { ButtonType } from './button-type.enum';
const DEFAULT_SEPARATOR = ', '; const DEFAULT_SEPARATOR = ', ';
@@ -57,7 +58,8 @@ const DEFAULT_SEPARATOR = ', ';
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy { export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
@ViewChild(MatExpansionPanel) panel: MatExpansionPanel; @ViewChild(MatExpansionPanel)
panel: MatExpansionPanel;
protected onDestroy$ = new Subject<boolean>(); protected onDestroy$ = new Subject<boolean>();
/** (required) The node entity to fetch metadata about */ /** (required) The node entity to fetch metadata about */
@@ -129,6 +131,10 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
@Input() @Input()
readOnly = false; readOnly = false;
/** Emitted when content's editable state is changed. **/
@Output()
editableChange = new EventEmitter<boolean>();
private _assignedTags: string[] = []; private _assignedTags: string[] = [];
private assignedTagsEntries: TagEntry[] = []; private assignedTagsEntries: TagEntry[] = [];
private _editable = false; private _editable = false;
@@ -152,9 +158,13 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
classifiableChanged = this.classifiableChangedSubject.asObservable(); classifiableChanged = this.classifiableChangedSubject.asObservable();
generalInfoPanelState: boolean; generalInfoPanelState: boolean;
tagsPanelState: boolean; tagsPanelState: boolean;
editableTags: boolean = false; editableTags = false;
categoriesPanelState: boolean; categoriesPanelState: boolean;
editableCategories: boolean = false; editableCategories = false;
hasAllowableOperations = false;
editableGroup: any;
buttonType = ButtonType;
group: CardViewGroup;
constructor( constructor(
private contentMetadataService: ContentMetadataService, private contentMetadataService: ContentMetadataService,
@@ -192,6 +202,7 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
.subscribe((node) => this.loadProperties(node)); .subscribe((node) => this.loadProperties(node));
this.loadProperties(this.node); this.loadProperties(this.node);
this.hasAllowableOperations = this.contentService.hasAllowableOperations(this.node, AllowableOperationsEnum.UPDATE);
} }
get assignedTags(): string[] { get assignedTags(): string[] {
@@ -260,8 +271,9 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
* Called after clicking save button. It confirms all changes done for metadata and hides both category and tag name controls. * Called after clicking save button. It confirms all changes done for metadata and hides both category and tag name controls.
* Before clicking on that button they are not saved. * Before clicking on that button they are not saved.
*/ */
saveChanges(event: Event) { saveChanges(buttonType: ButtonType, event: MouseEvent, group?: CardViewGroup) {
event.stopPropagation(); event.stopPropagation();
this.toggleEditMode(buttonType, group);
this._saving = true; this._saving = true;
this.tagNameControlVisible = false; this.tagNameControlVisible = false;
this.categoryControlVisible = false; this.categoryControlVisible = false;
@@ -274,19 +286,18 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
} }
} }
saveEditChanges(buttonType: string, event: Event, group?: any) { toggleEditMode(buttonType: ButtonType, group?: CardViewGroup) {
this.saveChanges(event);
switch (buttonType) { switch (buttonType) {
case 'generalInfo': case ButtonType.GeneralInfo:
this.editable = !this.editable; this.editable = !this.editable;
break; break;
case 'tags': case ButtonType.Tags:
this.editableTags = !this.editableTags; this.editableTags = !this.editableTags;
break; break;
case 'categories': case ButtonType.Categories:
this.editableCategories = !this.editableCategories; this.editableCategories = !this.editableCategories;
break; break;
case 'group': case ButtonType.Group:
if (group) { if (group) {
group.editable = !group.editable; group.editable = !group.editable;
} }
@@ -325,69 +336,65 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
this.categoryControlVisible = false; this.categoryControlVisible = false;
} }
cancelChanges(event: Event) { cancelChanges(buttonType: ButtonType, event: MouseEvent) {
event.stopPropagation(); event.stopPropagation();
this.toggleEditMode(buttonType);
this.revertChanges(); this.revertChanges();
this.loadProperties(this.node); this.loadProperties(this.node);
} }
cancelEditChanges(buttonType: string, event: Event, group?: any) { cancelEditChanges() {
this.cancelChanges(event); this.revertChanges();
switch (buttonType) { this.loadProperties(this.node);
case 'generalInfo':
this.editable = !this.editable;
break;
case 'tags':
this.editableTags = !this.editableTags;
break;
case 'categories':
this.editableCategories = !this.editableCategories;
break;
case 'group':
if (group) {
group.editable = !group.editable;
}
break;
default:
break;
}
} }
toggleGeneralEdit(event: Event): void { toggleGeneralEdit(event: MouseEvent): void {
event.stopPropagation(); event.stopPropagation();
this.editable = !this.editable; this.editable = !this.editable;
this.cancelEditChanges();
if (this.editable) { if (this.editable) {
this.panel.open(); this.panel.open();
this.editableTags = false;
this.editableCategories = false;
} }
} }
toggleTagsEdit(event: Event): void { toggleTagsEdit(event: MouseEvent): void {
event.stopPropagation(); event.stopPropagation();
this.editableTags = !this.editableTags; this.editableTags = !this.editableTags;
this.cancelEditChanges();
this.tagNameControlVisible = true; this.tagNameControlVisible = true;
if (this.editableTags) { if (this.editableTags) {
this.tagsPanelState = true; this.tagsPanelState = true;
} else { this.editable = false;
this.tagsPanelState = false; this.editableCategories = false;
} }
} }
toggleCategoriesEdit(event: Event): void { toggleCategoriesEdit(event: MouseEvent): void {
event.stopPropagation(); event.stopPropagation();
this.cancelEditChanges();
this.editableCategories = !this.editableCategories; this.editableCategories = !this.editableCategories;
this.categoryControlVisible = true; this.categoryControlVisible = true;
if (this.editableCategories) { if (this.editableCategories) {
this.categoriesPanelState = true; this.categoriesPanelState = true;
} else { this.editable = false;
this.categoriesPanelState = false; this.editableTags = false;
} }
} }
toggleEdit(group: any, event: Event): void { toggleEdit(event: MouseEvent, group: CardViewGroup): void {
event.stopPropagation(); event.stopPropagation();
if (this.editableGroup && this.editableGroup !== group) {
this.editableGroup.editable = false;
}
group.editable = !group.editable; group.editable = !group.editable;
if(group.editable) { this.editableGroup = group.editable ? group : null;
if (group.editable) {
group.expanded = true; group.expanded = true;
this.editable = false;
this.editableTags = false;
this.editableCategories = false;
} }
} }
@@ -406,6 +413,12 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
this.cdr.detectChanges(); this.cdr.detectChanges();
} }
showGroup(group: CardViewGroup): boolean {
const properties = group.properties.filter((property) => !this.isEmpty(property.displayValue));
return properties.length > 0;
}
canExpandTheCard(group: CardViewGroup): boolean { canExpandTheCard(group: CardViewGroup): boolean {
return group.title === this.displayAspect; return group.title === this.displayAspect;
} }
@@ -414,10 +427,6 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
return !this.expanded || this.displayAspect === 'Properties'; return !this.expanded || this.displayAspect === 'Properties';
} }
hasAllowableOperations() {
return this.contentService.hasAllowableOperations(this.node, AllowableOperationsEnum.UPDATE);
}
keyDown(event: KeyboardEvent) { keyDown(event: KeyboardEvent) {
if (event.keyCode === 37 || event.keyCode === 39) { // ArrowLeft && ArrowRight if (event.keyCode === 37 || event.keyCode === 39) { // ArrowLeft && ArrowRight
event.stopPropagation(); event.stopPropagation();
@@ -495,6 +504,10 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
})); }));
} }
private isEmpty(value: any): boolean {
return value === undefined || value === null || value === '';
}
private loadCategoriesForNode(nodeId: string) { private loadCategoriesForNode(nodeId: string) {
this.assignedCategories = []; this.assignedCategories = [];
this.categoryService.getCategoryLinksForNode(nodeId).subscribe((categoryPaging) => { this.categoryService.getCategoryLinksForNode(nodeId).subscribe((categoryPaging) => {
@@ -21,5 +21,5 @@ export interface CardViewGroup {
title: string; title: string;
properties: CardViewItem[]; properties: CardViewItem[];
editable: boolean; editable: boolean;
expanded: boolean expanded: boolean;
} }
+2 -1
View File
@@ -488,7 +488,8 @@
"TAGS": "Tags", "TAGS": "Tags",
"ADD_TAG_TOOLTIP": "Add tag", "ADD_TAG_TOOLTIP": "Add tag",
"HEADER_TITLE": "General info", "HEADER_TITLE": "General info",
"NO_TAGS_ADDED": "There are currently no tags added" "NO_TAGS_ADDED": "There are currently no tags added",
"NO_ITEMS_MESSAGE": "There are currently no {{ groupTitle }} added"
}, },
"CONTENT_TYPE": { "CONTENT_TYPE": {
"DIALOG" :{ "DIALOG" :{
@@ -6,7 +6,6 @@
autocomplete="off" autocomplete="off"
[formControl]="tagNameControl" [formControl]="tagNameControl"
(keyup.enter)="addTag()" (keyup.enter)="addTag()"
aria-labelledby="adf-tag-name-input-label"
adf-auto-focus adf-auto-focus
placeholder="{{'TAG.TAGS_CREATOR.INPUT_PLACEHOLDER' | translate}}" placeholder="{{'TAG.TAGS_CREATOR.INPUT_PLACEHOLDER' | translate}}"
/> />