Skip to content

Commit

Permalink
feat(edit-content) add selected component in sidebar, remove item and…
Browse files Browse the repository at this point in the history
… clear all button #28493
  • Loading branch information
oidacra committed Jul 18, 2024
1 parent 1c26ebf commit 545084d
Show file tree
Hide file tree
Showing 12 changed files with 408 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@
<p-tableCheckbox [value]="category"></p-tableCheckbox>
</td>
<td>{{ category.value }}</td>
<td>{{ category.path }}</td>
<td>
<span [pTooltip]="category.path" tooltipPosition="top">
{{ category.path }}
</span>
</td>
</tr>
</ng-template>
</p-table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';

import { SkeletonModule } from 'primeng/skeleton';
import { TableModule } from 'primeng/table';
import { TooltipModule } from 'primeng/tooltip';

import { debounceTime } from 'rxjs/operators';

Expand All @@ -33,7 +34,14 @@ import { DotTableSkeletonComponent } from '../dot-table-skeleton/dot-table-skele
@Component({
selector: 'dot-category-field-search-list',
standalone: true,
imports: [CommonModule, TableModule, SkeletonModule, DotTableSkeletonComponent, DotMessagePipe],
imports: [
CommonModule,
TableModule,
SkeletonModule,
DotTableSkeletonComponent,
DotMessagePipe,
TooltipModule
],
templateUrl: './dot-category-field-search-list.component.html',
styleUrl: './dot-category-field-search-list.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
data-testId="search-input"
pInputText
type="text" />
@if (searchControl.value && !$isLoading()) {
@if (!searchControl.pristine && !$isLoading()) {
<span
data-testId="search-icon-clear"
(click)="clearInput()"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { EMPTY, of } from 'rxjs';

import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, EventEmitter, input, Output } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormControl, ReactiveFormsModule } from '@angular/forms';

import { InputTextModule } from 'primeng/inputtext';

import { debounceTime, filter } from 'rxjs/operators';
import { debounceTime, switchMap } from 'rxjs/operators';

import { DotMessagePipe } from '@dotcms/ui';

Expand Down Expand Up @@ -45,10 +47,22 @@ export class DotCategoryFieldSearchComponent {
.pipe(
takeUntilDestroyed(),
debounceTime(DEBOUNCE_TIME),
filter((value: string) => value.length >= MINIMUM_CHARACTERS)
switchMap((value: string) => {
if (value.length >= MINIMUM_CHARACTERS) {
return of(value);
} else if (value.length === 0) {
this.clearInput();

return of('');
}

return EMPTY;
})
)
.subscribe((value: string) => {
this.term.emit(value);
if (value.length >= MINIMUM_CHARACTERS) {
this.term.emit(value);
}
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<ul class="category-list">
@for (category of $categories(); track category.key) {
<li class="category-list__item" @fadeAnimation>
<div class="category-list__item-content">
<div class="category-list__title">{{ category.value }}</div>
<div class="category-list__path">
<span
[pTooltip]="category.path"
tooltipPosition="top"
class="category-list__path-content">
{{ category.path }}
</span>
</div>
</div>

<div class="category-list__remove">
<button
(click)="removeItem.emit(category.key)"
icon="pi pi-times"
class="p-button-sm p-button-text p-button-secondary"
data-testId="category-list__remove-btn"
pButton></button>
</div>
</li>

} @empty {
<li>No Categories selected</li>
}
</ul>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@use "variables" as *;

.category-list {
list-style: none;
padding: $spacing-3;
margin: 0;
}

.category-list__item {
display: grid;
grid-template-columns: 1fr 40px;
align-items: center;
padding: $spacing-1 0;
border-bottom: 1px solid $color-palette-gray-300;
}

.category-list__item-content {
display: flex;
justify-content: space-between;
width: 100%;
overflow: hidden;
gap: $spacing-1;
flex-direction: column;
}

.category-list__title {
color: $black;
font-size: $font-size-smd;
font-weight: $font-weight-medium-bold;
flex-shrink: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.category-list__path {
flex-grow: 1;
overflow: hidden;
}

.category-list__path-content {
font-size: $font-size-smd;
color: $color-palette-gray-700;
font-weight: $font-weight-regular-bold;
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
direction: rtl;
text-align: left;
}

.category-list__remove {
display: flex;
align-items: center;
justify-content: center;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { animate, state, style, transition, trigger } from '@angular/animations';
import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, EventEmitter, input, Output } from '@angular/core';

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

import { DotMessagePipe } from '@dotcms/ui';

import { DotCategoryFieldKeyValueObj } from '../../models/dot-category-field.models';
import { DotCategoryFieldSearchListComponent } from '../dot-category-field-search-list/dot-category-field-search-list.component';

@Component({
selector: 'dot-category-field-selected',
standalone: true,
imports: [
CommonModule,
ButtonModule,
DotMessagePipe,
DotCategoryFieldSearchListComponent,
ChipModule,
TooltipModule
],
templateUrl: './dot-category-field-selected.component.html',
styleUrl: './dot-category-field-selected.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
animations: [
trigger('fadeAnimation', [
state(
'void',
style({
opacity: 0
})
),
transition(':enter, :leave', [animate('50ms ease-in-out')])
])
]
})
export class DotCategoryFieldSelectedComponent {
/**
* Represents the array of selected categories.
*/
$categories = input<DotCategoryFieldKeyValueObj[]>([], {
alias: 'categories'
});

@Output()
removeItem = new EventEmitter<string>();

private convertPathToArray(path: string): string[] {
if (!path) {
return [];
}

return path.split(' / ');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ export class DotEditContentCategoryFieldComponent implements OnInit {
}

ngOnInit(): void {
this.store.load(this.field(), this.contentlet());
this.store.load({
field: this.field(),
contentlet: this.contentlet()
});
}

private setSidebarListener() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import { DotCategory, DotCMSContentlet, DotCMSContentTypeField } from '@dotcms/dotcms-models';

export interface DotCategoryField {
field: DotCMSContentTypeField;
contentlet: DotCMSContentlet;
}

/**
* Object representing a key-value pair.
* @interface
Expand All @@ -11,6 +18,13 @@ export interface DotCategoryFieldKeyValueObj {
hasChildren?: boolean;
}

/**
* The HierarchyParent type represents a parent object in a hierarchical structure.
* It is defined as a subset of the DotCategory type, which includes the categoryName,
* inode, and parentList properties.
*/
export type HierarchyParent = Pick<DotCategory, 'categoryName' | 'inode' | 'parentList'>;

/**
* Represents an clicked item in a DotCategoryField.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { pluck } from 'rxjs/operators';
import { DotCMSResponse } from '@dotcms/dotcms-js';
import { DotCategory } from '@dotcms/dotcms-models';

import { HierarchyParent } from '../models/dot-category-field.models';

export const API_URL = '/api/v1/categories';

export const ITEMS_PER_PAGE = 7000;
Expand Down Expand Up @@ -55,6 +57,19 @@ export class CategoriesService {
.pipe(pluck('entity'));
}

/**
* Retrieves the complete hierarchy for the given selected keys.
*
*
* @return {Observable<DotCategory[]>} - An Observable that emits the complete hierarchy as an array of DotCategory objects.
* @param keys
*/
getSelectedHierarchy(keys: string[]): Observable<HierarchyParent[]> {
return this.#http
.post<DotCMSResponse<DotCategory[]>>(`${API_URL}/hierarchy`, { keys })
.pipe(pluck('entity'));
}

/**
* Merges default parameters with provided parameters.
*
Expand Down
Loading

0 comments on commit 545084d

Please sign in to comment.