From 756270f69757d60c3194ab33c93941f4d10733b8 Mon Sep 17 00:00:00 2001 From: Romuald Caplier Date: Fri, 24 May 2024 15:34:11 +0200 Subject: [PATCH] feat(datahub): finish organization-page --- .../src/e2e/organization-page.cy.ts | 118 ++++++++++++++++++ apps/datahub-e2e/src/e2e/organizations.cy.ts | 9 +- apps/datahub/src/app/app.module.ts | 2 +- .../organization-header.component.html | 54 -------- .../organization-details.component.css | 15 +++ .../organization-details.component.html | 105 +++++++++------- .../organization-details.component.spec.ts | 85 ++++--------- .../organization-details.component.ts | 112 ++++++++++------- .../organization-header.component.css | 0 .../organization-header.component.html | 60 +++++++++ .../organization-header.component.spec.ts | 0 .../organization-header.component.ts | 13 +- .../organization-page.component.ts | 2 +- .../organizations-from-groups.service.spec.ts | 3 + ...rganizations-from-metadata.service.spec.ts | 7 +- .../domain/src/lib/model/user/user.model.ts | 2 +- libs/feature/catalog/src/index.ts | 1 + .../catalog/src/lib/my-org/my-org.service.ts | 4 +- .../organisations.component.spec.ts | 18 +-- .../src/lib/default/router.service.spec.ts | 16 ++- .../src/lib/error/error.component.html | 32 +++-- .../elements/src/lib/error/error.component.ts | 1 + .../related-record-card.component.html | 2 +- .../related-record-card.component.ts | 23 +++- .../lib/max-lines/max-lines.component.spec.ts | 13 +- .../max-lines/max-lines.component.stories.ts | 2 +- .../docker-entrypoint-initdb.d/dump | Bin 460488 -> 460655 bytes translations/de.json | 2 + translations/en.json | 2 + translations/es.json | 2 + translations/fr.json | 2 + translations/it.json | 2 + translations/nl.json | 2 + translations/pt.json | 2 + translations/sk.json | 2 + 35 files changed, 475 insertions(+), 240 deletions(-) create mode 100644 apps/datahub-e2e/src/e2e/organization-page.cy.ts delete mode 100644 apps/datahub/src/app/organization/header-organization/organization-header.component.html rename apps/datahub/src/app/organization/{header-organization => organization-header}/organization-header.component.css (100%) create mode 100644 apps/datahub/src/app/organization/organization-header/organization-header.component.html rename apps/datahub/src/app/organization/{header-organization => organization-header}/organization-header.component.spec.ts (100%) rename apps/datahub/src/app/organization/{header-organization => organization-header}/organization-header.component.ts (75%) diff --git a/apps/datahub-e2e/src/e2e/organization-page.cy.ts b/apps/datahub-e2e/src/e2e/organization-page.cy.ts new file mode 100644 index 0000000000..5cddc7935c --- /dev/null +++ b/apps/datahub-e2e/src/e2e/organization-page.cy.ts @@ -0,0 +1,118 @@ +import 'cypress-real-events' + +describe('organizations', () => { + beforeEach(() => { + cy.visit('organization/Barbie%20Inc.') + + // aliases + cy.get('gn-ui-navigation-button').as('backButton') + cy.get('[data-test="organizationHeaderName"]').as('organizationHeaderName') + cy.get('[data-test="organizationHeaderWebsiteLink"]').as( + 'organizationHeaderWebsiteLink' + ) + cy.get('[data-test="organizationDescription"]').as( + 'organizationDescription' + ) + cy.get('gn-ui-max-lines').contains('Read more').as('readMoreButton') + cy.get('[data-test="organizationLogo"]').as('organizationLogo') + cy.get('[data-test="organizationDatasetCount"]').as( + 'organizationDatasetCount' + ) + cy.get('[data-test="organizationEmail"]').as('organizationEmail') + cy.get('[data-test="orgPageLasPubDat"]').as('orgPageLasPubDat') + cy.get('[data-test="orgDetailsSearchAllBtn"]').as('orgDetailsSearchAllBtn') + }) + + describe('general display', () => { + describe('header', () => { + describe('back button', () => { + beforeEach(() => { + cy.visit('organisations') + cy.visit('organization/Barbie%20Inc.') + }) + + it('back button goes to the previous visited page', () => { + cy.get('@backButton').click() + cy.url().should('include', '/organisations') + }) + }) + + it('should display the organization name', () => { + cy.get('@organizationHeaderName').should('contain', 'Barbie Inc.') + }) + + it('should display the organization website link', () => { + cy.get('@organizationHeaderWebsiteLink') + .should('be.visible') + .should('have.attr', 'href', 'https://www.barbie-inc.com/') + .and('have.attr', 'target', '_blank') + }) + }) + + describe('details', () => { + describe('left column', () => { + it('should display the organization description', () => { + cy.get('@organizationDescription').should('be.visible') + }) + + it('click on read more should expand the organization description', () => { + let initialDescription + let newDescription + + cy.get('@organizationDescription').then((firstDescription) => { + initialDescription = firstDescription + cy.get('@readMoreButton').trigger('click') + cy.get('@organizationDescription').then((secondDescription) => { + newDescription = secondDescription + expect(newDescription).to.not.equal(initialDescription) + }) + }) + }) + }) + + describe('right column', () => { + it('should display the organization logo', () => { + cy.get('@organizationLogo').should('be.visible') + }) + + it('should display the organization dataset count', () => { + cy.get('@organizationDatasetCount').should('be.visible') + }) + + it('a click on the organization dataset count should open the dataset search page filtered on the organization', () => { + cy.get('@organizationDatasetCount').then(($link) => { + const url = $link.prop('href') + cy.wrap($link).click() + + cy.url().should('eq', url) + }) + }) + + it('should display the organization email', () => { + cy.get('@organizationEmail') + .should('be.visible') + .and('have.attr', 'href', 'mailto:contact@barbie-inc.com') + }) + }) + + describe('last published datasets', () => { + it('should display the last published datasets', () => { + cy.get('@orgPageLasPubDat').should('be.visible') + }) + + it('should display the search all button', () => { + cy.get('@orgDetailsSearchAllBtn').should('be.visible') + }) + + it('a click on the search all button should open the dataset search page filtered on the organization', () => { + cy.get('@orgDetailsSearchAllBtn').then(($link) => { + const url = $link.prop('href') + cy.wrap($link).click() + + cy.url().should('eq', url) + }) + }) + }) + }) + }) +}) diff --git a/apps/datahub-e2e/src/e2e/organizations.cy.ts b/apps/datahub-e2e/src/e2e/organizations.cy.ts index b39da4ca39..ded2dc026d 100644 --- a/apps/datahub-e2e/src/e2e/organizations.cy.ts +++ b/apps/datahub-e2e/src/e2e/organizations.cy.ts @@ -77,14 +77,15 @@ describe('organizations', () => { }) describe('list features', () => { - it('should search with a filter on the selected org on click', () => { + it('should open the organization page', () => { cy.get('@organizationsName') .eq(10) .then(($clickedName) => { cy.get('@organizations').eq(10).click() - cy.url() - .should('include', 'publisher=') - .and('include', encodeURIComponent($clickedName.text().trim())) + cy.url().should( + 'contain', + `organization/${encodeURIComponent($clickedName.text().trim())}` + ) }) }) }) diff --git a/apps/datahub/src/app/app.module.ts b/apps/datahub/src/app/app.module.ts index 534338f09d..0c69562559 100644 --- a/apps/datahub/src/app/app.module.ts +++ b/apps/datahub/src/app/app.module.ts @@ -5,6 +5,7 @@ import { BrowserModule } from '@angular/platform-browser' import { Router, RouterModule } from '@angular/router' import { FeatureCatalogModule, + ORGANIZATION_PAGE_URL_TOKEN, ORGANIZATION_URL_TOKEN, } from '@geonetwork-ui/feature/catalog' import { @@ -94,7 +95,6 @@ import { UiWidgetsModule } from '@geonetwork-ui/ui/widgets' import { RecordUserFeedbacksComponent } from './record/record-user-feedbacks/record-user-feedbacks.component' import { LetDirective } from '@ngrx/component' import { OrganizationPageComponent } from './organization/organization-page/organization-page.component' -import { ORGANIZATION_PAGE_URL_TOKEN } from '../../../../libs/feature/catalog/src/lib/organization-url.token' export const metaReducers: MetaReducer[] = !environment.production ? [] : [] diff --git a/apps/datahub/src/app/organization/header-organization/organization-header.component.html b/apps/datahub/src/app/organization/header-organization/organization-header.component.html deleted file mode 100644 index 9c16ff9bc0..0000000000 --- a/apps/datahub/src/app/organization/header-organization/organization-header.component.html +++ /dev/null @@ -1,54 +0,0 @@ -
-
-
-
- - -
-
- -
-
-
- {{ organization.name }} -
-
- folder -

- {{ organization.recordCount }} -

-

- organization.header.recordCount -

- -

- - {{ organization.website.href }} - open_in_new -
-
-
-
diff --git a/apps/datahub/src/app/organization/organization-details/organization-details.component.css b/apps/datahub/src/app/organization/organization-details/organization-details.component.css index e69de29bb2..c0d50f2d1c 100644 --- a/apps/datahub/src/app/organization/organization-details/organization-details.component.css +++ b/apps/datahub/src/app/organization/organization-details/organization-details.component.css @@ -0,0 +1,15 @@ +.list-page-dot { + width: 6px; + height: 6px; + border-radius: 6px; + position: relative; +} + +.list-page-dot:after { + content: ''; + position: absolute; + left: -7px; + top: -7px; + width: 20px; + height: 20px; +} diff --git a/apps/datahub/src/app/organization/organization-details/organization-details.component.html b/apps/datahub/src/app/organization/organization-details/organization-details.component.html index 9ef5da0aef..0b8a8cb232 100644 --- a/apps/datahub/src/app/organization/organization-details/organization-details.component.html +++ b/apps/datahub/src/app/organization/organization-details/organization-details.component.html @@ -1,10 +1,7 @@ - +
@@ -74,44 +65,52 @@ > organization.lastPublishedDatasets

- + - - - + + + +
- +
+
+ +
- +
- - + + >
@@ -142,3 +155,7 @@
+ + + + diff --git a/apps/datahub/src/app/organization/organization-details/organization-details.component.spec.ts b/apps/datahub/src/app/organization/organization-details/organization-details.component.spec.ts index 6e4d6078ac..ffe1ae3e36 100644 --- a/apps/datahub/src/app/organization/organization-details/organization-details.component.spec.ts +++ b/apps/datahub/src/app/organization/organization-details/organization-details.component.spec.ts @@ -52,10 +52,6 @@ class OrganisationsServiceMock { } const anOrganizationWithManyDatasets: Organization = ORGANISATIONS_FIXTURE[0] -const anOrganizationWithOnlyOneDataset: Organization = { - ...ORGANISATIONS_FIXTURE[0], - recordCount: 1, -} const oneDataset = [DATASET_RECORDS[0]] const manyDatasets = DATASET_RECORDS.concat(DATASET_RECORDS[0]) @@ -204,14 +200,9 @@ describe('OrganizationDetailsComponent', () => { organizationIsLoading.next(true) fixture.detectChanges() - const organizationDetailsLastPublishedDatasetsPreviousNextButtons = - getHTMLElement( - 'organizationDetailsLastPublishedDatasetsPreviousNextButtons' - ) + const orgDetailsNavBtn = getHTMLElement('orgDetailsNavBtn') - expect( - organizationDetailsLastPublishedDatasetsPreviousNextButtons - ).toBeFalsy() + expect(orgDetailsNavBtn).toBeFalsy() }) it('should not be displayed organization is loaded but has no pagination', () => { @@ -219,14 +210,9 @@ describe('OrganizationDetailsComponent', () => { totalPages.next(1) fixture.detectChanges() - const organizationDetailsLastPublishedDatasetsPreviousNextButtons = - getHTMLElement( - 'organizationDetailsLastPublishedDatasetsPreviousNextButtons' - ) + const orgDetailsNavBtn = getHTMLElement('orgDetailsNavBtn') - expect( - organizationDetailsLastPublishedDatasetsPreviousNextButtons - ).toBeFalsy() + expect(orgDetailsNavBtn).toBeFalsy() }) it('should be displayed if organization is loadded and have pagination', () => { @@ -234,39 +220,29 @@ describe('OrganizationDetailsComponent', () => { totalPages.next(10) fixture.detectChanges() - const organizationDetailsLastPublishedDatasetsPreviousNextButtons = - getHTMLElement( - 'organizationDetailsLastPublishedDatasetsPreviousNextButtons' - ) + const orgDetailsNavBtn = getHTMLElement('orgDetailsNavBtn') - expect( - organizationDetailsLastPublishedDatasetsPreviousNextButtons - ).toBeTruthy() + expect(orgDetailsNavBtn).toBeTruthy() }) it('should call paginate from the facade if button is clicked', () => { const initialPageNumber = currentPage.getValue() const nextPageNumber = initialPageNumber + 1 - const organizationDetailsLastPublishedDatasetsPreviousNextButtons = - getHTMLElement( - 'organizationDetailsLastPublishedDatasetsPreviousNextButtons' - ) + const orgDetailsNavBtn = getHTMLElement('orgDetailsNavBtn') - const nextButton = - organizationDetailsLastPublishedDatasetsPreviousNextButtons?.querySelector( - '[data-test="nextButton"]' - ) as HTMLElement + const nextButton = orgDetailsNavBtn?.querySelector( + '[data-test="nextButton"]' + ) as HTMLElement ;(nextButton?.firstChild as HTMLElement).click() fixture.detectChanges() expect(searchFacade.paginate).toHaveBeenCalledWith(nextPageNumber) - const previousButton = - organizationDetailsLastPublishedDatasetsPreviousNextButtons?.querySelector( - '[data-test="previousButton"]' - ) as HTMLElement + const previousButton = orgDetailsNavBtn?.querySelector( + '[data-test="previousButton"]' + ) as HTMLElement ;(previousButton?.firstChild as HTMLElement).click() fixture.detectChanges() @@ -276,20 +252,13 @@ describe('OrganizationDetailsComponent', () => { describe('Search all button', () => { it('should send to the search page filtered on the correct organization', () => { - const organizationDetailsLastPublishedDatasetsSearchAllButton = - getHTMLElement( - 'organizationDetailsLastPublishedDatasetsSearchAllButton' - ) - - expect( - organizationDetailsLastPublishedDatasetsSearchAllButton - ).toBeTruthy() - - expect( - organizationDetailsLastPublishedDatasetsSearchAllButton?.getAttribute( - 'href' - ) - ).toEqual( + const orgDetailsSearchAllBtn = getHTMLElement( + 'orgDetailsSearchAllBtn' + ) + + expect(orgDetailsSearchAllBtn).toBeTruthy() + + expect(orgDetailsSearchAllBtn?.getAttribute('href')).toEqual( `/${ROUTER_ROUTE_SEARCH}?publisher=${encodeURIComponent( anOrganizationWithManyDatasets.name )}` @@ -300,21 +269,15 @@ describe('OrganizationDetailsComponent', () => { describe('Last published datasets', () => { it('should display the datasets properly', () => { - const organizationPageLastPublishedDatasets = getHTMLElement( - 'organizationPageLastPublishedDatasets' - ) + const orgPageLasPubDat = getHTMLElement('orgPageLasPubDat') - expect(organizationPageLastPublishedDatasets).toBeTruthy() - expect(organizationPageLastPublishedDatasets?.children.length).toEqual( - desiredPageSize - ) + expect(orgPageLasPubDat).toBeTruthy() + expect(orgPageLasPubDat?.children.length).toEqual(desiredPageSize) results.next(oneDataset) fixture.detectChanges() - expect(organizationPageLastPublishedDatasets?.children.length).toEqual( - 1 - ) + expect(orgPageLasPubDat?.children.length).toEqual(1) }) }) }) diff --git a/apps/datahub/src/app/organization/organization-details/organization-details.component.ts b/apps/datahub/src/app/organization/organization-details/organization-details.component.ts index 23ab3fd7a2..57ded79580 100644 --- a/apps/datahub/src/app/organization/organization-details/organization-details.component.ts +++ b/apps/datahub/src/app/organization/organization-details/organization-details.component.ts @@ -4,11 +4,13 @@ import { ChangeDetectorRef, Component, Input, + OnChanges, OnDestroy, OnInit, + SimpleChanges, ViewChild, } from '@angular/core' -import { AsyncPipe, NgForOf, NgIf } from '@angular/common' +import { AsyncPipe, NgClass, NgForOf, NgIf } from '@angular/common' import { CatalogRecord, Organization, @@ -32,12 +34,21 @@ import { } from '@geonetwork-ui/ui/elements' import { UiSearchModule } from '@geonetwork-ui/ui/search' import { SearchFacade } from '@geonetwork-ui/feature/search' -import { Observable, of, Subscription, switchMap } from 'rxjs' +import { + BehaviorSubject, + combineLatest, + distinctUntilChanged, + Observable, + of, + Subscription, + switchMap, +} from 'rxjs' import { UiDatavizModule } from '@geonetwork-ui/ui/dataviz' import { RouterLink } from '@angular/router' import { ROUTER_ROUTE_SEARCH } from '@geonetwork-ui/feature/router' import { OrganizationsServiceInterface } from '@geonetwork-ui/common/domain/organizations.service.interface' import { UiWidgetsModule } from '@geonetwork-ui/ui/widgets' +import { startWith } from 'rxjs/operators' @Component({ selector: 'datahub-organization-details', @@ -63,27 +74,36 @@ import { UiWidgetsModule } from '@geonetwork-ui/ui/widgets' UiDatavizModule, RouterLink, UiWidgetsModule, + NgClass, ], }) export class OrganizationDetailsComponent - implements OnInit, AfterViewInit, OnDestroy + implements OnInit, AfterViewInit, OnDestroy, OnChanges { protected readonly Error = Error protected readonly ErrorType = ErrorType + protected readonly ROUTER_ROUTE_SEARCH = ROUTER_ROUTE_SEARCH - @Input() organization: Organization + protected get pages() { + return new Array(this.totalPages).fill(0).map((_, i) => i + 1) + } lastPublishedDatasets$: Observable = of([]) subscriptions$: Subscription = new Subscription() - isOrganizationsLoading = true + isSearchFacadeLoading = true totalPages = 0 currentPage = 1 isFirstPage = this.currentPage === 1 isLastPage = false + organizationHasChanged$ = new BehaviorSubject(undefined) + + @Input() organization?: Organization + @Input() paginationContainerClass = 'w-full bottom-0 top-auto' + @ViewChild(BlockListComponent) list: BlockListComponent constructor( @@ -95,19 +115,30 @@ export class OrganizationDetailsComponent ngOnInit(): void { this.searchFacade.setPageSize(3) - this.lastPublishedDatasets$ = this.organizationsService - .getFiltersForOrgs([this.organization]) - .pipe( - switchMap((filters) => { - return this.searchFacade - .setFilters(filters) - .setSortBy(['desc', 'changeDate']).results$ - }) - ) + this.lastPublishedDatasets$ = this.organizationHasChanged$.pipe( + startWith([]), + switchMap(() => { + return this.organizationsService + .getFiltersForOrgs([this.organization]) + .pipe( + switchMap((filters) => { + return this.searchFacade + .setFilters(filters) + .setSortBy(['desc', 'changeDate']).results$ + }) + ) + }) + ) this.manageSubscriptions() } + ngOnChanges(changes: SimpleChanges): void { + if (changes['organization']) { + this.organizationHasChanged$.next() + } + } + ngAfterViewInit() { // this is required to show the pagination correctly this.changeDetector.detectChanges() @@ -129,38 +160,35 @@ export class OrganizationDetailsComponent } } - private manageSubscriptions() { - this.subscriptions$.add( - this.searchFacade.isLoading$.subscribe( - (isOrganizationsLoading) => - (this.isOrganizationsLoading = isOrganizationsLoading) - ) - ) - - this.subscriptions$.add( - this.searchFacade.totalPages$.subscribe( - (totalPages) => (this.totalPages = totalPages) - ) - ) - - this.subscriptions$.add( - this.searchFacade.isBeginningOfResults$.subscribe( - (isBeginningOfResults) => (this.isFirstPage = isBeginningOfResults) - ) - ) - - this.subscriptions$.add( - this.searchFacade.isEndOfResults$.subscribe( - (isEndOfResults) => (this.isLastPage = isEndOfResults) - ) - ) + goToPage(page: number) { + this.searchFacade.paginate(page) + } + private manageSubscriptions() { this.subscriptions$.add( - this.searchFacade.currentPage$.subscribe( - (currentPage) => (this.currentPage = currentPage) + combineLatest([ + this.searchFacade.isLoading$.pipe(distinctUntilChanged()), + this.searchFacade.totalPages$.pipe(distinctUntilChanged()), + this.searchFacade.isBeginningOfResults$.pipe(distinctUntilChanged()), + this.searchFacade.isEndOfResults$.pipe(distinctUntilChanged()), + this.searchFacade.currentPage$.pipe(distinctUntilChanged()), + ]).subscribe( + ([ + isSearchFacadeLoading, + totalPages, + isBeginningOfResults, + isEndOfResults, + currentPage, + ]) => { + this.isSearchFacadeLoading = isSearchFacadeLoading + this.totalPages = totalPages + this.isFirstPage = isBeginningOfResults + this.isLastPage = isEndOfResults + this.currentPage = currentPage + } ) ) } - protected readonly ROUTER_ROUTE_SEARCH = ROUTER_ROUTE_SEARCH + protected readonly errorTypes = ErrorType } diff --git a/apps/datahub/src/app/organization/header-organization/organization-header.component.css b/apps/datahub/src/app/organization/organization-header/organization-header.component.css similarity index 100% rename from apps/datahub/src/app/organization/header-organization/organization-header.component.css rename to apps/datahub/src/app/organization/organization-header/organization-header.component.css diff --git a/apps/datahub/src/app/organization/organization-header/organization-header.component.html b/apps/datahub/src/app/organization/organization-header/organization-header.component.html new file mode 100644 index 0000000000..42e90a94bd --- /dev/null +++ b/apps/datahub/src/app/organization/organization-header/organization-header.component.html @@ -0,0 +1,60 @@ +
+
+
+
+ + +
+
+ +
+
+ +
+ {{ organization.name }} +
+
+ folder +

+ {{ organization.recordCount }} +

+

+ organization.header.recordCount +

+ +

+ + {{ organization.website.href }} + open_in_new +
+
+
+
+
diff --git a/apps/datahub/src/app/organization/header-organization/organization-header.component.spec.ts b/apps/datahub/src/app/organization/organization-header/organization-header.component.spec.ts similarity index 100% rename from apps/datahub/src/app/organization/header-organization/organization-header.component.spec.ts rename to apps/datahub/src/app/organization/organization-header/organization-header.component.spec.ts diff --git a/apps/datahub/src/app/organization/header-organization/organization-header.component.ts b/apps/datahub/src/app/organization/organization-header/organization-header.component.ts similarity index 75% rename from apps/datahub/src/app/organization/header-organization/organization-header.component.ts rename to apps/datahub/src/app/organization/organization-header/organization-header.component.ts index 58c51e903f..8e62fd986d 100644 --- a/apps/datahub/src/app/organization/header-organization/organization-header.component.ts +++ b/apps/datahub/src/app/organization/organization-header/organization-header.component.ts @@ -6,6 +6,8 @@ import { UiCatalogModule } from '@geonetwork-ui/ui/catalog' import { Organization } from '@geonetwork-ui/common/domain/model/record' import { AsyncPipe, Location, NgIf } from '@angular/common' import { MatIconModule } from '@angular/material/icon' +import { ErrorType, UiElementsModule } from '@geonetwork-ui/ui/elements' +import { Router } from '@angular/router' @Component({ selector: 'datahub-organization-header', @@ -20,10 +22,11 @@ import { MatIconModule } from '@angular/material/icon' NgIf, MatIconModule, AsyncPipe, + UiElementsModule, ], }) export class OrganizationHeaderComponent { - @Input() organization: Organization + @Input() organization?: Organization backgroundCss = getThemeConfig().HEADER_BACKGROUND || @@ -31,9 +34,13 @@ export class OrganizationHeaderComponent { foregroundColor = getThemeConfig().HEADER_FOREGROUND_COLOR || '#ffffff' showLanguageSwitcher = getGlobalConfig().LANGUAGES?.length > 0 - constructor(private location: Location) {} + constructor(private location: Location, private router: Router) {} back() { - this.location.back() + this.organization + ? this.location.back() + : this.router.navigateByUrl('/organisations') } + + protected readonly errorTypes = ErrorType } diff --git a/apps/datahub/src/app/organization/organization-page/organization-page.component.ts b/apps/datahub/src/app/organization/organization-page/organization-page.component.ts index a1dc77c981..99cc91b16b 100644 --- a/apps/datahub/src/app/organization/organization-page/organization-page.component.ts +++ b/apps/datahub/src/app/organization/organization-page/organization-page.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core' import { RouterFacade } from '@geonetwork-ui/feature/router' import { AsyncPipe, NgIf } from '@angular/common' -import { OrganizationHeaderComponent } from '../header-organization/organization-header.component' +import { OrganizationHeaderComponent } from '../organization-header/organization-header.component' import { OrganizationDetailsComponent } from '../organization-details/organization-details.component' import { combineLatest, Observable, of, switchMap } from 'rxjs' import { filter } from 'rxjs/operators' diff --git a/libs/api/repository/src/lib/gn4/organizations/organizations-from-groups.service.spec.ts b/libs/api/repository/src/lib/gn4/organizations/organizations-from-groups.service.spec.ts index fe4c0ad104..dd77d0a52c 100644 --- a/libs/api/repository/src/lib/gn4/organizations/organizations-from-groups.service.spec.ts +++ b/libs/api/repository/src/lib/gn4/organizations/organizations-from-groups.service.spec.ts @@ -50,12 +50,14 @@ const sampleOrgA: Organization = { recordCount: 80, description: 'A description for Köniz Municipality', website: new URL('https://www.koeniz.ch/'), + email: 'reto.jau@koeniz.ch', } const sampleOrgB: Organization = { logoUrl: new URL('http://localhost/geonetwork/images/harvesting/bakom.png'), name: 'Office fédéral de la communication OFCOM', recordCount: 50, website: new URL('http://www.bakom.admin.ch/'), + email: 'christian.meier@bakom.admin.ch', } const sampleOrgC: Organization = { logoUrl: new URL( @@ -65,6 +67,7 @@ const sampleOrgC: Organization = { recordCount: 20, description: 'A description for ARE', website: new URL('http://www.are.admin.ch/'), + email: 'rolf.giezendanner@are.admin.ch', } class SearchApiServiceMock { diff --git a/libs/api/repository/src/lib/gn4/organizations/organizations-from-metadata.service.spec.ts b/libs/api/repository/src/lib/gn4/organizations/organizations-from-metadata.service.spec.ts index 10fb3101b8..5f17e9e1d7 100644 --- a/libs/api/repository/src/lib/gn4/organizations/organizations-from-metadata.service.spec.ts +++ b/libs/api/repository/src/lib/gn4/organizations/organizations-from-metadata.service.spec.ts @@ -25,21 +25,22 @@ const sampleOrgA: Organization = { name: 'ARE', recordCount: 5, website: new URL('http://www.are.admin.ch/'), + email: 'rolf.giezendanner@are.admin.ch', } const sampleOrgB: Organization = { logoUrl: new URL('http://localhost/geonetwork/images/harvesting/bakom.png'), name: 'BAKOM', recordCount: 2, website: new URL('http://www.bakom.admin.ch/'), + email: 'christian.meier@bakom.admin.ch', } const sampleOrgC: Organization = { - logoUrl: new URL( - 'http://localhost/geonetwork/images/harvesting/ifremer-org.png' - ), + logoUrl: new URL('http://localhost/geonetwork/images/harvesting/ifremer.png'), name: 'Ifremer', recordCount: 1, description: "Institut français de recherche pour l'exploitation de la mer", website: new URL('https://www.ifremer.fr/'), + email: 'ifremer.ifremer@ifremer.admin.fr', } let geonetworkVersion: string diff --git a/libs/common/domain/src/lib/model/user/user.model.ts b/libs/common/domain/src/lib/model/user/user.model.ts index fefd657049..591fc7bf18 100644 --- a/libs/common/domain/src/lib/model/user/user.model.ts +++ b/libs/common/domain/src/lib/model/user/user.model.ts @@ -5,6 +5,6 @@ export interface UserModel { name: string surname: string email: string - organization: string + organisation: string profileIcon?: string } diff --git a/libs/feature/catalog/src/index.ts b/libs/feature/catalog/src/index.ts index efa22c7852..54cc255a57 100644 --- a/libs/feature/catalog/src/index.ts +++ b/libs/feature/catalog/src/index.ts @@ -1,4 +1,5 @@ export * from './lib/feature-catalog.module' +export * from './lib/organization-url.token' export * from './lib/sources/sources.service' export * from './lib/sources/sources.model' export * from './lib/records/records.service' diff --git a/libs/feature/catalog/src/lib/my-org/my-org.service.ts b/libs/feature/catalog/src/lib/my-org/my-org.service.ts index 324884f5a7..8840cc3bba 100644 --- a/libs/feature/catalog/src/lib/my-org/my-org.service.ts +++ b/libs/feature/catalog/src/lib/my-org/my-org.service.ts @@ -27,12 +27,12 @@ export class MyOrgService { this.orgService.organisations$, ]).pipe( map(([user, allUsers, orgs]) => { - const orgName = user.organization + const orgName = user.organisation const org = orgs.find((org) => org.name === orgName) const logoUrl = org?.logoUrl?.toString() const recordCount = org?.recordCount const userList = allUsers.filter( - (user) => user.organization === orgName + (user) => user.organisation === orgName ) const userCount = userList.length return { diff --git a/libs/feature/catalog/src/lib/organisations/organisations.component.spec.ts b/libs/feature/catalog/src/lib/organisations/organisations.component.spec.ts index 70e97b09b7..138e62fdeb 100644 --- a/libs/feature/catalog/src/lib/organisations/organisations.component.spec.ts +++ b/libs/feature/catalog/src/lib/organisations/organisations.component.spec.ts @@ -4,6 +4,7 @@ import { DebugElement, EventEmitter, Input, + NO_ERRORS_SCHEMA, Output, } from '@angular/core' import { ComponentFixture, TestBed } from '@angular/core/testing' @@ -27,8 +28,8 @@ class OrganisationsFilterMockComponent { template: '
', }) class OrganisationPreviewMockComponent { - @Input() organisation: Organization - @Output() clickedOrganisation = new EventEmitter() + @Input() organization: Organization + @Output() clickedOrganization = new EventEmitter() } @Component({ @@ -85,6 +86,7 @@ describe('OrganisationsComponent', () => { useClass: OrganisationsServiceMock, }, ], + schemas: [NO_ERRORS_SCHEMA], }) .overrideComponent(OrganisationsComponent, { set: { changeDetection: ChangeDetectionStrategy.Default }, @@ -118,10 +120,10 @@ describe('OrganisationsComponent', () => { .map((debugElement) => debugElement.componentInstance) }) it('should pass first organisation (sorted by name-asc) to first ui preview component', () => { - expect(orgPreviewComponents[0].organisation.name).toEqual('A Data Org') + expect(orgPreviewComponents[0].organization.name).toEqual('A Data Org') }) it('should pass 6th organisation (sorted by name-asc) on page to 6th ui preview component', () => { - expect(orgPreviewComponents[5].organisation.name).toEqual('E Data Org') + expect(orgPreviewComponents[5].organization.name).toEqual('E Data Org') }) }) describe('pass params to ui pagination component', () => { @@ -152,13 +154,13 @@ describe('OrganisationsComponent', () => { expect(paginationComponentDE.componentInstance.currentPage).toEqual(2) }) it('should pass first organisation of second page (sorted by name-asc) to first ui preview component', () => { - expect(orgPreviewComponents[0].organisation.name).toEqual( + expect(orgPreviewComponents[0].organization.name).toEqual( 'é Data Org' ) }) it('should pass last organisation of second page (sorted by name-asc) to last ui preview component', () => { expect( - orgPreviewComponents[orgPreviewComponents.length - 1].organisation + orgPreviewComponents[orgPreviewComponents.length - 1].organization .name ).toEqual('J Data Org') }) @@ -193,12 +195,12 @@ describe('OrganisationsComponent', () => { expect(organisations[0]).toEqual(ORGANISATIONS_FIXTURE[5]) }) it('should pass organisation with max recordCount to first preview component', () => { - expect(orgPreviewComponents[0].organisation).toEqual( + expect(orgPreviewComponents[0].organization).toEqual( ORGANISATIONS_FIXTURE[5] ) }) it('should pass organisation with 6th highest recordCount to 6th preview component', () => { - expect(orgPreviewComponents[5].organisation).toEqual( + expect(orgPreviewComponents[5].organization).toEqual( ORGANISATIONS_FIXTURE[3] ) }) diff --git a/libs/feature/router/src/lib/default/router.service.spec.ts b/libs/feature/router/src/lib/default/router.service.spec.ts index bfae57c838..02e1736354 100644 --- a/libs/feature/router/src/lib/default/router.service.spec.ts +++ b/libs/feature/router/src/lib/default/router.service.spec.ts @@ -3,18 +3,24 @@ import { Router } from '@angular/router' import { RouterService } from './router.service' import { ROUTER_CONFIG } from './router.config' +import { ROUTER_ROUTE_ORGANIZATION } from './constants' const SearchRouteComponent = { name: 'searchRoute', } const RecordRouteComponent = { - name: 'recordhRoute', + name: 'recordRoute', +} + +const OrganizationRouteComponent = { + name: 'organizationRoute', } const routerConfigMock = { searchStateId: 'main', searchRouteComponent: SearchRouteComponent, recordRouteComponent: RecordRouteComponent, + organizationRouteComponent: OrganizationRouteComponent, } const RouterMock = { resetConfig: jest.fn(), @@ -37,10 +43,16 @@ const expectedRoutes = [ }, { component: { - name: 'recordhRoute', + name: 'recordRoute', }, path: 'dataset/:metadataUuid', }, + { + path: `${ROUTER_ROUTE_ORGANIZATION}/:name`, + component: { + name: 'organizationRoute', + }, + }, ] describe('RouterService', () => { let service: RouterService diff --git a/libs/ui/elements/src/lib/error/error.component.html b/libs/ui/elements/src/lib/error/error.component.html index 0b0c302281..e06e2a1b2f 100644 --- a/libs/ui/elements/src/lib/error/error.component.html +++ b/libs/ui/elements/src/lib/error/error.component.html @@ -8,11 +8,11 @@
face question_mark + >question_mark + question_mark + >question_mark +
search.error.couldNotReachApi
@@ -36,12 +36,11 @@
computer question_mark + >question_mark +
search.error.organizationHasNoDataset
-
computer question_mark + >question_mark +
search.error.recordNotFound
{{ error }}
+
+
+ computer + question_mark + +
+
+ search.error.organizationNotFound +
+
{{ error }}
+
diff --git a/libs/ui/elements/src/lib/error/error.component.ts b/libs/ui/elements/src/lib/error/error.component.ts index 6129f28a5f..a7b79425b0 100644 --- a/libs/ui/elements/src/lib/error/error.component.ts +++ b/libs/ui/elements/src/lib/error/error.component.ts @@ -6,6 +6,7 @@ export enum ErrorType { RECORD_NOT_FOUND, DATASET_HAS_NO_LINK, ORGANIZATION_HAS_NO_DATASET, + ORGANIZATION_NOT_FOUND, } @Component({ diff --git a/libs/ui/elements/src/lib/related-record-card/related-record-card.component.html b/libs/ui/elements/src/lib/related-record-card/related-record-card.component.html index 932c405b23..85fb920c14 100644 --- a/libs/ui/elements/src/lib/related-record-card/related-record-card.component.html +++ b/libs/ui/elements/src/lib/related-record-card/related-record-card.component.html @@ -1,5 +1,5 @@ diff --git a/libs/ui/elements/src/lib/related-record-card/related-record-card.component.ts b/libs/ui/elements/src/lib/related-record-card/related-record-card.component.ts index f883b3c31b..c166ea575d 100644 --- a/libs/ui/elements/src/lib/related-record-card/related-record-card.component.ts +++ b/libs/ui/elements/src/lib/related-record-card/related-record-card.component.ts @@ -1,4 +1,4 @@ -import { Component, ChangeDetectionStrategy, Input } from '@angular/core' +import { ChangeDetectionStrategy, Component, Input } from '@angular/core' import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record' @Component({ @@ -8,5 +8,26 @@ import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record' changeDetection: ChangeDetectionStrategy.OnPush, }) export class RelatedRecordCardComponent { + private readonly baseClasses: string + @Input() record: CatalogRecord + @Input() extraClass = '' + + constructor() { + this.baseClasses = [ + 'w-72', + 'h-96', + 'overflow-hidden', + 'rounded-lg', + 'bg-white', + 'cursor-pointer', + 'block', + 'hover:-translate-y-2 ', + 'duration-[180ms]', + ].join(' ') + } + + get classList() { + return `${this.baseClasses} ${this.extraClass}` + } } diff --git a/libs/ui/layout/src/lib/max-lines/max-lines.component.spec.ts b/libs/ui/layout/src/lib/max-lines/max-lines.component.spec.ts index dc28d6869c..075b5aae7c 100644 --- a/libs/ui/layout/src/lib/max-lines/max-lines.component.spec.ts +++ b/libs/ui/layout/src/lib/max-lines/max-lines.component.spec.ts @@ -4,6 +4,13 @@ import { MaxLinesComponent } from './max-lines.component' import { Component, importProvidersFrom } from '@angular/core' import { TranslateModule } from '@ngx-translate/core' +// Mock implementation of ResizeObserver +class ResizeObserverMock { + observe = jest.fn() + unobserve = jest.fn() + disconnect = jest.fn() +} + @Component({ template: ` @@ -22,10 +29,12 @@ describe('MaxLinesComponent', () => { let maxLinesComponent: MaxLinesComponent beforeEach(() => { + ;(window as any).ResizeObserver = ResizeObserverMock + TestBed.configureTestingModule({ - imports: [TranslateModule.forRoot()], + imports: [TranslateModule.forRoot(), MaxLinesComponent], providers: [importProvidersFrom(TranslateModule.forRoot())], - declarations: [MaxLinesComponent, TestHostComponent], + declarations: [TestHostComponent], }) fixture = TestBed.createComponent(TestHostComponent) hostComponent = fixture.componentInstance diff --git a/libs/ui/layout/src/lib/max-lines/max-lines.component.stories.ts b/libs/ui/layout/src/lib/max-lines/max-lines.component.stories.ts index c93ce310e2..1a811f97ab 100644 --- a/libs/ui/layout/src/lib/max-lines/max-lines.component.stories.ts +++ b/libs/ui/layout/src/lib/max-lines/max-lines.component.stories.ts @@ -10,7 +10,7 @@ import { TranslateModule } from '@ngx-translate/core' import { TRANSLATE_DEFAULT_CONFIG, UtilI18nModule, -} from '../../../../../util/i18n/src' +} from '@geonetwork-ui/util/i18n' import { importProvidersFrom } from '@angular/core' export default { diff --git a/support-services/docker-entrypoint-initdb.d/dump b/support-services/docker-entrypoint-initdb.d/dump index 0a433c68ec163548b3136110c93fbcc891a0406e..f1f88acdffc6bb1d1fc7a5db1139104e15296fc2 100644 GIT binary patch delta 3287 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 diff --git a/translations/de.json b/translations/de.json index 51ea7ea43e..1f7936a6b2 100644 --- a/translations/de.json +++ b/translations/de.json @@ -245,6 +245,7 @@ "organization.details.mailContact": "", "organization.datasets": "", "organization.lastPublishedDatasets": "", + "organization.lastPublishedDatasets.searchAllButton": "", "pagination.nextPage": "Nächste Seite", "pagination.page": "Seite", "pagination.pageOf": "von", @@ -345,6 +346,7 @@ "search.error.receivedError": "Ein Fehler ist aufgetreten", "search.error.recordHasnolink": "", "search.error.recordNotFound": "Der Datensatz mit der Kennung \"{ id }\" konnte nicht gefunden werden.", + "search.error.organizationNotFound": "", "search.error.organizationHasNoDataset": "", "search.field.any.placeholder": "Suche Datensätze ...", "search.field.sortBy": "Sortieren nach:", diff --git a/translations/en.json b/translations/en.json index c9c3eff5dd..4ea86a9ea6 100644 --- a/translations/en.json +++ b/translations/en.json @@ -245,6 +245,7 @@ "organization.details.mailContact": "Contact by email", "organization.datasets": "Datasets", "organization.lastPublishedDatasets": "Last published datasets", + "organization.lastPublishedDatasets.searchAllButton": "Search all", "pagination.nextPage": "Next page", "pagination.page": "page", "pagination.pageOf": "of", @@ -345,6 +346,7 @@ "search.error.receivedError": "An error was received", "search.error.recordHasnolink": "This record currently has no link yet, please come back later.", "search.error.recordNotFound": "The record with identifier \"{ id }\" could not be found.", + "search.error.organizationNotFound": "This organization could not be found.", "search.error.organizationHasNoDataset": "This organization has no dataset yet.", "search.field.any.placeholder": "Search datasets ...", "search.field.sortBy": "Sort by:", diff --git a/translations/es.json b/translations/es.json index 6905a25102..341cc8961f 100644 --- a/translations/es.json +++ b/translations/es.json @@ -245,6 +245,7 @@ "organization.details.mailContact": "", "organization.datasets": "", "organization.lastPublishedDatasets": "", + "organization.lastPublishedDatasets.searchAllButton": "", "pagination.nextPage": "", "pagination.page": "", "pagination.pageOf": "", @@ -345,6 +346,7 @@ "search.error.receivedError": "", "search.error.recordHasnolink": "", "search.error.recordNotFound": "", + "search.error.organizationNotFound": "", "search.error.organizationHasNoDataset": "", "search.field.any.placeholder": "", "search.field.sortBy": "", diff --git a/translations/fr.json b/translations/fr.json index 90b6272333..5175e9ad24 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -245,6 +245,7 @@ "organization.details.mailContact": "Contacter par mail", "organization.datasets": "Données", "organization.lastPublishedDatasets": "Dernières données publiées", + "organization.lastPublishedDatasets.searchAllButton": "Rechercher tous", "pagination.nextPage": "Page suivante", "pagination.page": "page", "pagination.pageOf": "sur", @@ -345,6 +346,7 @@ "search.error.receivedError": "Erreur retournée", "search.error.recordHasnolink": "Ce dataset n'a pas encore de lien, réessayez plus tard s'il vous plaît.", "search.error.recordNotFound": "Cette donnée n'a pu être trouvée.", + "search.error.organizationNotFound": "L'organisation n'a pas pu être trouvée.", "search.error.organizationHasNoDataset": "Cette organisation n'a pas encore de données.", "search.field.any.placeholder": "Rechercher une donnée...", "search.field.sortBy": "Trier par :", diff --git a/translations/it.json b/translations/it.json index 88b55b64bb..bfcb2c988f 100644 --- a/translations/it.json +++ b/translations/it.json @@ -245,6 +245,7 @@ "organization.details.mailContact": "", "organization.datasets": "", "organization.lastPublishedDatasets": "", + "organization.lastPublishedDatasets.searchAllButton": "", "pagination.nextPage": "Pagina successiva", "pagination.page": "pagina", "pagination.pageOf": "di", @@ -345,6 +346,7 @@ "search.error.receivedError": "Errore ricevuto", "search.error.recordHasnolink": "", "search.error.recordNotFound": "Impossibile trovare questo dato", + "search.error.organizationNotFound": "", "search.error.organizationHasNoDataset": "", "search.field.any.placeholder": "Cerca un dato...", "search.field.sortBy": "Ordina per:", diff --git a/translations/nl.json b/translations/nl.json index 837e08bd73..b7d0823e3a 100644 --- a/translations/nl.json +++ b/translations/nl.json @@ -245,6 +245,7 @@ "organization.details.mailContact": "", "organization.datasets": "", "organization.lastPublishedDatasets": "", + "organization.lastPublishedDatasets.searchAllButton": "", "pagination.nextPage": "", "pagination.page": "", "pagination.pageOf": "", @@ -345,6 +346,7 @@ "search.error.receivedError": "", "search.error.recordHasnolink": "", "search.error.recordNotFound": "", + "search.error.organizationNotFound": "", "search.error.organizationHasNoDataset": "", "search.field.any.placeholder": "", "search.field.sortBy": "", diff --git a/translations/pt.json b/translations/pt.json index d79183c173..096eef05fd 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -245,6 +245,7 @@ "organization.details.mailContact": "", "organization.datasets": "", "organization.lastPublishedDatasets": "", + "organization.lastPublishedDatasets.searchAllButton": "", "pagination.nextPage": "", "pagination.page": "", "pagination.pageOf": "", @@ -345,6 +346,7 @@ "search.error.receivedError": "", "search.error.recordHasnolink": "", "search.error.recordNotFound": "", + "search.error.organizationNotFound": "", "search.error.organizationHasNoDataset": "", "search.field.any.placeholder": "", "search.field.sortBy": "", diff --git a/translations/sk.json b/translations/sk.json index 4c601e5da3..56768147b0 100644 --- a/translations/sk.json +++ b/translations/sk.json @@ -245,6 +245,7 @@ "organization.details.mailContact": "", "organization.datasets": "", "organization.lastPublishedDatasets": "", + "organization.lastPublishedDatasets.searchAllButton": "", "pagination.nextPage": "Ďalšia stránka", "pagination.page": "strana", "pagination.pageOf": "z", @@ -345,6 +346,7 @@ "search.error.receivedError": "Bola zaznamenaná chyba", "search.error.recordHasnolink": "", "search.error.recordNotFound": "Záznam s identifikátorom \"{ id }\" sa nepodarilo nájsť.", + "search.error.organizationNotFound": "", "search.error.organizationHasNoDataset": "", "search.field.any.placeholder": "Hľadať datasety ...", "search.field.sortBy": "Zoradiť podľa:",