Skip to content

Commit

Permalink
feat(me): Create record by duplicating remote record.
Browse files Browse the repository at this point in the history
  • Loading branch information
Romuald Caplier committed Sep 12, 2024
1 parent 9075aa6 commit 4f73dd2
Show file tree
Hide file tree
Showing 28 changed files with 1,073 additions and 78 deletions.
79 changes: 79 additions & 0 deletions apps/metadata-editor-e2e/src/e2e/import.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// eslint-disable-next-line @nx/enforce-module-boundaries
import { simpleDatasetRecordAsXmlFixture } from '@geonetwork-ui/common/fixtures'

describe('import', () => {
beforeEach(() => {
cy.login('admin', 'admin', false)
cy.visit('/catalog/search')
})

describe('import a record', () => {
beforeEach(() => {
// Open the import overlay
cy.get('[data-test="import-record"]').click()
})

it('should show the import menu overlay', () => {
cy.get('gn-ui-import-record').should('be.visible')
cy.get('[data-test="importMenuMainSection"]').should('be.visible')
})

describe('import by URL section', () => {
beforeEach(() => {
cy.get('[data-test="importFromUrlButton"]').click()
})

it('should show the import by URL section', () => {
cy.get('[data-test="importMenuImportExternalFileSection"]').should(
'be.visible'
)
})

it('should show the import by URL section', () => {
cy.get('[data-test="importMenuImportExternalFileSection"]').should(
'be.visible'
)
})

it('should import a record', () => {
cy.get('[data-test="importMenuImportExternalFileSection"]')
.find('gn-ui-url-input')
.type('http://www.marvelous-record/xml/download')

cy.intercept(
{
method: 'GET',
url: /\/xml\/download$/,
},
{
statusCode: 200,
body: simpleDatasetRecordAsXmlFixture(),
}
).as('importUrlRequest')

cy.get('gn-ui-url-input').find('gn-ui-button').find('button').click()

// Check that the record is correctly displayed
cy.get('gn-ui-record-form').should('be.visible')

cy.get('gn-ui-record-form')
.find('gn-ui-form-field')
.eq(0)
.find('input')
.invoke('val')
.should('contain', 'Copy')
})

it('should be able to navigate back to the main section', () => {
cy.get(
'[data-test="importMenuImportExternalFileSectionBackButton"]'
).click()

cy.get('[data-test="importMenuMainSection"]').should('be.visible')
cy.get('[data-test="importMenuImportExternalFileSection"]').should(
'not.exist'
)
})
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export class RecordsListComponent {
paginate(page: number) {
this.searchService.setPage(page)
}

createRecord() {
this.router.navigate(['/create'])
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ <h1 class="text-[16px] text-main font-title font-bold" translate>
<span class="uppercase" translate>dashboard.results.listResources</span>
</div>
<div class="grow"></div>
<gn-ui-button
cdkOverlayOrigin
#importRecordButton
(buttonClick)="importRecord()"
type="default"
data-test="import-record"
>
<span translate>dashboard.importRecord</span>
<mat-icon *ngIf="!isImportMenuOpen" class="material-symbols-outlined"
>keyboard_arrow_down</mat-icon
>
<mat-icon *ngIf="isImportMenuOpen" class="material-symbols-outlined"
>keyboard_arrow_up</mat-icon
>
</gn-ui-button>
<ng-template #template>
<gn-ui-import-record
(closeImportMenu)="closeImportMenu()"
></gn-ui-import-record>
</ng-template>
<gn-ui-button
(buttonClick)="createRecord()"
type="primary"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { SearchFacade, SearchService } from '@geonetwork-ui/feature/search'
import { SearchRecordsComponent } from './search-records-list.component'
import {
Component,
CUSTOM_ELEMENTS_SCHEMA,
EventEmitter,
importProvidersFrom,
Input,
Expand Down Expand Up @@ -73,17 +74,19 @@ class SearchServiceMock {
}

class RouterMock {
navigate = jest.fn()
navigate = jest.fn(() => Promise.resolve(true))
}

describe('SearchRecordsComponent', () => {
let component: SearchRecordsComponent
let fixture: ComponentFixture<SearchRecordsComponent>
let router: Router
let searchService: SearchService
let searchFacade: SearchFacade

beforeEach(() => {
TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
importProvidersFrom(TranslateModule.forRoot()),
{
Expand Down Expand Up @@ -115,6 +118,8 @@ describe('SearchRecordsComponent', () => {
fixture = TestBed.createComponent(SearchRecordsComponent)
router = TestBed.inject(Router)
searchService = TestBed.inject(SearchService)
searchFacade = TestBed.inject(SearchFacade)

component = fixture.componentInstance
fixture.detectChanges()
})
Expand All @@ -123,6 +128,54 @@ describe('SearchRecordsComponent', () => {
expect(component).toBeTruthy()
})

it('should map search filters to searchText$', (done) => {
component.searchText$.subscribe((text) => {
expect(text).toBe('hello world')
done()
})
})

describe('when clicking createRecord', () => {
beforeEach(() => {
component.createRecord()
})

it('navigates to the create record page', () => {
expect(router.navigate).toHaveBeenCalledWith(['/create'])
})
})

describe('when importing a record', () => {
beforeEach(() => {
component.importRecord()
})

it('sets isImportMenuOpen to true', () => {
expect(component.isImportMenuOpen).toBe(true)
})
})

describe('when closing the import menu', () => {
let overlaySpy: any

beforeEach(() => {
overlaySpy = {
dispose: jest.fn(),
}
component['overlayRef'] = overlaySpy

component.closeImportMenu()
})

it('sets isImportMenuOpen to false', () => {
expect(component.isImportMenuOpen).toBe(false)
})

it('disposes the overlay', () => {
expect(overlaySpy.dispose).toHaveBeenCalled()
})
})

describe('when search results', () => {
let table, pagination
beforeEach(() => {
Expand All @@ -141,6 +194,7 @@ describe('SearchRecordsComponent', () => {
expect(pagination.currentPage).toEqual(currentPage)
expect(pagination.totalPages).toEqual(totalPages)
})

describe('when click on a record', () => {
const uniqueIdentifier = 123
const singleRecord = {
Expand All @@ -154,6 +208,7 @@ describe('SearchRecordsComponent', () => {
expect(router.navigate).toHaveBeenCalledWith(['/edit', 123])
})
})

describe('when asking for record duplication', () => {
const uniqueIdentifier = 123
const singleRecord = {
Expand All @@ -167,6 +222,7 @@ describe('SearchRecordsComponent', () => {
expect(router.navigate).toHaveBeenCalledWith(['/duplicate', 123])
})
})

describe('when click on pagination', () => {
beforeEach(() => {
pagination.newCurrentPageEvent.emit(3)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { CommonModule } from '@angular/common'
import { Component } from '@angular/core'
import {
ChangeDetectorRef,
Component,
ElementRef,
TemplateRef,
ViewChild,
ViewContainerRef,
} from '@angular/core'
import {
ResultsTableContainerComponent,
SearchFacade,
Expand All @@ -14,6 +21,14 @@ import { Observable } from 'rxjs'
import { UiElementsModule } from '@geonetwork-ui/ui/elements'
import { UiInputsModule } from '@geonetwork-ui/ui/inputs'
import { MatIconModule } from '@angular/material/icon'
import {
CdkConnectedOverlay,
CdkOverlayOrigin,
Overlay,
OverlayRef,
} from '@angular/cdk/overlay'
import { TemplatePortal } from '@angular/cdk/portal'
import { ImportRecordComponent } from '@geonetwork-ui/feature/editor'

@Component({
selector: 'md-editor-search-records-list',
Expand All @@ -28,32 +43,88 @@ import { MatIconModule } from '@angular/material/icon'
UiElementsModule,
UiInputsModule,
MatIconModule,
ImportRecordComponent,
CdkOverlayOrigin,
CdkConnectedOverlay,
],
})
export class SearchRecordsComponent {
@ViewChild('importRecordButton', { read: ElementRef })
private importRecordButton!: ElementRef
@ViewChild('template') template!: TemplateRef<any>
private overlayRef!: OverlayRef

searchText$: Observable<string | null> =
this.searchFacade.searchFilters$.pipe(
map((filters) => ('any' in filters ? (filters['any'] as string) : null))
)

isImportMenuOpen = false

constructor(
private router: Router,
public searchFacade: SearchFacade,
public searchService: SearchService
public searchService: SearchService,
private overlay: Overlay,
private viewContainerRef: ViewContainerRef,
private cdr: ChangeDetectorRef
) {
this.searchFacade.setPageSize(15)
this.searchFacade.resetSearch()
}

editRecord(record: CatalogRecord) {
this.router.navigate(['/edit', record.uniqueIdentifier])
this.router
.navigate(['/edit', record.uniqueIdentifier])
.catch((err) => console.error(err))
}

duplicateRecord(record: CatalogRecord) {
this.router.navigate(['/duplicate', record.uniqueIdentifier])
this.router
.navigate(['/duplicate', record.uniqueIdentifier])
.catch((err) => console.error(err))
}

createRecord() {
this.router.navigate(['/create'])
this.router.navigate(['/create']).catch((err) => console.error(err))
}

importRecord() {
this.isImportMenuOpen = true

const positionStrategy = this.overlay
.position()
.flexibleConnectedTo(this.importRecordButton)
.withPositions([
{
originX: 'end',
originY: 'bottom',
overlayX: 'end',
overlayY: 'top',
},
])

this.overlayRef = this.overlay.create({
hasBackdrop: true,
backdropClass: 'cdk-overlay-transparent-backdrop',
positionStrategy: positionStrategy,
scrollStrategy: this.overlay.scrollStrategies.reposition(),
})

const portal = new TemplatePortal(this.template, this.viewContainerRef)

this.overlayRef.attach(portal)

this.overlayRef.backdropClick().subscribe(() => {
this.closeImportMenu()
})
}

closeImportMenu() {
if (this.overlayRef) {
this.isImportMenuOpen = false
this.overlayRef.dispose()
this.cdr.markForCheck()
}
}
}
4 changes: 4 additions & 0 deletions apps/metadata-editor/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ body {
@apply text-2xl px-9 py-3;
}

.cdk-overlay-transparent-backdrop {
@apply bg-transparent;
}

.mat-mdc-button-base {
line-height: normal;
}
1 change: 1 addition & 0 deletions libs/api/metadata-converter/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './lib/iso19139'
export * from './lib/iso19115-3'
export * from './lib/find-converter'
export * from './lib/gn4'
export * from './lib/xml-utils'
Loading

0 comments on commit 4f73dd2

Please sign in to comment.