Skip to content

Commit

Permalink
feat(editor): add record action menu to duplicate
Browse files Browse the repository at this point in the history
  • Loading branch information
LHBruneton-C2C committed Jul 23, 2024
1 parent 2c0e9e6 commit 2f64df2
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ <h1 class="text-[16px] text-main font-title font-bold">
>
<gn-ui-results-table-container
(recordClick)="editRecord($event)"
(duplicateRecord)="duplicateRecord($event)"
></gn-ui-results-table-container>
<div class="px-5 py-5 flex justify-center gap-8 items-baseline">
<div class="grow">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const totalPages = 25
})
export class ResultsTableContainerComponent {
@Output() recordClick = new EventEmitter<CatalogRecord>()
@Output() duplicateRecord = new EventEmitter<CatalogRecord>()
}

@Component({
Expand Down Expand Up @@ -136,6 +137,19 @@ describe('RecordsListComponent', () => {
expect(router.navigate).toHaveBeenCalledWith(['/edit', 123])
})
})
describe('when asking for record duplication', () => {
const uniqueIdentifier = 123
const singleRecord = {
...DATASET_RECORDS[0],
uniqueIdentifier,
}
beforeEach(() => {
table.duplicateRecord.emit(singleRecord)
})
it('routes to record duplication', () => {
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
Expand Up @@ -67,6 +67,10 @@ export class RecordsListComponent {
this.router.navigate(['/edit', record.uniqueIdentifier])
}

duplicateRecord(record: CatalogRecord) {
this.router.navigate(['/duplicate', record.uniqueIdentifier])
}

showUsers() {
this.router.navigate(['/users/my-org'])
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ <h1 class="text-[16px] text-main font-title font-bold" translate>
<gn-ui-results-table-container
class="text-[14px]"
(recordClick)="editRecord($event)"
(duplicateRecord)="duplicateRecord($event)"
></gn-ui-results-table-container>

<div class="px-5 py-5 flex justify-center gap-8 items-baseline">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const totalPages = 25
})
export class ResultsTableContainerComponent {
@Output() recordClick = new EventEmitter<CatalogRecord>()
@Output() duplicateRecord = new EventEmitter<CatalogRecord>()
}

@Component({
Expand Down Expand Up @@ -152,6 +153,19 @@ describe('SearchRecordsComponent', () => {
expect(router.navigate).toHaveBeenCalledWith(['/edit', 123])
})
})
describe('when asking for record duplication', () => {
const uniqueIdentifier = 123
const singleRecord = {
...DATASET_RECORDS[0],
uniqueIdentifier,
}
beforeEach(() => {
table.duplicateRecord.emit(singleRecord)
})
it('routes to record duplication', () => {
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
Expand Up @@ -48,6 +48,10 @@ export class SearchRecordsComponent {
this.router.navigate(['/edit', record.uniqueIdentifier])
}

duplicateRecord(record: CatalogRecord) {
this.router.navigate(['/duplicate', record.uniqueIdentifier])
}

createRecord() {
this.router.navigate(['/create'])
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[selectedRecordsIdentifiers]="selectedRecords$ | async"
[sortOrder]="sortBy$ | async"
(recordClick)="handleRecordClick($event)"
(duplicateRecord)="handleDuplicateRecord($event)"
(recordsSelectedChange)="handleRecordsSelectedChange($event[0], $event[1])"
(sortByChange)="handleSortByChange($event[0], $event[1])"
></gn-ui-results-table>
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { DATASET_RECORDS } from '@geonetwork-ui/common/fixtures'
import { ResultsTableContainerComponent } from './results-table-container.component'
import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record'
import { By } from '@angular/platform-browser'
import { NoopAnimationsModule } from '@angular/platform-browser/animations'
import { SelectionService } from '@geonetwork-ui/api/repository'
import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record'
import { RecordsRepositoryInterface } from '@geonetwork-ui/common/domain/repository/records-repository.interface'
import { DATASET_RECORDS } from '@geonetwork-ui/common/fixtures'
import { TranslateModule } from '@ngx-translate/core'
import { BehaviorSubject } from 'rxjs'
import { SearchFacade } from '../state/search.facade'
import { SearchService } from '../utils/service/search.service'
import { SelectionService } from '@geonetwork-ui/api/repository'
import { TranslateModule } from '@ngx-translate/core'
import { RecordsRepositoryInterface } from '@geonetwork-ui/common/domain/repository/records-repository.interface'
import { ResultsTableContainerComponent } from './results-table-container.component'

class SearchFacadeMock {
results$ = new BehaviorSubject(DATASET_RECORDS)
Expand Down Expand Up @@ -40,7 +41,7 @@ describe('ResultsTableContainerComponent', () => {

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [TranslateModule.forRoot()],
imports: [TranslateModule.forRoot(), NoopAnimationsModule],
providers: [
{
provide: SearchFacade,
Expand Down Expand Up @@ -106,7 +107,7 @@ describe('ResultsTableContainerComponent', () => {
})
})

describe('clicking on a dataset', () => {
describe('clicking on a title', () => {
let clickedRecord: CatalogRecord

beforeEach(() => {
Expand All @@ -115,14 +116,36 @@ describe('ResultsTableContainerComponent', () => {
})

it('emits a recordClick event', () => {
const tableRow = fixture.debugElement.queryAll(
By.css('.table-row-cell')
)[1].nativeElement as HTMLDivElement
tableRow.parentElement.click()
const titleCell = fixture.debugElement.query(
By.css('[data-test="record-title-cell"]')
).nativeElement as HTMLDivElement
titleCell.click()
expect(clickedRecord).toEqual(DATASET_RECORDS[0])
})
})

describe('duplicating a dataset', () => {
let recordToBeDuplicated: CatalogRecord

beforeEach(() => {
recordToBeDuplicated = null
component.duplicateRecord.subscribe((r) => (recordToBeDuplicated = r))
})

it('emits a duplicateRecord event', () => {
const menuButton = fixture.debugElement.query(
By.css('[data-test="record-menu-button"]')
).nativeElement as HTMLButtonElement
menuButton.click()
fixture.detectChanges()
const duplicateButton = fixture.debugElement.query(
By.css('[data-test="record-menu-duplicate-button"]')
).nativeElement as HTMLButtonElement
duplicateButton.click()
expect(recordToBeDuplicated).toEqual(DATASET_RECORDS[0])
})
})

describe('#hasDraft', () => {
it('calls the repository service', () => {
const record = DATASET_RECORDS[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { CommonModule } from '@angular/common'
})
export class ResultsTableContainerComponent {
@Output() recordClick = new EventEmitter<CatalogRecord>()
@Output() duplicateRecord = new EventEmitter<CatalogRecord>()

records$ = this.searchFacade.results$
selectedRecords$ = this.selectionService.selectedRecordsIdentifiers$
Expand All @@ -35,6 +36,10 @@ export class ResultsTableContainerComponent {
this.recordClick.emit(item as CatalogRecord)
}

handleDuplicateRecord(item: unknown) {
this.duplicateRecord.emit(item as CatalogRecord)
}

handleSortByChange(col: string, order: 'asc' | 'desc') {
this.searchService.setSortBy([order, col])
}
Expand Down
34 changes: 29 additions & 5 deletions libs/ui/search/src/lib/results-table/results-table.component.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
<gn-ui-interactive-table
[items]="records"
(itemClick)="handleRecordClick($event)"
>
<gn-ui-interactive-table [items]="records">
<!-- SELECTED COLUMN -->
<gn-ui-interactive-table-column>
<ng-template #header>
Expand Down Expand Up @@ -34,7 +31,11 @@
<span translate>record.metadata.title</span>
</ng-template>
<ng-template #cell let-item>
<div class="flex flex-row items-center gap-2 max-w-full">
<div
class="flex flex-row items-center gap-2 max-w-full"
(click)="handleRecordClick(item)"
data-test="record-title-cell"
>
<span class="overflow-hidden text-ellipsis">{{ item.title }}</span>
<gn-ui-badge
*ngIf="recordHasDraft(item)"
Expand Down Expand Up @@ -120,4 +121,27 @@
{{ dateToString(item.recordUpdated) }}
</ng-template>
</gn-ui-interactive-table-column>

<!-- ACTION MENU COLUMN -->
<gn-ui-interactive-table-column>
<ng-template #header> </ng-template>
<ng-template #cell let-item>
<button
[matMenuTriggerFor]="menu"
(click)="$event.stopPropagation()"
data-test="record-menu-button"
>
<mat-icon class="material-symbols-outlined">more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button
mat-menu-item
(click)="handleDuplicateClick($event, item)"
data-test="record-menu-duplicate-button"
>
<span translate>record.action.duplicate</span>
</button>
</mat-menu>
</ng-template>
</gn-ui-interactive-table-column>
</gn-ui-interactive-table>
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { DATASET_RECORDS } from '@geonetwork-ui/common/fixtures'
import { ResultsTableComponent } from './results-table.component'
import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record'
import { By } from '@angular/platform-browser'
import { NoopAnimationsModule } from '@angular/platform-browser/animations'
import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record'
import { DATASET_RECORDS } from '@geonetwork-ui/common/fixtures'
import { TranslateModule } from '@ngx-translate/core'
import { ResultsTableComponent } from './results-table.component'

describe('ResultsTableComponent', () => {
let component: ResultsTableComponent
let fixture: ComponentFixture<ResultsTableComponent>

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [TranslateModule.forRoot()],
imports: [TranslateModule.forRoot(), NoopAnimationsModule],
}).compileComponents()

fixture = TestBed.createComponent(ResultsTableComponent)
Expand Down Expand Up @@ -133,7 +134,7 @@ describe('ResultsTableComponent', () => {
})
})

describe('clicking on a dataset', () => {
describe('clicking on a title', () => {
let clickedRecord: CatalogRecord

beforeEach(() => {
Expand All @@ -142,11 +143,33 @@ describe('ResultsTableComponent', () => {
})

it('emits a recordClick event', () => {
const tableRow = fixture.debugElement.queryAll(
By.css('.table-row-cell')
)[1].nativeElement as HTMLDivElement
tableRow.parentElement.click()
const tableRow = fixture.debugElement.query(
By.css('[data-test="record-title-cell"]')
).nativeElement as HTMLDivElement
tableRow.click()
expect(clickedRecord).toEqual(DATASET_RECORDS[0])
})
})

describe('duplicating a dataset', () => {
let recordToBeDuplicated: CatalogRecord

beforeEach(() => {
recordToBeDuplicated = null
component.duplicateRecord.subscribe((r) => (recordToBeDuplicated = r))
})

it('emits a duplicateRecord event', () => {
const menuButton = fixture.debugElement.query(
By.css('[data-test="record-menu-button"]')
).nativeElement as HTMLButtonElement
menuButton.click()
fixture.detectChanges()
const duplicateButton = fixture.debugElement.query(
By.css('[data-test="record-menu-duplicate-button"]')
).nativeElement as HTMLButtonElement
duplicateButton.click()
expect(recordToBeDuplicated).toEqual(DATASET_RECORDS[0])
})
})
})
30 changes: 19 additions & 11 deletions libs/ui/search/src/lib/results-table/results-table.component.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import { CommonModule } from '@angular/common'
import { Component, EventEmitter, Input, Output } from '@angular/core'
import { MatIconModule } from '@angular/material/icon'
import { MatMenuModule } from '@angular/material/menu'
import { CatalogRecord } from '@geonetwork-ui/common/domain/model/record'
import {
FileFormat,
getBadgeColor,
getFileFormat,
getFormatPriority,
} from '@geonetwork-ui/util/shared'
FieldSort,
SortByField,
} from '@geonetwork-ui/common/domain/model/search'
import { BadgeComponent, UiInputsModule } from '@geonetwork-ui/ui/inputs'
import {
InteractiveTableColumnComponent,
InteractiveTableComponent,
} from '@geonetwork-ui/ui/layout'
import { MatIconModule } from '@angular/material/icon'
import { TranslateModule } from '@ngx-translate/core'
import { CommonModule } from '@angular/common'
import {
FieldSort,
SortByField,
} from '@geonetwork-ui/common/domain/model/search'
FileFormat,
getBadgeColor,
getFileFormat,
getFormatPriority,
} from '@geonetwork-ui/util/shared'
import { TranslateModule } from '@ngx-translate/core'

@Component({
selector: 'gn-ui-results-table',
Expand All @@ -32,6 +33,7 @@ import {
MatIconModule,
TranslateModule,
BadgeComponent,
MatMenuModule,
],
})
export class ResultsTableComponent {
Expand All @@ -43,6 +45,7 @@ export class ResultsTableComponent {
// emits the column (field) as well as the order
@Output() sortByChange = new EventEmitter<[string, 'asc' | 'desc']>()
@Output() recordClick = new EventEmitter<CatalogRecord>()
@Output() duplicateRecord = new EventEmitter<CatalogRecord>()
@Output() recordsSelectedChange = new EventEmitter<
[CatalogRecord[], boolean]
>()
Expand Down Expand Up @@ -89,6 +92,11 @@ export class ResultsTableComponent {
this.recordClick.emit(item as CatalogRecord)
}

handleDuplicateClick(event: Event, item: unknown) {
event.stopPropagation()
this.duplicateRecord.emit(item as CatalogRecord)
}

setSortBy(col: string, order: 'asc' | 'desc') {
this.sortByChange.emit([col, order])
}
Expand Down

0 comments on commit 2f64df2

Please sign in to comment.