From 13e6ff2531009ce3f2f01565f38512dc336b2bad Mon Sep 17 00:00:00 2001 From: Tobias Kohr Date: Thu, 19 Dec 2024 14:49:13 +0100 Subject: [PATCH 1/4] feat(search): always search in all-records --- .../src/e2e/dashboard.cy.ts | 12 ++-- .../dashboard/dashboard-page.component.html | 3 + .../all-records/all-records.component.html | 3 - .../all-records/all-records.component.ts | 56 +++++++++++-------- .../records/my-draft/my-draft.component.html | 2 +- .../my-records/my-records.component.html | 7 +-- 6 files changed, 48 insertions(+), 35 deletions(-) diff --git a/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts b/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts index 5b76e1b938..07e5185ad8 100644 --- a/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts +++ b/apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts @@ -272,10 +272,6 @@ describe('dashboard (authenticated)', () => { cy.get('md-editor-dashboard-menu').find('a').eq(5).click() cy.get('gn-ui-autocomplete').should('have.value', '') }) - it('should hide the search input when navigating to my drafts', () => { - cy.get('md-editor-dashboard-menu').find('a').eq(4).click() - cy.get('gn-ui-autocomplete').should('not.exist') - }) }) describe('myRecords search input', () => { beforeEach(() => { @@ -293,6 +289,14 @@ describe('dashboard (authenticated)', () => { cy.get('md-editor-dashboard-menu').find('a').first().click() cy.get('gn-ui-autocomplete').should('have.value', '') }) + it('should allow to search in the entire catalog', () => { + cy.get('gn-ui-autocomplete').type('mat{enter}') + cy.get('gn-ui-interactive-table') + .find('[data-cy="table-row"]') + .should('have.length', '1') + cy.url().should('include', '/search?q=mat') + cy.url().should('not.include', 'owner') + }) }) }) describe('search filters', () => { diff --git a/apps/metadata-editor/src/app/dashboard/dashboard-page.component.html b/apps/metadata-editor/src/app/dashboard/dashboard-page.component.html index a01307fce2..b0bee6b00b 100644 --- a/apps/metadata-editor/src/app/dashboard/dashboard-page.component.html +++ b/apps/metadata-editor/src/app/dashboard/dashboard-page.component.html @@ -7,6 +7,9 @@
+
+ +
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 3cd22212c3..29ac1b8ca3 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 @@ -1,6 +1,3 @@ -
- -
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 4b68e87f52..7a025b0ee5 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 @@ -3,32 +3,24 @@ import { ChangeDetectorRef, Component, ElementRef, + OnDestroy, + OnInit, TemplateRef, ViewChild, ViewContainerRef, } from '@angular/core' -import { - ResultsTableContainerComponent, - SearchFacade, - SearchService, -} from '@geonetwork-ui/feature/search' +import { SearchFacade, SearchService } from '@geonetwork-ui/feature/search' import { TranslateModule } from '@ngx-translate/core' import { Router } from '@angular/router' import { RecordsCountComponent } from '../records-count/records-count.component' -import { Observable } from 'rxjs' +import { Observable, Subscription } from 'rxjs' import { UiElementsModule } from '@geonetwork-ui/ui/elements' import { UiInputsModule } from '@geonetwork-ui/ui/inputs' -import { - CdkConnectedOverlay, - CdkOverlayOrigin, - Overlay, - OverlayRef, -} from '@angular/cdk/overlay' +import { CdkOverlayOrigin, Overlay, OverlayRef } from '@angular/cdk/overlay' import { TemplatePortal } from '@angular/cdk/portal' 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 { map, take } from 'rxjs/operators' import { SearchFiltersComponent } from '../../dashboard/search-filters/search-filters.component' import { NgIconComponent, @@ -50,14 +42,11 @@ import { CommonModule, TranslateModule, RecordsCountComponent, - ResultsTableContainerComponent, UiElementsModule, UiInputsModule, ImportRecordComponent, CdkOverlayOrigin, - CdkConnectedOverlay, RecordsListComponent, - SearchHeaderComponent, SearchFiltersComponent, NgIconComponent, ], @@ -72,16 +61,14 @@ import { }), ], }) -export class AllRecordsComponent { +export class AllRecordsComponent implements OnInit, OnDestroy { @ViewChild('importRecordButton', { read: ElementRef }) importRecordButton!: ElementRef @ViewChild('template') template!: TemplateRef private overlayRef!: OverlayRef searchFields = ['user', 'changeDate'] - searchText$: Observable = - this.searchFacade.searchFilters$.pipe( - map((filters) => ('any' in filters ? (filters['any'] as string) : null)) - ) + searchText$: Observable + subscription: Subscription isImportMenuOpen = false @@ -94,6 +81,31 @@ export class AllRecordsComponent { private cdr: ChangeDetectorRef ) {} + ngOnInit() { + this.subscription = this.searchFacade.searchFilters$ + .pipe( + map((filters) => { + if ('owner' in filters) { + const { owner, ...rest } = filters + return rest + } + return filters + }), + take(1) + ) + .subscribe((filters) => { + this.searchService.setFilters(filters) + }) + this.searchText$ = this.searchFacade.searchFilters$.pipe( + map((filters) => ('any' in filters ? (filters['any'] as string) : null)) + ) + } + + ngOnDestroy() { + this.searchFacade.updateFilters({ any: '' }) + this.subscription.unsubscribe() + } + createRecord() { this.router.navigate(['/create']).catch((err) => console.error(err)) } diff --git a/apps/metadata-editor/src/app/records/my-draft/my-draft.component.html b/apps/metadata-editor/src/app/records/my-draft/my-draft.component.html index f65d41a994..8d50b66d55 100644 --- a/apps/metadata-editor/src/app/records/my-draft/my-draft.component.html +++ b/apps/metadata-editor/src/app/records/my-draft/my-draft.component.html @@ -1,7 +1,7 @@
-

+

dashboard.records.myDraft

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 2864f6a746..0642f47789 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 @@ -1,11 +1,8 @@ -
- -

@@ -16,7 +13,7 @@

-

+

dashboard.records.myRecords

From e4c83e2634963f79a212726b7cf9f2fee313ece4 Mon Sep 17 00:00:00 2001 From: cmoinier Date: Thu, 19 Dec 2024 15:39:19 +0100 Subject: [PATCH 2/4] feat: remove white space and grey bar of my-drafts --- .../src/app/records/my-draft/my-draft.component.html | 1 - .../src/app/records/my-draft/my-draft.component.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/metadata-editor/src/app/records/my-draft/my-draft.component.html b/apps/metadata-editor/src/app/records/my-draft/my-draft.component.html index 8d50b66d55..fdfb8f2069 100644 --- a/apps/metadata-editor/src/app/records/my-draft/my-draft.component.html +++ b/apps/metadata-editor/src/app/records/my-draft/my-draft.component.html @@ -1,4 +1,3 @@ -

diff --git a/apps/metadata-editor/src/app/records/my-draft/my-draft.component.ts b/apps/metadata-editor/src/app/records/my-draft/my-draft.component.ts index 2cf263ff81..5d59d4e53a 100644 --- a/apps/metadata-editor/src/app/records/my-draft/my-draft.component.ts +++ b/apps/metadata-editor/src/app/records/my-draft/my-draft.component.ts @@ -12,7 +12,7 @@ import { startWith, switchMap } from 'rxjs' import { RecordsCountComponent } from '../records-count/records-count.component' import { RecordsListComponent } from '../records-list.component' @Component({ - selector: 'md-editor-my-my-draft', + selector: 'md-editor-my-draft', templateUrl: './my-draft.component.html', styleUrls: ['./my-draft.component.css'], standalone: true, From 183e6a593e3658aba293e32242be194f44633d54 Mon Sep 17 00:00:00 2001 From: Tobias Kohr Date: Thu, 19 Dec 2024 16:39:50 +0100 Subject: [PATCH 3/4] chore(my-records): remove unused search logic --- .../records/my-records/my-records.component.html | 16 ++-------------- .../my-records/my-records.component.spec.ts | 7 ------- .../records/my-records/my-records.component.ts | 8 -------- 3 files changed, 2 insertions(+), 29 deletions(-) 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 0642f47789..2ee7cfac97 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 @@ -1,25 +1,13 @@
- -

- dashboard.records.search -

-
- -
-
- +

dashboard.records.myRecords

-
+
{ owner: user.id, }) }) - - it('should map search filters to searchText$', (done) => { - component.searchText$.subscribe((text) => { - expect(text).toBe('hello world') - done() - }) - }) }) }) 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 de10855ff2..e255dff1d3 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 @@ -24,8 +24,6 @@ import { TemplatePortal } from '@angular/cdk/portal' import { RecordsCountComponent } from '../records-count/records-count.component' import { ButtonComponent } from '@geonetwork-ui/ui/inputs' 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' import { NgIconComponent, @@ -54,7 +52,6 @@ const FILTER_OWNER = 'owner' ButtonComponent, ImportRecordComponent, FeatureSearchModule, - SearchHeaderComponent, SearchFiltersComponent, NgIconComponent, ], @@ -76,7 +73,6 @@ export class MyRecordsComponent implements OnInit { @ViewChild('template') template!: TemplateRef private overlayRef!: OverlayRef searchFields = ['changeDate'] - searchText$: Observable isImportMenuOpen = false @@ -100,10 +96,6 @@ export class MyRecordsComponent implements OnInit { this.searchFacade.updateFilters(filters) }) }) - - this.searchText$ = this.searchFacade.searchFilters$.pipe( - map((filters) => ('any' in filters ? (filters['any'] as string) : null)) - ) } createRecord() { From 737e2bfd74a96a227c3dd04d9db468922e75ed38 Mon Sep 17 00:00:00 2001 From: Tobias Kohr Date: Fri, 20 Dec 2024 10:08:53 +0100 Subject: [PATCH 4/4] test(all-record): add UTs for search --- .../all-records/all-records.component.spec.ts | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/apps/metadata-editor/src/app/records/all-records/all-records.component.spec.ts b/apps/metadata-editor/src/app/records/all-records/all-records.component.spec.ts index a1bc98c57d..c33a1b77da 100644 --- a/apps/metadata-editor/src/app/records/all-records/all-records.component.spec.ts +++ b/apps/metadata-editor/src/app/records/all-records/all-records.component.spec.ts @@ -6,7 +6,7 @@ import { } from '@geonetwork-ui/feature/search' import { ChangeDetectionStrategy } from '@angular/core' import { TranslateModule } from '@ngx-translate/core' -import { BehaviorSubject, of } from 'rxjs' +import { BehaviorSubject, firstValueFrom, of } from 'rxjs' import { barbieUserFixture } from '@geonetwork-ui/common/fixtures' import { ActivatedRoute, Router } from '@angular/router' import { AllRecordsComponent } from './all-records.component' @@ -25,6 +25,7 @@ describe('AllRecordsComponent', () => { const searchFilters = new BehaviorSubject({ any: 'hello world', + owner: {}, }) let component: AllRecordsComponent @@ -34,6 +35,7 @@ describe('AllRecordsComponent', () => { let searchFacade: SearchFacade let platformService: PlatformServiceInterface let fieldsService: FieldsService + let searchService: SearchService beforeEach(() => { return MockBuilder(AllRecordsComponent) @@ -76,6 +78,7 @@ describe('AllRecordsComponent', () => { router = TestBed.inject(Router) searchFacade = TestBed.inject(SearchFacade) + searchService = TestBed.inject(SearchService) platformService = TestBed.inject(PlatformServiceInterface) fieldsService = TestBed.inject(FieldsService) @@ -103,6 +106,8 @@ describe('AllRecordsComponent', () => { searchFacade.setPageSize = jest.fn(() => this) searchFacade.setConfigRequestFields = jest.fn(() => this) + searchService.setFilters = jest.fn(() => this) + component = fixture.componentInstance fixture.detectChanges() @@ -119,6 +124,35 @@ describe('AllRecordsComponent', () => { }) }) + describe('when updating the search filters', () => { + beforeEach(() => { + searchFilters.next({ any: 'new search', owner: { 1: true } }) + }) + + it('updates the search text', async () => { + const searchText = await firstValueFrom(component.searchText$) + expect(searchText).toBe('new search') + }) + it('resets the owner filter', () => { + expect(searchService.setFilters).toHaveBeenCalledWith({ + any: 'new search', + }) + }) + }) + + describe('when destroying the component', () => { + beforeEach(() => { + component.ngOnDestroy() + }) + + it('resets the search filters', () => { + expect(searchFacade.updateFilters).toHaveBeenCalledWith({ any: '' }) + }) + it('unsubscribes from component subscription', () => { + expect(component.subscription.closed).toBe(true) + }) + }) + describe('when clicking createRecord', () => { beforeEach(() => { component.createRecord()