diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.html b/src/app/shared/search/search-export-csv/search-export-csv.component.html index 7bf8704300..8c92ff8fbd 100644 --- a/src/app/shared/search/search-export-csv/search-export-csv.component.html +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.html @@ -1,7 +1,20 @@ + + + {{tooltipMsg | translate}} + + + + + + {{tooltipMsg | translate}} + {{exportLimitExceededMsg}} + + + + [title]="tooltipMsg | translate" [attr.aria-label]="(shouldShowWarning$ | async) ? ((tooltipMsg | translate) + ' ' + exportLimitExceededMsg): (tooltipMsg | translate)"> - \ No newline at end of file + diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts index 9abdd8d366..f067263712 100644 --- a/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts @@ -9,6 +9,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import { of as observableOf } from 'rxjs'; +import { ConfigurationDataService } from '../../../core/data/configuration-data.service'; import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; import { ScriptDataService } from '../../../core/data/processes/script-data.service'; import { getProcessDetailRoute } from '../../../process-page/process-page-routing.paths'; @@ -31,6 +32,7 @@ describe('SearchExportCsvComponent', () => { let authorizationDataService: AuthorizationDataService; let notificationsService; let router; + let configurationDataService: jasmine.SpyObj; const process = Object.assign(new Process(), { processId: 5, scriptName: 'metadata-export-search' }); @@ -45,6 +47,10 @@ describe('SearchExportCsvComponent', () => { ], }); + configurationDataService = jasmine.createSpyObj('ConfigurationDataService', { + findByPropertyName: observableOf({ payload: { value: '500' } }), + }); + function initBeforeEachAsync() { scriptDataService = jasmine.createSpyObj('scriptDataService', { scriptWithNameExistsAndCanExecute: observableOf(true), @@ -64,6 +70,7 @@ describe('SearchExportCsvComponent', () => { { provide: AuthorizationDataService, useValue: authorizationDataService }, { provide: NotificationsService, useValue: notificationsService }, { provide: Router, useValue: router }, + { provide: ConfigurationDataService, useValue: configurationDataService }, ], }).compileComponents(); } diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.ts index f8ec2012b1..2727c6cce7 100644 --- a/src/app/shared/search/search-export-csv/search-export-csv.component.ts +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.ts @@ -5,7 +5,9 @@ import { import { Component, Input, + OnChanges, OnInit, + SimpleChanges, } from '@angular/core'; import { Router } from '@angular/router'; import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; @@ -21,10 +23,12 @@ import { switchMap, } from 'rxjs/operators'; +import { ConfigurationDataService } from '../../../core/data/configuration-data.service'; import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; import { ScriptDataService } from '../../../core/data/processes/script-data.service'; import { RemoteData } from '../../../core/data/remote-data'; +import { ConfigurationProperty } from '../../../core/shared/configuration-property.model'; import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; import { getProcessDetailRoute } from '../../../process-page/process-page-routing.paths'; import { Process } from '../../../process-page/processes/process.model'; @@ -46,13 +50,18 @@ import { SearchFilter } from '../models/search-filter.model'; /** * Display a button to export the current search results as csv */ -export class SearchExportCsvComponent implements OnInit { +export class SearchExportCsvComponent implements OnInit, OnChanges { /** * The current configuration of the search */ @Input() searchConfig: PaginatedSearchOptions; + /** + * The total number of items in the search results which can be exported + */ + @Input() total: number; + /** * Observable used to determine whether the button should be shown */ @@ -63,12 +72,18 @@ export class SearchExportCsvComponent implements OnInit { */ tooltipMsg = 'metadata-export-search.tooltip'; + exportLimitExceededKey = 'metadata-export-search.submit.error.limit-exceeded'; + + exportLimitExceededMsg = ''; + + shouldShowWarning$: Observable; + constructor(private scriptDataService: ScriptDataService, private authorizationDataService: AuthorizationDataService, private notificationsService: NotificationsService, private translateService: TranslateService, private router: Router, - ) { + private configurationService: ConfigurationDataService) { } ngOnInit(): void { @@ -78,6 +93,31 @@ export class SearchExportCsvComponent implements OnInit { map((canExecute: boolean) => canExecute), startWith(false), ); + this.shouldShowWarning$ = this.itemExceeds(); + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes.total) { + this.shouldShowWarning$ = this.itemExceeds(); + } + } + + /** + * Checks if the export limit has been exceeded and updates the tooltip accordingly + */ + private itemExceeds(): Observable { + return this.configurationService.findByPropertyName('bulkedit.export.max.items').pipe( + getFirstCompletedRemoteData(), + map((response: RemoteData) => { + const limit = Number(response.payload?.values?.[0]) || 500; + if (limit < this.total) { + this.exportLimitExceededMsg = this.translateService.instant(this.exportLimitExceededKey, { limit: String(limit) }); + return true; + } else { + return false; + } + }), + ); } /** diff --git a/src/app/shared/search/search-results/search-results.component.html b/src/app/shared/search/search-results/search-results.component.html index ecc4672b0a..91f8a010f1 100644 --- a/src/app/shared/search/search-results/search-results.component.html +++ b/src/app/shared/search/search-results/search-results.component.html @@ -12,7 +12,8 @@ {{ (configuration ? configuration + '.search.results.head' : 'search.results.head') | translate }} - + 0" @fadeIn>
{{tooltipMsg | translate}}
{{exportLimitExceededMsg}}