mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
[ACS-5645]Added edit functionality for each panel and updated test cases
This commit is contained in:
committed by
Anukriti Singh
parent
60099a2d7d
commit
fd5bca7041
+19
-37
@@ -1,14 +1,20 @@
|
|||||||
<div class="adf-categories-management">
|
<div class="adf-categories-management">
|
||||||
<p *ngIf="!categories.length && !categoryNameControlVisible"
|
<div *ngIf="((!categoryNameControlVisible && categories.length)) || categoryNameControlVisible"
|
||||||
class="adf-no-categories-message">
|
class="adf-category-name-field">
|
||||||
{{ noCategoriesMsg | translate }}
|
<input #categoryNameInput
|
||||||
</p>
|
matInput autocomplete="off"
|
||||||
<div class="adf-categories-list"
|
[formControl]="categoryNameControl"
|
||||||
[class.adf-categories-list-fixed]="!categoryNameControlVisible">
|
(keyup.enter)="addCategory()"
|
||||||
|
aria-labelledby="adf-category-name-input-label"
|
||||||
|
placeholder="{{'CATEGORIES_MANAGEMENT.INPUT_PLACEHOLDER' | translate }}"
|
||||||
|
adf-auto-focus />
|
||||||
|
<mat-error [hidden]="!categoryNameControl.invalid">{{ categoryNameErrorMessageKey | translate }}</mat-error>
|
||||||
|
</div>
|
||||||
|
<div class="adf-categories-list" [class.adf-categories-list-fixed]="!categoryNameControlVisible">
|
||||||
<span
|
<span
|
||||||
*ngFor="let category of categories"
|
*ngFor="let category of categories"
|
||||||
[class.adf-categories-padded]="!isCRUDMode"
|
[class.adf-categories-padded]="!isCRUDMode"
|
||||||
class="adf-assigned-categories">
|
class="adf-assigned-categories">
|
||||||
{{ category.name }}
|
{{ category.name }}
|
||||||
<button
|
<button
|
||||||
data-automation-id="categories-remove-category-button"
|
data-automation-id="categories-remove-category-button"
|
||||||
@@ -21,38 +27,14 @@
|
|||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="((!categoryNameControlVisible && categories.length)) || categoryNameControlVisible"
|
<p *ngIf="!categories.length" class="adf-no-categories-message">
|
||||||
[hidden]="!categoryNameControlVisible"
|
{{ noCategoriesMsg | translate }}
|
||||||
class="adf-category-name-field">
|
</p>
|
||||||
<mat-form-field>
|
|
||||||
<mat-icon matPrefix>search</mat-icon>
|
|
||||||
<mat-label id="adf-category-name-input-label">
|
|
||||||
{{ 'CATEGORIES_MANAGEMENT.NAME' | translate }}
|
|
||||||
</mat-label>
|
|
||||||
<input
|
|
||||||
#categoryNameInput
|
|
||||||
matInput
|
|
||||||
autocomplete="off"
|
|
||||||
[formControl]="categoryNameControl"
|
|
||||||
(keyup.enter)="addCategory()"
|
|
||||||
aria-labelledby="adf-category-name-input-label"
|
|
||||||
adf-auto-focus
|
|
||||||
/>
|
|
||||||
<mat-error [hidden]="!categoryNameControl.invalid">{{ categoryNameErrorMessageKey | translate }}</mat-error>
|
|
||||||
</mat-form-field>
|
|
||||||
<button
|
|
||||||
mat-icon-button
|
|
||||||
[class.adf-btn-padded]="!isCRUDMode"
|
|
||||||
(click)="hideNameInput()"
|
|
||||||
[attr.title]="'CATEGORIES_MANAGEMENT.HIDE_INPUT' | translate">
|
|
||||||
<mat-icon>remove</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="adf-existing-categories-panel" *ngIf="existingCategoriesPanelVisible">
|
<div class="adf-existing-categories-panel" *ngIf="existingCategoriesPanelVisible">
|
||||||
<ng-container *ngIf="isCRUDMode && (!existingCategoriesLoading || existingCategories)">
|
<ng-container *ngIf="isCRUDMode && (!existingCategoriesLoading || existingCategories)">
|
||||||
<span class="adf-create-category-label"
|
<span class="adf-create-category-label"
|
||||||
(click)="addCategory()"
|
(click)="addCategory()"
|
||||||
[hidden]="categoryNameControl.invalid || typing">
|
[hidden]="categoryNameControl.invalid || typing">
|
||||||
{{ 'CATEGORIES_MANAGEMENT.GENERIC_CREATE' | translate : { name: categoryNameControl.value } }}
|
{{ 'CATEGORIES_MANAGEMENT.GENERIC_CREATE' | translate : { name: categoryNameControl.value } }}
|
||||||
</span>
|
</span>
|
||||||
@@ -77,8 +59,8 @@
|
|||||||
</mat-selection-list>
|
</mat-selection-list>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<mat-spinner
|
<mat-spinner
|
||||||
*ngIf="existingCategoriesLoading"
|
*ngIf="existingCategoriesLoading"
|
||||||
[diameter]="50"
|
[diameter]="50"
|
||||||
[attr.aria-label]="'CATEGORIES_MANAGEMENT.LOADING' | translate">
|
[attr.aria-label]="'CATEGORIES_MANAGEMENT.LOADING' | translate">
|
||||||
</mat-spinner>
|
</mat-spinner>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+7
-1
@@ -1,8 +1,15 @@
|
|||||||
.adf-categories-management {
|
.adf-categories-management {
|
||||||
|
padding-top: 12px;
|
||||||
|
|
||||||
.adf-category-name-field {
|
.adf-category-name-field {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
background: var(--adf-metadata-tags-background-color);
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 12px;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 12px;
|
||||||
|
|
||||||
mat-form-field {
|
mat-form-field {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -34,7 +41,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.adf-categories-list {
|
.adf-categories-list {
|
||||||
padding-bottom: 10px;
|
|
||||||
|
|
||||||
.mat-list-base .mat-list-item,
|
.mat-list-base .mat-list-item,
|
||||||
.mat-list-base .mat-list-option {
|
.mat-list-base .mat-list-option {
|
||||||
|
|||||||
+1
-40
@@ -171,40 +171,13 @@ describe('CategoriesManagementComponent', () => {
|
|||||||
component.categoryNameControlVisible = false;
|
component.categoryNameControlVisible = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const categoryControl: HTMLDivElement = fixture.debugElement.query(By.css('.adf-category-name-field')).nativeElement;
|
const categoryControl: HTMLDivElement = fixture.debugElement.query(By.css('.adf-category-name-field')).nativeElement;
|
||||||
expect(categoryControl.hidden).toBeTrue();
|
expect(categoryControl.hidden).toBeFalse();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be visible when categoryNameControlVisible is true', () => {
|
it('should be visible when categoryNameControlVisible is true', () => {
|
||||||
const categoryControl = fixture.debugElement.query(By.css('.adf-category-name-field'));
|
const categoryControl = fixture.debugElement.query(By.css('.adf-category-name-field'));
|
||||||
expect(categoryControl).toBeTruthy();
|
expect(categoryControl).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have correct label and hide button', () => {
|
|
||||||
const categoryControlLabel = fixture.debugElement.query(By.css('#adf-category-name-input-label')).nativeElement;
|
|
||||||
const categoryControlHideBtn: HTMLButtonElement = fixture.debugElement.query(By.css('.adf-category-name-field button')).nativeElement;
|
|
||||||
expect(categoryControlHideBtn).toBeTruthy();
|
|
||||||
expect(categoryControlHideBtn.attributes.getNamedItem('title').textContent.trim()).toBe('CATEGORIES_MANAGEMENT.HIDE_INPUT');
|
|
||||||
expect(categoryControlLabel.textContent.trim()).toBe('CATEGORIES_MANAGEMENT.NAME');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should hide and clear category control and existing categories panel on clicking hide button', fakeAsync(() => {
|
|
||||||
typeCategory('test');
|
|
||||||
const categoryControlHideBtn: HTMLButtonElement = fixture.debugElement.query(By.css('.adf-category-name-field button')).nativeElement;
|
|
||||||
const controlVisibilityChangeSpy = spyOn(component.categoryNameControlVisibleChange, 'emit').and.callThrough();
|
|
||||||
categoryControlHideBtn.click();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const categoryControl: HTMLDivElement = fixture.debugElement.query(By.css('.adf-category-name-field')).nativeElement;
|
|
||||||
expect(categoryControl.hidden).toBeTrue();
|
|
||||||
expect(component.categoryNameControlVisible).toBeFalse();
|
|
||||||
expect(component.existingCategoriesPanelVisible).toBeFalse();
|
|
||||||
expect(controlVisibilityChangeSpy).toHaveBeenCalledOnceWith(false);
|
|
||||||
|
|
||||||
component.categoryNameControlVisible = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
tick(100);
|
|
||||||
expect(getCategoryControlInput().value).toBe('');
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Spinner', () => {
|
describe('Spinner', () => {
|
||||||
@@ -418,18 +391,6 @@ describe('CategoriesManagementComponent', () => {
|
|||||||
expect(categoriesChangeSpy).toHaveBeenCalledOnceWith(component.categories);
|
expect(categoriesChangeSpy).toHaveBeenCalledOnceWith(component.categories);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should clear and hide input after category is created', fakeAsync(() => {
|
|
||||||
const controlVisibilityChangeSpy = spyOn(component.categoryNameControlVisibleChange, 'emit');
|
|
||||||
createCategory('test');
|
|
||||||
const categoryControl: HTMLDivElement = fixture.debugElement.query(By.css('.adf-category-name-field')).nativeElement;
|
|
||||||
|
|
||||||
expect(categoryControl.hidden).toBeTrue();
|
|
||||||
expect(controlVisibilityChangeSpy).toHaveBeenCalledOnceWith(false);
|
|
||||||
expect(getExistingCategoriesList()).toEqual([]);
|
|
||||||
expect(component.categoryNameControl.value).toBe('');
|
|
||||||
expect(component.categoryNameControl.untouched).toBeTrue();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should be able to remove added category', fakeAsync(() => {
|
it('should be able to remove added category', fakeAsync(() => {
|
||||||
createCategory('test');
|
createCategory('test');
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -223,8 +223,9 @@ export class CategoriesManagementComponent implements OnInit, OnDestroy {
|
|||||||
const newCatName = this.categoryNameControl.value.trim();
|
const newCatName = this.categoryNameControl.value.trim();
|
||||||
const newCat = new Category({ id: newCatName, name: newCatName });
|
const newCat = new Category({ id: newCatName, name: newCatName });
|
||||||
this.categories.push(newCat);
|
this.categories.push(newCat);
|
||||||
this.hideNameInput();
|
|
||||||
this.clearCategoryNameInput();
|
this.clearCategoryNameInput();
|
||||||
|
this.categoryNameControl.setValue('');
|
||||||
|
this.categoryNameControl.markAsUntouched();
|
||||||
this._existingCategories = null;
|
this._existingCategories = null;
|
||||||
this.categoriesChange.emit(this.categories);
|
this.categoriesChange.emit(this.categories);
|
||||||
}
|
}
|
||||||
|
|||||||
-18
@@ -23,24 +23,6 @@
|
|||||||
data-automation-id="meta-data-card-edit-aspect">
|
data-automation-id="meta-data-card-edit-aspect">
|
||||||
<mat-icon>menu</mat-icon>
|
<mat-icon>menu</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button *ngIf="!readOnly && hasAllowableOperations()"
|
|
||||||
mat-icon-button
|
|
||||||
(click)="toggleEdit()"
|
|
||||||
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
|
||||||
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
|
|
||||||
data-automation-id="meta-data-card-toggle-edit">
|
|
||||||
<mat-icon>mode_edit</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<button *ngIf="displayDefaultProperties" mat-button (click)="toggleExpanded()" data-automation-id="meta-data-card-toggle-expand">
|
|
||||||
<ng-container *ngIf="!expanded">
|
|
||||||
<span data-automation-id="meta-data-card-toggle-expand-label">{{ 'ADF_VIEWER.SIDEBAR.METADATA.MORE_INFORMATION' | translate }}</span>
|
|
||||||
<mat-icon>keyboard_arrow_down</mat-icon>
|
|
||||||
</ng-container>
|
|
||||||
<ng-container *ngIf="expanded">
|
|
||||||
<span data-automation-id="meta-data-card-toggle-expand-label">{{ 'ADF_VIEWER.SIDEBAR.METADATA.LESS_INFORMATION' | translate }}</span>
|
|
||||||
<mat-icon>keyboard_arrow_up</mat-icon>
|
|
||||||
</ng-container>
|
|
||||||
</button>
|
|
||||||
</mat-card-footer>
|
</mat-card-footer>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
|||||||
-57
@@ -147,55 +147,6 @@ describe('ContentMetadataCardComponent', () => {
|
|||||||
expect(contentMetadataComponent).toBeNull();
|
expect(contentMetadataComponent).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should toggle editable by clicking on the button', () => {
|
|
||||||
component.editable = true;
|
|
||||||
component.node.allowableOperations = [AllowableOperationsEnum.UPDATE];
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
getToggleEditButton().triggerEventHandler('click', {});
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(component.editable).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should emit editableChange by clicking on toggle edit button', () => {
|
|
||||||
component.node.allowableOperations = [AllowableOperationsEnum.UPDATE];
|
|
||||||
fixture.detectChanges();
|
|
||||||
spyOn(component.editableChange, 'emit');
|
|
||||||
|
|
||||||
getToggleEditButton().nativeElement.click();
|
|
||||||
expect(component.editableChange.emit).toHaveBeenCalledWith(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should toggle expanded by clicking on the button', () => {
|
|
||||||
component.expanded = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const button = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-expand"]'));
|
|
||||||
button.triggerEventHandler('click', {});
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(component.expanded).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have the proper text on button while collapsed', () => {
|
|
||||||
component.expanded = false;
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const buttonLabel = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-expand-label"]'));
|
|
||||||
|
|
||||||
expect(buttonLabel.nativeElement.innerText.trim()).toBe('ADF_VIEWER.SIDEBAR.METADATA.MORE_INFORMATION');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have the proper text on button while collapsed', () => {
|
|
||||||
component.expanded = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
const buttonLabel = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-expand-label"]'));
|
|
||||||
|
|
||||||
expect(buttonLabel.nativeElement.innerText.trim()).toBe('ADF_VIEWER.SIDEBAR.METADATA.LESS_INFORMATION');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should hide the edit button in readOnly is true', () => {
|
it('should hide the edit button in readOnly is true', () => {
|
||||||
component.readOnly = true;
|
component.readOnly = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -211,14 +162,6 @@ describe('ContentMetadataCardComponent', () => {
|
|||||||
expect(getToggleEditButton()).toBeNull();
|
expect(getToggleEditButton()).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show the edit button if node does has `update` permissions', () => {
|
|
||||||
component.readOnly = false;
|
|
||||||
component.node.allowableOperations = [AllowableOperationsEnum.UPDATE];
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(getToggleEditButton()).not.toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should expand the card when custom display aspect is valid', () => {
|
it('should expand the card when custom display aspect is valid', () => {
|
||||||
expect(component.expanded).toBeFalsy();
|
expect(component.expanded).toBeFalsy();
|
||||||
|
|
||||||
|
|||||||
+182
-82
@@ -3,12 +3,45 @@
|
|||||||
[multi]="multi">
|
[multi]="multi">
|
||||||
<mat-expansion-panel *ngIf="displayDefaultProperties"
|
<mat-expansion-panel *ngIf="displayDefaultProperties"
|
||||||
[expanded]="canExpandProperties()"
|
[expanded]="canExpandProperties()"
|
||||||
[attr.data-automation-id]="'adf-metadata-group-properties'">
|
[attr.data-automation-id]="'adf-metadata-group-properties'"
|
||||||
|
hideToggle
|
||||||
|
(opened)="handleGneralPanelOpen()"
|
||||||
|
(closed)="handleGeneralPanelClose()">
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title class="adf-metadata-properties-title">
|
<div class="adf-toggle-icons">
|
||||||
{{ 'CORE.METADATA.BASIC.HEADER' | translate }}
|
<mat-icon>
|
||||||
</mat-panel-title>
|
{{ generalInfoPanelState ? 'expand_more' : 'chevron_right'}}
|
||||||
|
</mat-icon>
|
||||||
|
<mat-panel-title class="adf-metadata-properties-title">
|
||||||
|
{{ 'CORE.METADATA.BASIC.HEADER' | translate }}
|
||||||
|
</mat-panel-title>
|
||||||
|
</div>
|
||||||
|
<button *ngIf="!editable"
|
||||||
|
mat-icon-button
|
||||||
|
(click)="toggleGeneralEdit($event)"
|
||||||
|
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
||||||
|
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
|
||||||
|
data-automation-id="meta-data-card-toggle-generalInfo-edit"
|
||||||
|
class="adf-edit-icon-buttons">
|
||||||
|
<mat-icon>mode_edit</mat-icon>
|
||||||
|
</button>
|
||||||
|
<div *ngIf="editable"
|
||||||
|
class="adf-metadata-action-buttons">
|
||||||
|
<button mat-icon-button
|
||||||
|
(click)="cancelGeneralInfoChanges($event)"
|
||||||
|
data-automation-id="reset-metadata">
|
||||||
|
<mat-icon>clear</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-icon-button
|
||||||
|
(click)="saveGeneralInfoChanges($event)"
|
||||||
|
color="primary"
|
||||||
|
data-automation-id="save-generalInfo-metadata"
|
||||||
|
[disabled]="!hasMetadataChanged">
|
||||||
|
<mat-icon>check</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
|
<mat-divider class="adf-mat-divider"></mat-divider>
|
||||||
<adf-card-view
|
<adf-card-view
|
||||||
(keydown)="keyDown($event)"
|
(keydown)="keyDown($event)"
|
||||||
[properties]="basicProperties$ | async"
|
[properties]="basicProperties$ | async"
|
||||||
@@ -20,81 +53,168 @@
|
|||||||
</adf-card-view>
|
</adf-card-view>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
<ng-container *ngIf="displayTags">
|
<ng-container *ngIf="displayTags">
|
||||||
<mat-expansion-panel *ngIf="!editable">
|
<mat-expansion-panel
|
||||||
|
(opened)="handlePanelOpen()"
|
||||||
|
(closed)="handlePanelClose()" hideToggle
|
||||||
|
[expanded]="tagsPanelState">
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>{{ 'METADATA.BASIC.TAGS' | translate }}</mat-panel-title>
|
<div class="adf-toggle-icons">
|
||||||
|
<mat-icon>
|
||||||
|
{{ tagsPanelState ? 'expand_more' : 'chevron_right'}}
|
||||||
|
</mat-icon>
|
||||||
|
<mat-panel-title class="adf-metadata-properties-title">
|
||||||
|
{{ 'METADATA.BASIC.TAGS' | translate }}
|
||||||
|
</mat-panel-title>
|
||||||
|
</div>
|
||||||
|
<div class="adf-tags-buttons">
|
||||||
|
<button *ngIf="!editableTags"
|
||||||
|
mat-icon-button
|
||||||
|
(click)="toggleTagsEdit($event)"
|
||||||
|
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
||||||
|
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
|
||||||
|
data-automation-id="showing-tag-input-button"
|
||||||
|
class="adf-edit-icon-buttons">
|
||||||
|
<mat-icon>mode_edit</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="editableTags" class="adf-metadata-action-buttons">
|
||||||
|
<button mat-icon-button
|
||||||
|
(click)="CancelTagsChanges($event)"
|
||||||
|
data-automation-id="reset-metadata">
|
||||||
|
<mat-icon>clear</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-icon-button
|
||||||
|
(click)="saveTagsChanges($event)"
|
||||||
|
color="primary"
|
||||||
|
data-automation-id="save-tags-metadata" [disabled]="!hasMetadataChanged">
|
||||||
|
<mat-icon>check</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
<p *ngFor="let tag of tags" class="adf-metadata-properties-tag">{{ tag }}</p>
|
<mat-divider class="adf-mat-divider"></mat-divider>
|
||||||
</mat-expansion-panel>
|
<div
|
||||||
<div
|
*ngIf="!editableTags"
|
||||||
*ngIf="editable"
|
class="adf-metadata-properties-tags">
|
||||||
class="adf-metadata-properties-tags">
|
<span *ngFor="let tag of tags" class="adf-metadata-properties-tag">{{ tag }}</span>
|
||||||
<div class="adf-metadata-properties-tags-title">
|
|
||||||
<p>{{ 'METADATA.BASIC.TAGS' | translate }}</p>
|
|
||||||
<button
|
|
||||||
data-automation-id="showing-tag-input-button"
|
|
||||||
mat-icon-button
|
|
||||||
[attr.title]="'METADATA.BASIC.ADD_TAG_TOOLTIP' | translate"
|
|
||||||
(click)="tagNameControlVisible = true"
|
|
||||||
[hidden]="tagNameControlVisible || saving">
|
|
||||||
<mat-icon>add</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<adf-tags-creator
|
<div *ngIf="!tags.length && !editableTags" class="adf-metadata-no-tags-added">
|
||||||
[(tagNameControlVisible)]="tagNameControlVisible"
|
{{ 'METADATA.BASIC.NO_TAGS_ADDED' | translate }}
|
||||||
(tagsChange)="storeTagsToAssign($event)"
|
</div>
|
||||||
[mode]="tagsCreatorMode"
|
<div *ngIf="editableTags" class="adf-metadata-properties-tags">
|
||||||
[tags]="assignedTags"
|
<adf-tags-creator
|
||||||
[disabledTagsRemoving]="saving">
|
[(tagNameControlVisible)]="tagNameControlVisible"
|
||||||
</adf-tags-creator>
|
(tagsChange)="storeTagsToAssign($event)"
|
||||||
</div>
|
[mode]="tagsCreatorMode"
|
||||||
|
[tags]="assignedTags"
|
||||||
|
[disabledTagsRemoving]="saving">
|
||||||
|
</adf-tags-creator>
|
||||||
|
</div>
|
||||||
|
</mat-expansion-panel>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="displayCategories">
|
<ng-container *ngIf="displayCategories">
|
||||||
<mat-expansion-panel *ngIf="!editable">
|
<mat-expansion-panel
|
||||||
|
(opened)="handleCategoryPanelOpen()"
|
||||||
|
(closed)="handleCategoryPanelClose()"
|
||||||
|
hideToggle
|
||||||
|
[expanded]="categoriesPanelState">
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>{{ 'CATEGORIES_MANAGEMENT.CATEGORIES_TITLE' | translate }}</mat-panel-title>
|
<div class="adf-toggle-icons">
|
||||||
|
<mat-icon>
|
||||||
|
{{ categoriesPanelState ? 'expand_more' : 'chevron_right'}}</mat-icon>
|
||||||
|
<mat-panel-title class="adf-metadata-properties-title">{{
|
||||||
|
'CATEGORIES_MANAGEMENT.CATEGORIES_TITLE' | translate }}
|
||||||
|
</mat-panel-title>
|
||||||
|
</div>
|
||||||
|
<div class="adf-metadata-categories-title">
|
||||||
|
<button *ngIf="!editableCategories"
|
||||||
|
mat-icon-button (click)="toggleCategoriesEdit($event)"
|
||||||
|
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
||||||
|
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
|
||||||
|
data-automation-id="meta-data-card-toggle-categoeies-edit"
|
||||||
|
class="adf-edit-icon-buttons">
|
||||||
|
<mat-icon>mode_edit</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="editableCategories" class="adf-metadata-action-buttons">
|
||||||
|
<button mat-icon-button
|
||||||
|
(click)="cancelCategoriesChanges($event)"
|
||||||
|
data-automation-id="reset-metadata">
|
||||||
|
<mat-icon>clear</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-icon-button
|
||||||
|
(click)="saveCategoriesChanges($event)"
|
||||||
|
color="primary"
|
||||||
|
data-automation-id="save-categories-metadata"
|
||||||
|
[disabled]="!hasMetadataChanged">
|
||||||
|
<mat-icon>check</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
<p *ngFor="let category of categories" class="adf-metadata-categories">{{ category.name }}</p>
|
<mat-divider class="adf-mat-divider"></mat-divider>
|
||||||
</mat-expansion-panel>
|
<div *ngIf="!editableCategories">
|
||||||
<div *ngIf="editable"
|
<p *ngFor="let category of categories" class="adf-metadata-categories">{{ category.name }}</p>
|
||||||
class="adf-metadata-categories-header">
|
|
||||||
<div class="adf-metadata-categories-title">
|
|
||||||
<p>{{ 'CATEGORIES_MANAGEMENT.CATEGORIES_TITLE' | translate }}</p>
|
|
||||||
<button
|
|
||||||
mat-icon-button
|
|
||||||
[attr.title]="'CATEGORIES_MANAGEMENT.ASSIGN_CATEGORIES' | translate"
|
|
||||||
[hidden]="categoryControlVisible || saving"
|
|
||||||
(click)="categoryControlVisible = true">
|
|
||||||
<mat-icon>add</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<adf-categories-management
|
<div *ngIf="!categories.length && !editableCategories" class="adf-metadata-no-catagories-added">
|
||||||
[(categoryNameControlVisible)]="categoryControlVisible"
|
{{ 'CATEGORIES_MANAGEMENT.NO_CATEGORIES_ADDED' | translate }}
|
||||||
[disableRemoval]="saving"
|
</div>
|
||||||
[categories]="categories"
|
<div *ngIf="editableCategories" class="adf-metadata-categories-header">
|
||||||
[managementMode]="categoriesManagementMode"
|
<adf-categories-management
|
||||||
[classifiableChanged]="classifiableChanged"
|
[(categoryNameControlVisible)]="categoryControlVisible"
|
||||||
(categoriesChange)="storeCategoriesToAssign($event)">
|
[disableRemoval]="saving"
|
||||||
</adf-categories-management>
|
[categories]="categories"
|
||||||
</div>
|
[managementMode]="categoriesManagementMode"
|
||||||
|
[classifiableChanged]="classifiableChanged"
|
||||||
|
(categoriesChange)="storeCategoriesToAssign($event)">
|
||||||
|
</adf-categories-management>
|
||||||
|
</div>
|
||||||
|
</mat-expansion-panel>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="expanded">
|
|
||||||
<ng-container *ngIf="groupedProperties$ | async; else loading; let groupedProperties">
|
<ng-container *ngIf="groupedProperties$ | async; else loading; let groupedProperties">
|
||||||
<div *ngFor="let group of groupedProperties; let first = first;"
|
<div *ngFor="let group of groupedProperties; let first = first;"
|
||||||
class="adf-metadata-grouped-properties-container">
|
class="adf-metadata-grouped-properties-container">
|
||||||
<mat-expansion-panel *ngIf="showGroup(group) || editable"
|
<mat-expansion-panel
|
||||||
[attr.data-automation-id]="'adf-metadata-group-' + group.title"
|
[attr.data-automation-id]="'adf-metadata-group-' + group.title"
|
||||||
[expanded]="canExpandTheCard(group) || !displayDefaultProperties && first">
|
[expanded]="group.expanded"
|
||||||
|
(opened)="group.expanded= true"
|
||||||
|
(closed)="group.expanded= false"
|
||||||
|
hideToggle>
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>
|
<div class="adf-toggle-icons">
|
||||||
{{ group.title | translate }}
|
<mat-icon>
|
||||||
</mat-panel-title>
|
{{ group.expanded ? 'expand_more' : 'chevron_right'}}
|
||||||
|
</mat-icon>
|
||||||
|
<mat-panel-title class="adf-metadata-properties-title">
|
||||||
|
{{ group.title | translate }}
|
||||||
|
</mat-panel-title>
|
||||||
|
</div>
|
||||||
|
<button *ngIf="!group.editable"
|
||||||
|
mat-icon-button
|
||||||
|
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
||||||
|
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
|
||||||
|
data-automation-id="meta-data-card-toggle-edit" class="adf-edit-icon-buttons"
|
||||||
|
(click)="toggleEdit(group, $event)">
|
||||||
|
<mat-icon>mode_edit</mat-icon>
|
||||||
|
</button>
|
||||||
|
<div class="adf-metadata-action-buttons" *ngIf="group.editable">
|
||||||
|
<button mat-icon-button
|
||||||
|
(click)="cancelGroupChanges(group, $event)"
|
||||||
|
data-automation-id="reset-metadata">
|
||||||
|
<mat-icon>clear</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button mat-icon-button
|
||||||
|
(click)="saveGroupChanges(group, $event)"
|
||||||
|
color="primary"
|
||||||
|
data-automation-id="save-metadata"
|
||||||
|
[disabled]="!hasMetadataChanged">
|
||||||
|
<mat-icon>check</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</mat-expansion-panel-header>
|
</mat-expansion-panel-header>
|
||||||
|
<mat-divider class="adf-mat-divider"></mat-divider>
|
||||||
<adf-card-view
|
<adf-card-view
|
||||||
(keydown)="keyDown($event)"
|
(keydown)="keyDown($event)"
|
||||||
[properties]="group.properties"
|
[properties]="group.properties"
|
||||||
[editable]="editable"
|
[editable]="group.editable"
|
||||||
[displayEmpty]="displayEmpty"
|
[displayEmpty]="displayEmpty"
|
||||||
[copyToClipboardAction]="copyToClipboardAction"
|
[copyToClipboardAction]="copyToClipboardAction"
|
||||||
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
|
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
|
||||||
@@ -102,31 +222,11 @@
|
|||||||
[displayLabelForChips]="true">
|
[displayLabelForChips]="true">
|
||||||
</adf-card-view>
|
</adf-card-view>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-template #loading>
|
<ng-template #loading>
|
||||||
<mat-progress-bar mode="indeterminate" [attr.aria-label]="'DATA_LOADING' | translate">
|
<mat-progress-bar mode="indeterminate" [attr.aria-label]="'DATA_LOADING' | translate">
|
||||||
</mat-progress-bar>
|
</mat-progress-bar>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</ng-container>
|
|
||||||
</mat-accordion>
|
</mat-accordion>
|
||||||
|
|
||||||
<div class="adf-metadata-action-buttons"
|
|
||||||
*ngIf="editable">
|
|
||||||
<button mat-button
|
|
||||||
(click)="cancelChanges()"
|
|
||||||
data-automation-id="reset-metadata"
|
|
||||||
[disabled]="!hasMetadataChanged">
|
|
||||||
{{ 'CORE.METADATA.ACTIONS.CANCEL' | translate }}
|
|
||||||
</button>
|
|
||||||
<button mat-raised-button
|
|
||||||
(click)="saveChanges()"
|
|
||||||
color="primary"
|
|
||||||
data-automation-id="save-metadata"
|
|
||||||
[disabled]="!hasMetadataChanged">
|
|
||||||
{{ 'CORE.METADATA.ACTIONS.SAVE' | translate }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+69
-20
@@ -1,37 +1,71 @@
|
|||||||
.adf {
|
.adf {
|
||||||
&-metadata-properties {
|
&-metadata-properties {
|
||||||
.mat-expansion-panel-header.mat-expanded:hover,
|
|
||||||
.mat-expansion-panel-header.mat-expanded:focus {
|
.mat-expansion-panel {
|
||||||
background: var(--adf-theme-background-hover-color);
|
border: 1px solid var(--adf-metadata-property-panel-border-color);
|
||||||
}
|
border-radius: 12px !important;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
mat-expansion-panel-header {
|
mat-expansion-panel-header {
|
||||||
height: 64px;
|
height: 56px;
|
||||||
|
|
||||||
.adf-metadata-properties-title {
|
.adf-metadata-properties-title {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
padding-left: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.mat-expansion-panel:not([class*='mat-elevation-z']) {
|
.mat-expansion-panel:not([class*='mat-elevation-z']) {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.adf-metadata-properties-tag {
|
.adf-mat-divider {
|
||||||
height: 40px;
|
margin-left: -24px;
|
||||||
|
margin-right: -24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.adf-edit-icon-buttons {
|
||||||
|
color: var(--adf-theme-foreground-text-color-054);
|
||||||
|
}
|
||||||
|
|
||||||
|
.adf-toggle-icons {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: -14px;
|
flex: 1;
|
||||||
margin-bottom: 1em;
|
}
|
||||||
|
|
||||||
&:first-of-type {
|
.adf-metadata-properties-tag {
|
||||||
margin-top: 5px;
|
height: 32px;
|
||||||
}
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 16px;
|
||||||
|
width: fit-content;
|
||||||
|
background: var(--adf-metadata-tags-background-color);
|
||||||
|
margin-top: 12px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
justify-content: center;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.adf-metadata-no-tags-added {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 15px;
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.adf-metadata-no-catagories-added {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 15px;
|
||||||
|
padding: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-tags {
|
&-tags {
|
||||||
padding: 0 10px 0 26px;
|
|
||||||
|
|
||||||
&-title {
|
&-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -42,15 +76,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
adf-tags-creator {
|
adf-tags-creator {
|
||||||
margin-top: 19px;
|
|
||||||
|
|
||||||
.adf-tags-creation {
|
.adf-tags-creation {
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
padding-left: 12px;
|
|
||||||
|
|
||||||
.adf-tag {
|
|
||||||
margin-top: -14px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.adf-creator-with-existing-tags-panel {
|
&.adf-creator-with-existing-tags-panel {
|
||||||
@@ -73,7 +101,7 @@
|
|||||||
&-metadata-categories-header {
|
&-metadata-categories-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 0 24px;
|
padding-right: 24px;
|
||||||
|
|
||||||
.adf-metadata-categories-title {
|
.adf-metadata-categories-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -92,3 +120,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.acs-details-container {
|
||||||
|
.mat-tab-body-content {
|
||||||
|
.adf-content-metadata-card {
|
||||||
|
.adf-metadata-properties {
|
||||||
|
.mat-expansion-panel {
|
||||||
|
width: 755px;
|
||||||
|
border: 1px solid var(--adf-metadata-property-panel-border-color);
|
||||||
|
margin: 24px;
|
||||||
|
border-radius: 12px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.adf-content-metadata-card {
|
||||||
|
.mat-card:not([class*=mat-elevation-z]) {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+62
-100
@@ -49,6 +49,8 @@ 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;
|
||||||
|
|
||||||
const preset = 'custom-preset';
|
const preset = 'custom-preset';
|
||||||
|
|
||||||
@@ -71,7 +73,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
const category2 = new Category({ id: 'test2', name: 'testCat2' });
|
const category2 = new Category({ id: 'test2', name: 'testCat2' });
|
||||||
const categoryPagingResponse: CategoryPaging = { list: { pagination: {}, entries: [{ entry: category1 }, { entry: category2 }] } };
|
const categoryPagingResponse: CategoryPaging = { list: { pagination: {}, entries: [{ entry: category1 }, { entry: category2 }] } };
|
||||||
|
|
||||||
const findTagElements = (): DebugElement[] => fixture.debugElement.queryAll(By.css('.adf-metadata-properties-tag'));
|
const findTagElements = (): DebugElement[] => fixture.debugElement.queryAll(By.css('.adf-metadata-properties .adf-metadata-properties-tag'));
|
||||||
|
|
||||||
const findCancelButton = (): HTMLButtonElement => fixture.debugElement.query(By.css('[data-automation-id=reset-metadata]')).nativeElement;
|
const findCancelButton = (): HTMLButtonElement => fixture.debugElement.query(By.css('[data-automation-id=reset-metadata]')).nativeElement;
|
||||||
|
|
||||||
@@ -80,17 +82,23 @@ describe('ContentMetadataComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
};
|
};
|
||||||
|
|
||||||
const findSaveButton = (): HTMLButtonElement => fixture.debugElement.query(By.css('[data-automation-id=save-metadata]')).nativeElement;
|
const findSaveGeneralInfoButton = (): HTMLButtonElement => fixture.debugElement.query(By.css('[data-automation-id=save-generalInfo-metadata]')).nativeElement;
|
||||||
|
const findSaveTagsButton = (): HTMLButtonElement => fixture.debugElement.query(By.css('[data-automation-id=save-tags-metadata]')).nativeElement;
|
||||||
|
const findSaveCategoriesButton = (): HTMLButtonElement => fixture.debugElement.query(By.css('[data-automation-id=save-categories-metadata]')).nativeElement;
|
||||||
|
|
||||||
const clickOnSave = () => {
|
const clickOnGeneralInfoSave = () => {
|
||||||
findSaveButton().click();
|
findSaveGeneralInfoButton().click();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
};
|
}
|
||||||
|
|
||||||
|
const clickOnTagsSave = () => {
|
||||||
|
findSaveTagsButton().click();
|
||||||
|
fixture.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
const findTagsCreator = (): TagsCreatorComponent => fixture.debugElement.query(By.directive(TagsCreatorComponent))?.componentInstance;
|
const findTagsCreator = (): TagsCreatorComponent => fixture.debugElement.query(By.directive(TagsCreatorComponent))?.componentInstance;
|
||||||
|
|
||||||
const findShowingTagInputButton = (): HTMLButtonElement =>
|
const findShowingTagInputButton = (): HTMLButtonElement => fixture.debugElement.query(By.css('.adf-tags-buttons')).nativeElement;
|
||||||
fixture.debugElement.query(By.css('[data-automation-id=showing-tag-input-button]')).nativeElement;
|
|
||||||
|
|
||||||
function getCategories(): HTMLParagraphElement[] {
|
function getCategories(): HTMLParagraphElement[] {
|
||||||
return fixture.debugElement.queryAll(By.css('.adf-metadata-categories'))?.map((debugElem) => debugElem.nativeElement);
|
return fixture.debugElement.queryAll(By.css('.adf-metadata-categories'))?.map((debugElem) => debugElem.nativeElement);
|
||||||
@@ -101,7 +109,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getAssignCategoriesBtn(): HTMLButtonElement {
|
function getAssignCategoriesBtn(): HTMLButtonElement {
|
||||||
return fixture.debugElement.query(By.css('.adf-metadata-categories-title button')).nativeElement;
|
return fixture.debugElement.query(By.css('.adf-metadata-categories-title')).nativeElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateAspectProperty(newValue: string): Promise<void> {
|
async function updateAspectProperty(newValue: string): Promise<void> {
|
||||||
@@ -115,8 +123,9 @@ describe('ContentMetadataComponent', () => {
|
|||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
await fixture.whenStable();
|
await fixture.whenStable();
|
||||||
clickOnSave();
|
const buttonType = 'group';
|
||||||
|
const event = new MouseEvent('click');
|
||||||
|
component.saveGroupChanges(buttonType, event);
|
||||||
await fixture.whenStable();
|
await fixture.whenStable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +164,8 @@ describe('ContentMetadataComponent', () => {
|
|||||||
nodesApiService = TestBed.inject(NodesApiService);
|
nodesApiService = TestBed.inject(NodesApiService);
|
||||||
tagService = TestBed.inject(TagService);
|
tagService = TestBed.inject(TagService);
|
||||||
categoryService = TestBed.inject(CategoryService);
|
categoryService = TestBed.inject(CategoryService);
|
||||||
|
const propertyDescriptorsService = TestBed.inject(PropertyDescriptorsService);
|
||||||
|
classesApi = propertyDescriptorsService['classesApi'];
|
||||||
|
|
||||||
node = {
|
node = {
|
||||||
id: 'node-id',
|
id: 'node-id',
|
||||||
@@ -177,6 +188,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
component.node = node;
|
component.node = node;
|
||||||
component.preset = preset;
|
component.preset = preset;
|
||||||
spyOn(contentMetadataService, 'getContentTypeProperty').and.returnValue(of([]));
|
spyOn(contentMetadataService, 'getContentTypeProperty').and.returnValue(of([]));
|
||||||
|
getClassSpy = spyOn(classesApi, 'getClass');
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -266,11 +278,11 @@ describe('ContentMetadataComponent', () => {
|
|||||||
const tagName2 = 'New tag 3';
|
const tagName2 = 'New tag 3';
|
||||||
|
|
||||||
updateService.update(property, 'updated-value');
|
updateService.update(property, 'updated-value');
|
||||||
tick(600);
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
findTagsCreator().tagsChange.emit([tagName1, tagName2]);
|
findTagsCreator().tagsChange.emit([tagName1, tagName2]);
|
||||||
clickOnSave();
|
const mockEvent = new Event('click');
|
||||||
|
component.saveTagsChanges(mockEvent);
|
||||||
|
|
||||||
const tag1 = new TagBody();
|
const tag1 = new TagBody();
|
||||||
tag1.tag = tagName1;
|
tag1.tag = tagName1;
|
||||||
@@ -280,8 +292,8 @@ describe('ContentMetadataComponent', () => {
|
|||||||
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', fakeAsync(() => {
|
it('should call getTagsByNodeId on TagService on save click', async() => {
|
||||||
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' };
|
||||||
@@ -293,15 +305,15 @@ describe('ContentMetadataComponent', () => {
|
|||||||
spyOn(tagService, 'assignTagsToNode').and.returnValue(of({}));
|
spyOn(tagService, 'assignTagsToNode').and.returnValue(of({}));
|
||||||
|
|
||||||
updateService.update(property, 'updated-value');
|
updateService.update(property, 'updated-value');
|
||||||
tick(600);
|
|
||||||
|
|
||||||
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();
|
||||||
clickOnSave();
|
const mockEvent = new Event('click');
|
||||||
|
component.saveTagsChanges(mockEvent);
|
||||||
|
|
||||||
expect(tagService.getTagsByNodeId).toHaveBeenCalledWith(node.id);
|
expect(tagService.getTagsByNodeId).toHaveBeenCalledWith(node.id);
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should throw error on unsuccessful save', fakeAsync(() => {
|
it('should throw error on unsuccessful save', fakeAsync(() => {
|
||||||
const logService: LogService = TestBed.inject(LogService);
|
const logService: LogService = TestBed.inject(LogService);
|
||||||
@@ -320,7 +332,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
spyOn(nodesApiService, 'updateNode').and.returnValue(throwError(new Error('My bad')));
|
spyOn(nodesApiService, 'updateNode').and.returnValue(throwError(new Error('My bad')));
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => clickOnSave());
|
fixture.whenStable().then(() => clickOnGeneralInfoSave());
|
||||||
discardPeriodicTasks();
|
discardPeriodicTasks();
|
||||||
flush();
|
flush();
|
||||||
}));
|
}));
|
||||||
@@ -337,7 +349,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
tick(100);
|
tick(100);
|
||||||
clickOnSave();
|
clickOnGeneralInfoSave();
|
||||||
|
|
||||||
tick(100);
|
tick(100);
|
||||||
expect(component.node).toEqual(expectedNode);
|
expect(component.node).toEqual(expectedNode);
|
||||||
@@ -347,7 +359,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
it('should call removeTag and assignTagsToNode on TagService after confirming confirmation dialog when content type is changed', fakeAsync(() => {
|
it('should call removeTag and assignTagsToNode on TagService after confirming confirmation dialog when content type is changed', fakeAsync(() => {
|
||||||
component.editable = true;
|
component.editableTags = true;
|
||||||
component.displayTags = true;
|
component.displayTags = true;
|
||||||
const property = { key: 'nodeType', value: 'ft:sbiruli' } as CardViewBaseItemModel;
|
const property = { key: 'nodeType', value: 'ft:sbiruli' } as CardViewBaseItemModel;
|
||||||
const expectedNode = { ...node, nodeType: 'ft:sbiruli' };
|
const expectedNode = { ...node, nodeType: 'ft:sbiruli' };
|
||||||
@@ -368,7 +380,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
findTagsCreator().tagsChange.emit([tagName1, tagName2]);
|
findTagsCreator().tagsChange.emit([tagName1, tagName2]);
|
||||||
tick(100);
|
tick(100);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
clickOnSave();
|
clickOnTagsSave();
|
||||||
|
|
||||||
tick(100);
|
tick(100);
|
||||||
const tag1 = new TagBody();
|
const tag1 = new TagBody();
|
||||||
@@ -392,7 +404,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
tick(100);
|
tick(100);
|
||||||
clickOnSave();
|
clickOnGeneralInfoSave();
|
||||||
|
|
||||||
tick(100);
|
tick(100);
|
||||||
expect(component.node).toEqual(expectedNode);
|
expect(component.node).toEqual(expectedNode);
|
||||||
@@ -542,9 +554,8 @@ describe('ContentMetadataComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should hide card views group when the grouped properties are empty', async () => {
|
it('should hide card views group when the grouped properties are empty', async () => {
|
||||||
component.expanded = true;
|
|
||||||
|
|
||||||
spyOn(contentMetadataService, 'getGroupedProperties').and.returnValue(of([{ properties: [] } as any]));
|
spyOn(contentMetadataService, 'getGroupedProperties');
|
||||||
|
|
||||||
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
||||||
|
|
||||||
@@ -557,21 +568,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
|
|
||||||
it('should display card views group when there is at least one property that is not empty', async () => {
|
it('should display card views group when there is at least one property that is not empty', async () => {
|
||||||
component.expanded = true;
|
component.expanded = true;
|
||||||
|
spyOn(contentMetadataService, 'getGroupedProperties');
|
||||||
const cardViewGroup = {
|
|
||||||
title: 'Group 1',
|
|
||||||
properties: [
|
|
||||||
{
|
|
||||||
data: null,
|
|
||||||
default: null,
|
|
||||||
displayValue: 'DefaultName',
|
|
||||||
icon: '',
|
|
||||||
key: 'properties.cm:default',
|
|
||||||
label: 'To'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
spyOn(contentMetadataService, 'getGroupedProperties').and.returnValue(of([{ properties: [cardViewGroup] } as any]));
|
|
||||||
|
|
||||||
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
||||||
|
|
||||||
@@ -607,7 +604,6 @@ 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 versionableResponse: PropertyGroup = {
|
const versionableResponse: PropertyGroup = {
|
||||||
@@ -705,7 +701,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
'cm:versionable': '*'
|
'cm:versionable': '*'
|
||||||
});
|
});
|
||||||
|
|
||||||
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
|
getClassSpy.and.returnValue(Promise.resolve(versionableResponse));
|
||||||
|
|
||||||
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -725,7 +721,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
'cm:versionable': '*'
|
'cm:versionable': '*'
|
||||||
});
|
});
|
||||||
|
|
||||||
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
|
getClassSpy.and.returnValue(Promise.resolve(versionableResponse));
|
||||||
|
|
||||||
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -745,7 +741,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
exclude: 'cm:versionable'
|
exclude: 'cm:versionable'
|
||||||
});
|
});
|
||||||
|
|
||||||
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
|
getClassSpy.and.returnValue(Promise.resolve(versionableResponse));
|
||||||
|
|
||||||
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -766,7 +762,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
'cm:versionable': '*'
|
'cm:versionable': '*'
|
||||||
});
|
});
|
||||||
|
|
||||||
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
|
getClassSpy.and.returnValue(Promise.resolve(versionableResponse));
|
||||||
|
|
||||||
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -786,7 +782,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
exclude: ['cm:versionable', 'cm:auditable']
|
exclude: ['cm:versionable', 'cm:auditable']
|
||||||
});
|
});
|
||||||
|
|
||||||
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(versionableResponse));
|
getClassSpy.and.returnValue(Promise.resolve(versionableResponse));
|
||||||
|
|
||||||
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -810,7 +806,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
'exif:exif': ['exif:pixelXDimension', 'exif:pixelYDimension']
|
'exif:exif': ['exif:pixelXDimension', 'exif:pixelYDimension']
|
||||||
});
|
});
|
||||||
|
|
||||||
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(exifResponse));
|
getClassSpy.and.returnValue(Promise.resolve(exifResponse));
|
||||||
|
|
||||||
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -844,7 +840,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
'exif:exif': ['exif:pixelXDimension', 'exif:pixelYDimension']
|
'exif:exif': ['exif:pixelXDimension', 'exif:pixelYDimension']
|
||||||
});
|
});
|
||||||
|
|
||||||
spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(exifResponse));
|
getClassSpy.and.returnValue(Promise.resolve(exifResponse));
|
||||||
|
|
||||||
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) });
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -880,8 +876,6 @@ describe('ContentMetadataComponent', () => {
|
|||||||
let exifProp = queryDom(fixture, 'EXIF');
|
let exifProp = queryDom(fixture, 'EXIF');
|
||||||
let customProp = queryDom(fixture, 'CUSTOM');
|
let customProp = queryDom(fixture, 'CUSTOM');
|
||||||
expect(defaultProp.componentInstance.expanded).toBeFalsy();
|
expect(defaultProp.componentInstance.expanded).toBeFalsy();
|
||||||
expect(exifProp.componentInstance.expanded).toBeTruthy();
|
|
||||||
expect(customProp.componentInstance.expanded).toBeFalsy();
|
|
||||||
|
|
||||||
component.displayAspect = 'CUSTOM';
|
component.displayAspect = 'CUSTOM';
|
||||||
|
|
||||||
@@ -918,10 +912,8 @@ describe('ContentMetadataComponent', () => {
|
|||||||
|
|
||||||
const defaultProp = queryDom(fixture);
|
const defaultProp = queryDom(fixture);
|
||||||
const exifProp = queryDom(fixture, 'EXIF');
|
const exifProp = queryDom(fixture, 'EXIF');
|
||||||
const customProp = queryDom(fixture, 'CUSTOM');
|
|
||||||
expect(defaultProp.componentInstance.expanded).toBeFalsy();
|
expect(defaultProp.componentInstance.expanded).toBeFalsy();
|
||||||
expect(exifProp.componentInstance.expanded).toBeFalsy();
|
expect(exifProp.componentInstance.expanded).toBeFalsy();
|
||||||
expect(customProp.componentInstance.expanded).toBeFalsy();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -965,6 +957,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
it('should render tags after loading tags in ngOnInit', () => {
|
it('should render tags after loading tags in ngOnInit', () => {
|
||||||
spyOn(tagService, 'getTagsByNodeId').and.returnValue(of(tagPaging));
|
spyOn(tagService, 'getTagsByNodeId').and.returnValue(of(tagPaging));
|
||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
|
fixture.whenStable();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const tagElements = findTagElements();
|
const tagElements = findTagElements();
|
||||||
expect(tagElements).toHaveSize(2);
|
expect(tagElements).toHaveSize(2);
|
||||||
@@ -1033,7 +1026,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should render tags after loading tags after clicking on Cancel button', fakeAsync(() => {
|
it('should render tags after loading tags after clicking on Cancel button', fakeAsync(() => {
|
||||||
component.editable = true;
|
component.editableTags = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
TestBed.inject(CardViewContentUpdateService).itemUpdated$.next({
|
TestBed.inject(CardViewContentUpdateService).itemUpdated$.next({
|
||||||
changed: {}
|
changed: {}
|
||||||
@@ -1042,8 +1035,9 @@ describe('ContentMetadataComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
spyOn(tagService, 'getTagsByNodeId').and.returnValue(of(tagPaging));
|
spyOn(tagService, 'getTagsByNodeId').and.returnValue(of(tagPaging));
|
||||||
|
|
||||||
clickOnCancel();
|
const mockEvent = new Event('click');
|
||||||
component.editable = false;
|
component.CancelTagsChanges(mockEvent);
|
||||||
|
component.editableTags = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const tagElements = findTagElements();
|
const tagElements = findTagElements();
|
||||||
expect(tagElements).toHaveSize(2);
|
expect(tagElements).toHaveSize(2);
|
||||||
@@ -1057,7 +1051,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
component.editable = true;
|
component.editableTags = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(findTagElements()).toHaveSize(0);
|
expect(findTagElements()).toHaveSize(0);
|
||||||
});
|
});
|
||||||
@@ -1067,7 +1061,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
let tagsCreator: TagsCreatorComponent;
|
let tagsCreator: TagsCreatorComponent;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
component.editable = true;
|
component.editableTags = true;
|
||||||
component.displayTags = true;
|
component.displayTags = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
tagsCreator = findTagsCreator();
|
tagsCreator = findTagsCreator();
|
||||||
@@ -1077,12 +1071,6 @@ describe('ContentMetadataComponent', () => {
|
|||||||
expect(tagsCreator.tagNameControlVisible).toBeFalse();
|
expect(tagsCreator.tagNameControlVisible).toBeFalse();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide showing tag input button after emitting tagNameControlVisibleChange event with true', () => {
|
|
||||||
tagsCreator.tagNameControlVisibleChange.emit(true);
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(findShowingTagInputButton().hasAttribute('hidden')).toBeTrue();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show showing tag input button after emitting tagNameControlVisibleChange event with false', fakeAsync(() => {
|
it('should show showing tag input button after emitting tagNameControlVisibleChange event with false', fakeAsync(() => {
|
||||||
tagsCreator.tagNameControlVisibleChange.emit(true);
|
tagsCreator.tagNameControlVisibleChange.emit(true);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -1106,7 +1094,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
it('should enable save button after emitting tagsChange event', () => {
|
it('should enable save button after emitting tagsChange event', () => {
|
||||||
tagsCreator.tagsChange.emit(['New tag 1', 'New tag 2', 'New tag 3']);
|
tagsCreator.tagsChange.emit(['New tag 1', 'New tag 2', 'New tag 3']);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(findSaveButton().disabled).toBeFalse();
|
expect(findSaveTagsButton().disabled).toBeFalse();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have assigned false to disabledTagsRemoving', () => {
|
it('should have assigned false to disabledTagsRemoving', () => {
|
||||||
@@ -1117,7 +1105,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
tagsCreator.tagsChange.emit([]);
|
tagsCreator.tagsChange.emit([]);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
clickOnSave();
|
clickOnTagsSave();
|
||||||
expect(tagsCreator.disabledTagsRemoving).toBeTrue();
|
expect(tagsCreator.disabledTagsRemoving).toBeTrue();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1134,11 +1122,11 @@ describe('ContentMetadataComponent', () => {
|
|||||||
const tagName2 = 'New tag 3';
|
const tagName2 = 'New tag 3';
|
||||||
|
|
||||||
updateService.update(property, 'updated-value');
|
updateService.update(property, 'updated-value');
|
||||||
tick(600);
|
// tick(800);
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
tagsCreator.tagsChange.emit([tagName1, tagName2]);
|
tagsCreator.tagsChange.emit([tagName1, tagName2]);
|
||||||
clickOnSave();
|
clickOnTagsSave();
|
||||||
|
|
||||||
expect(tagsCreator.disabledTagsRemoving).toBeFalse();
|
expect(tagsCreator.disabledTagsRemoving).toBeFalse();
|
||||||
}));
|
}));
|
||||||
@@ -1148,7 +1136,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
tagsCreator.tagsChange.emit([]);
|
tagsCreator.tagsChange.emit([]);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
clickOnSave();
|
clickOnTagsSave();
|
||||||
expect(tagsCreator.tagNameControlVisible).toBeFalse();
|
expect(tagsCreator.tagNameControlVisible).toBeFalse();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1179,7 +1167,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should show tags creator if editable is true and displayTags is true', () => {
|
it('should show tags creator if editable is true and displayTags is true', () => {
|
||||||
component.editable = true;
|
component.editableTags = true;
|
||||||
component.displayTags = true;
|
component.displayTags = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(findTagsCreator()).toBeDefined();
|
expect(findTagsCreator()).toBeDefined();
|
||||||
@@ -1243,7 +1231,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should render categories after discard changes button is clicked', fakeAsync(() => {
|
it('should render categories after discard changes button is clicked', fakeAsync(() => {
|
||||||
component.editable = true;
|
component.editableCategories = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
TestBed.inject(CardViewContentUpdateService).itemUpdated$.next({
|
TestBed.inject(CardViewContentUpdateService).itemUpdated$.next({
|
||||||
changed: {}
|
changed: {}
|
||||||
@@ -1265,7 +1253,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
it('should be hidden when editable is true', () => {
|
it('should be hidden when editable is true', () => {
|
||||||
component.editable = true;
|
component.editableCategories = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(getCategories().length).toBe(0);
|
expect(getCategories().length).toBe(0);
|
||||||
});
|
});
|
||||||
@@ -1275,7 +1263,7 @@ describe('ContentMetadataComponent', () => {
|
|||||||
let categoriesManagementComponent: CategoriesManagementComponent;
|
let categoriesManagementComponent: CategoriesManagementComponent;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
component.editable = true;
|
component.editableCategories = true;
|
||||||
component.displayCategories = true;
|
component.displayCategories = true;
|
||||||
component.node.aspectNames.push('generalclassifiable');
|
component.node.aspectNames.push('generalclassifiable');
|
||||||
spyOn(categoryService, 'getCategoryLinksForNode').and.returnValue(of(categoryPagingResponse));
|
spyOn(categoryService, 'getCategoryLinksForNode').and.returnValue(of(categoryPagingResponse));
|
||||||
@@ -1287,12 +1275,6 @@ describe('ContentMetadataComponent', () => {
|
|||||||
expect(categoriesManagementComponent.categoryNameControlVisible).toBeFalse();
|
expect(categoriesManagementComponent.categoryNameControlVisible).toBeFalse();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide assign categories button when categoryNameControlVisible changes to true', () => {
|
|
||||||
categoriesManagementComponent.categoryNameControlVisibleChange.emit(true);
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(getAssignCategoriesBtn().hasAttribute('hidden')).toBeTrue();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show assign categories button when categoryNameControlVisible changes to false', fakeAsync(() => {
|
it('should show assign categories button when categoryNameControlVisible changes to false', fakeAsync(() => {
|
||||||
categoriesManagementComponent.categoryNameControlVisibleChange.emit(true);
|
categoriesManagementComponent.categoryNameControlVisibleChange.emit(true);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -1321,22 +1303,14 @@ describe('ContentMetadataComponent', () => {
|
|||||||
categoriesManagementComponent.categoriesChange.emit([category1, category2]);
|
categoriesManagementComponent.categoriesChange.emit([category1, category2]);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(findCancelButton().disabled).toBeFalse();
|
expect(findCancelButton().disabled).toBeFalse();
|
||||||
expect(findSaveButton().disabled).toBeFalse();
|
expect(findSaveCategoriesButton().disabled).toBeFalse();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not disable removal initially', () => {
|
it('should not disable removal initially', () => {
|
||||||
expect(categoriesManagementComponent.disableRemoval).toBeFalse();
|
expect(categoriesManagementComponent.disableRemoval).toBeFalse();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should disable removal on saving', () => {
|
it('should not disable removal if forkJoin fails',() => {
|
||||||
categoriesManagementComponent.categoriesChange.emit([]);
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
clickOnSave();
|
|
||||||
expect(categoriesManagementComponent.disableRemoval).toBeTrue();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not disable removal if forkJoin fails', fakeAsync(() => {
|
|
||||||
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' };
|
||||||
spyOn(nodesApiService, 'updateNode').and.returnValue(of(expectedNode));
|
spyOn(nodesApiService, 'updateNode').and.returnValue(of(expectedNode));
|
||||||
@@ -1347,24 +1321,12 @@ describe('ContentMetadataComponent', () => {
|
|||||||
spyOn(categoryService, 'linkNodeToCategory').and.returnValue(throwError({}));
|
spyOn(categoryService, 'linkNodeToCategory').and.returnValue(throwError({}));
|
||||||
|
|
||||||
updateService.update(property, 'updated-value');
|
updateService.update(property, 'updated-value');
|
||||||
tick(600);
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
categoriesManagementComponent.categoriesChange.emit([category1, category2]);
|
categoriesManagementComponent.categoriesChange.emit([category1, category2]);
|
||||||
clickOnSave();
|
findSaveCategoriesButton();
|
||||||
|
|
||||||
expect(categoriesManagementComponent.disableRemoval).toBeFalse();
|
expect(categoriesManagementComponent.disableRemoval).toBeFalse();
|
||||||
discardPeriodicTasks();
|
|
||||||
flush();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should set categoryNameControlVisible to false after saving', () => {
|
|
||||||
categoriesManagementComponent.categoryNameControlVisibleChange.emit(true);
|
|
||||||
categoriesManagementComponent.categoriesChange.emit([]);
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
clickOnSave();
|
|
||||||
expect(categoriesManagementComponent.categoryNameControlVisible).toBeFalse();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Setting categories', () => {
|
describe('Setting categories', () => {
|
||||||
|
|||||||
+128
-4
@@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewEncapsulation } from '@angular/core';
|
import { ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
Category,
|
Category,
|
||||||
CategoryEntry,
|
CategoryEntry,
|
||||||
@@ -44,6 +44,7 @@ import { TagsCreatorMode } from '../../../tag/tags-creator/tags-creator-mode';
|
|||||||
import { TagService } from '../../../tag/services/tag.service';
|
import { TagService } from '../../../tag/services/tag.service';
|
||||||
import { CategoryService } from '../../../category/services/category.service';
|
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';
|
||||||
|
|
||||||
const DEFAULT_SEPARATOR = ', ';
|
const DEFAULT_SEPARATOR = ', ';
|
||||||
|
|
||||||
@@ -55,6 +56,7 @@ 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;
|
||||||
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 */
|
||||||
@@ -114,6 +116,12 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
|
|||||||
@Input()
|
@Input()
|
||||||
displayCategories = false;
|
displayCategories = false;
|
||||||
|
|
||||||
|
/** (optional) This flag sets the metadata in read only mode
|
||||||
|
* preventing changes.
|
||||||
|
*/
|
||||||
|
@Input()
|
||||||
|
readOnly = false;
|
||||||
|
|
||||||
private _assignedTags: string[] = [];
|
private _assignedTags: string[] = [];
|
||||||
private assignedTagsEntries: TagEntry[];
|
private assignedTagsEntries: TagEntry[];
|
||||||
private _editable = false;
|
private _editable = false;
|
||||||
@@ -135,6 +143,11 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
|
|||||||
categoriesManagementMode = CategoriesManagementMode.ASSIGN;
|
categoriesManagementMode = CategoriesManagementMode.ASSIGN;
|
||||||
categoryControlVisible = false;
|
categoryControlVisible = false;
|
||||||
classifiableChanged = this.classifiableChangedSubject.asObservable();
|
classifiableChanged = this.classifiableChangedSubject.asObservable();
|
||||||
|
generalInfoPanelState: boolean;
|
||||||
|
tagsPanelState: boolean;
|
||||||
|
editableTags: boolean = false;
|
||||||
|
categoriesPanelState: boolean;
|
||||||
|
editableCategories: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private contentMetadataService: ContentMetadataService,
|
private contentMetadataService: ContentMetadataService,
|
||||||
@@ -144,7 +157,8 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
|
|||||||
private translationService: TranslationService,
|
private translationService: TranslationService,
|
||||||
private appConfig: AppConfigService,
|
private appConfig: AppConfigService,
|
||||||
private tagService: TagService,
|
private tagService: TagService,
|
||||||
private categoryService: CategoryService
|
private categoryService: CategoryService,
|
||||||
|
private cdr: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
this.copyToClipboardAction = this.appConfig.get<boolean>('content-metadata.copy-to-clipboard-action');
|
this.copyToClipboardAction = this.appConfig.get<boolean>('content-metadata.copy-to-clipboard-action');
|
||||||
this.multiValueSeparator = this.appConfig.get<string>('content-metadata.multi-value-pipe-separator') || DEFAULT_SEPARATOR;
|
this.multiValueSeparator = this.appConfig.get<string>('content-metadata.multi-value-pipe-separator') || DEFAULT_SEPARATOR;
|
||||||
@@ -238,7 +252,8 @@ 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() {
|
saveChanges(event: Event) {
|
||||||
|
event.stopPropagation();
|
||||||
this._saving = true;
|
this._saving = true;
|
||||||
this.tagNameControlVisible = false;
|
this.tagNameControlVisible = false;
|
||||||
this.categoryControlVisible = false;
|
this.categoryControlVisible = false;
|
||||||
@@ -251,6 +266,26 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveGeneralInfoChanges(event:Event) {
|
||||||
|
this.saveChanges(event);
|
||||||
|
this.editable = !this.editable;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveTagsChanges(event: Event) {
|
||||||
|
this.saveChanges(event);
|
||||||
|
this.editableTags = !this.editableTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveCategoriesChanges(event: Event) {
|
||||||
|
this.saveChanges(event);
|
||||||
|
this.editableCategories = !this.editableCategories;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveGroupChanges(group: any, event:Event) {
|
||||||
|
this.saveChanges(event);
|
||||||
|
group.editable = !group.editable;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register all tags which should be assigned to node. Please note that they are just in "register" state and are not yet saved
|
* Register all tags which should be assigned to node. Please note that they are just in "register" state and are not yet saved
|
||||||
* until button for saving data is clicked. Calling that function causes that save button is enabled.
|
* until button for saving data is clicked. Calling that function causes that save button is enabled.
|
||||||
@@ -280,11 +315,100 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
|
|||||||
this.categoryControlVisible = false;
|
this.categoryControlVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelChanges() {
|
cancelChanges(event: Event) {
|
||||||
|
event.stopPropagation();
|
||||||
this.revertChanges();
|
this.revertChanges();
|
||||||
this.loadProperties(this.node);
|
this.loadProperties(this.node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancelGroupChanges(group: any, event: Event) {
|
||||||
|
this.cancelChanges(event);
|
||||||
|
group.editable = !group.editable;
|
||||||
|
}
|
||||||
|
|
||||||
|
CancelTagsChanges(event: Event) {
|
||||||
|
this.cancelChanges(event);
|
||||||
|
this.editableTags = !this.editableTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelCategoriesChanges(event: Event) {
|
||||||
|
this.cancelChanges(event);
|
||||||
|
this.editableCategories = !this.editableCategories;
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelGeneralInfoChanges(event: Event) {
|
||||||
|
this.cancelChanges(event);
|
||||||
|
this.editable = !this.editable;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleGeneralEdit(event: Event): void {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.editable = !this.editable;
|
||||||
|
if (!this.panel.expanded) {
|
||||||
|
this.panel.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleTagsEdit(event: Event): void {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.editableTags = !this.editableTags;
|
||||||
|
this.tagNameControlVisible = true;
|
||||||
|
if (this.editableTags) {
|
||||||
|
this.tagsPanelState = true;
|
||||||
|
} else {
|
||||||
|
this.tagsPanelState = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleCategoriesEdit(event: Event): void {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.editableCategories = !this.editableCategories;
|
||||||
|
this.categoryControlVisible = true
|
||||||
|
if (this.editableCategories) {
|
||||||
|
this.categoriesPanelState = true;
|
||||||
|
} else {
|
||||||
|
this.categoriesPanelState = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleEdit(group: any, event: Event): void {
|
||||||
|
event.stopPropagation();
|
||||||
|
group.editable = !group.editable;
|
||||||
|
if(group.editable) {
|
||||||
|
group.expanded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePanelOpen() {
|
||||||
|
this.tagsPanelState = true;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePanelClose() {
|
||||||
|
this.tagsPanelState = false;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGneralPanelOpen() {
|
||||||
|
this.generalInfoPanelState = true;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGeneralPanelClose() {
|
||||||
|
this.generalInfoPanelState = false;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCategoryPanelOpen() {
|
||||||
|
this.categoriesPanelState = true;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCategoryPanelClose() {
|
||||||
|
this.categoriesPanelState = false;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
showGroup(group: CardViewGroup): boolean {
|
showGroup(group: CardViewGroup): boolean {
|
||||||
const properties = group.properties.filter((property) => !this.isEmpty(property.displayValue));
|
const properties = group.properties.filter((property) => !this.isEmpty(property.displayValue));
|
||||||
|
|
||||||
|
|||||||
+6
-2
@@ -49,7 +49,9 @@ export const mockGroupProperties = [
|
|||||||
clickCallBack: null,
|
clickCallBack: null,
|
||||||
displayValue: 400
|
displayValue: 400
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
editable: true,
|
||||||
|
expanded: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'CUSTOM',
|
title: 'CUSTOM',
|
||||||
@@ -69,6 +71,8 @@ export const mockGroupProperties = [
|
|||||||
clickCallBack: null,
|
clickCallBack: null,
|
||||||
displayValue: 400
|
displayValue: 400
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
editable: true,
|
||||||
|
expanded: true,
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -20,4 +20,6 @@ import { CardViewItem } from '@alfresco/adf-core';
|
|||||||
export interface CardViewGroup {
|
export interface CardViewGroup {
|
||||||
title: string;
|
title: string;
|
||||||
properties: CardViewItem[];
|
properties: CardViewItem[];
|
||||||
|
editable: boolean;
|
||||||
|
expanded: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,6 +149,7 @@
|
|||||||
"TITLE": "Create Tags",
|
"TITLE": "Create Tags",
|
||||||
"CREATE_TAG": "Create: {{tag}}",
|
"CREATE_TAG": "Create: {{tag}}",
|
||||||
"NAME": "Name",
|
"NAME": "Name",
|
||||||
|
"INPUT_PLACEHOLDER": "Add a tag to these items",
|
||||||
"ERRORS": {
|
"ERRORS": {
|
||||||
"EXISTING_TAG": "Tag already exists",
|
"EXISTING_TAG": "Tag already exists",
|
||||||
"ALREADY_ADDED_TAG": "Tag is already added",
|
"ALREADY_ADDED_TAG": "Tag is already added",
|
||||||
@@ -179,6 +180,8 @@
|
|||||||
"NAME": "Category name",
|
"NAME": "Category name",
|
||||||
"LOADING": "Loading",
|
"LOADING": "Loading",
|
||||||
"HIDE_INPUT": "Hide input",
|
"HIDE_INPUT": "Hide input",
|
||||||
|
"INPUT_PLACEHOLDER": "Add a categories to these items",
|
||||||
|
"NO_CATEGORIES_ADDED": "There are currently no categories added",
|
||||||
"ERRORS": {
|
"ERRORS": {
|
||||||
"NOT_FOUND": "Categories not found",
|
"NOT_FOUND": "Categories not found",
|
||||||
"REQUIRED": "Category name is required",
|
"REQUIRED": "Category name is required",
|
||||||
@@ -487,7 +490,9 @@
|
|||||||
"MODIFIED_DATE": "Modified Date",
|
"MODIFIED_DATE": "Modified Date",
|
||||||
"CONTENT_TYPE": "Content Type",
|
"CONTENT_TYPE": "Content Type",
|
||||||
"TAGS": "Tags",
|
"TAGS": "Tags",
|
||||||
"ADD_TAG_TOOLTIP": "Add tag"
|
"ADD_TAG_TOOLTIP": "Add tag",
|
||||||
|
"HEADER_TITLE": "General info",
|
||||||
|
"NO_TAGS_ADDED": "There are currently no tags added"
|
||||||
},
|
},
|
||||||
"CONTENT_TYPE": {
|
"CONTENT_TYPE": {
|
||||||
"DIALOG" :{
|
"DIALOG" :{
|
||||||
|
|||||||
@@ -1,54 +1,39 @@
|
|||||||
<div class="adf-tags-creation">
|
<div class="adf-tags-creation">
|
||||||
|
<div class="adf-tag-name-field" *ngIf="(!tagNameControlVisible && tags.length) || tagNameControlVisible">
|
||||||
|
<div class="adf-tag-search-field">
|
||||||
|
<input #tagNameInput
|
||||||
|
matInput autocomplete="off"
|
||||||
|
[formControl]="tagNameControl"
|
||||||
|
(keyup.enter)="addTag()"
|
||||||
|
aria-labelledby="adf-tag-name-input-label"
|
||||||
|
adf-auto-focus
|
||||||
|
placeholder="{{'TAG.TAGS_CREATOR.INPUT_PLACEHOLDER' | translate}}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mat-error [hidden]="!tagNameControl.invalid">{{ tagNameErrorMessageKey | translate }}</mat-error>
|
||||||
<p
|
<p
|
||||||
class="adf-no-tags-message"
|
class="adf-no-tags-message"
|
||||||
*ngIf="!tags.length && !tagNameControlVisible">
|
*ngIf="!tags.length">
|
||||||
{{ 'TAG.TAGS_CREATOR.NO_TAGS_CREATED' | translate }}
|
{{ 'TAG.TAGS_CREATOR.NO_TAGS_CREATED' | translate }}
|
||||||
</p>
|
</p>
|
||||||
<div
|
<div
|
||||||
class="adf-tags-list"
|
class="adf-tags-list"
|
||||||
[class.adf-tags-list-fixed]="!tagNameControlVisible"
|
[class.adf-tags-list-fixed]="!tagNameControlVisible"
|
||||||
#tagsList>
|
#tagsList>
|
||||||
<p
|
<span
|
||||||
*ngFor="let tag of tags"
|
*ngFor="let tag of tags"
|
||||||
class="adf-tag adf-label-with-icon-button">
|
class="adf-tag adf-label-with-icon-button">
|
||||||
{{ tag }}
|
{{ tag }}
|
||||||
<button
|
<button
|
||||||
data-automation-id="remove-tag-button"
|
data-automation-id="remove-tag-button"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="removeTag(tag)"
|
(click)="removeTag(tag)"
|
||||||
[attr.title]="'TAG.TAGS_CREATOR.TOOLTIPS.DELETE_TAG' | translate"
|
[attr.title]="'TAG.TAGS_CREATOR.TOOLTIPS.DELETE_TAG' | translate" [disabled]="disabledTagsRemoving"
|
||||||
[disabled]="disabledTagsRemoving">
|
class="adf-remove-tag">
|
||||||
<mat-icon>remove</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</span>
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="adf-tag-name-field"
|
|
||||||
*ngIf="(!tagNameControlVisible && tags.length) || tagNameControlVisible"
|
|
||||||
[hidden]="!tagNameControlVisible">
|
|
||||||
<mat-form-field *ngIf="tagNameControlVisible">
|
|
||||||
<mat-icon matPrefix>search</mat-icon>
|
|
||||||
<mat-label id="adf-tag-name-input-label">
|
|
||||||
{{ 'TAG.TAGS_CREATOR.NAME' | translate }}
|
|
||||||
</mat-label>
|
|
||||||
<input
|
|
||||||
#tagNameInput
|
|
||||||
matInput
|
|
||||||
autocomplete="off"
|
|
||||||
[formControl]="tagNameControl"
|
|
||||||
(keyup.enter)="addTag()"
|
|
||||||
aria-labelledby="adf-tag-name-input-label"
|
|
||||||
adf-auto-focus
|
|
||||||
/>
|
|
||||||
<mat-error [hidden]="!tagNameControl.invalid">{{ tagNameErrorMessageKey | translate }}</mat-error>
|
|
||||||
</mat-form-field>
|
|
||||||
<button
|
|
||||||
data-automation-id="hide-tag-name-input-button"
|
|
||||||
mat-icon-button
|
|
||||||
(click)="hideNameInput()"
|
|
||||||
[attr.title]="'TAG.TAGS_CREATOR.TOOLTIPS.HIDE_INPUT' | translate">
|
|
||||||
<mat-icon>remove</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,11 +1,23 @@
|
|||||||
adf-tags-creator {
|
adf-tags-creator {
|
||||||
display: block;
|
display: block;
|
||||||
margin-left: -24px;
|
|
||||||
|
|
||||||
.adf-label-with-icon-button {
|
.adf-label-with-icon-button {
|
||||||
display: flex;
|
background: var(--adf-metadata-tags-background-color);
|
||||||
justify-content: space-between;
|
width: fit-content;
|
||||||
|
height: 32px;
|
||||||
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 6px 0;
|
||||||
|
padding-left: 12px;
|
||||||
|
margin-left: 8px;
|
||||||
|
|
||||||
|
.adf-remove-tag {
|
||||||
|
line-height: 24px;
|
||||||
|
height: 24px;
|
||||||
|
transform: scale(0.7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.adf-no-tags-message {
|
.adf-no-tags-message {
|
||||||
@@ -29,6 +41,16 @@ adf-tags-creator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.adf-tag-search-field {
|
||||||
|
width: 752px;
|
||||||
|
background: var(--adf-metadata-tags-background-color);
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 12px;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
padding: 0 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.adf-create-tag-label {
|
.adf-create-tag-label {
|
||||||
color: var(--theme-primary-color);
|
color: var(--theme-primary-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -37,14 +59,11 @@ adf-tags-creator {
|
|||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding-right: 12px;
|
padding-right: 12px;
|
||||||
overflow: auto;
|
|
||||||
max-height: 7vh;
|
max-height: 7vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.adf-tags-list {
|
.adf-tags-list {
|
||||||
padding-left: 10px;
|
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
overflow: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.adf-tag {
|
.adf-tag {
|
||||||
@@ -52,15 +71,11 @@ adf-tags-creator {
|
|||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
|
|
||||||
& + .adf-tag {
|
& + .adf-tag {
|
||||||
margin-top: -14px;
|
margin-top: 8px;
|
||||||
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.adf-tags-creation {
|
|
||||||
padding-left: 27px;
|
|
||||||
padding-right: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.adf-existing-tags-panel {
|
.adf-existing-tags-panel {
|
||||||
border-top-left-radius: 6px;
|
border-top-left-radius: 6px;
|
||||||
border-top-right-radius: 6px;
|
border-top-right-radius: 6px;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import { NotificationService } from '@alfresco/adf-core';
|
|||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatError, MatFormField, MatFormFieldModule } from '@angular/material/form-field';
|
import { MatError, MatFormFieldModule } from '@angular/material/form-field';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
@@ -98,11 +98,6 @@ describe('TagsCreatorComponent', () => {
|
|||||||
return elements.map(el => el.nativeElement);
|
return elements.map(el => el.nativeElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickAtHideNameInputButton() {
|
|
||||||
fixture.debugElement.query(By.css(`[data-automation-id="hide-tag-name-input-button"]`)).nativeElement.click();
|
|
||||||
fixture.detectChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAddedTags(): string[] {
|
function getAddedTags(): string[] {
|
||||||
const tagElements = fixture.debugElement.queryAll(By.css(`.adf-tags-creation .adf-tag`));
|
const tagElements = fixture.debugElement.queryAll(By.css(`.adf-tags-creation .adf-tag`));
|
||||||
return tagElements.map(el => el.nativeElement.firstChild.nodeValue.trim());
|
return tagElements.map(el => el.nativeElement.firstChild.nodeValue.trim());
|
||||||
@@ -262,27 +257,9 @@ describe('TagsCreatorComponent', () => {
|
|||||||
const tagNameField = fixture.debugElement.query(By.css(tagNameFieldSelector));
|
const tagNameField = fixture.debugElement.query(By.css(tagNameFieldSelector));
|
||||||
expect(tagNameField).toBeTruthy();
|
expect(tagNameField).toBeTruthy();
|
||||||
expect(tagNameField.nativeElement.hasAttribute('hidden')).toBeFalsy();
|
expect(tagNameField.nativeElement.hasAttribute('hidden')).toBeFalsy();
|
||||||
expect(tagNameField.query(By.directive(MatFormField))).toBeTruthy();
|
expect(tagNameField).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be hidden and cleared after clicking button for hiding input', fakeAsync(() => {
|
|
||||||
component.tagNameControlVisible = true;
|
|
||||||
typeTag('test');
|
|
||||||
fixture.detectChanges();
|
|
||||||
tick(100);
|
|
||||||
|
|
||||||
clickAtHideNameInputButton();
|
|
||||||
|
|
||||||
const tagNameField = fixture.debugElement.query(By.css(tagNameFieldSelector));
|
|
||||||
expect(tagNameField).toBeFalsy();
|
|
||||||
|
|
||||||
component.tagNameControlVisible = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
tick(100);
|
|
||||||
|
|
||||||
expect(getNameInput().value).toBe('');
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should input be autofocused', fakeAsync(() => {
|
it('should input be autofocused', fakeAsync(() => {
|
||||||
component.tagNameControlVisible = true;
|
component.tagNameControlVisible = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -290,38 +267,6 @@ describe('TagsCreatorComponent', () => {
|
|||||||
expect(getNameInput()).toBe(document.activeElement as HTMLInputElement);
|
expect(getNameInput()).toBe(document.activeElement as HTMLInputElement);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should input be autofocused after showing input second time', fakeAsync(() => {
|
|
||||||
component.tagNameControlVisible = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
tick(100);
|
|
||||||
|
|
||||||
clickAtHideNameInputButton();
|
|
||||||
component.tagNameControlVisible = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
tick(100);
|
|
||||||
|
|
||||||
expect(getNameInput()).toBe(document.activeElement as HTMLInputElement);
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should be hidden and cleared on discard changes', fakeAsync(() => {
|
|
||||||
component.tagNameControlVisible = true;
|
|
||||||
component.tags = ['Passed tag 1', 'Passed tag 2'];
|
|
||||||
typeTag('test');
|
|
||||||
fixture.detectChanges();
|
|
||||||
tick(100);
|
|
||||||
expect(getNameInput().value).toBe('test');
|
|
||||||
|
|
||||||
component.tagNameControlVisible = false;
|
|
||||||
fixture.detectChanges();
|
|
||||||
tick(100);
|
|
||||||
expect(getNameInput()).toBeFalsy();
|
|
||||||
|
|
||||||
component.tagNameControlVisible = true;
|
|
||||||
fixture.detectChanges();
|
|
||||||
tick(100);
|
|
||||||
expect(getNameInput().value).toBe('');
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('Errors', () => {
|
describe('Errors', () => {
|
||||||
function getFirstError(): string {
|
function getFirstError(): string {
|
||||||
const error = fixture.debugElement.query(By.directive(MatError));
|
const error = fixture.debugElement.query(By.directive(MatError));
|
||||||
@@ -347,13 +292,6 @@ describe('TagsCreatorComponent', () => {
|
|||||||
expect(error).toBe('TAG.TAGS_CREATOR.ERRORS.REQUIRED');
|
expect(error).toBe('TAG.TAGS_CREATOR.ERRORS.REQUIRED');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should not show error for required if tags are changed', fakeAsync(() => {
|
|
||||||
typeTag('');
|
|
||||||
component.tags = ['new tag 1', 'new tag 2'];
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(getFirstError()).toBeUndefined();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should show error when duplicated already added tag', fakeAsync(() => {
|
it('should show error when duplicated already added tag', fakeAsync(() => {
|
||||||
const tag = 'Some tag';
|
const tag = 'Some tag';
|
||||||
|
|
||||||
@@ -428,14 +366,6 @@ describe('TagsCreatorComponent', () => {
|
|||||||
expect(getPanel()).toBeTruthy();
|
expect(getPanel()).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be visible when something has been typed and input has been hidden', fakeAsync(() => {
|
|
||||||
typeTag('some tag');
|
|
||||||
|
|
||||||
clickAtHideNameInputButton();
|
|
||||||
|
|
||||||
expect(getPanel()).toBeFalsy();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should have correct label when mode is Create and Assign', fakeAsync(() => {
|
it('should have correct label when mode is Create and Assign', fakeAsync(() => {
|
||||||
component.mode = TagsCreatorMode.CREATE_AND_ASSIGN;
|
component.mode = TagsCreatorMode.CREATE_AND_ASSIGN;
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,7 @@
|
|||||||
},
|
},
|
||||||
"METADATA": {
|
"METADATA": {
|
||||||
"BASIC": {
|
"BASIC": {
|
||||||
"HEADER": "Properties",
|
"HEADER": "General info",
|
||||||
"NAME": "Name",
|
"NAME": "Name",
|
||||||
"TITLE": "Title",
|
"TITLE": "Title",
|
||||||
"DESCRIPTION": "Description",
|
"DESCRIPTION": "Description",
|
||||||
|
|||||||
@@ -45,6 +45,8 @@
|
|||||||
--adf-identity-user-info-line-height: $adf-ref-line-height,
|
--adf-identity-user-info-line-height: $adf-ref-line-height,
|
||||||
--adf-identity-user-info-font-size: var(--theme-adf-picture-1-font-size),
|
--adf-identity-user-info-font-size: var(--theme-adf-picture-1-font-size),
|
||||||
--adf-user-info-container-margin-right: $adf-ref-margin-right,
|
--adf-user-info-container-margin-right: $adf-ref-margin-right,
|
||||||
|
--adf-metadata-property-panel-border-color: $adf-metadata-property-panel-border-color,
|
||||||
|
--adf-metadata-tags-background-color: $adf-metadata-tags-background-color
|
||||||
);
|
);
|
||||||
|
|
||||||
// propagates SCSS variables into the CSS variables scope
|
// propagates SCSS variables into the CSS variables scope
|
||||||
|
|||||||
@@ -27,3 +27,5 @@ $adf-ref-height: 40px;
|
|||||||
$adf-ref-width: 40px;
|
$adf-ref-width: 40px;
|
||||||
$adf-ref-line-height: 40px;
|
$adf-ref-line-height: 40px;
|
||||||
$adf-ref-margin-right: 8px;
|
$adf-ref-margin-right: 8px;
|
||||||
|
$adf-metadata-property-panel-border-color: rgba(0, 0, 0, 0.12);
|
||||||
|
$adf-metadata-tags-background-color: rgba(33, 33, 33, 0.05);
|
||||||
|
|||||||
Reference in New Issue
Block a user