refactor: simplify panel state management and enhance template syntax in content metadata component

- Replaced inline conditional checks with dedicated methods for panel expansion and editing states.
- Updated template syntax to improve readability and maintainability using @if syntax.
- Removed unused CommonModule import and added AsyncPipe for better performance.
This commit is contained in:
Denys Vuika
2026-02-27 13:05:52 +00:00
parent 24a7e55b68
commit 8b4324cfec
2 changed files with 198 additions and 172 deletions
@@ -1,66 +1,72 @@
@let isExpandedProperties = (currentPanel.panelTitle === DefaultPanels.PROPERTIES && currentPanel.expanded) ?? false; @let isExpandedProperties = isPanelExpanded(DefaultPanels.PROPERTIES);
@let isExpandedTags = (currentPanel.panelTitle === DefaultPanels.TAGS && currentPanel.expanded) ?? false; @let isExpandedTags = isPanelExpanded(DefaultPanels.TAGS);
@let isExpandedCategories = (currentPanel.panelTitle === DefaultPanels.CATEGORIES && currentPanel.expanded) ?? false; @let isExpandedCategories = isPanelExpanded(DefaultPanels.CATEGORIES);
@let isEditingTags = isPanelEditing(DefaultPanels.TAGS);
@let isEditingCategories = isPanelEditing(DefaultPanels.CATEGORIES);
@let isEditingProperties = isPanelEditing(DefaultPanels.PROPERTIES);
<mat-accordion displayMode="flat" [multi]="multi" class="adf-metadata-properties"> <mat-accordion displayMode="flat" [multi]="multi" class="adf-metadata-properties">
<mat-expansion-panel @if (displayDefaultProperties) {
*ngIf="displayDefaultProperties" <mat-expansion-panel
class="adf-content-metadata-panel" class="adf-content-metadata-panel"
[expanded]="isExpandedProperties" [expanded]="isExpandedProperties"
(opened)="expandPanel(DefaultPanels.PROPERTIES)" (opened)="expandPanel(DefaultPanels.PROPERTIES)"
(closed)="closePanel(DefaultPanels.PROPERTIES)" (closed)="closePanel(DefaultPanels.PROPERTIES)"
[attr.data-automation-id]="'adf-metadata-group-properties'" [attr.data-automation-id]="'adf-metadata-group-properties'"
hideToggle> hideToggle>
<mat-expansion-panel-header <mat-expansion-panel-header
class="adf-metadata-properties-header" class="adf-metadata-properties-header"
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.SECTION' | translate: { sectionName: ('CORE.METADATA.BASIC.HEADER' | translate) }" [attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.SECTION' | translate: { sectionName: ('CORE.METADATA.BASIC.HEADER' | translate) }"
[class.adf-metadata-properties-header-expanded]="isExpandedProperties"> [class.adf-metadata-properties-header-expanded]="isExpandedProperties">
<adf-content-metadata-header <adf-content-metadata-header
[title]="'CORE.METADATA.BASIC.HEADER'" [title]="'CORE.METADATA.BASIC.HEADER'"
[expanded]="isExpandedProperties"> [expanded]="isExpandedProperties">
<button @if (!readOnly && !isEditingProperties) {
*ngIf="!readOnly && !isPanelEditing(DefaultPanels.PROPERTIES)" <button
mat-icon-button mat-icon-button
(click)="toggleGroupEditing(DefaultPanels.PROPERTIES, $event)" (click)="toggleGroupEditing(DefaultPanels.PROPERTIES, $event)"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate" [attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate: { sectionName: ('CORE.METADATA.BASIC.HEADER' | translate) }" [attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate: { sectionName: ('CORE.METADATA.BASIC.HEADER' | translate) }"
data-automation-id="meta-data-general-info-edit" data-automation-id="meta-data-general-info-edit"
class="adf-edit-icon-buttons"> class="adf-edit-icon-buttons">
<mat-icon adf-icon="mode_edit" /> <mat-icon adf-icon="mode_edit" />
</button> </button>
<div *ngIf="isPanelEditing(DefaultPanels.PROPERTIES)" class="adf-metadata-action-buttons"> }
<button @if (isEditingProperties) {
mat-icon-button <div class="adf-metadata-action-buttons">
[attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate" <button
(click)="cancelGroupEditing(DefaultPanels.PROPERTIES, $event)" mat-icon-button
data-automation-id="reset-metadata" [attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate"
class="adf-metadata-action-buttons-clear"> (click)="cancelGroupEditing(DefaultPanels.PROPERTIES, $event)"
<mat-icon adf-icon="clear" /> data-automation-id="reset-metadata"
</button> class="adf-metadata-action-buttons-clear">
<button <mat-icon adf-icon="clear" />
mat-icon-button </button>
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate" <button
(click)="saveChanges($event)" mat-icon-button
color="primary" [attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate"
data-automation-id="save-general-info-metadata" (click)="saveChanges($event)"
[disabled]="!hasMetadataChanged || invalidProperties.size > 0"> color="primary"
<mat-icon adf-icon="check" /> data-automation-id="save-general-info-metadata"
</button> [disabled]="!hasMetadataChanged || invalidProperties.size > 0">
</div> <mat-icon adf-icon="check" />
</adf-content-metadata-header> </button>
</mat-expansion-panel-header> </div>
<adf-card-view }
class="adf-metadata-properties-expansion-panel" </adf-content-metadata-header>
(keydown)="keyDown($event)" </mat-expansion-panel-header>
[properties]="(basicProperties$ | async) ?? []" <adf-card-view
[editable]="!readOnly && isPanelEditing(DefaultPanels.PROPERTIES)" class="adf-metadata-properties-expansion-panel"
[displayEmpty]="displayEmpty" (keydown)="keyDown($event)"
[copyToClipboardAction]="copyToClipboardAction" [properties]="(basicProperties$ | async) ?? []"
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty" [editable]="!readOnly && isEditingProperties"
[multiValueSeparator]="multiValueSeparator" /> [displayEmpty]="displayEmpty"
</mat-expansion-panel> [copyToClipboardAction]="copyToClipboardAction"
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
<ng-container *ngIf="displayTags"> [multiValueSeparator]="multiValueSeparator" />
</mat-expansion-panel>
}
@if (displayTags) {
<mat-expansion-panel <mat-expansion-panel
hideToggle hideToggle
[expanded]="isExpandedTags" [expanded]="isExpandedTags"
@@ -73,56 +79,63 @@
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.SECTION' | translate: { sectionName: ('METADATA.BASIC.TAGS' | translate) }" [attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.SECTION' | translate: { sectionName: ('METADATA.BASIC.TAGS' | translate) }"
[class.adf-metadata-properties-header-expanded]="isExpandedTags"> [class.adf-metadata-properties-header-expanded]="isExpandedTags">
<adf-content-metadata-header [title]="'METADATA.BASIC.TAGS'" [expanded]="isExpandedTags"> <adf-content-metadata-header [title]="'METADATA.BASIC.TAGS'" [expanded]="isExpandedTags">
<button @if (!readOnly && !isEditingTags) {
*ngIf="!readOnly && !isPanelEditing(DefaultPanels.TAGS)"
mat-icon-button
(click)="toggleGroupEditing(DefaultPanels.TAGS, $event)"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate: { sectionName: ('METADATA.BASIC.TAGS' | translate) }"
data-automation-id="showing-tag-input-button"
class="adf-edit-icon-buttons">
<mat-icon adf-icon="mode_edit" />
</button>
<div *ngIf="isPanelEditing(DefaultPanels.TAGS)" class="adf-metadata-action-buttons">
<button <button
mat-icon-button mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate" (click)="toggleGroupEditing(DefaultPanels.TAGS, $event)"
(click)="cancelGroupEditing(DefaultPanels.TAGS, $event)" [attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
data-automation-id="reset-tags-metadata" [attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate: { sectionName: ('METADATA.BASIC.TAGS' | translate) }"
class="adf-metadata-action-buttons-clear"> data-automation-id="showing-tag-input-button"
<mat-icon adf-icon="clear" /> class="adf-edit-icon-buttons">
<mat-icon adf-icon="mode_edit" />
</button> </button>
<button }
mat-icon-button @if (isEditingTags) {
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate" <div class="adf-metadata-action-buttons">
(click)="saveChanges($event)" <button
color="primary" mat-icon-button
data-automation-id="save-tags-metadata" [attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate"
[disabled]="!hasMetadataChanged"> (click)="cancelGroupEditing(DefaultPanels.TAGS, $event)"
<mat-icon adf-icon="check" /> data-automation-id="reset-tags-metadata"
</button> class="adf-metadata-action-buttons-clear">
</div> <mat-icon adf-icon="clear" />
</button>
<button
mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate"
(click)="saveChanges($event)"
color="primary"
data-automation-id="save-tags-metadata"
[disabled]="!hasMetadataChanged">
<mat-icon adf-icon="check" />
</button>
</div>
}
</adf-content-metadata-header> </adf-content-metadata-header>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<div *ngIf="currentPanel.panelTitle === DefaultPanels.TAGS && editedPanelTitle !== DefaultPanels.TAGS" @if (!isEditingTags) {
class="adf-metadata-properties-tags"> <div class="adf-metadata-properties-tags">
<adf-dynamic-chip-list [chips]="tagsToDisplay" [showDelete]="false" /> <adf-dynamic-chip-list [chips]="tagsToDisplay" [showDelete]="false" />
</div> </div>
<div *ngIf="showEmptyTagMessage" class="adf-metadata-no-item-added"> }
{{ 'METADATA.BASIC.NO_TAGS_ADDED' | translate }} @if (showEmptyTagMessage) {
</div> <div class="adf-metadata-no-item-added">
<adf-tags-creator {{ 'METADATA.BASIC.NO_TAGS_ADDED' | translate }}
*ngIf="!readOnly && isPanelEditing(DefaultPanels.TAGS)" </div>
class="adf-metadata-properties-tags" }
[tagNameControlVisible]="editing" @if (!readOnly && isEditingTags) {
(tagsChange)="storeTagsToAssign($event)" <adf-tags-creator
[mode]="tagsCreatorMode" class="adf-metadata-properties-tags"
[tags]="assignedTags" [tagNameControlVisible]="editing"
[disabledTagsRemoving]="saving" /> (tagsChange)="storeTagsToAssign($event)"
[mode]="tagsCreatorMode"
[tags]="assignedTags"
[disabledTagsRemoving]="saving" />
}
</mat-expansion-panel> </mat-expansion-panel>
</ng-container> }
<ng-container *ngIf="displayCategories"> @if (displayCategories) {
<mat-expansion-panel <mat-expansion-panel
hideToggle hideToggle
[expanded]="isExpandedCategories" [expanded]="isExpandedCategories"
@@ -137,38 +150,41 @@
<adf-content-metadata-header <adf-content-metadata-header
[title]="'CATEGORIES_MANAGEMENT.CATEGORIES_TITLE'" [title]="'CATEGORIES_MANAGEMENT.CATEGORIES_TITLE'"
[expanded]="isExpandedCategories"> [expanded]="isExpandedCategories">
<button @if (!readOnly && !isEditingCategories) {
*ngIf="!readOnly && !isPanelEditing(DefaultPanels.CATEGORIES)"
mat-icon-button
(click)="toggleGroupEditing(DefaultPanels.CATEGORIES, $event)"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate: { sectionName: ('CATEGORIES_MANAGEMENT.CATEGORIES_TITLE' | translate) }"
data-automation-id="meta-data-categories-edit"
class="adf-categories-button adf-edit-icon-buttons">
<mat-icon adf-icon="mode_edit" />
</button>
<div *ngIf="isPanelEditing(DefaultPanels.CATEGORIES)" class="adf-metadata-action-buttons">
<button <button
mat-icon-button mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate" (click)="toggleGroupEditing(DefaultPanels.CATEGORIES, $event)"
(click)="cancelGroupEditing(DefaultPanels.CATEGORIES, $event)" [attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
data-automation-id="reset-metadata" [attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate: { sectionName: ('CATEGORIES_MANAGEMENT.CATEGORIES_TITLE' | translate) }"
class="adf-metadata-action-buttons-clear"> data-automation-id="meta-data-categories-edit"
<mat-icon adf-icon="clear" /> class="adf-categories-button adf-edit-icon-buttons">
<mat-icon adf-icon="mode_edit" />
</button> </button>
<button }
mat-icon-button @if (isEditingCategories) {
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate" <div class="adf-metadata-action-buttons">
(click)="saveChanges($event)" <button
color="primary" mat-icon-button
data-automation-id="save-categories-metadata" [attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate"
[disabled]="!hasMetadataChanged"> (click)="cancelGroupEditing(DefaultPanels.CATEGORIES, $event)"
<mat-icon adf-icon="check" /> data-automation-id="reset-metadata"
</button> class="adf-metadata-action-buttons-clear">
</div> <mat-icon adf-icon="clear" />
</button>
<button
mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate"
(click)="saveChanges($event)"
color="primary"
data-automation-id="save-categories-metadata"
[disabled]="!hasMetadataChanged">
<mat-icon adf-icon="check" />
</button>
</div>
}
</adf-content-metadata-header> </adf-content-metadata-header>
</mat-expansion-panel-header> </mat-expansion-panel-header>
@if (currentPanel.panelTitle === DefaultPanels.CATEGORIES && editedPanelTitle !== DefaultPanels.CATEGORIES) { @if (!isEditingCategories) {
<div> <div>
@for (category of categories; track category.id) { @for (category of categories; track category.id) {
<p class="adf-metadata-categories">{{ category.name }}</p> <p class="adf-metadata-categories">{{ category.name }}</p>
@@ -180,17 +196,18 @@
{{ 'CATEGORIES_MANAGEMENT.NO_CATEGORIES_ADDED' | translate }} {{ 'CATEGORIES_MANAGEMENT.NO_CATEGORIES_ADDED' | translate }}
</div> </div>
} }
<adf-categories-management @if (!readOnly && isEditingCategories) {
*ngIf="!readOnly && isPanelEditing(DefaultPanels.CATEGORIES)" <adf-categories-management
class="adf-metadata-categories-header" class="adf-metadata-categories-header"
[categoryNameControlVisible]="editing" [categoryNameControlVisible]="editing"
[disableRemoval]="saving" [disableRemoval]="saving"
[categories]="categories" [categories]="categories"
[managementMode]="categoriesManagementMode" [managementMode]="categoriesManagementMode"
[classifiableChanged]="classifiableChanged" [classifiableChanged]="classifiableChanged"
(categoriesChange)="storeCategoriesToAssign($event)" /> (categoriesChange)="storeCategoriesToAssign($event)" />
}
</mat-expansion-panel> </mat-expansion-panel>
</ng-container> }
@for (customPanel of customPanels; track customPanel.panelTitle) { @for (customPanel of customPanels; track customPanel.panelTitle) {
@let isExpandedCustomPanel = (currentPanel.panelTitle === customPanel.panelTitle && currentPanel.expanded) ?? false; @let isExpandedCustomPanel = (currentPanel.panelTitle === customPanel.panelTitle && currentPanel.expanded) ?? false;
@@ -232,40 +249,45 @@
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.SECTION' | translate: { sectionName: (group.title | translate) }" [attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.SECTION' | translate: { sectionName: (group.title | translate) }"
[class.adf-metadata-properties-header-expanded]="isExpandedGroup"> [class.adf-metadata-properties-header-expanded]="isExpandedGroup">
<adf-content-metadata-header [title]="group.title" [expanded]="isExpandedGroup"> <adf-content-metadata-header [title]="group.title" [expanded]="isExpandedGroup">
<button @if (group.editable && !this.readOnly && !isPanelEditing(group.title)) {
*ngIf="group.editable && !this.readOnly && !isPanelEditing(group.title)"
mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate: { sectionName: (group.title | translate) }"
data-automation-id="meta-data-card-toggle-edit"
class="adf-edit-icon-buttons"
(click)="toggleGroupEditing(group.title, $event)">
<mat-icon adf-icon="mode_edit" />
</button>
<div class="adf-metadata-action-buttons" *ngIf="group.editable && isPanelEditing(group.title)">
<button <button
mat-icon-button mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate" [attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
(click)="cancelGroupEditing(group.title, $event)" [attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate: { sectionName: (group.title | translate) }"
data-automation-id="reset-metadata" data-automation-id="meta-data-card-toggle-edit"
class="adf-metadata-action-buttons-clear"> class="adf-edit-icon-buttons"
<mat-icon adf-icon="clear" /> (click)="toggleGroupEditing(group.title, $event)">
<mat-icon adf-icon="mode_edit" />
</button> </button>
<button }
mat-icon-button @if (group.editable && isPanelEditing(group.title)) {
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate" <div class="adf-metadata-action-buttons">
(click)="saveChanges($event)" <button
color="primary" mat-icon-button
data-automation-id="save-metadata" [attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate"
[disabled]="!hasMetadataChanged || invalidProperties.size > 0"> (click)="cancelGroupEditing(group.title, $event)"
<mat-icon adf-icon="check" /> data-automation-id="reset-metadata"
</button> class="adf-metadata-action-buttons-clear">
</div> <mat-icon adf-icon="clear" />
</button>
<button
mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate"
(click)="saveChanges($event)"
color="primary"
data-automation-id="save-metadata"
[disabled]="!hasMetadataChanged || invalidProperties.size > 0">
<mat-icon adf-icon="check" />
</button>
</div>
}
</adf-content-metadata-header> </adf-content-metadata-header>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<div *ngIf="!showGroup(group) && !displayEmpty && group.editable && editedPanelTitle !== group.title" class="adf-metadata-no-item-added"> @if (!showGroup(group) && !displayEmpty && group.editable && editedPanelTitle !== group.title) {
{{ 'METADATA.BASIC.NO_ITEMS_MESSAGE' | translate : { groupTitle: group.title | translate } }} <div class="adf-metadata-no-item-added">
</div> {{ 'METADATA.BASIC.NO_ITEMS_MESSAGE' | translate : { groupTitle: group.title | translate } }}
</div>
}
<adf-card-view <adf-card-view
class="adf-metadata-properties-expansion-panel" class="adf-metadata-properties-expansion-panel"
(keydown)="keyDown($event)" (keydown)="keyDown($event)"
@@ -41,7 +41,6 @@ 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 { AllowableOperationsEnum } from '../../../common/models/allowable-operations.enum'; import { AllowableOperationsEnum } from '../../../common/models/allowable-operations.enum';
import { ContentService } from '../../../common/services/content.service'; import { ContentService } from '../../../common/services/content.service';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatChipsModule } from '@angular/material/chips'; import { MatChipsModule } from '@angular/material/chips';
import { MatExpansionModule } from '@angular/material/expansion'; import { MatExpansionModule } from '@angular/material/expansion';
@@ -52,6 +51,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { TranslatePipe } from '@ngx-translate/core'; import { TranslatePipe } from '@ngx-translate/core';
import { ContentMetadataHeaderComponent } from './content-metadata-header.component'; import { ContentMetadataHeaderComponent } from './content-metadata-header.component';
import { CategoriesManagementComponent } from '../../../category/categories-management/categories-management.component'; import { CategoriesManagementComponent } from '../../../category/categories-management/categories-management.component';
import { AsyncPipe } from '@angular/common';
const DEFAULT_SEPARATOR = ', '; const DEFAULT_SEPARATOR = ', ';
@@ -66,7 +66,7 @@ export type DefaultPanels = (typeof DefaultPanels)[keyof typeof DefaultPanels];
@Component({ @Component({
selector: 'adf-content-metadata', selector: 'adf-content-metadata',
imports: [ imports: [
CommonModule, AsyncPipe,
MatExpansionModule, MatExpansionModule,
ContentMetadataHeaderComponent, ContentMetadataHeaderComponent,
MatButtonModule, MatButtonModule,
@@ -246,6 +246,10 @@ export class ContentMetadataComponent implements OnChanges, OnInit {
); );
} }
isPanelExpanded(panelTitle: string): boolean {
return (this.currentPanel.panelTitle === panelTitle && this.currentPanel.expanded) ?? false;
}
protected handleUpdateError(error: Error) { protected handleUpdateError(error: Error) {
let statusCode = 0; let statusCode = 0;