diff --git a/apps/metadata-editor-e2e/src/e2e/create.cy.ts b/apps/metadata-editor-e2e/src/e2e/create.cy.ts index 4d8bd6b97a..e3a72f498b 100644 --- a/apps/metadata-editor-e2e/src/e2e/create.cy.ts +++ b/apps/metadata-editor-e2e/src/e2e/create.cy.ts @@ -39,5 +39,24 @@ describe('create', () => { cy.go('back') cy.url().should('include', '/catalog/search') }) + + it('the created record should have the registered user as point of contact in the data managers section', () => { + // First create a record and its draft + cy.get('[data-cy="create-record"]').click() + + cy.get('[data-test=pageSelectorButtons]') + .find('gn-ui-button') + .eq(2) + .click() + + cy.get('[data-test=displayedRoles]').children().should('have.length', 1) + + cy.get('[data-test=displayedRoles]') + .children() + .find('gn-ui-contact-card') + .get('[data-test=contactCardName]') + .invoke('text') + .should('contain', 'admin admin') + }) }) }) diff --git a/apps/metadata-editor-e2e/src/e2e/edit.cy.ts b/apps/metadata-editor-e2e/src/e2e/edit.cy.ts index 8dcc1b5fe8..102b0687ef 100644 --- a/apps/metadata-editor-e2e/src/e2e/edit.cy.ts +++ b/apps/metadata-editor-e2e/src/e2e/edit.cy.ts @@ -75,7 +75,6 @@ describe('editor form', () => { beforeEach(() => { cy.login('admin', 'admin', false) - // Alpine convention record cy.visit('/edit/accroche_velos') cy.get('@accessAndContactPageSelectorButton').click() diff --git a/apps/metadata-editor/src/app/edit/edit-page.component.ts b/apps/metadata-editor/src/app/edit/edit-page.component.ts index ab23e2ba26..02514391db 100644 --- a/apps/metadata-editor/src/app/edit/edit-page.component.ts +++ b/apps/metadata-editor/src/app/edit/edit-page.component.ts @@ -59,6 +59,7 @@ export class EditPageComponent implements OnInit, OnDestroy { ngOnInit(): void { const [currentRecord, currentRecordSource, currentRecordAlreadySaved] = this.route.snapshot.data['record'] + this.facade.openRecord( currentRecord, currentRecordSource, diff --git a/apps/metadata-editor/src/app/new-record.resolver.spec.ts b/apps/metadata-editor/src/app/new-record.resolver.spec.ts index e77e545fcd..ffa10dc50c 100644 --- a/apps/metadata-editor/src/app/new-record.resolver.spec.ts +++ b/apps/metadata-editor/src/app/new-record.resolver.spec.ts @@ -1,8 +1,30 @@ import { TestBed } from '@angular/core/testing' -import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record' import { RecordsRepositoryInterface } from '@geonetwork-ui/common/domain/repository/records-repository.interface' import { MockProvider } from 'ng-mocks' +import { + CatalogRecord, + Individual, +} from '@geonetwork-ui/common/domain/model/record' import { NewRecordResolver } from './new-record.resolver' +import { NO_ERRORS_SCHEMA } from '@angular/core' +import { PlatformServiceInterface } from '@geonetwork-ui/common/domain/platform.service.interface' +import { OrganizationsServiceInterface } from '@geonetwork-ui/common/domain/organizations.service.interface' +import { BehaviorSubject, of } from 'rxjs' +import { + ORGANISATIONS_FIXTURE, + REGION_HAUT_DE_FRANCE_ORG_FIXTURE, + USER_FIXTURE, +} from '@geonetwork-ui/common/fixtures' + +const user = USER_FIXTURE() + +class PlatformServiceInterfaceMock { + getMe = jest.fn(() => new BehaviorSubject(user)) +} + +class OrganizationsServiceInterfaceMock { + organisations$ = of(ORGANISATIONS_FIXTURE) +} describe('NewRecordResolver', () => { let resolver: NewRecordResolver @@ -10,6 +32,20 @@ describe('NewRecordResolver', () => { let recordsRepository: RecordsRepositoryInterface beforeEach(() => { + TestBed.configureTestingModule({ + schemas: [NO_ERRORS_SCHEMA], + providers: [ + { + provide: PlatformServiceInterface, + useClass: PlatformServiceInterfaceMock, + }, + { + provide: OrganizationsServiceInterface, + useClass: OrganizationsServiceInterfaceMock, + }, + ], + }) + TestBed.configureTestingModule({ providers: [MockProvider(RecordsRepositoryInterface)], }) @@ -28,12 +64,24 @@ describe('NewRecordResolver', () => { resolver.resolve().subscribe((r) => (resolvedData = r)) recordsRepository.generateTemporaryId = jest.fn(() => 'TEMP-ID-123') }) - it('creates a new empty record with a pregenerated id', () => { + + it('creates a new empty record with a pregenerated id and connected user information as contact for ressource with the point_of_contact role.', () => { + const expectedContactsForResource = [ + { + firstName: user.name, + lastName: user.surname, + email: user.email, + role: 'point_of_contact', + organization: REGION_HAUT_DE_FRANCE_ORG_FIXTURE(), + } as Individual, + ] + expect(resolvedData).toMatchObject([ { abstract: '', kind: 'dataset', recordUpdated: expect.any(Date), + contactsForResource: expectedContactsForResource, status: 'ongoing', temporalExtents: [], title: expect.stringMatching(/^My new record/), diff --git a/apps/metadata-editor/src/app/new-record.resolver.ts b/apps/metadata-editor/src/app/new-record.resolver.ts index bfd2cc6a8d..345ad9ee08 100644 --- a/apps/metadata-editor/src/app/new-record.resolver.ts +++ b/apps/metadata-editor/src/app/new-record.resolver.ts @@ -1,42 +1,91 @@ import { Injectable } from '@angular/core' -import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record' +import { + CatalogRecord, + Individual, + Organization, +} from '@geonetwork-ui/common/domain/model/record' import { RecordsRepositoryInterface } from '@geonetwork-ui/common/domain/repository/records-repository.interface' import { Observable, of } from 'rxjs' +import { map, switchMap } from 'rxjs/operators' +import { PlatformServiceInterface } from '@geonetwork-ui/common/domain/platform.service.interface' +import { OrganizationsServiceInterface } from '@geonetwork-ui/common/domain/organizations.service.interface' @Injectable({ providedIn: 'root', }) export class NewRecordResolver { - constructor(private recordsRepository: RecordsRepositoryInterface) {} + constructor( + private recordsRepository: RecordsRepositoryInterface, + private platformService: PlatformServiceInterface, + private organizationsServiceInterface: OrganizationsServiceInterface + ) {} resolve(): Observable<[CatalogRecord, string, boolean]> { - return of([ - { - uniqueIdentifier: this.recordsRepository.generateTemporaryId(), - title: `My new record (${new Date().toISOString()})`, - abstract: '', - ownerOrganization: {}, - contacts: [], - recordUpdated: new Date(), - updateFrequency: 'unknown', - languages: [], - topics: [], - keywords: [], - licenses: [], - legalConstraints: [], - securityConstraints: [], - otherConstraints: [], - overviews: [], - contactsForResource: [], - kind: 'dataset', - status: 'ongoing', - lineage: '', - distributions: [], - spatialExtents: [], - temporalExtents: [], - } as CatalogRecord, - null, - false, - ]) + return this.getCurrentUserAsPointOfContact().pipe( + map((contactsForResource) => { + const catalogRecord = { + uniqueIdentifier: this.recordsRepository.generateTemporaryId(), + title: `My new record (${new Date().toISOString()})`, + abstract: '', + ownerOrganization: {}, + contacts: [], + recordUpdated: new Date(), + updateFrequency: 'unknown', + languages: [], + topics: [], + keywords: [], + licenses: [], + legalConstraints: [], + securityConstraints: [], + otherConstraints: [], + overviews: [], + contactsForResource: contactsForResource ? [contactsForResource] : [], + kind: 'dataset', + status: 'ongoing', + lineage: '', + distributions: [], + spatialExtents: [], + temporalExtents: [], + } as CatalogRecord + + return [catalogRecord, null, false] + }) + ) + } + + getCurrentUserAsPointOfContact(): Observable { + return this.platformService.getMe().pipe( + switchMap((user) => { + if (!user) { + // todo: maybe notify the user that they need to log in? + return of(null) + } + + return this.organizationsServiceInterface.organisations$.pipe( + map((organizations) => { + let organization = organizations.find( + (org) => org.name === user.organisation + ) + + if (!organization) { + organization = { + name: '', + } as Organization + } + + const individual: Individual = { + email: user.email ?? '', + address: '', + firstName: user.name ?? '', + lastName: user.surname ?? '', + role: 'point_of_contact', + organization: organization, + } + + return individual + }) + ) + }) + ) } } 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 591fc7bf18..0c25e2fde2 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 - organisation: string + organisation?: string profileIcon?: string } diff --git a/libs/common/fixtures/src/lib/organisations.fixture.ts b/libs/common/fixtures/src/lib/organisations.fixture.ts index a2c5818b36..9ca4d95091 100644 --- a/libs/common/fixtures/src/lib/organisations.fixture.ts +++ b/libs/common/fixtures/src/lib/organisations.fixture.ts @@ -1,6 +1,15 @@ import { deepFreeze } from './utils/freeze' import { Organization } from '@geonetwork-ui/common/domain/model/record' +export const REGION_HAUT_DE_FRANCE_ORG_FIXTURE = (): Organization => ({ + name: 'Région Hauts-de-France', + description: 'A very sweet description about Région Hauts-de-France.', + email: 'contact@region-haut-de-france.com', + website: new URL('https://region-haut-de-france.com/'), + logoUrl: new URL('https://region-haut-de-france.com/logo.png'), + recordCount: 4, +}) + export const ORGANISATIONS_FIXTURE: Organization[] = deepFreeze([ { name: 'I Data Org', @@ -114,4 +123,5 @@ export const ORGANISATIONS_FIXTURE: Organization[] = deepFreeze([ logoUrl: new URL('https://my-geonetwork.org/logo12.png'), recordCount: 2, }, + REGION_HAUT_DE_FRANCE_ORG_FIXTURE(), ]) diff --git a/libs/feature/editor/src/lib/components/contact-card/contact-card.component.html b/libs/feature/editor/src/lib/components/contact-card/contact-card.component.html index a205e4c41f..b6a73272a4 100644 --- a/libs/feature/editor/src/lib/components/contact-card/contact-card.component.html +++ b/libs/feature/editor/src/lib/components/contact-card/contact-card.component.html @@ -7,11 +7,13 @@ >
- {{ contact.firstName }} {{ contact.lastName }}
-
{{ contact.email }}
+
{{ contact.email }}