From: Bill Erickson <berickxx@gmail.com> Date: Thu, 20 Jan 2022 21:16:10 +0000 (-0500) Subject: LP1958581 Angular Grid Copy To Clipboard X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=647f704c5501602f4ffd668944ecd79b4c26e438;p=evergreen%2Fequinox.git LP1958581 Angular Grid Copy To Clipboard To test, right click on a row in an Angular grid. A dialog should appear which allows the user to click on a value to select the value into the clipboard. Once selected, the dialog should close. Signed-off-by: Bill Erickson <berickxx@gmail.com> Signed-off-by: Mike Rylander <mrylander@gmail.com> --- diff --git a/Open-ILS/src/eg2/src/app/share/clipboard/clipboard-dialog.component.html b/Open-ILS/src/eg2/src/app/share/clipboard/clipboard-dialog.component.html new file mode 100644 index 0000000000..1ff5fa23fb --- /dev/null +++ b/Open-ILS/src/eg2/src/app/share/clipboard/clipboard-dialog.component.html @@ -0,0 +1,25 @@ +<ng-template #dialogContent> + <div class="modal-header bg-info"> + <h4 class="modal-title" i18n>Copy Data to Clipboard</h4> + <button type="button" class="close" + i18n-aria-label aria-label="Close" (click)="close()"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body common-form striped-odd"> + <div class="row" *ngFor="let value of values"> + <div class="col-lg-4 font-weight-bold border-right">{{value.label}}</div> + <div class="col-lg-8"> + <a href="javascript:;" (click)="copyValue(value.value)">{{value.value}}</a> + </div> + </div> + + <!-- hidden landing spot for copy-able text --> + <textarea style="display:none;visibility:hidden" id='clipboard-textarea'> + </textarea> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-warning" + (click)="close()" i18n>Cancel</button> + </div> +</ng-template> diff --git a/Open-ILS/src/eg2/src/app/share/clipboard/clipboard-dialog.component.ts b/Open-ILS/src/eg2/src/app/share/clipboard/clipboard-dialog.component.ts new file mode 100644 index 0000000000..46e0141ebf --- /dev/null +++ b/Open-ILS/src/eg2/src/app/share/clipboard/clipboard-dialog.component.ts @@ -0,0 +1,43 @@ +import {Component, Input, ViewChild, TemplateRef} from '@angular/core'; +import {DialogComponent} from '@eg/share/dialog/dialog.component'; + +interface ClipboardValues { + label: string; + value: string; +} + +@Component({ + selector: 'eg-clipboard-dialog', + templateUrl: './clipboard-dialog.component.html' +}) + +/** + * Copy To Clipboard dialog + */ +export class ClipboardDialogComponent extends DialogComponent { + + @Input() values: ClipboardValues[]; + + copyValue(value: string) { + + const node = + document.getElementById('clipboard-textarea') as HTMLTextAreaElement; + + // Un-hide the textarea just long enough to copy its data. + // Using node.style instead of *ngIf for snappier show/hide. + node.style.visibility = 'visible'; + node.style.display = 'block'; + node.value = value; + node.focus(); + node.select(); + + document.execCommand('copy'); + + node.style.visibility = 'hidden'; + node.style.display = 'none'; + + this.close(); + } +} + + diff --git a/Open-ILS/src/eg2/src/app/share/common-widgets.module.ts b/Open-ILS/src/eg2/src/app/share/common-widgets.module.ts index fda671ec2c..49fdc7bce0 100644 --- a/Open-ILS/src/eg2/src/app/share/common-widgets.module.ts +++ b/Open-ILS/src/eg2/src/app/share/common-widgets.module.ts @@ -17,6 +17,7 @@ import {DateTimeSelectComponent} from '@eg/share/datetime-select/datetime-select import {ContextMenuModule} from '@eg/share/context-menu/context-menu.module'; import {FileReaderComponent} from '@eg/share/file-reader/file-reader.component'; import {IntervalInputComponent} from '@eg/share/interval-input/interval-input.component'; +import {ClipboardDialogComponent} from '@eg/share/clipboard/clipboard-dialog.component'; @NgModule({ @@ -28,6 +29,7 @@ import {IntervalInputComponent} from '@eg/share/interval-input/interval-input.co DateRangeSelectComponent, DateTimeSelectComponent, FileReaderComponent, + ClipboardDialogComponent, IdlClassTemplateDirective, IntervalInputComponent, ], @@ -50,6 +52,7 @@ import {IntervalInputComponent} from '@eg/share/interval-input/interval-input.co OrgSelectComponent, DateRangeSelectComponent, DateTimeSelectComponent, + ClipboardDialogComponent, ContextMenuModule, FileReaderComponent, IntervalInputComponent, diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html b/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html index fed22766ba..8cf795fc68 100644 --- a/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html +++ b/Open-ILS/src/eg2/src/app/share/grid/grid-body.component.html @@ -1,6 +1,6 @@ <!-- uses dropdown menu CSS for easy stying, but it's not a dropdown --> <ng-template #contextMenu let-gridContext="gridContext"> - <eg-grid-toolbar-actions-menu [gridContext]="gridContext"> + <eg-grid-toolbar-actions-menu [gridContext]="gridContext" [viaContextMenu]="true"> </eg-grid-toolbar-actions-menu> </ng-template> diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.html b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.html index 97db338210..8bc8e326c1 100644 --- a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.html +++ b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.html @@ -1,3 +1,13 @@ +<!-- Copy To Clipboard is only displayed when using a row-specific + context menu as the entry point. --> +<button *ngIf="viaContextMenu" class="dropdown-item scrollable-menu" + (click)="openCopyToClipboard()" tabindex="0"> + <div i18n>Copy to Clipboard</div> + <div class="dropdown-divider"></div> +</button> + +<eg-clipboard-dialog #clipboardDialog></eg-clipboard-dialog> + <ng-container *ngFor="let action of gridContext.toolbarActions; let idx = index"> <button class="dropdown-item scrollable-menu" *ngIf="!action.hidden" diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.ts b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.ts index 2d8cffd151..87f4c2c240 100644 --- a/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.ts +++ b/Open-ILS/src/eg2/src/app/share/grid/grid-toolbar-actions-menu.component.ts @@ -1,5 +1,6 @@ -import {Component, Input, OnInit, Host} from '@angular/core'; +import {Component, Input, OnInit, Host, ViewChild} from '@angular/core'; import {GridToolbarAction, GridContext} from '@eg/share/grid/grid'; +import {ClipboardDialogComponent} from '@eg/share/clipboard/clipboard-dialog.component'; /** Models a list of toolbar action menu entries */ @@ -12,6 +13,10 @@ export class GridToolbarActionsMenuComponent { @Input() gridContext: GridContext; + @Input() viaContextMenu = false; + + @ViewChild('clipboardDialog') clipboardDialog: ClipboardDialogComponent; + performAction(action: GridToolbarAction) { if (action.isGroup || action.isSeparator) { return; // These don't perform actions @@ -27,5 +32,21 @@ export class GridToolbarActionsMenuComponent { } return false; } + + openCopyToClipboard() { + const row = this.gridContext.getSelectedRows()[0]; + if (!row) { return; } + const values = []; + this.gridContext.columnSet.displayColumns().forEach(col => { + values.push({ + label: col.label, + value: this.gridContext.getRowColumnValue(row, col) + }); + }); + + + this.clipboardDialog.values = values; + this.clipboardDialog.open({size: 'lg'}).toPromise(); + } }