Skip to content

Commit

Permalink
Fix clear all button in Category Field Dialog (#30052)
Browse files Browse the repository at this point in the history
### Proposed Changes
* Fix clear all button in Category Field Dialog


### Checklist
- [x] Tests
- [ ] Translations
- [ ] Security Implications Contemplated (add notes if applicable)

### Additional Info
** any additional useful context or info **

### Screenshots
Original             |  Updated
No visual changes
  • Loading branch information
oidacra authored Sep 20, 2024
1 parent 7a6c6e5 commit 4359825
Show file tree
Hide file tree
Showing 11 changed files with 246 additions and 178 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
CATEGORY_LIST_MOCK,
CATEGORY_LIST_MOCK_TRANSFORMED_MATRIX,
CATEGORY_MOCK_TRANSFORMED,
SELECTED_LIST_MOCK
MOCK_SELECTED_CATEGORIES_KEYS
} from '../../mocks/category-field.mocks';
import { DotCategoryFieldListSkeletonComponent } from '../dot-category-field-list-skeleton/dot-category-field-list-skeleton.component';

Expand All @@ -29,7 +29,7 @@ describe('DotCategoryFieldCategoryListComponent', () => {
beforeEach(() => {
spectator = createComponent();
spectator.setInput('categories', CATEGORY_LIST_MOCK_TRANSFORMED_MATRIX);
spectator.setInput('selected', SELECTED_LIST_MOCK);
spectator.setInput('selected', MOCK_SELECTED_CATEGORIES_KEYS);
spectator.setInput('state', ComponentStatus.INIT);
spectator.setInput('breadcrumbs', []);

Expand Down Expand Up @@ -81,7 +81,7 @@ describe('DotCategoryFieldCategoryListComponent', () => {

it('should apply selected class to the correct item', () => {
spectator.setInput('categories', [CATEGORY_MOCK_TRANSFORMED]);
spectator.setInput('selected', SELECTED_LIST_MOCK);
spectator.setInput('selected', MOCK_SELECTED_CATEGORIES_KEYS);
spectator.setInput('state', ComponentStatus.LOADED);

spectator.detectChanges();
Expand All @@ -97,7 +97,7 @@ describe('DotCategoryFieldCategoryListComponent', () => {
const testCategories = Array(minColumns).fill(CATEGORY_LIST_MOCK_TRANSFORMED_MATRIX[0]);

spectator.setInput('categories', testCategories);
spectator.setInput('selected', SELECTED_LIST_MOCK);
spectator.setInput('selected', MOCK_SELECTED_CATEGORIES_KEYS);
spectator.setInput('state', ComponentStatus.LOADED);

spectator.detectChanges();
Expand All @@ -107,7 +107,7 @@ describe('DotCategoryFieldCategoryListComponent', () => {

it('should render the skeleton component if is loading', () => {
spectator.setInput('categories', [CATEGORY_MOCK_TRANSFORMED]);
spectator.setInput('selected', SELECTED_LIST_MOCK);
spectator.setInput('selected', MOCK_SELECTED_CATEGORIES_KEYS);
spectator.setInput('state', ComponentStatus.LOADING);

spectator.detectChanges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,31 @@
(rowClicked)="store.getCategories($event)"
[categories]="store.categoryList()"
[state]="store.listState()"
[selected]="store.confirmedCategoriesValues()"
[selected]="store.dialogSelectedKeys()"
[breadcrumbs]="store.breadcrumbMenu()" />
} @else {
<dot-category-field-search-list
(itemChecked)="store.addSelected($event)"
(removeItem)="store.removeSelected($event)"
[state]="store.searchState()"
[categories]="store.searchCategoryList()"
[selected]="store.selected()" />
[selected]="store.dialog.selected()" />
}
</div>
</div>

<div
class="category-field__right-pane flex flex-column"
[ngClass]="{ empty: !store.selected().length }">
@if (store.selected().length) {
[ngClass]="{ empty: !store.dialog.selected().length }">
@if (store.dialog.selected().length) {
<div class="category-field__selected-categories-list flex-1">
<dot-category-field-selected
(removeItem)="store.removeSelected($event)"
[categories]="store.selected()" />
[categories]="store.dialog.selected()" />
</div>
<div class="category-field__actions flex justify-content-end">
<button
(click)="store.removeSelected($allCategoryKeys())"
(click)="store.removeSelected(store.dialogSelectedKeys())"
class="p-button p-button-link"
data-testId="clear_all-btn"
pButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,11 @@ describe('DotCategoryFieldDialogComponent', () => {

it('should save the changes and apply the categories when the apply button is clicked', () => {
const closedDialogSpy = jest.spyOn(spectator.component.closedDialog, 'emit');
const addConfirmedCategoriesSky = jest.spyOn(store, 'addConfirmedCategories');
const categories = { key: '1234', value: 'test' };
store.addSelected({ key: '1234', value: 'test' });
const addConfirmedCategoriesSky = jest.spyOn(store, 'applyDialogSelection');
spectator.detectChanges();

expect(store.selected()).toEqual([categories]);
expect(store.confirmedCategories()).toEqual([]);

spectator.click(byTestId('dialog-apply'));

expect(store.confirmedCategories()).toEqual([categories]);
expect(closedDialogSpy).toHaveBeenCalled();
expect(addConfirmedCategoriesSky).toHaveBeenCalled();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { NgClass } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
computed,
inject,
model,
OnDestroy,
Expand Down Expand Up @@ -68,11 +67,6 @@ export class DotCategoryFieldDialogComponent implements OnInit, OnDestroy {
*/
readonly store = inject(CategoryFieldStore);

/**
* Computed property for retrieving all category keys.
*/
$allCategoryKeys = computed(() => this.store.selected().map((category) => category.key));

ngOnInit(): void {
this.store.getCategories();
}
Expand All @@ -82,7 +76,7 @@ export class DotCategoryFieldDialogComponent implements OnInit, OnDestroy {
}

confirmCategories(): void {
this.store.addConfirmedCategories();
this.store.applyDialogSelection();
this.closedDialog.emit();
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
@if (store.confirmedCategories().length) {
@if (store.selected().length) {
<dot-category-field-chips
data-testId="category-chip-list"
[categories]="store.confirmedCategories()"
(remove)="store.removeConfirmedCategories($event)" />
[categories]="store.selected()"
(remove)="store.removeRootSelected($event)" />
}

<div class="dot-category-field__select">
<button
type="button"
(click)="openCategoriesDialog()"
[disabled]="$showCategoriesDialog()"
[disabled]="store.isDialogOpen()"
[label]="'edit.content.category-field.show-categories-dialog' | dm"
class="p-button-sm p-button-text p-button-secondary"
data-testId="show-dialog-btn"
pButton></button>
</div>

@if ($showCategoriesDialog()) {
@defer (when $showCategoriesDialog()) {
@if (store.isDialogOpen()) {
@defer (when store.isDialogOpen()) {
<dot-category-field-dialog
[isVisible]="$showCategoriesDialog()"
(closedDialog)="closeCategoriesDialog()"
[isVisible]="store.isDialogOpen()"
(closedDialog)="store.closeDialog()"
data-testId="dialog-placeholder" />
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import {
CATEGORY_FIELD_MOCK,
CATEGORY_FIELD_VARIABLE_NAME,
CATEGORY_HIERARCHY_MOCK,
SELECTED_LIST_MOCK
CATEGORY_LEVEL_2,
MOCK_SELECTED_CATEGORIES_OBJECT
} from './mocks/category-field.mocks';
import { DotCategoryFieldKeyValueObj } from './models/dot-category-field.models';
import { CategoriesService } from './services/categories.service';
import { CategoryFieldStore } from './store/content-category-field.store';

Expand Down Expand Up @@ -86,7 +88,7 @@ describe('DotEditContentCategoryFieldComponent', () => {
it('should categoryFieldControl has the values loaded on the store', () => {
const categoryValue = spectator.component.categoryFieldControl.value;

expect(categoryValue).toEqual(SELECTED_LIST_MOCK);
expect(categoryValue).toEqual(MOCK_SELECTED_CATEGORIES_OBJECT);
});
});

Expand Down Expand Up @@ -186,30 +188,50 @@ describe('DotEditContentCategoryFieldComponent', () => {
// Check if the form has the correct value
const categoryValue = spectator.component.categoryFieldControl.value;

expect(categoryValue).toEqual(SELECTED_LIST_MOCK);
expect(categoryValue).toEqual(MOCK_SELECTED_CATEGORIES_OBJECT);
}));

it('should set categoryFieldControl value when adding a new category', () => {
store.addSelected({
key: '1234',
value: 'test'
});
store.addConfirmedCategories();
spectator.flushEffects();
const newItem: DotCategoryFieldKeyValueObj = {
key: CATEGORY_LEVEL_2[0].key,
value: CATEGORY_LEVEL_2[0].categoryName,
inode: CATEGORY_LEVEL_2[0].inode,
path: CATEGORY_LEVEL_2[0].categoryName
};

const categoryValue = spectator.component.categoryFieldControl.value;
// this apply selected to the dialog
store.openDialog();

// Add the new category
store.addSelected(newItem);
// Apply the selected to the field
store.applyDialogSelection();

spectator.detectChanges();

const categoryValues = spectator.component.categoryFieldControl.value;

expect(categoryValue).toEqual([...SELECTED_LIST_MOCK, '1234']);
expect(categoryValues).toEqual([...MOCK_SELECTED_CATEGORIES_OBJECT, newItem]);
});

it('should set categoryFieldControl value when removing a category', () => {
store.removeConfirmedCategories(SELECTED_LIST_MOCK[0]);
const categoryValue: DotCategoryFieldKeyValueObj[] =
spectator.component.categoryFieldControl.value;

spectator.flushEffects();
const expectedSelected = [categoryValue[0]];

const categoryValue = spectator.component.categoryFieldControl.value;
expect(categoryValue.length).toBe(2);
store.openDialog(); // this apply selected to the dialog

store.removeSelected(categoryValue[1].key);
store.applyDialogSelection(); // this apply the selected in the dialog to the final selected

spectator.detectChanges();

const newCategoryValue = spectator.component.categoryFieldControl.value;

expect(categoryValue).toEqual([SELECTED_LIST_MOCK[1]]);
expect(newCategoryValue).toEqual(expectedSelected);
expect(newCategoryValue.length).toBe(1);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import {
inject,
Injector,
input,
OnInit,
signal
OnInit
} from '@angular/core';
import { ControlContainer, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';

Expand Down Expand Up @@ -45,8 +44,8 @@ import { CategoryFieldStore } from './store/content-category-field.store';
styleUrl: './dot-edit-content-category-field.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
'[class.dot-category-field__container--has-categories]': '$hasConfirmedCategories()',
'[class.dot-category-field__container]': '!$hasConfirmedCategories()'
'[class.dot-category-field__container--has-categories]': '$hasSelectedCategories()',
'[class.dot-category-field__container]': '!$hasSelectedCategories()'
},
viewProviders: [
{
Expand All @@ -60,10 +59,7 @@ export class DotEditContentCategoryFieldComponent implements OnInit {
readonly store = inject(CategoryFieldStore);
readonly #form = inject(ControlContainer).control as FormGroup;
readonly #injector = inject(Injector);
/**
* Disable the button to open the dialog
*/
$showCategoriesDialog = signal(false);

/**
* The `field` variable is of type `DotCMSContentTypeField` and is a required input.
* @description The variable represents a field of a DotCMS content type and is a required input.
Expand All @@ -79,7 +75,7 @@ export class DotEditContentCategoryFieldComponent implements OnInit {
*
* @returns {Boolean} - True if there are selected categories, false otherwise.
*/
$hasConfirmedCategories = computed(() => !!this.store.hasConfirmedCategories());
$hasSelectedCategories = computed(() => !!this.store.selected());
/**
* Getter to retrieve the category field control.
*
Expand All @@ -100,7 +96,7 @@ export class DotEditContentCategoryFieldComponent implements OnInit {
});
effect(
() => {
const categoryValues = this.store.confirmedCategoriesValues();
const categoryValues = this.store.selected();

if (this.categoryFieldControl) {
this.categoryFieldControl.setValue(categoryValues);
Expand All @@ -117,15 +113,6 @@ export class DotEditContentCategoryFieldComponent implements OnInit {
* @memberof DotEditContentCategoryFieldComponent
*/
openCategoriesDialog(): void {
this.store.setSelectedCategories();
this.$showCategoriesDialog.set(true);
}
/**
* Close the categories dialog.
*
* @memberof DotEditContentCategoryFieldComponent
*/
closeCategoriesDialog() {
this.$showCategoriesDialog.set(false);
this.store.openDialog();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const CATEGORY_FIELD_CONTENTLET_MOCK: DotCMSContentlet = {
baseType: 'CONTENT',
[CATEGORY_FIELD_VARIABLE_NAME]: [
{
'1f208488057007cedda0e0b5d52ee3b3': 'Electrical'
'1f208488057007cedda0e0b5d52ee3b3': 'Cleaning Supplies'
},
{
cb83dc32c0a198fd0ca427b3b587f4ce: 'Doors & Windows'
Expand Down Expand Up @@ -197,14 +197,32 @@ export const CATEGORY_LEVEL_2: DotCategory[] = [
export const CATEGORY_LIST_MOCK: DotCategory[][] = [[...CATEGORY_LEVEL_1], [...CATEGORY_LEVEL_2]];

/**
* Represent the selected categories
* Represent the selected categories keys
*/
export const SELECTED_LIST_MOCK = [CATEGORY_LEVEL_1[0].key, CATEGORY_LEVEL_1[1].key];
export const MOCK_SELECTED_CATEGORIES_KEYS = [CATEGORY_LEVEL_1[0].key, CATEGORY_LEVEL_1[1].key];

/**
* Represent the selected categories as an object
*/
export const MOCK_SELECTED_CATEGORIES_OBJECT: DotCategoryFieldKeyValueObj[] = [
{
key: CATEGORY_LEVEL_1[0].key,
value: CATEGORY_LEVEL_1[0].categoryName,
inode: CATEGORY_LEVEL_1[0].inode,
path: CATEGORY_LEVEL_1[0].categoryName // root categories is the categoryName
},
{
key: CATEGORY_LEVEL_1[1].key,
value: CATEGORY_LEVEL_1[1].categoryName,
inode: CATEGORY_LEVEL_1[1].inode,
path: CATEGORY_LEVEL_1[1].categoryName // root categories is the categoryName
}
];

export const CATEGORY_LIST_MOCK_TRANSFORMED_MATRIX: DotCategoryFieldKeyValueObj[][] =
CATEGORY_LIST_MOCK.map(
(categoryLevel) => transformCategories(categoryLevel) as DotCategoryFieldKeyValueObj[],
SELECTED_LIST_MOCK
MOCK_SELECTED_CATEGORIES_KEYS
);

export const CATEGORY_MOCK_TRANSFORMED: DotCategoryFieldKeyValueObj[] = [
Expand Down Expand Up @@ -295,9 +313,9 @@ export const CATEGORY_HIERARCHY_MOCK: HierarchyParent[] = [
name: CATEGORY_FIELD_MOCK.categories.categoryName
},
{
inode: CATEGORY_LEVEL_1[0].inode,
key: CATEGORY_LEVEL_1[0].key,
name: CATEGORY_LEVEL_1[0].categoryName
inode: CATEGORY_LEVEL_1[1].inode,
key: CATEGORY_LEVEL_1[1].key,
name: CATEGORY_LEVEL_1[1].categoryName
}
]
}
Expand Down
Loading

0 comments on commit 4359825

Please sign in to comment.