Compare commits

...
12 Commits
Author SHA1 Message Date
Yasa-Nataliya 77960e37ad modified code 2023-07-28 04:32:08 +00:00
Yasa-Nataliya 3d6ac31eb0 modified the data-automation-id 2023-07-27 15:20:20 +00:00
Yasa-Nataliya f190795c48 added unit test cases for new functionality 2023-07-27 09:13:51 +00:00
Yasa-Nataliya b208f2e688 fix for unit test 2023-07-27 05:06:27 +00:00
Yasa-Nataliya 7e13faf645 fix for unit test cases 2023-07-26 17:08:47 +00:00
Yasa-Nataliya b4e541161d fix for unit test 2023-07-26 14:58:19 +00:00
Yasa-Nataliya 1119d7f135 empty commit 2023-07-26 14:37:00 +00:00
Yasa-Nataliya 75d7e98dff minor changes 2023-07-26 11:25:42 +00:00
Yasa-Nataliya 12e98b9371 modified changes 2023-07-26 10:51:27 +00:00
Yasa-Nataliya d9e3a903d1 added styles 2023-07-26 08:28:51 +00:00
Yasa-Nataliya 4dbed99fd8 changes for theme colors 2023-07-26 06:26:27 +00:00
Yasa-Nataliya 0a4b316c9b Implemented changes as per the requirement 2023-07-25 17:53:51 +00:00
23 changed files with 589 additions and 371 deletions
@@ -1,8 +1,17 @@
<div class="adf-categories-management">
<p *ngIf="!categories.length && !categoryNameControlVisible"
class="adf-no-categories-message">
{{ noCategoriesMsg | translate }}
</p>
<div
class="adf-category-name-field">
<input #categoryNameInput
matInput
autocomplete="off"
[formControl]="categoryNameControl"
(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
@@ -21,33 +30,10 @@
</button>
</span>
</div>
<div *ngIf="((!categoryNameControlVisible && categories.length)) || categoryNameControlVisible"
[hidden]="!categoryNameControlVisible"
class="adf-category-name-field">
<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>
<p *ngIf="!categories.length && !categoryNameControlVisible"
class="adf-no-categories-message">
{{ noCategoriesMsg | translate }}
</p>
</div>
<div class="adf-existing-categories-panel" *ngIf="existingCategoriesPanelVisible">
<ng-container *ngIf="isCRUDMode && (!existingCategoriesLoading || existingCategories)">
@@ -57,7 +43,7 @@
{{ 'CATEGORIES_MANAGEMENT.GENERIC_CREATE' | translate : { name: categoryNameControl.value } }}
</span>
</ng-container>
<div *ngIf="categoryNameControlVisible" class="adf-categories-list">
<div class="adf-categories-list">
<ng-container *ngIf="!existingCategoriesLoading && existingCategories">
<p class="adf-existing-categories-label">
{{ existingCategoriesMsg | translate }}
@@ -1,8 +1,15 @@
.adf-categories-management {
padding-top: 12px;
.adf-category-name-field {
display: flex;
justify-content: space-between;
width: 100%;
background: var(--adf-metadata-tags-background-color);
height: 32px;
border-radius: 12px;
align-items: center;
padding: 0 12px;
mat-form-field {
width: 100%;
@@ -34,7 +41,6 @@
}
.adf-categories-list {
padding-bottom: 10px;
.mat-list-base .mat-list-item,
.mat-list-base .mat-list-option {
@@ -167,38 +167,11 @@ describe('CategoriesManagementComponent', () => {
component.categoryNameControlVisible = true;
fixture.detectChanges();
});
it('should be hidden initially', () => {
component.categoryNameControlVisible = false;
fixture.detectChanges();
const categoryControl: HTMLDivElement = fixture.debugElement.query(By.css('.adf-category-name-field')).nativeElement;
expect(categoryControl.hidden).toBeTrue();
});
it('should be visible when categoryNameControlVisible is true', () => {
const categoryControl = fixture.debugElement.query(By.css('.adf-category-name-field'));
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 category control and existing categories panel on clicking hide button', () => {
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);
});
});
describe('Spinner', () => {
@@ -415,9 +388,7 @@ describe('CategoriesManagementComponent', () => {
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('');
@@ -484,4 +455,15 @@ describe('CategoriesManagementComponent', () => {
}));
});
});
it('should remove a category', fakeAsync(() => {
component.managementMode = CategoriesManagementMode.ASSIGN;
const categoryToRemove: Category = { id: 'catToRemove', name: 'Category to Remove' };
component.categories = [categoryToRemove];
component['_existingCategories'] = [];
component.initialCategories = [];
component.removeCategoryTitle = 'Remove Category';
component.removeCategory(categoryToRemove);
expect(component.categories.length).toBe(0);
}));
});
@@ -83,9 +83,7 @@ export class CategoriesManagementComponent implements OnInit, OnDestroy {
set categoryNameControlVisible(categoryNameControlVisible: boolean) {
this._categoryNameControlVisible = categoryNameControlVisible;
if (categoryNameControlVisible) {
setTimeout(() => {
this.categoryNameInputElement.nativeElement.scrollIntoView();
});
this._existingCategoriesPanelVisible = true;
} else {
this._existingCategoriesPanelVisible = false;
@@ -23,24 +23,6 @@
data-automation-id="meta-data-card-edit-aspect">
<mat-icon>menu</mat-icon>
</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>
<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>
@@ -145,72 +145,6 @@ describe('ContentMetadataCardComponent', () => {
expect(contentMetadataComponent).toBeNull();
});
it('should toggle editable by clicking on the button', () => {
component.editable = true;
component.node.allowableOperations = [AllowableOperationsEnum.UPDATE];
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-edit"]'));
button.triggerEventHandler('click', {});
fixture.detectChanges();
expect(component.editable).toBe(false);
});
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', () => {
component.readOnly = true;
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-edit"]'));
expect(button).toBeNull();
});
it('should hide the edit button if node does not have `update` permissions', () => {
component.readOnly = false;
component.node.allowableOperations = null;
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-edit"]'));
expect(button).toBeNull();
});
it('should show the edit button if node does has `update` permissions', () => {
component.readOnly = false;
component.node.allowableOperations = [AllowableOperationsEnum.UPDATE];
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-edit"]'));
expect(button).not.toBeNull();
});
it('should expand the card when custom display aspect is valid', () => {
expect(component.expanded).toBeFalsy();
@@ -109,14 +109,6 @@ export class ContentMetadataCardComponent implements OnChanges {
this.expanded = !this._displayDefaultProperties;
}
toggleEdit(): void {
this.editable = !this.editable;
}
toggleExpanded(): void {
this.expanded = !this.expanded;
}
hasAllowableOperations() {
return this.contentService.hasAllowableOperations(this.node, AllowableOperationsEnum.UPDATE);
}
@@ -1,131 +1,171 @@
<div class="adf-metadata-properties">
<mat-accordion displayMode="flat"
[multi]="multi">
<mat-expansion-panel *ngIf="displayDefaultProperties"
[expanded]="canExpandProperties()"
[attr.data-automation-id]="'adf-metadata-group-properties'">
<mat-accordion displayMode="flat" [multi]="multi">
<mat-expansion-panel *ngIf="displayDefaultProperties" [expanded]="true"
[attr.data-automation-id]="'adf-metadata-group-properties'" (opened)="generalInfoPanelState = true"
(closed)="generalInfoPanelState = false" hideToggle>
<mat-expansion-panel-header>
<mat-panel-title class="adf-metadata-properties-title">
{{ 'CORE.METADATA.BASIC.HEADER' | translate }}
</mat-panel-title>
<div class="adf-toggle-icons">
<mat-icon>
{{ generalInfoPanelState ? 'expand_more' : 'chevron_right'}}</mat-icon>
<mat-panel-title class="adf-metadata-properties-title">
{{ 'CORE.METADATA.HEADER_TITLE' | translate }}
</mat-panel-title>
</div>
<button *ngIf="!editableGeneralInfo" 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 class="adf-metadata-action-buttons" *ngIf="editableGeneralInfo">
<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>
<adf-card-view
(keydown)="keyDown($event)"
[properties]="basicProperties$ | async"
[editable]="editable"
[displayEmpty]="displayEmpty"
<mat-divider class="adf-mat-divider"></mat-divider>
<adf-card-view (keydown)="keyDown($event)" [properties]="basicProperties$ | async"
[editableGeneralInfo]="editableGeneralInfo" [displayEmpty]="displayEmpty"
[copyToClipboardAction]="copyToClipboardAction"
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
[multiValueSeparator]="multiValueSeparator">
</adf-card-view>
</mat-expansion-panel>
<ng-container *ngIf="displayTags">
<mat-expansion-panel *ngIf="!editable">
<mat-expansion-panel (opened)="tagsPanelState = true" (closed)="tagsPanelState = false" hideToggle
[expanded]="tagsPanelState">
<mat-expansion-panel-header>
<mat-panel-title>{{ 'METADATA.BASIC.TAGS' | translate }}</mat-panel-title>
</mat-expansion-panel-header>
<p *ngFor="let tag of tags" class="adf-metadata-properties-tag">{{ tag }}</p>
</mat-expansion-panel>
<div
*ngIf="editable"
class="adf-metadata-properties-tags">
<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>
<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>
<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="meta-data-card-toggle-tags-edit" class="adf-edit-icon-buttons">
<mat-icon>mode_edit</mat-icon>
</button>
<div class="adf-metadata-action-buttons" *ngIf="editableTags">
<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-divider class="adf-mat-divider"></mat-divider>
<div *ngIf="!editableTags">
<span *ngFor="let tag of tags" class="adf-metadata-properties-tag">{{ tag }}</span>
</div>
<adf-tags-creator
[(tagNameControlVisible)]="tagNameControlVisible"
(tagsChange)="storeTagsToAssign($event)"
[mode]="tagsCreatorMode"
[tags]="assignedTags"
[disabledTagsRemoving]="saving">
</adf-tags-creator>
</div>
<div *ngIf="!tags.length && !editableTags" class="adf-metadata-no-tags-added">
{{ 'METADATA.BASIC.NO_TAGS_ADDED' | translate }}
</div>
<div *ngIf="editableTags" class="adf-metadata-properties-tags">
<adf-tags-creator [(tagNameControlVisible)]="tagNameControlVisible"
(tagsChange)="storeTagsToAssign($event)" [mode]="tagsCreatorMode" [tags]="assignedTags"
[disabledTagsRemoving]="saving">
</adf-tags-creator>
</div>
</mat-expansion-panel>
</ng-container>
<ng-container *ngIf="displayCategories">
<mat-expansion-panel *ngIf="!editable">
<mat-expansion-panel (opened)="categoriesPanelState = true" (closed)="categoriesPanelState = false"
hideToggle [expanded]="categoriesPanelState">
<mat-expansion-panel-header>
<mat-panel-title>{{ 'CATEGORIES_MANAGEMENT.CATEGORIES_TITLE' | translate }}</mat-panel-title>
</mat-expansion-panel-header>
<p *ngFor="let category of categories" class="adf-metadata-categories">{{ category.name }}</p>
</mat-expansion-panel>
<div *ngIf="editable"
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>
<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>
<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 class="adf-metadata-action-buttons" *ngIf="editableCategories">
<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-divider class="adf-mat-divider"></mat-divider>
<div *ngIf="!editableCategories">
<p *ngFor="let category of categories" class="adf-metadata-categories">{{ category.name }}</p>
</div>
<adf-categories-management
[(categoryNameControlVisible)]="categoryControlVisible"
[disableRemoval]="saving"
[categories]="categories"
[managementMode]="categoriesManagementMode"
[classifiableChanged]="classifiableChanged"
(categoriesChange)="storeCategoriesToAssign($event)">
</adf-categories-management>
</div>
<div *ngIf="!categories.length && !editableCategories" class="adf-metadata-no-catagories-added">
{{ 'CATEGORIES_MANAGEMENT.NO_CATEGORIES_ADDED' | translate }}
</div>
<div *ngIf="editableCategories" class="adf-metadata-categories-header">
<adf-categories-management [(categoryNameControlVisible)]="categoryControlVisible"
[disableRemoval]="saving" [categories]="categories" [managementMode]="categoriesManagementMode"
[classifiableChanged]="classifiableChanged"
(categoriesChange)="storeCategoriesToAssign($event)">
</adf-categories-management>
</div>
</mat-expansion-panel>
</ng-container>
<ng-container *ngIf="expanded">
<ng-container *ngIf="groupedProperties$ | async; else loading; let groupedProperties">
<div *ngFor="let group of groupedProperties; let first = first;"
class="adf-metadata-grouped-properties-container">
<mat-expansion-panel *ngIf="showGroup(group) || editable"
[attr.data-automation-id]="'adf-metadata-group-' + group.title"
[expanded]="canExpandTheCard(group) || !displayDefaultProperties && first">
<mat-expansion-panel-header>
<mat-panel-title>
<ng-container *ngIf="groupedProperties$ | async; else loading; let groupedProperties">
<div *ngFor="let group of groupedProperties; let first = first;"
class="adf-metadata-grouped-properties-container">
<mat-expansion-panel [attr.data-automation-id]="'adf-metadata-group-' + group.title"
[expanded]="group.expanded" (opened)="group.expanded= true" (closed)="group.expanded= false"
hideToggle>
<mat-expansion-panel-header>
<div class="adf-toggle-icons">
<mat-icon>
{{ group.expanded || aspectPanelstate ? 'expand_more' : 'chevron_right'}}</mat-icon>
<mat-panel-title class="adf-metadata-properties-title">
{{ group.title | translate }}
</mat-panel-title>
</mat-expansion-panel-header>
<adf-card-view
(keydown)="keyDown($event)"
[properties]="group.properties"
[editable]="editable"
[displayEmpty]="displayEmpty"
[copyToClipboardAction]="copyToClipboardAction"
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
[multiValueSeparator]="multiValueSeparator">
</adf-card-view>
</mat-expansion-panel>
</div>
</ng-container>
<ng-template #loading>
<mat-progress-bar mode="indeterminate" [attr.aria-label]="'DATA_LOADING' | translate">
</mat-progress-bar>
</ng-template>
</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-divider class="adf-mat-divider"></mat-divider>
<adf-card-view (keydown)="keyDown($event)" [properties]="group.properties"
[editable]="group.editable" [displayEmpty]="displayEmpty"
[copyToClipboardAction]="copyToClipboardAction"
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
[multiValueSeparator]="multiValueSeparator">
</adf-card-view>
</mat-expansion-panel>
</div>
</ng-container>
<ng-template #loading>
<mat-progress-bar mode="indeterminate" [attr.aria-label]="'DATA_LOADING' | translate">
</mat-progress-bar>
</ng-template>
</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>
@@ -1,37 +1,71 @@
.adf {
&-metadata-properties {
.mat-expansion-panel-header.mat-expanded:hover,
.mat-expansion-panel-header.mat-expanded:focus {
background: var(--adf-theme-background-hover-color);
}
.mat-expansion-panel {
border: 1px solid var(--adf-metadata-property-panel-border-color);
border-radius: 12px !important;
margin-bottom: 12px;
mat-expansion-panel-header {
height: 64px;
height: 56px;
.adf-metadata-properties-title {
font-weight: normal;
font-size: 15px;
padding-left: 12px;
}
}
}
.mat-expansion-panel:not([class*='mat-elevation-z']) {
box-shadow: none;
}
.adf-metadata-properties-tag {
height: 40px;
.adf-mat-divider {
margin-left: -24px;
margin-right: -24px;
}
.adf-edit-icon-buttons {
color: var(--adf-theme-foreground-text-color-054);
}
.adf-toggle-icons {
display: flex;
align-items: center;
margin-top: -14px;
margin-bottom: 1em;
flex: 1;
}
&:first-of-type {
margin-top: 5px;
}
.adf-metadata-properties-tag {
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 {
padding: 0 10px 0 26px;
&-title {
display: flex;
@@ -42,15 +76,9 @@
}
adf-tags-creator {
margin-top: 19px;
.adf-tags-creation {
padding-right: 0;
padding-left: 12px;
.adf-tag {
margin-top: -14px;
}
}
&.adf-creator-with-existing-tags-panel {
@@ -73,7 +101,7 @@
&-metadata-categories-header {
display: flex;
flex-direction: column;
padding: 0 24px;
padding-right: 24px;
.adf-metadata-categories-title {
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;
}
}
@@ -34,6 +34,9 @@ import { CardViewContentUpdateService } from '../../../common/services/card-view
import { PropertyGroup } from '../../interfaces/property-group.interface';
import { PropertyDescriptorsService } from '../../services/property-descriptors.service';
import { CategoriesManagementComponent, CategoriesManagementMode, CategoryService, TagsCreatorComponent, TagsCreatorMode, TagService } from '@alfresco/adf-content-services';
import { MatIconModule } from '@angular/material/icon';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatDividerModule } from '@angular/material/divider';
describe('ContentMetadataComponent', () => {
let component: ContentMetadataComponent;
@@ -104,7 +107,10 @@ describe('ContentMetadataComponent', () => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
ContentTestingModule,
MatIconModule,
MatExpansionModule,
MatDividerModule
],
providers: [
{
@@ -221,7 +227,7 @@ describe('ContentMetadataComponent', () => {
}));
it('should save changedProperties on save click', fakeAsync(async () => {
component.editable = true;
component.editableGeneralInfo = true;
const property = { key: 'properties.property-key', value: 'original-value' } as CardViewBaseItemModel;
const expectedNode = { ...node, name: 'some-modified-value' };
spyOn(nodesApiService, 'updateNode').and.returnValue(of(expectedNode));
@@ -231,15 +237,15 @@ describe('ContentMetadataComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
clickOnSave();
const mockEvent = new Event('click');
component.saveGeneralInfoChanges(mockEvent);
await fixture.whenStable();
expect(component.node).toEqual(expectedNode);
expect(nodesApiService.updateNode).toHaveBeenCalled();
}));
it('should call removeTag and assignTagsToNode on TagService on save click', fakeAsync( () => {
component.editable = true;
it('should call removeTag and assignTagsToNode on TagService on save click', () => {
component.editableTags = true;
component.displayTags = true;
const property = { key: 'properties.property-key', value: 'original-value' } as CardViewBaseItemModel;
const expectedNode = { ...node, name: 'some-modified-value' };
@@ -253,11 +259,11 @@ describe('ContentMetadataComponent', () => {
const tagName2 = 'New tag 3';
updateService.update(property, 'updated-value');
tick(600);
fixture.detectChanges();
findTagsCreator().tagsChange.emit([tagName1, tagName2]);
clickOnSave();
const mockEvent = new Event('click');
component.saveTagsChanges(mockEvent);
const tag1 = new TagBody();
tag1.tag = tagName1;
@@ -265,10 +271,10 @@ describe('ContentMetadataComponent', () => {
tag2.tag = tagName2;
expect(tagService.removeTag).toHaveBeenCalledWith(node.id, tagPaging.list.entries[1].entry.id);
expect(tagService.assignTagsToNode).toHaveBeenCalledWith(node.id, [tag1, tag2]);
}));
});
it('should call getTagsByNodeId on TagService on save click', fakeAsync( () => {
component.editable = true;
it('should call getTagsByNodeId on TagService on save click', () => {
component.editableTags = true;
component.displayTags = true;
const property = { key: 'properties.property-key', value: 'original-value' } as CardViewBaseItemModel;
const expectedNode = { ...node, name: 'some-modified-value' };
@@ -280,15 +286,15 @@ describe('ContentMetadataComponent', () => {
spyOn(tagService, 'assignTagsToNode').and.returnValue(of({}));
updateService.update(property, 'updated-value');
tick(600);
fixture.detectChanges();
findTagsCreator().tagsChange.emit([tagPaging.list.entries[0].entry.tag, 'New tag 3']);
getTagsByNodeIdSpy.calls.reset();
clickOnSave();
const mockEvent = new Event('click');
component.saveTagsChanges(mockEvent);
expect(tagService.getTagsByNodeId).toHaveBeenCalledWith(node.id);
}));
});
it('should throw error on unsuccessful save', fakeAsync(() => {
const logService: LogService = TestBed.inject(LogService);
@@ -313,7 +319,7 @@ describe('ContentMetadataComponent', () => {
}));
it('should open the confirm dialog when content type is changed', fakeAsync(() => {
component.editable = true;
component.editableGeneralInfo = true;
const property = { key: 'nodeType', value: 'ft:sbiruli' } as CardViewBaseItemModel;
const expectedNode = { ...node, nodeType: 'ft:sbiruli' };
spyOn(contentMetadataService, 'openConfirmDialog').and.returnValue(of(true));
@@ -324,8 +330,8 @@ describe('ContentMetadataComponent', () => {
fixture.detectChanges();
tick(100);
clickOnSave();
const mockEvent = new Event('click');
component.saveGeneralInfoChanges(mockEvent);
tick(100);
expect(component.node).toEqual(expectedNode);
expect(contentMetadataService.openConfirmDialog).toHaveBeenCalledWith({nodeType: 'ft:poppoli'});
@@ -333,8 +339,8 @@ describe('ContentMetadataComponent', () => {
discardPeriodicTasks();
}));
it('should call removeTag and assignTagsToNode on TagService after confirming confirmation dialog when content type is changed', fakeAsync(() => {
component.editable = true;
it('should call removeTag and assignTagsToNode on TagService after confirming confirmation dialog when content type is changed',() => {
component.editableTags = true;
component.displayTags = true;
const property = { key: 'nodeType', value: 'ft:sbiruli' } as CardViewBaseItemModel;
const expectedNode = { ...node, nodeType: 'ft:sbiruli' };
@@ -349,25 +355,23 @@ describe('ContentMetadataComponent', () => {
const tagName2 = 'New tag 3';
updateService.update(property, 'ft:poppoli');
tick(600);
fixture.detectChanges();
findTagsCreator().tagsChange.emit([tagName1, tagName2]);
tick(100);
fixture.detectChanges();
clickOnSave();
const mockEvent = new Event('click');
component.saveTagsChanges(mockEvent);
tick(100);
const tag1 = new TagBody();
tag1.tag = tagName1;
const tag2 = new TagBody();
tag2.tag = tagName2;
expect(tagService.removeTag).toHaveBeenCalledWith(node.id, tagPaging.list.entries[1].entry.id);
expect(tagService.assignTagsToNode).toHaveBeenCalledWith(node.id, [tag1, tag2]);
}));
});
it('should retrigger the load of the properties when the content type has changed', fakeAsync(() => {
component.editable = true;
component.editableGeneralInfo = true;
const property = { key: 'nodeType', value: 'ft:sbiruli' } as CardViewBaseItemModel;
const expectedNode = Object.assign({}, node, { nodeType: 'ft:sbiruli' });
spyOn(contentMetadataService, 'openConfirmDialog').and.returnValue(of(true));
@@ -379,14 +383,137 @@ describe('ContentMetadataComponent', () => {
fixture.detectChanges();
tick(100);
clickOnSave();
const mockEvent = new Event('click');
component.saveGeneralInfoChanges(mockEvent);
tick(100);
expect(component.node).toEqual(expectedNode);
expect(updateService.updateNodeAspect).toHaveBeenCalledWith(expectedNode);
}));
it('should save general info changes and toggle editableGeneralInfo', () => {
const event = new Event('click');
spyOn(component, 'saveChanges');
component.editableGeneralInfo = true;
component.saveGeneralInfoChanges(event);
expect(component.saveChanges).toHaveBeenCalledWith(event);
expect(component.editableGeneralInfo).toBe(false);
});
it('should save group changes and set group editable to false', () => {
const group = { editable: true };
const event = new Event('click');
spyOn(component, 'saveChanges');
component.saveGroupChanges(group, event);
expect(component.saveChanges).toHaveBeenCalledWith(event);
expect(group.editable).toBe(false);
});
});
describe('cancelChanges', () => {
it('should cancel group changes and set group editable to false', () => {
const group = { editable: true };
const event = new Event('click');
spyOn(component, 'cancelChanges');
component.cancelGroupChanges(group, event);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(group.editable).toBe(false);
});
it('should cancel general info changes and toggle editableGeneralInfo', () => {
const event = new Event('click');
spyOn(component, 'cancelChanges');
component.editableGeneralInfo = true;
component.cancelGeneralInfoChanges(event);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(component.editableGeneralInfo).toBe(false);
});
it('should cancel tags changes and toggle editableTags', () => {
const event = new Event('click');
spyOn(component, 'cancelChanges');
component.editableTags = true;
component.CancelTagsChanges(event);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(component.editableTags).toBe(false);
});
it('should cancel categories changes and toggle editableCategories', () => {
const event = new Event('click');
spyOn(component, 'cancelChanges');
component.editableCategories = true;
component.cancelCategoriesChanges(event);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(component.editableCategories).toBe(false);
});
})
describe('editing', () => {
it('should toggle categories edit and set categoriesPanelState accordingly', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
component.editableCategories = false;
component.categoriesPanelState = false;
component.toggleCategoriesEdit(event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(component.editableCategories).toBe(true);
expect(component.categoriesPanelState).toBe(true);
component.toggleCategoriesEdit(event);
expect(component.editableCategories).toBe(false);
expect(component.categoriesPanelState).toBe(false);
});
it('should toggle group edit and expand the panel if editable', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
const group = { editable: false };
component.expandePanel = jasmine.createSpy();
component.toggleEdit(group, event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(group.editable).toBe(true);
expect(component.expandePanel).toHaveBeenCalledWith(group);
});
it('should toggle group edit but not expand the panel if not editable', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
const group = { editable: true };
component.expandePanel = jasmine.createSpy();
component.toggleEdit(group, event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(group.editable).toBe(false);
expect(component.expandePanel).not.toHaveBeenCalled();
});
it('should toggle general info edit and set generalInfoPanelState accordingly', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
component.generalInfoPanelState = true;
component.editableGeneralInfo = false;
component.toggleGeneralEdit(event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(component.editableGeneralInfo).toBe(true);
expect(component.generalInfoPanelState).toBe(true);
component.toggleGeneralEdit(event);
expect(component.editableGeneralInfo).toBe(false);
expect(component.generalInfoPanelState).toBe(true);
});
it('should toggle tags edit and set tagsPanelState accordingly', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
component.editableTags = false;
component.tagsPanelState = false;
component.toggleTagsEdit(event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(component.editableTags).toBe(true);
expect(component.tagsPanelState).toBe(true);
component.toggleTagsEdit(event);
expect(component.editableTags).toBe(false);
expect(component.tagsPanelState).toBe(false);
});
})
describe('Reseting', () => {
it('should reset changedProperties on reset click', async () => {
component.changedProperties = { properties: { 'property-key': 'updated-value' } };
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
import { Category, CategoryEntry, CategoryLinkBody, CategoryPaging, Node, TagBody, TagEntry, TagPaging } from '@alfresco/js-api';
import { Observable, Subject, of, zip, forkJoin } from 'rxjs';
import {
@@ -35,6 +35,7 @@ import { TagsCreatorMode } from '../../../tag/tags-creator/tags-creator-mode';
import { TagService } from '../../../tag/services/tag.service';
import { CategoryService } from '../../../category/services/category.service';
import { CategoriesManagementMode } from '../../../category/categories-management/categories-management-mode';
import { MatExpansionPanel } from '@angular/material/expansion';
const DEFAULT_SEPARATOR = ', ';
@@ -46,6 +47,7 @@ const DEFAULT_SEPARATOR = ', ';
encapsulation: ViewEncapsulation.None
})
export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
@ViewChild(MatExpansionPanel) panel: MatExpansionPanel;
protected onDestroy$ = new Subject<boolean>();
/** (required) The node entity to fetch metadata about */
@@ -126,6 +128,13 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
categoriesManagementMode = CategoriesManagementMode.ASSIGN;
categoryControlVisible = false;
classifiableChanged = this.classifiableChangedSubject.asObservable();
generalInfoPanelState: boolean;
editableGeneralInfo: boolean;
tagsPanelState: boolean;
editableTags: boolean = false;
categoriesPanelState: boolean;
editableCategories: boolean = false;
aspectPanelstate: boolean = false;
constructor(
private contentMetadataService: ContentMetadataService,
@@ -229,10 +238,10 @@ 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.
* Before clicking on that button they are not saved.
*/
saveChanges() {
saveChanges(event: Event) {
event.stopPropagation();
this._saving = true;
this.tagNameControlVisible = false;
this.categoryControlVisible = false;
if (this.hasContentTypeChanged(this.changedProperties)) {
this.contentMetadataService.openConfirmDialog(this.changedProperties).subscribe(() => {
this.updateNode();
@@ -242,6 +251,29 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
}
}
saveGroupChanges(group: any, event: Event) {
this.saveChanges(event);
group.editable = !group.editable;
}
saveGeneralInfoChanges(event: Event) {
this.saveChanges(event);
this.editableGeneralInfo = !this.editableGeneralInfo;
}
saveTagsChanges(event: Event) {
this.saveChanges(event);
this.tagNameControlVisible = false;
this.editableTags = !this.editableTags;
}
saveCategoriesChanges(event: Event) {
this.saveChanges(event);
this.categoryControlVisible = false;
this.editableCategories = !this.editableCategories;
}
/**
* 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.
@@ -269,11 +301,32 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
this.hasMetadataChanged = false;
}
cancelChanges() {
cancelChanges(event: Event) {
event.stopPropagation();
this.revertChanges();
this.loadProperties(this.node);
}
cancelGroupChanges(group: any, event: Event) {
this.cancelChanges(event);
group.editable = !group.editable;
}
cancelGeneralInfoChanges(event: Event) {
this.cancelChanges(event);
this.editableGeneralInfo = !this.editableGeneralInfo;
}
CancelTagsChanges(event: Event) {
this.cancelChanges(event);
this.editableTags = !this.editableTags;
}
cancelCategoriesChanges(event: Event) {
this.cancelChanges(event);
this.editableCategories = !this.editableCategories;
}
showGroup(group: CardViewGroup): boolean {
const properties = group.properties.filter((property) => !this.isEmpty(property.displayValue));
@@ -284,10 +337,6 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
return group.title === this.displayAspect;
}
canExpandProperties(): boolean {
return !this.expanded || this.displayAspect === 'Properties';
}
keyDown(event: KeyboardEvent) {
if (event.keyCode === 37 || event.keyCode === 39) { // ArrowLeft && ArrowRight
event.stopPropagation();
@@ -420,4 +469,51 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
}
return observables;
}
toggleGeneralEdit(event: Event): void {
event.stopPropagation();
this.editableGeneralInfo = !this.editableGeneralInfo;
if (!this.panel.expanded) {
this.panel.open();
}
}
toggleTagsEdit(event: Event): void {
event.stopPropagation();
this.editableTags = !this.editableTags;
if (this.editableTags) {
this.tagsPanelState = true;
} else {
this.tagsPanelState = false;
}
}
toggleCategoriesEdit(event: Event): void {
event.stopPropagation();
this.editableCategories = !this.editableCategories;
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) {
this.expandePanel(group);
}
}
expandePanel(group: any) {
group.expanded = true;
}
onPanelOpened(group: any): void {
group.aspectPanelstate = true;
}
onPanelClosed(group: any): void {
group.aspectPanelstate = false;
}
}
@@ -25,6 +25,7 @@ export const mockGroupProperties = [
key: 'properties.exif:pixelXDimension',
default: null,
editable: true,
editableTags: true,
clickable: false,
icon: '',
data: null,
@@ -40,6 +41,7 @@ export const mockGroupProperties = [
key: 'properties.exif:pixelYDimension',
default: null,
editable: true,
editableTags: true,
clickable: false,
icon: '',
data: null,
@@ -49,7 +51,9 @@ export const mockGroupProperties = [
clickCallBack: null,
displayValue: 400
}
]
],
editable: true,
expanded: true,
},
{
title: 'CUSTOM',
@@ -60,6 +64,7 @@ export const mockGroupProperties = [
key: 'properties.custom:abc',
default: null,
editable: true,
editableTags: true,
clickable: false,
icon: '',
data: null,
@@ -69,6 +74,8 @@ export const mockGroupProperties = [
clickCallBack: null,
displayValue: 400
}
]
],
editable: true,
expanded: true,
}
];
@@ -20,4 +20,6 @@ import { CardViewItem } from '@alfresco/adf-core';
export interface CardViewGroup {
title: string;
properties: CardViewItem[];
editable: boolean;
expanded: boolean;
}
+6 -1
View File
@@ -149,6 +149,7 @@
"TITLE": "Create Tags",
"CREATE_TAG": "Create: {{tag}}",
"NAME": "Name",
"INPUT_PLACEHOLDER": "Add a tag to these items",
"ERRORS": {
"EXISTING_TAG": "Tag already exists",
"ALREADY_ADDED_TAG": "Tag is already added",
@@ -179,6 +180,8 @@
"NAME": "Category name",
"LOADING": "Loading",
"HIDE_INPUT": "Hide input",
"INPUT_PLACEHOLDER": "Add a categories to these items",
"NO_CATEGORIES_ADDED": "There are currently no categories added",
"ERRORS": {
"NOT_FOUND": "Categories not found",
"REQUIRED": "Category name is required",
@@ -487,7 +490,9 @@
"MODIFIED_DATE": "Modified Date",
"CONTENT_TYPE": "Content Type",
"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": {
"DIALOG" :{
@@ -1,14 +1,28 @@
<div class="adf-tags-creation">
<p
class="adf-no-tags-message"
*ngIf="!tags.length && !tagNameControlVisible">
<div class="adf-tag-name-field">
<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>
<p
class="adf-no-tags-message"
*ngIf="!tags.length && !tagNameControlVisible">
{{ 'TAG.TAGS_CREATOR.NO_TAGS_CREATED' | translate }}
</p>
<div
class="adf-tags-list"
[class.adf-tags-list-fixed]="!tagNameControlVisible"
#tagsList>
<p
<span
*ngFor="let tag of tags"
class="adf-tag adf-label-with-icon-button">
{{ tag }}
@@ -17,38 +31,11 @@
mat-icon-button
(click)="removeTag(tag)"
[attr.title]="'TAG.TAGS_CREATOR.TOOLTIPS.DELETE_TAG' | translate"
[disabled]="disabledTagsRemoving">
<mat-icon>remove</mat-icon>
[disabled]="disabledTagsRemoving"
class="adf-remove-tag">
<mat-icon>close</mat-icon>
</button>
</p>
</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>
</span>
</div>
</div>
<div
@@ -1,11 +1,22 @@
adf-tags-creator {
display: block;
margin-left: -24px;
.adf-label-with-icon-button {
display: flex;
justify-content: space-between;
background: var(--adf-metadata-tags-background-color);
width: fit-content;
height: 32px;
display: inline-flex;
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;
}
}
.adf-no-tags-message {
@@ -29,6 +40,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 {
color: var(--theme-primary-color);
cursor: pointer;
@@ -37,30 +58,23 @@ adf-tags-creator {
overflow-wrap: anywhere;
display: inline-block;
padding-right: 12px;
overflow: auto;
max-height: 7vh;
}
.adf-tags-list {
padding-left: 10px;
padding-right: 0;
overflow: auto;
}
.adf-tag {
margin-top: 0;
overflow-wrap: anywhere;
& + .adf-tag {
margin-top: -14px;
&+.adf-tag {
margin-top: 8px;
margin-left: 8px;
}
}
.adf-tags-creation {
padding-left: 27px;
padding-right: 22px;
}
.adf-existing-tags-panel {
border-top-left-radius: 6px;
border-top-right-radius: 6px;
@@ -3,7 +3,7 @@
<div [attr.data-automation-id]="'header-'+property.key" class="adf-property">
<adf-card-view-item-dispatcher
[property]="property"
[editable]="editable"
[editable]="editable || editableGeneralInfo"
[displayEmpty]="displayEmpty"
[displayNoneOption]="property['displayNoneOption'] !== undefined ? property['displayNoneOption'] : displayNoneOption"
[displayClearAction]="displayClearAction"
@@ -34,6 +34,9 @@ export class CardViewComponent {
@Input()
editable: boolean;
@Input()
editableGeneralInfo: boolean;
/** Toggles whether or not to show empty items in non-editable mode. */
@Input()
displayEmpty: boolean = true;
@@ -23,6 +23,7 @@ export interface CardViewItemProperties {
key: any;
default?: any;
editable?: boolean;
editableGeneralInfo?: boolean;
clickable?: any;
icon?: string;
hint?: string;
@@ -23,5 +23,6 @@ export interface CardViewItem {
type: string;
displayValue: any;
editable?: boolean;
editableGeneralInfo?: boolean;
icon?: string;
}
@@ -24,6 +24,7 @@ export abstract class CardViewBaseItemModel {
key: any;
default: any;
editable: boolean;
editableGeneralInfo: boolean;
clickable: boolean;
icon?: string;
hint?: string;
@@ -38,6 +39,7 @@ export abstract class CardViewBaseItemModel {
this.key = cardViewItemProperties.key;
this.default = cardViewItemProperties.default;
this.editable = !!cardViewItemProperties.editable;
this.editableGeneralInfo = !!cardViewItemProperties.editableGeneralInfo;
this.clickable = !!cardViewItemProperties.clickable;
this.icon = cardViewItemProperties.icon || '';
this.hint = cardViewItemProperties.hint || '';
@@ -45,6 +45,8 @@
--adf-identity-user-info-line-height: $adf-ref-line-height,
--adf-identity-user-info-font-size: var(--theme-adf-picture-1-font-size),
--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
@@ -27,3 +27,5 @@ $adf-ref-height: 40px;
$adf-ref-width: 40px;
$adf-ref-line-height: 40px;
$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);