Skip to content

Commit

Permalink
search list: improve export button
Browse files Browse the repository at this point in the history
When the maximum rest results size is reached, export button is disabled.
On mouse hover, a message is displayed to the end user to explain why the button is disabled.

Co-Authored-by: Laurent Dubois <laurent.dubois@itld-solutions.be>
  • Loading branch information
lauren-d committed Apr 29, 2021
1 parent d6401ba commit 5c838e2
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,33 +51,67 @@ <h5 *ngIf="types.length == 1 && showLabel">
<i class="fa fa-plus mr-0 mr-sm-1"></i>
<span class="d-none d-sm-inline">{{ 'Add' | translate }}</span>
</a>
<a id="search-export-button" role="button" class="btn btn-outline-primary ml-2" *ngIf="exportFormats && exportFormats.length == 1"
[class.disabled]="total === 0"
[href]="getExportFormatUrl(exportFormats[0].format)" >
<i class="fa fa-download mr-1"></i> {{ 'Export as' | translate }} {{ exportFormats[0].label }}
</a>
<div class="btn-group ml-2" dropdown *ngIf="exportFormats && exportFormats.length > 1">
<button
id="search-export-button-basic"
dropdownToggle
[disabled]="total === 0"
type="button"
class="btn btn-outline-primary dropdown-toggle"
>
<i class="fa fa-download mr-1"></i> {{ 'Export as' | translate }} ... <span class="caret"></span>
</button>
<ul
id="dropdown-export-basic"
*dropdownMenu
class="dropdown-menu"
role="menu"
aria-labelledby="button-export-basic"
>
<li role="menuitem" *ngFor="let format of exportFormats">
<a class="dropdown-item" [href]="getExportFormatUrl(format.format)" >{{ format.label }}</a>
</li>
</ul>
</div>
<!-- EXPORT BUTTON -->
<ng-container *ngIf="exportFormats">
<!-- check single export format -->
<ng-container *ngIf="exportFormats.length == 1; else multipleFormats">
<!-- check if we can export list -->
<ng-container *ngIf="canExport(exportFormats[0]); else cannotExport">
<a id="search-export-button"
role="button" class="btn btn-outline-primary ml-2"
[href]="getExportFormatUrl(exportFormats[0])">
<i class="fa fa-download mr-1"></i> {{ 'Export as' | translate }} {{ exportFormats[0].label }}
</a>
</ng-container>
<ng-template #cannotExport>
<button id="search-export-button"
role="button"
class="btn btn-outline-primary ml-2 disabled"
[popover]="cannotExportMessage"
triggers="mouseenter:mouseleave">
<i class="fa fa-download mr-1"></i> {{ 'Export as' | translate }} {{ exportFormats[0].label }}
</button>
</ng-template>
</ng-container>
<!-- display multiple export formats as dropdown list -->
<ng-template #multipleFormats>
<div class="btn-group ml-2" dropdown>
<button
id="search-export-button-basic"
dropdownToggle
[disabled]="total === 0"
type="button"
class="btn btn-outline-primary dropdown-toggle"
>
<i class="fa fa-download mr-1"></i> {{ 'Export as' | translate }} ... <span class="caret"></span>
</button>
<ul
id="dropdown-export-basic"
*dropdownMenu
class="dropdown-menu"
role="menu"
aria-labelledby="button-export-basic"
>
<li role="menuitem" *ngFor="let format of exportFormats">
<!-- check if we can export list -->
<ng-container *ngIf="canExport(format); else cannotExport">
<a class="dropdown-item" [href]="getExportFormatUrl(format)">{{ format.label }}</a>
</ng-container>
<ng-template #cannotExport>
<!-- use tooltip to display error message -->
<span [tooltip]="cannotExportMessage" placement="right">
<button disabled class="btn btn-link dropdown-item">{{ format.label }}</button>
</span>
</ng-template>
</li>
</ul>
</div>
</ng-template>
</ng-container>
<ng-template #cannotExportMessage>
<div [innerHtml]="exportInfoMessage | nl2br"></div>
</ng-template>
<!-- END EXPORT BUTTON -->
<div class="btn-group ml-2" dropdown>
<button
id="button-basic"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,13 +545,20 @@ export class RecordSearchComponent implements OnInit, OnChanges, OnDestroy {

/**
* Get export format url.
* @param format - string, export format
* @param format - export format object
* @return formatted url for an export format.
*/
getExportFormatUrl(format: string) {
const baseUrl = this._apiService.getEndpointByType(this._currentIndex());
let url = `${baseUrl}?q=${encodeURIComponent(this.q)}&format=${format}&size=${RecordService.MAX_REST_RESULTS_SIZE}`;
getExportFormatUrl(format: any) {
// TODO: maybe we can use URLSerializer to build query string
const baseUrl = format.endpoint
? format.endpoint
: this._apiService.getEndpointByType(this._currentIndex());
let url = `${baseUrl}?q=${encodeURIComponent(this.q)}&format=${format.format}`;

// check if max rest result size is disabled
if (!format.disableMaxRestResultsSize) {
url += `&size=${RecordService.MAX_REST_RESULTS_SIZE}`;
}
// preFilters
if (this._config && this._config.preFilters) {
for (const [key, value] of Object.entries(this._config.preFilters)) {
Expand All @@ -573,6 +580,28 @@ export class RecordSearchComponent implements OnInit, OnChanges, OnDestroy {
return url;
}

/**
* Check if a record list can be exported
* @param format - export format object
* @return Boolean
*/
canExport(format: any): boolean {
return (format.hasOwnProperty('disableMaxRestResultsSize') && format.disableMaxRestResultsSize)
? this.total > 0
: this.total > 0 && this.total < RecordService.MAX_REST_RESULTS_SIZE;
}

/**
* Return a message containing the reasons why record list cannot be exported
*/
get exportInfoMessage(): string {
return (this.total === 0)
? this._translateService.instant('Result list is empty.')
: this._translateService.instant('Too many items. Should be less than {{max}}.',
{ max: RecordService.MAX_REST_RESULTS_SIZE }
);
}

/**
* Aggregations order (facets)
* @param aggr - Aggregations dictonary
Expand Down

0 comments on commit 5c838e2

Please sign in to comment.