From e3baf868e783c3db2708826ef16ab112f148f8b1 Mon Sep 17 00:00:00 2001 From: Tobias Kohr Date: Thu, 10 Oct 2024 15:46:07 +0200 Subject: [PATCH 1/6] feat(me-search): introduce search-filters.component for md-editor with a first filter to filter on editor/user --- .../search-filters.component.css | 0 .../search-filters.component.html | 10 ++++++++ .../search-filters.component.spec.ts | 21 ++++++++++++++++ .../search-filters.component.ts | 22 ++++++++++++++++ .../all-records/all-records.component.html | 2 +- .../all-records/all-records.component.ts | 2 ++ .../src/lib/utils/service/fields.service.ts | 3 +++ .../search/src/lib/utils/service/fields.ts | 25 +++++++++++++++++++ translations/de.json | 3 +-- translations/en.json | 3 +-- translations/es.json | 3 +-- translations/fr.json | 3 +-- translations/it.json | 3 +-- translations/nl.json | 3 +-- translations/pt.json | 3 +-- translations/sk.json | 3 +-- 16 files changed, 92 insertions(+), 17 deletions(-) create mode 100644 apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.css create mode 100644 apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html create mode 100644 apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts create mode 100644 apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts diff --git a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.css b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html new file mode 100644 index 0000000000..82828e98bf --- /dev/null +++ b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html @@ -0,0 +1,10 @@ +
+ +
diff --git a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts new file mode 100644 index 0000000000..78cc0bf2fa --- /dev/null +++ b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing' +import { SearchFiltersComponent } from './search-filters.component' + +describe('SearchFiltersComponent', () => { + let component: SearchFiltersComponent + let fixture: ComponentFixture + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [SearchFiltersComponent], + }).compileComponents() + + fixture = TestBed.createComponent(SearchFiltersComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it('should create', () => { + expect(component).toBeTruthy() + }) +}) diff --git a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts new file mode 100644 index 0000000000..fd141b60bc --- /dev/null +++ b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts @@ -0,0 +1,22 @@ +import { Component, OnInit } from '@angular/core' +import { CommonModule } from '@angular/common' +import { TranslateModule } from '@ngx-translate/core' +import { FeatureSearchModule } from '@geonetwork-ui/feature/search' + +@Component({ + selector: 'md-editor-search-filters', + standalone: true, + imports: [CommonModule, TranslateModule, FeatureSearchModule], + templateUrl: './search-filters.component.html', + styleUrls: ['./search-filters.component.css'], +}) +export class SearchFiltersComponent implements OnInit { + searchConfig: { fieldName: string; title: string }[] + + ngOnInit(): void { + this.searchConfig = ['user'].map((filter) => ({ + fieldName: filter, + title: `search.filters.${filter}`, + })) + } +} diff --git a/apps/metadata-editor/src/app/records/all-records/all-records.component.html b/apps/metadata-editor/src/app/records/all-records/all-records.component.html index b63f271f04..f4557d9807 100644 --- a/apps/metadata-editor/src/app/records/all-records/all-records.component.html +++ b/apps/metadata-editor/src/app/records/all-records/all-records.component.html @@ -77,6 +77,6 @@

