Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(editor-content): Limit the amount categories #29208

Merged
merged 10 commits into from
Jul 12, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<div class="flex gap-3 align-items-center flex-wrap" data-testId="category-list">
@for (category of $categoriesToShow(); track category.key) {
<p-chip
[pTooltip]="category.value"
[removable]="true"
[label]="category.value"
tooltipPosition="top"
styleClass="p-chip-sm" />
} @if ($showAllBtn()) {
<button
(click)="toogleShowAll()"
[label]="$btnLabel()"
class="p-button-sm p-button-text p-button-secondary"
data-testId="show-btn"
pButton></button>
}
</div>
nicobytes marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { createComponentFactory, mockProvider, Spectator } from '@ngneat/spectator/jest';

import { DotMessageService } from '@dotcms/data-access';

import { DotCategoryFieldChipsComponent } from './dot-category-field-chips.component';

import { CATEGORIES_KEY_VALUE } from '../../mocks/category-field.mocks';

describe('DotCategoryFieldChipsComponent', () => {
let spectator: Spectator<DotCategoryFieldChipsComponent>;

const createComponent = createComponentFactory({
component: DotCategoryFieldChipsComponent,
providers: [mockProvider(DotMessageService)]
});

beforeEach(() => {
spectator = createComponent({
detectChanges: false,
props: {
max: 8,
categories: CATEGORIES_KEY_VALUE
} as unknown as DotCategoryFieldChipsComponent
});
});

it('should be created', () => {
spectator.detectChanges();
expect(spectator.component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { ChangeDetectionStrategy, Component, computed, inject, input, signal } from '@angular/core';

import { ButtonModule } from 'primeng/button';
import { ChipModule } from 'primeng/chip';
import { TooltipModule } from 'primeng/tooltip';

import { DotMessageService } from '@dotcms/data-access';

import { MAX_CHIPS } from '../../dot-edit-content-category-field.const';
import { DotCategoryFieldKeyValueObj } from '../../models/dot-category-field.models';

/**
* Represents the Dot Category Field Chips component.
*
* @export
* @class DotCategoryFieldChipsComponent
*/
@Component({
selector: 'dot-category-field-chips',
standalone: true,
imports: [ButtonModule, ChipModule, TooltipModule],
templateUrl: './dot-category-field-chips.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DotCategoryFieldChipsComponent {
/**
* Represents the variable 'dotMessageService' which is of type 'DotMessageService'.
*
* @memberof DotCategoryFieldChipsComponent
*/
readonly #dotMessageService = inject(DotMessageService);
/**
* Represents the variable 'showAll' which is of type 'signal<boolean>'.
*
* @memberof DotCategoryFieldChipsComponent
*/
$showAll = signal(false);
/**
* Represents the variable 'max' which is of type 'number'.
*
* @memberof DotCategoryFieldChipsComponent
*/
$max = input<number>(MAX_CHIPS, { alias: 'max' });
/**
* Represents the variable 'categories' which is of type 'DotCategoryFieldKeyValueObj[]'.
*
* @memberof DotCategoryFieldChipsComponent
*/
$categories = input.required<DotCategoryFieldKeyValueObj[]>({ alias: 'categories' });
/**
* Represents the variable 'label' which is of type 'string'.
*
* @memberof DotCategoryFieldChipsComponent
*/
$categoriesToShow = computed(() => {
nicobytes marked this conversation as resolved.
Show resolved Hide resolved
const categories = this.$categories();
if (this.$showAll()) {
return categories;
}

return categories.slice(0, this.$max());
});
/**
* Represents the variable '$showAllBtn' which is of type 'computed<boolean>'.
*
* @memberof DotCategoryFieldChipsComponent
*/
$showAllBtn = computed(() => {
const size = this.$categories().length;

if (size > this.$max()) {
return true;
}

return false;
});
/**
* Represents the variable 'btnLabel' which is of type 'computed<string>'.
*
* @memberof DotCategoryFieldChipsComponent
*/
$btnLabel = computed(() => {
const size = this.$categories().length;
const max = this.$max();

if (this.$showAll()) {
return this.#dotMessageService.get('edit.content.category-field.list.show.less');
}

if (size > max) {
return this.#dotMessageService.get(
'edit.content.category-field.list.show.more',
`${size - max}`
);
}

return null;
});

/**
* Method to toogle the show all categories.
*
* @memberof DotCategoryFieldChipsComponent
*/
toogleShowAll(): void {
this.$showAll.update((showAll) => !showAll);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { DotMessagePipe } from '@dotcms/ui';

import { CategoryFieldStore } from '../../store/content-category-field.store';
import { DotCategoryFieldCategoryListComponent } from '../dot-category-field-category-list/dot-category-field-category-list.component';

/**
* The DotCategoryFieldSidebarComponent is a sidebar panel that allows editing of content category field.
* It provides interfaces for item selection and click handling, and communicates with a store
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
@if (store.selected().length) {
<div class="dot-category-field__categories" data-testId="category-chip-list">
@for (category of store.selected(); track category.key) {
<p-chip
[pTooltip]="category.value"
[removable]="true"
[label]="category.value"
tooltipPosition="top"
styleClass="p-chip-sm" />
}
</div>
<div class="dot-category-field__categories" data-testId="category-chip-list">
<dot-category-field-chips [categories]="store.selected()" />
</div>
}

<div class="dot-category-field__select">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
border-radius: 0 0 $border-radius-md $border-radius-md;
}

&.dot-category-field__container--has-categories .dot-category-field__categories {
&.dot-category-field__container--has-categories dot-category-field-chips {
border-bottom: none;
padding: $spacing-1;
}
}

.dot-category-field__categories,
dot-category-field-chips,
.dot-category-field__select {
border: $field-border-size solid $color-palette-gray-400;
display: flex;
flex-wrap: wrap;
align-items: center;
}

.dot-category-field__categories {
dot-category-field-chips {
nicobytes marked this conversation as resolved.
Show resolved Hide resolved
gap: $spacing-1;
border-radius: $border-radius-md $border-radius-md 0 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { ControlContainer, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';

import { ButtonModule } from 'primeng/button';
import { ChipModule } from 'primeng/chip';
import { ChipsModule } from 'primeng/chips';
import { TooltipModule } from 'primeng/tooltip';

import { delay } from 'rxjs/operators';

import { DotCMSContentlet, DotCMSContentTypeField } from '@dotcms/dotcms-models';
import { DotDynamicDirective, DotMessagePipe } from '@dotcms/ui';

import { DotCategoryFieldChipsComponent } from './components/dot-category-field-chips/dot-category-field-chips.component';
import { DotCategoryFieldSidebarComponent } from './components/dot-category-field-sidebar/dot-category-field-sidebar.component';
import { CLOSE_SIDEBAR_CSS_DELAY_MS } from './dot-edit-content-category-field.const';
import { CategoriesService } from './services/categories.service';
Expand All @@ -40,14 +38,12 @@ import { CategoryFieldStore } from './store/content-category-field.store';
selector: 'dot-edit-content-category-field',
standalone: true,
imports: [
ChipsModule,
ReactiveFormsModule,
ButtonModule,
ChipModule,
NgClass,
TooltipModule,
DotMessagePipe,
DotDynamicDirective
DotDynamicDirective,
DotCategoryFieldChipsComponent
],
templateUrl: './dot-edit-content-category-field.component.html',
styleUrl: './dot-edit-content-category-field.component.scss',
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export const CLOSE_SIDEBAR_CSS_DELAY_MS = 300;

export const MAX_CHIPS = 10;
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { DotCMSContentlet, DotCMSContentTypeField } from '@dotcms/dotcms-models';

import { DotCategoryFieldCategory } from '../models/dot-category-field.models';
import {
DotCategoryFieldCategory,
DotCategoryFieldKeyValueObj
} from '../models/dot-category-field.models';

export const CATEGORY_FIELD_VARIABLE_NAME = 'categorias';

Expand Down Expand Up @@ -203,3 +206,16 @@ export const CATEGORY_LIST_MOCK: DotCategoryFieldCategory[][] = [
* Represent the selected categories
*/
export const SELECTED_LIST_MOCK = [CATEGORY_LEVEL_1[1].inode, CATEGORY_LEVEL_1[2].inode];

export const CATEGORIES_KEY_VALUE: DotCategoryFieldKeyValueObj[] = [
{
key: '0ab5e687775e4793679970e561380560',
value: 'Electrical',
path: 'Electrical'
},
{
key: 'cb83dc32c0a198fd0ca427b3b587f4ce',
value: 'Doors & Windows',
path: 'Doors & Windows'
}
];
2 changes: 2 additions & 0 deletions dotCMS/src/main/webapp/WEB-INF/messages/Language.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5746,3 +5746,5 @@ content.type.form.banner.message= Enable <b>Edit Content Beta</b> for a fresh ed
edit.content.category-field.show-categories-dialog=Select
edit.content.category-field.sidebar.header.select-categories=Select categories
edit.content.category-field.sidebar.button.clear-all=Clear all
edit.content.category-field.list.show.more={0} More
edit.content.category-field.list.show.less=Less
Loading