From 6353ca65ca5c70b9e718a66c97013ad97ad6fd17 Mon Sep 17 00:00:00 2001 From: Nicolas Molina Date: Fri, 4 Oct 2024 21:22:27 -0400 Subject: [PATCH] chore(dotcms-ui): Fix error with autocomplete #30249 --- .../dotcms-theme/components/form/common.scss | 4 +- .../add-style-classes-dialog.component.html | 13 ++-- .../add-style-classes-dialog.component.scss | 6 +- ...-style-classes-dialog.component.stories.ts | 15 ++-- .../add-style-classes-dialog.component.ts | 78 ++++--------------- .../services/json-classes.service.ts | 17 ++-- 6 files changed, 48 insertions(+), 85 deletions(-) diff --git a/core-web/libs/dotcms-scss/angular/dotcms-theme/components/form/common.scss b/core-web/libs/dotcms-scss/angular/dotcms-theme/components/form/common.scss index 845873a7011a..8feb4f0d7111 100644 --- a/core-web/libs/dotcms-scss/angular/dotcms-theme/components/form/common.scss +++ b/core-web/libs/dotcms-scss/angular/dotcms-theme/components/form/common.scss @@ -65,8 +65,8 @@ $select-border-size: 2px; background: $color-palette-gray-200; color: $color-palette-primary; width: $field-height-md; - border-top-right-radius: $border-radius-md; - border-bottom-right-radius: $border-radius-md; + border-top-left-radius: $border-radius-md; + border-bottom-left-radius: $border-radius-md; height: 100%; } diff --git a/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.html b/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.html index 71197946830b..15cb965763e2 100644 --- a/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.html +++ b/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.html @@ -1,20 +1,21 @@
- @let isJsonClasses = $isJsonClasses(); + @let hasClasses = $hasClasses(); - @if (isJsonClasses) { + appendTo="body" + dotSelectItem + /> + @if (hasClasses) {
  • diff --git a/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.scss b/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.scss index 355dc8a68a91..038ed6540016 100644 --- a/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.scss +++ b/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.scss @@ -10,9 +10,13 @@ justify-content: flex-end; } -p-autoComplete { +:host ::ng-deep p-autoComplete { margin-bottom: $spacing-3; display: block; + .p-autocomplete-dropdown.p-element.p-button { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } } ul { diff --git a/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.stories.ts b/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.stories.ts index fffbba37090c..b0d9d66661d7 100644 --- a/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.stories.ts +++ b/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.stories.ts @@ -1,7 +1,7 @@ import { Meta, moduleMetadata, StoryObj, applicationConfig } from '@storybook/angular'; import { of } from 'rxjs'; -import { HttpClient, provideHttpClient } from '@angular/common/http'; +import { provideHttpClient } from '@angular/common/http'; import { FormsModule } from '@angular/forms'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -46,18 +46,17 @@ const meta: Meta = { } } }, - { - provide: HttpClient, - useValue: { - get: (_: string) => of(MOCK_STYLE_CLASSES_FILE) - } - }, { provide: DotMessageService, useValue: DOT_MESSAGE_SERVICE_TB_MOCK }, DynamicDialogRef, - JsonClassesService + { + provide: JsonClassesService, + useValue: { + getClasses: () => of(MOCK_STYLE_CLASSES_FILE.classes) + } + } ] }) ] diff --git a/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.ts b/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.ts index 9a32bed31884..7059a8514794 100644 --- a/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.ts +++ b/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/add-style-classes-dialog.component.ts @@ -1,5 +1,3 @@ -import { of } from 'rxjs'; - import { ChangeDetectionStrategy, Component, @@ -11,16 +9,15 @@ import { import { toSignal } from '@angular/core/rxjs-interop'; import { FormsModule } from '@angular/forms'; -import { AutoCompleteModule } from 'primeng/autocomplete'; +import { AutoCompleteCompleteEvent, AutoCompleteModule } from 'primeng/autocomplete'; import { ButtonModule } from 'primeng/button'; import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog'; -import { catchError, map, shareReplay, tap } from 'rxjs/operators'; - import { DotMessagePipe, DotSelectItemDirective } from '@dotcms/ui'; import { JsonClassesService } from './services/json-classes.service'; + @Component({ selector: 'dotcms-add-style-classes-dialog', standalone: true, @@ -49,17 +46,12 @@ export class AddStyleClassesDialogComponent implements OnInit { * @memberof AddStyleClassesDialogComponent */ readonly #dialogRef = inject(DynamicDialogRef); + readonly #dynamicDialogConfig = inject(DynamicDialogConfig<{selectedClasses: string[]}>); /** * Selected classes to be added * @memberof AddStyleClassesDialogComponent */ $selectedClasses = signal([]); - /** - * Classes to be displayed - * - * @memberof AddStyleClassesDialogComponent - */ - $classes = signal([]); /** * Query to filter the classes * @@ -67,55 +59,23 @@ export class AddStyleClassesDialogComponent implements OnInit { */ $query = signal(null); /** - * Filtered suggestions based on the query + * Check if the JSON file has classes * * @memberof AddStyleClassesDialogComponent */ - $filteredSuggestions = computed(() => { - const classes = this.$classes(); - const query = this.$query(); - - if (!query) { - return classes; - } - - return classes.filter((item) => item.includes(query)); + $classes = toSignal(this.#jsonClassesService.getClasses(), { + initialValue: [] }); /** - * Check if there are classes in the JSON file + * Filtered suggestions based on the query * * @memberof AddStyleClassesDialogComponent */ - isJsonClasses$ = this.#jsonClassesService.getClasses().pipe( - tap(({ classes }) => { - if (classes?.length) { - this.$classes.set(classes); - } else { - this.$classes.set([]); - } - }), - map(({ classes }) => !!classes?.length), - catchError(() => { - this.$classes.set([]); + $filteredSuggestions = signal(this.$classes()); + + $hasClasses = computed(() => this.$classes().length > 0); - return of(false); - }), - shareReplay(1) - ); - /** - * Check if the JSON file has classes - * - * @memberof AddStyleClassesDialogComponent - */ - $isJsonClasses = toSignal(this.isJsonClasses$, { - initialValue: false - }); - constructor( - public dynamicDialogConfig: DynamicDialogConfig<{ - selectedClasses: string[]; - }> - ) {} /** * Set the selected classes @@ -123,10 +83,7 @@ export class AddStyleClassesDialogComponent implements OnInit { * @memberof AddStyleClassesDialogComponent */ ngOnInit() { - const data = this.dynamicDialogConfig.data; - if (data) { - this.$selectedClasses.set(data.selectedClasses); - } + this.$selectedClasses.set(this.#dynamicDialogConfig?.data?.selectedClasses || []); } /** @@ -136,15 +93,10 @@ export class AddStyleClassesDialogComponent implements OnInit { * @return {*} * @memberof AddStyleClassesDialogComponent */ - filterClasses({ query }: { query: string }): void { - /* - https://github.com/primefaces/primeng/blob/master/src/app/components/autocomplete/autocomplete.ts#L739 - - Sadly we need to pass suggestions all the time, even if they are empty because on the set is where the primeng remove the loading icon - */ - - // PrimeNG autocomplete doesn't support async pipe in the suggestions - this.$query.set(query); + filterClasses({ query }: AutoCompleteCompleteEvent): void { + const classes = this.$classes(); + const filteredClasses = query ? classes.filter((item) => item.includes(query)) : classes; + this.$filteredSuggestions.set([...filteredClasses]); } /** diff --git a/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/services/json-classes.service.ts b/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/services/json-classes.service.ts index eb0323d271f5..8ff5c95d0784 100644 --- a/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/services/json-classes.service.ts +++ b/core-web/libs/template-builder/src/lib/components/template-builder/components/add-style-classes-dialog/services/json-classes.service.ts @@ -1,15 +1,22 @@ -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; + +import { catchError, map } from 'rxjs/operators'; + +import { MOCK_STYLE_CLASSES_FILE } from '../../../utils/mocks'; export const STYLE_CLASSES_FILE_URL = '/application/templates/classes.json'; @Injectable() export class JsonClassesService { - constructor(private http: HttpClient) {} + readonly #http = inject(HttpClient); - getClasses(): Observable<{ classes: string[] }> { - return this.http.get<{ classes: string[] }>(STYLE_CLASSES_FILE_URL); + getClasses(): Observable { + return this.#http.get<{ classes: string[] }>(STYLE_CLASSES_FILE_URL).pipe( + map((res) => res.classes), + catchError(() => of(MOCK_STYLE_CLASSES_FILE.classes)) + ); } }