dashboard.createRecord - + diff --git a/apps/metadata-editor/src/app/records/all-records/all-records.component.ts b/apps/metadata-editor/src/app/records/all-records/all-records.component.ts index 46bfbfed2e..5099fd9048 100644 --- a/apps/metadata-editor/src/app/records/all-records/all-records.component.ts +++ b/apps/metadata-editor/src/app/records/all-records/all-records.component.ts @@ -30,6 +30,7 @@ import { ImportRecordComponent } from '@geonetwork-ui/feature/editor' import { RecordsListComponent } from '../records-list.component' import { map } from 'rxjs/operators' import { SearchHeaderComponent } from '../../dashboard/search-header/search-header.component' +import { SearchFiltersComponent } from '../../dashboard/search-filters/search-filters.component' @Component({ selector: 'md-editor-all-records', @@ -49,6 +50,7 @@ import { SearchHeaderComponent } from '../../dashboard/search-header/search-head CdkConnectedOverlay, RecordsListComponent, SearchHeaderComponent, + SearchFiltersComponent, ], }) export class AllRecordsComponent { diff --git a/libs/feature/search/src/lib/utils/service/fields.service.ts b/libs/feature/search/src/lib/utils/service/fields.service.ts index 76a1850932..016b3162f4 100644 --- a/libs/feature/search/src/lib/utils/service/fields.service.ts +++ b/libs/feature/search/src/lib/utils/service/fields.service.ts @@ -10,6 +10,7 @@ import { OwnerSearchField, SimpleSearchField, TranslatedSearchField, + UserSearchField, } from './fields' import { forkJoin, Observable, of } from 'rxjs' import { map } from 'rxjs/operators' @@ -33,6 +34,7 @@ marker('search.filters.topic') marker('search.filters.contact') marker('search.filters.producerOrg') marker('search.filters.publisherOrg') +marker('search.filters.user') @Injectable({ providedIn: 'root', @@ -84,6 +86,7 @@ export class FieldsService { 'asc', 'key' ), + user: new UserSearchField(this.injector), } as Record get supportedFields() { diff --git a/libs/feature/search/src/lib/utils/service/fields.ts b/libs/feature/search/src/lib/utils/service/fields.ts index 13f0bf2819..064dab4388 100644 --- a/libs/feature/search/src/lib/utils/service/fields.ts +++ b/libs/feature/search/src/lib/utils/service/fields.ts @@ -346,3 +346,28 @@ export class OwnerSearchField extends SimpleSearchField { return of([]) } } + +export class UserSearchField extends SimpleSearchField { + constructor(injector: Injector) { + super('userinfo.keyword', injector, 'asc') + } + + getAvailableValues(): Observable { + return super.getAvailableValues().pipe( + map((values) => + values.map((v) => ({ + ...v, + label: this.formatUserInfo(v.label), + })) + ) + ) + } + + private formatUserInfo(userInfo: string | unknown): string { + const infos = (typeof userInfo === 'string' ? userInfo : '').split('|') + if (infos && infos.length === 4) { + return `${infos[2]} ${infos[1]}` + } + return undefined + } +} diff --git a/translations/de.json b/translations/de.json index 0095630ab3..d4c8e1e642 100644 --- a/translations/de.json +++ b/translations/de.json @@ -36,9 +36,7 @@ "dashboard.records.all": "Katalog", "dashboard.records.hasDraft": "", "dashboard.records.myDraft": "Meine Entwürfe", - "dashboard.records.myLibrary": "Meine Bibliothek", "dashboard.records.myRecords": "Meine Datensätze", - "dashboard.records.publishedRecords": "{count, plural, =1{veröffentlichter Datensatz} other{veröffentlichte Datensätze}}", "dashboard.records.search": "Suche nach \"{searchText}\"", "dashboard.records.templates": "Vorlagen", "dashboard.records.userDetail": "Name", @@ -516,6 +514,7 @@ "search.filters.topic": "Themen", "search.filters.useSpatialFilter": "Zuerst Datensätze im Interessenbereich anzeigen", "search.filters.useSpatialFilterHelp": "Wenn diese Option aktiviert ist, werden Datensätze im Bereich des Katalogs zuerst angezeigt. Datensätze außerhalb dieses Bereichs werden nicht angezeigt.", + "search.filters.user": "Editor", "share.tab.permalink": "Teilen", "share.tab.webComponent": "Integrieren", "table.loading.data": "Daten werden geladen...", diff --git a/translations/en.json b/translations/en.json index 1c0638f91d..09413ac13b 100644 --- a/translations/en.json +++ b/translations/en.json @@ -36,9 +36,7 @@ "dashboard.records.all": "Metadata records", "dashboard.records.hasDraft": "draft", "dashboard.records.myDraft": "My drafts", - "dashboard.records.myLibrary": "My library", "dashboard.records.myRecords": "My Records", - "dashboard.records.publishedRecords": "{count, plural, =1{published record} other{published records}}", "dashboard.records.search": "Search for \"{searchText}\"", "dashboard.records.templates": "Templates", "dashboard.records.userDetail": "Name", @@ -516,6 +514,7 @@ "search.filters.topic": "Topics", "search.filters.useSpatialFilter": "Show records in the area of interest first", "search.filters.useSpatialFilterHelp": "When this is enabled, records within the catalog's area of interest are shown first; records outside of this area will not appear.", + "search.filters.user": "Editor", "share.tab.permalink": "Share", "share.tab.webComponent": "Integrate", "table.loading.data": "Loading data...", diff --git a/translations/es.json b/translations/es.json index c0a6c50667..da1de5db27 100644 --- a/translations/es.json +++ b/translations/es.json @@ -36,9 +36,7 @@ "dashboard.records.all": "Catálogo", "dashboard.records.hasDraft": "", "dashboard.records.myDraft": "Mis borradores", - "dashboard.records.myLibrary": "Mi biblioteca", "dashboard.records.myRecords": "Mis Registros", - "dashboard.records.publishedRecords": "", "dashboard.records.search": "Buscar \"{searchText}\"", "dashboard.records.templates": "", "dashboard.records.userDetail": "", @@ -516,6 +514,7 @@ "search.filters.topic": "", "search.filters.useSpatialFilter": "", "search.filters.useSpatialFilterHelp": "", + "search.filters.user": "", "share.tab.permalink": "", "share.tab.webComponent": "", "table.loading.data": "", diff --git a/translations/fr.json b/translations/fr.json index 1198b1c383..107d97f9b1 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -36,9 +36,7 @@ "dashboard.records.all": "Catalogue", "dashboard.records.hasDraft": "brouillon", "dashboard.records.myDraft": "Mes brouillons", - "dashboard.records.myLibrary": "Ma bibliothèque", "dashboard.records.myRecords": "Mes fiches publiées", - "dashboard.records.publishedRecords": "{count, plural, =1{donnée publiée} other{données publiées}}", "dashboard.records.search": "Résultats pour \"{searchText}\"", "dashboard.records.templates": "Modèles pré-remplis", "dashboard.records.userDetail": "Nom", @@ -516,6 +514,7 @@ "search.filters.topic": "Thèmes", "search.filters.useSpatialFilter": "Mettre en avant les résultats sur la zone d'intérêt", "search.filters.useSpatialFilterHelp": "Si cette option est activée, les fiches portant sur la zone d'intérêt du catalogue seront montrées en premier; les fiches en dehors de cette zone n'apparaîtront pas dans les résultats.", + "search.filters.user": "Éditeur", "share.tab.permalink": "Partager", "share.tab.webComponent": "Intégrer", "table.loading.data": "Chargement des données...", diff --git a/translations/it.json b/translations/it.json index a5c3b93f39..3fe791fb02 100644 --- a/translations/it.json +++ b/translations/it.json @@ -36,9 +36,7 @@ "dashboard.records.all": "Catalogo", "dashboard.records.hasDraft": "", "dashboard.records.myDraft": "Le mie bozze", - "dashboard.records.myLibrary": "La mia biblioteca", "dashboard.records.myRecords": "I miei dati", - "dashboard.records.publishedRecords": "dati pubblicati", "dashboard.records.search": "Risultati per \"{searchText}\"", "dashboard.records.templates": "", "dashboard.records.userDetail": "Nome", @@ -516,6 +514,7 @@ "search.filters.topic": "Argomenti", "search.filters.useSpatialFilter": "Evidenzia i risultati nell'area di interesse", "search.filters.useSpatialFilterHelp": "Se attivata, le schede relative all'area di interesse del catalogo saranno mostrate per prime; le schede al di fuori di questa area non appariranno nei risultati.", + "search.filters.user": "", "share.tab.permalink": "Condividere", "share.tab.webComponent": "Incorporare", "table.loading.data": "Caricamento dei dati...", diff --git a/translations/nl.json b/translations/nl.json index 3f8cf3fb7c..6c3b6d7945 100644 --- a/translations/nl.json +++ b/translations/nl.json @@ -36,9 +36,7 @@ "dashboard.records.all": "Catalogus", "dashboard.records.hasDraft": "", "dashboard.records.myDraft": "Mijn concepten", - "dashboard.records.myLibrary": "Mijn bibliotheek", "dashboard.records.myRecords": "Mijn Records", - "dashboard.records.publishedRecords": "", "dashboard.records.search": "Zoeken naar \"{searchText}\"", "dashboard.records.templates": "", "dashboard.records.userDetail": "", @@ -516,6 +514,7 @@ "search.filters.topic": "", "search.filters.useSpatialFilter": "", "search.filters.useSpatialFilterHelp": "", + "search.filters.user": "", "share.tab.permalink": "", "share.tab.webComponent": "", "table.loading.data": "", diff --git a/translations/pt.json b/translations/pt.json index 89d4ddc0c3..506e56b5ba 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -36,9 +36,7 @@ "dashboard.records.all": "Catálogo", "dashboard.records.hasDraft": "", "dashboard.records.myDraft": "Meus rascunhos", - "dashboard.records.myLibrary": "Minha biblioteca", "dashboard.records.myRecords": "Meus Registros", - "dashboard.records.publishedRecords": "", "dashboard.records.search": "Buscar por \"{searchText}\"", "dashboard.records.templates": "", "dashboard.records.userDetail": "", @@ -516,6 +514,7 @@ "search.filters.topic": "", "search.filters.useSpatialFilter": "", "search.filters.useSpatialFilterHelp": "", + "search.filters.user": "", "share.tab.permalink": "", "share.tab.webComponent": "", "table.loading.data": "", diff --git a/translations/sk.json b/translations/sk.json index 7af8363d38..10cbbab923 100644 --- a/translations/sk.json +++ b/translations/sk.json @@ -36,9 +36,7 @@ "dashboard.records.all": "Katalóg", "dashboard.records.hasDraft": "", "dashboard.records.myDraft": "Moje koncepty", - "dashboard.records.myLibrary": "Moja knižnica", "dashboard.records.myRecords": "Moje záznamy", - "dashboard.records.publishedRecords": "{count, plural, =1{zverejnený záznam} other{zverejnených záznamov}}", "dashboard.records.search": "Hľadať \"{searchText}\"", "dashboard.records.templates": "", "dashboard.records.userDetail": "Meno", @@ -516,6 +514,7 @@ "search.filters.topic": "Témy", "search.filters.useSpatialFilter": "Najskôr zobraziť záznamy v oblasti záujmu", "search.filters.useSpatialFilterHelp": "Keď je táto možnosť zapnutá, záznamy nachádzajúce sa v oblasti záujmu katalógu sa zobrazia ako prvé; záznamy mimo tejto oblasti sa nezobrazia.", + "search.filters.user": "", "share.tab.permalink": "Zdieľať", "share.tab.webComponent": "Integrovať", "table.loading.data": "Načítanie údajov...", From 392a75c15c8a7eda78ab8f70c01bc8703e72b061 Mon Sep 17 00:00:00 2001 From: Tobias Kohr Date: Tue, 15 Oct 2024 10:33:59 +0200 Subject: [PATCH 2/6] feat(dropdown-multiselect): make counter stylable and adapt it for md-editor --- .../search-filters/search-filters.component.html | 2 ++ .../dropdown-multiselect.component.html | 2 +- tailwind.base.css | 10 ++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html index 82828e98bf..aae0bde537 100644 --- a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html +++ b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html @@ -6,5 +6,7 @@ [fieldName]="filter.fieldName" [title]="filter.title | translate" [style.--gn-ui-button-height]="'32px'" + [style.--gn-ui-multiselect-counter-text-color]="'var(--color-primary)'" + [style.--gn-ui-multiselect-counter-background-color]="'white'" > diff --git a/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.html b/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.html index b94dad1bce..c0bfd3625b 100644 --- a/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.html +++ b/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.html @@ -14,7 +14,7 @@
{{ selected.length }}
diff --git a/tailwind.base.css b/tailwind.base.css index 210e076e71..5be20d7644 100644 --- a/tailwind.base.css +++ b/tailwind.base.css @@ -129,6 +129,16 @@ border border-white focus:ring-4 focus:ring-gray-300; } + /* DROPDOWN MULTISELECT CLASS */ + .gn-ui-multiselect-counter { + --text-color: var(--gn-ui-multiselect-counter-text-color, white); + --background-color: var( + --gn-ui-multiselect-counter-background-color, + var(--color-primary-lightest) + ); + @apply bg-[color:--background-color] text-[color:--text-color]; + } + /* BADGE CLASS */ .gn-ui-badge { --rounded: var(--gn-ui-badge-rounded, 0.25em); From dfa7de9fd2b7458f933860454bd62f96f414b067 Mon Sep 17 00:00:00 2001 From: Tobias Kohr Date: Tue, 15 Oct 2024 10:43:15 +0200 Subject: [PATCH 3/6] feat(search-filter): add mat icon for now --- .../app/dashboard/search-filters/search-filters.component.html | 3 ++- .../app/dashboard/search-filters/search-filters.component.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html index aae0bde537..f95bc2d95b 100644 --- a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html +++ b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.html @@ -1,6 +1,7 @@
+ filter_list Date: Tue, 15 Oct 2024 11:01:42 +0200 Subject: [PATCH 4/6] feat(search-filters): make fields configurable and add filter to my records with no fields for now --- .../app/dashboard/search-filters/search-filters.component.ts | 5 +++-- .../src/app/records/all-records/all-records.component.html | 4 +++- .../src/app/records/all-records/all-records.component.ts | 2 +- .../src/app/records/my-records/my-records.component.html | 4 +++- .../src/app/records/my-records/my-records.component.ts | 4 +++- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts index f12eaf0d40..5fd95b96ef 100644 --- a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts +++ b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core' +import { Component, Input, OnInit } from '@angular/core' import { CommonModule } from '@angular/common' import { TranslateModule } from '@ngx-translate/core' import { FeatureSearchModule } from '@geonetwork-ui/feature/search' @@ -12,10 +12,11 @@ import { MatIconModule } from '@angular/material/icon' styleUrls: ['./search-filters.component.css'], }) export class SearchFiltersComponent implements OnInit { + @Input() searchFields: string[] searchConfig: { fieldName: string; title: string }[] ngOnInit(): void { - this.searchConfig = ['user'].map((filter) => ({ + this.searchConfig = this.searchFields.map((filter) => ({ fieldName: filter, title: `search.filters.${filter}`, })) diff --git a/apps/metadata-editor/src/app/records/all-records/all-records.component.html b/apps/metadata-editor/src/app/records/all-records/all-records.component.html index f4557d9807..f306af4abb 100644 --- a/apps/metadata-editor/src/app/records/all-records/all-records.component.html +++ b/apps/metadata-editor/src/app/records/all-records/all-records.component.html @@ -77,6 +77,8 @@

dashboard.createRecord

- + diff --git a/apps/metadata-editor/src/app/records/all-records/all-records.component.ts b/apps/metadata-editor/src/app/records/all-records/all-records.component.ts index 5099fd9048..7cae55358c 100644 --- a/apps/metadata-editor/src/app/records/all-records/all-records.component.ts +++ b/apps/metadata-editor/src/app/records/all-records/all-records.component.ts @@ -58,7 +58,7 @@ export class AllRecordsComponent { importRecordButton!: ElementRef @ViewChild('template') template!: TemplateRef private overlayRef!: OverlayRef - + searchFields = ['user'] searchText$: Observable = this.searchFacade.searchFilters$.pipe( map((filters) => ('any' in filters ? (filters['any'] as string) : null)) diff --git a/apps/metadata-editor/src/app/records/my-records/my-records.component.html b/apps/metadata-editor/src/app/records/my-records/my-records.component.html index 95da1b8ed8..d496efb6fa 100644 --- a/apps/metadata-editor/src/app/records/my-records/my-records.component.html +++ b/apps/metadata-editor/src/app/records/my-records/my-records.component.html @@ -77,6 +77,8 @@

dashboard.createRecord - + diff --git a/apps/metadata-editor/src/app/records/my-records/my-records.component.ts b/apps/metadata-editor/src/app/records/my-records/my-records.component.ts index 72bc39f756..2a4c544175 100644 --- a/apps/metadata-editor/src/app/records/my-records/my-records.component.ts +++ b/apps/metadata-editor/src/app/records/my-records/my-records.component.ts @@ -27,6 +27,7 @@ import { MatIconModule } from '@angular/material/icon' import { ImportRecordComponent } from '@geonetwork-ui/feature/editor' import { SearchHeaderComponent } from '../../dashboard/search-header/search-header.component' import { map, Observable } from 'rxjs' +import { SearchFiltersComponent } from '../../dashboard/search-filters/search-filters.component' @Component({ selector: 'md-editor-my-records', @@ -45,6 +46,7 @@ import { map, Observable } from 'rxjs' ImportRecordComponent, FeatureSearchModule, SearchHeaderComponent, + SearchFiltersComponent, ], }) export class MyRecordsComponent implements OnInit { @@ -52,7 +54,7 @@ export class MyRecordsComponent implements OnInit { private importRecordButton!: ElementRef @ViewChild('template') template!: TemplateRef private overlayRef!: OverlayRef - + searchFields = [] searchText$: Observable isImportMenuOpen = false From 0edb25a6c100a207aeef2c36d1e1abd7c83bd2b4 Mon Sep 17 00:00:00 2001 From: Tobias Kohr Date: Tue, 15 Oct 2024 15:02:55 +0200 Subject: [PATCH 5/6] test(search-filters): add unit and e2e tests --- .../src/e2e/dashboard.cy.ts | 37 ++++++++++++ .../search-filters.component.spec.ts | 9 +-- .../search-filters.component.ts | 2 +- .../lib/utils/service/fields.service.spec.ts | 2 + .../src/lib/utils/service/fields.spec.ts | 57 +++++++++++++++++++ .../search/src/lib/utils/service/fields.ts | 3 +- 6 files changed, 104 insertions(+), 6 deletions(-) diff --git a/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts b/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts index 053bf0a7f6..352e230a49 100644 --- a/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts +++ b/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts @@ -313,6 +313,43 @@ describe('dashboard (authenticated)', () => { }) }) }) + describe('search filters', () => { + describe('allRecords search filter', () => { + beforeEach(() => { + cy.visit('/catalog/search') + }) + it('should filter the record list by editor (Barbara Roberts)', () => { + cy.get('md-editor-search-filters').find('gn-ui-button').first().click() + cy.get('.cdk-overlay-container') + .find('input[type="checkbox"]') + .eq(1) + .check() + cy.get('gn-ui-interactive-table') + .find('[data-cy="table-row"]') + .should('have.length', '5') + cy.get('gn-ui-results-table') + .find('[data-cy="table-row"]') + .first() + .as('record') + cy.get('@record') + .children('div') + .eq(4) + .find('span') + .invoke('text') + .should('eq', 'Barbara Roberts') + }) + }) + describe('myRecords search filters', () => { + beforeEach(() => { + cy.visit('/my-space/my-records') + }) + it('should contain filter component with no search filter for now', () => { + cy.get('md-editor-search-filters') + .find('gn-ui-button') + .should('not.exist') + }) + }) + }) }) describe('when the user is not logged in', () => { diff --git a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts index 78cc0bf2fa..1ab165aa5b 100644 --- a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts +++ b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts @@ -1,15 +1,16 @@ import { ComponentFixture, TestBed } from '@angular/core/testing' import { SearchFiltersComponent } from './search-filters.component' +import { MockBuilder } from 'ng-mocks' describe('SearchFiltersComponent', () => { let component: SearchFiltersComponent let fixture: ComponentFixture - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [SearchFiltersComponent], - }).compileComponents() + beforeEach(() => { + return MockBuilder(SearchFiltersComponent) + }) + beforeEach(() => { fixture = TestBed.createComponent(SearchFiltersComponent) component = fixture.componentInstance fixture.detectChanges() diff --git a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts index 5fd95b96ef..23e05c159e 100644 --- a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts +++ b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.ts @@ -12,7 +12,7 @@ import { MatIconModule } from '@angular/material/icon' styleUrls: ['./search-filters.component.css'], }) export class SearchFiltersComponent implements OnInit { - @Input() searchFields: string[] + @Input() searchFields: string[] = [] searchConfig: { fieldName: string; title: string }[] ngOnInit(): void { diff --git a/libs/feature/search/src/lib/utils/service/fields.service.spec.ts b/libs/feature/search/src/lib/utils/service/fields.service.spec.ts index eaf8b09deb..a973d029a8 100644 --- a/libs/feature/search/src/lib/utils/service/fields.service.spec.ts +++ b/libs/feature/search/src/lib/utils/service/fields.service.spec.ts @@ -101,6 +101,7 @@ describe('FieldsService', () => { 'owner', 'producerOrg', 'publisherOrg', + 'user', ]) }) }) @@ -184,6 +185,7 @@ describe('FieldsService', () => { owner: [], producerOrg: [], publisherOrg: [], + user: [], }) }) }) diff --git a/libs/feature/search/src/lib/utils/service/fields.spec.ts b/libs/feature/search/src/lib/utils/service/fields.spec.ts index 16ec9b9501..4ed0c76b97 100644 --- a/libs/feature/search/src/lib/utils/service/fields.spec.ts +++ b/libs/feature/search/src/lib/utils/service/fields.spec.ts @@ -8,6 +8,7 @@ import { OrganizationSearchField, SimpleSearchField, MultilingualSearchField, + UserSearchField, } from './fields' import { TestBed } from '@angular/core/testing' import { Injector } from '@angular/core' @@ -98,6 +99,25 @@ class RecordsRepositoryMock { ], }, }) + if (aggName === 'userinfo.keyword') + return of({ + 'userinfo.keyword': { + buckets: [ + { + term: 'admin|admin|admin|Administrator', + count: 10, + }, + { + term: 'barbie|Roberts|Barbara|UserAdmin', + count: 5, + }, + { + term: 'johndoe|Doe|John|Editor', + count: 1, + }, + ], + }, + }) const buckets = [ { term: 'First value', @@ -666,4 +686,41 @@ describe('search fields implementations', () => { }) }) }) + describe('UserSearchField', () => { + beforeEach(() => { + searchField = new UserSearchField(injector) + }) + describe('#getAvailableValues', () => { + let values + beforeEach(async () => { + values = await lastValueFrom(searchField.getAvailableValues()) + }) + it('orders results by ascending key', () => { + expect(repository.aggregate).toHaveBeenCalledWith({ + 'userinfo.keyword': { + type: 'terms', + limit: 1000, + field: 'userinfo.keyword', + sort: ['asc', 'key'], + }, + }) + }) + it('returns the available editors, order by ascending key (alphabetical)', () => { + expect(values).toEqual([ + { + label: 'admin admin (10)', + value: 'admin|admin|admin|Administrator', + }, + { + label: 'Barbara Roberts (5)', + value: 'barbie|Roberts|Barbara|UserAdmin', + }, + { + label: 'John Doe (1)', + value: 'johndoe|Doe|John|Editor', + }, + ]) + }) + }) + }) }) diff --git a/libs/feature/search/src/lib/utils/service/fields.ts b/libs/feature/search/src/lib/utils/service/fields.ts index 064dab4388..4a377ec969 100644 --- a/libs/feature/search/src/lib/utils/service/fields.ts +++ b/libs/feature/search/src/lib/utils/service/fields.ts @@ -365,8 +365,9 @@ export class UserSearchField extends SimpleSearchField { private formatUserInfo(userInfo: string | unknown): string { const infos = (typeof userInfo === 'string' ? userInfo : '').split('|') + const count = infos[3].split(' ')[1] if (infos && infos.length === 4) { - return `${infos[2]} ${infos[1]}` + return `${infos[2]} ${infos[1]} ${count}` } return undefined } From c31e2cfecc8d91a7e45fe953dbf2d4514623d809 Mon Sep 17 00:00:00 2001 From: Tobias Kohr Date: Thu, 17 Oct 2024 15:42:00 +0200 Subject: [PATCH 6/6] review(search-filters): address comments --- .../src/e2e/dashboard.cy.ts | 13 +++------- .../search-filters.component.spec.ts | 26 +++++++++++++++++-- .../src/lib/utils/service/fields.spec.ts | 4 +-- .../results-table.component.html | 4 ++- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts b/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts index 352e230a49..24359c624b 100644 --- a/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts +++ b/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts @@ -328,15 +328,10 @@ describe('dashboard (authenticated)', () => { .find('[data-cy="table-row"]') .should('have.length', '5') cy.get('gn-ui-results-table') - .find('[data-cy="table-row"]') - .first() - .as('record') - cy.get('@record') - .children('div') - .eq(4) - .find('span') - .invoke('text') - .should('eq', 'Barbara Roberts') + .find('[data-cy="ownerInfo"]') + .each(($ownerInfo) => { + cy.wrap($ownerInfo).invoke('text').should('eq', 'Barbara Roberts') + }) }) }) describe('myRecords search filters', () => { diff --git a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts index 1ab165aa5b..487bdb8615 100644 --- a/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts +++ b/apps/metadata-editor/src/app/dashboard/search-filters/search-filters.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing' import { SearchFiltersComponent } from './search-filters.component' import { MockBuilder } from 'ng-mocks' +import { TranslateModule } from '@ngx-translate/core' describe('SearchFiltersComponent', () => { let component: SearchFiltersComponent @@ -10,13 +11,34 @@ describe('SearchFiltersComponent', () => { return MockBuilder(SearchFiltersComponent) }) - beforeEach(() => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [SearchFiltersComponent, TranslateModule.forRoot()], + }).compileComponents() fixture = TestBed.createComponent(SearchFiltersComponent) component = fixture.componentInstance - fixture.detectChanges() }) it('should create', () => { expect(component).toBeTruthy() }) + + describe('searchFields', () => { + it('should correctly read searchFields and create searchConfig', () => { + const searchFields = ['user', 'publisherOrg', 'format', 'isSpatial'] + component.searchFields = searchFields + fixture.detectChanges() + expect(component.searchConfig).toEqual([ + { fieldName: 'user', title: 'search.filters.user' }, + { fieldName: 'publisherOrg', title: 'search.filters.publisherOrg' }, + { fieldName: 'format', title: 'search.filters.format' }, + { fieldName: 'isSpatial', title: 'search.filters.isSpatial' }, + ]) + }) + it('should read empty searchFields and create empty searchConfig', () => { + component.searchFields = [] + fixture.detectChanges() + expect(component.searchConfig).toEqual([]) + }) + }) }) diff --git a/libs/feature/search/src/lib/utils/service/fields.spec.ts b/libs/feature/search/src/lib/utils/service/fields.spec.ts index 4ed0c76b97..39facadac2 100644 --- a/libs/feature/search/src/lib/utils/service/fields.spec.ts +++ b/libs/feature/search/src/lib/utils/service/fields.spec.ts @@ -695,7 +695,7 @@ describe('search fields implementations', () => { beforeEach(async () => { values = await lastValueFrom(searchField.getAvailableValues()) }) - it('orders results by ascending key', () => { + it('calls aggregate with expected payload', () => { expect(repository.aggregate).toHaveBeenCalledWith({ 'userinfo.keyword': { type: 'terms', @@ -705,7 +705,7 @@ describe('search fields implementations', () => { }, }) }) - it('returns the available editors, order by ascending key (alphabetical)', () => { + it('returns the available users, in expected format', () => { expect(values).toEqual([ { label: 'admin admin (10)', diff --git a/libs/ui/search/src/lib/results-table/results-table.component.html b/libs/ui/search/src/lib/results-table/results-table.component.html index b4a6c4b926..fe2c86a8a5 100644 --- a/libs/ui/search/src/lib/results-table/results-table.component.html +++ b/libs/ui/search/src/lib/results-table/results-table.component.html @@ -95,7 +95,9 @@ person - {{ formatUserInfo(item.extras?.ownerInfo) }} + {{ + formatUserInfo(item.extras?.ownerInfo) + }}