From 3526fc3a4b18e56d58db8e1bbca8da69b12daecd Mon Sep 17 00:00:00 2001 From: Galen Charlton Date: Fri, 8 Nov 2019 18:39:34 -0500 Subject: [PATCH] LP#1850547: new Angular file-reader component This adds a ControlValueAccessor wrapper around a file reader form input. Any file loaded via that input is interpreted as a text file whose lines are to be split into an array on newlines, with leading and trailng whitespace removed. Usage is: Sponsored-by: Evergreen Community Development Initiative Sponsored-by: Georgia Public Library Service Sponsored-by: Indiana State Library Sponsored-by: C/W MARS Signed-off-by: Galen Charlton Signed-off-by: Tiffany Little Signed-off-by: Bill Erickson --- .../src/eg2/src/app/share/common-widgets.module.ts | 9 ++-- .../share/file-reader/file-reader.component.html | 1 + .../app/share/file-reader/file-reader.component.ts | 62 ++++++++++++++++++++++ .../src/app/staff/sandbox/sandbox.component.html | 9 ++++ .../eg2/src/app/staff/sandbox/sandbox.component.ts | 3 ++ 5 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 Open-ILS/src/eg2/src/app/share/file-reader/file-reader.component.html create mode 100644 Open-ILS/src/eg2/src/app/share/file-reader/file-reader.component.ts 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 e1f85cdd3e..5064f88964 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 @@ -15,6 +15,7 @@ import {OrgSelectComponent} from '@eg/share/org-select/org-select.component'; import {DateRangeSelectComponent} from '@eg/share/daterange-select/daterange-select.component'; import {DateTimeSelectComponent} from '@eg/share/datetime-select/datetime-select.component'; import {ContextMenuModule} from '@eg/share/context-menu/context-menu.module'; +import {FileReaderComponent} from '@eg/share/file-reader/file-reader.component'; @NgModule({ @@ -24,7 +25,8 @@ import {ContextMenuModule} from '@eg/share/context-menu/context-menu.module'; DateSelectComponent, OrgSelectComponent, DateRangeSelectComponent, - DateTimeSelectComponent + DateTimeSelectComponent, + FileReaderComponent, ], imports: [ CommonModule, @@ -45,8 +47,9 @@ import {ContextMenuModule} from '@eg/share/context-menu/context-menu.module'; OrgSelectComponent, DateRangeSelectComponent, DateTimeSelectComponent, - ContextMenuModule - ] + ContextMenuModule, + FileReaderComponent, + ], }) export class CommonWidgetsModule { } diff --git a/Open-ILS/src/eg2/src/app/share/file-reader/file-reader.component.html b/Open-ILS/src/eg2/src/app/share/file-reader/file-reader.component.html new file mode 100644 index 0000000000..d938bf6a21 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/share/file-reader/file-reader.component.html @@ -0,0 +1 @@ + diff --git a/Open-ILS/src/eg2/src/app/share/file-reader/file-reader.component.ts b/Open-ILS/src/eg2/src/app/share/file-reader/file-reader.component.ts new file mode 100644 index 0000000000..4cbe5deaf0 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/share/file-reader/file-reader.component.ts @@ -0,0 +1,62 @@ +/** + * + * + */ +import {Component, OnInit, Input, Output, ViewChild, + TemplateRef, EventEmitter, ElementRef, forwardRef} from '@angular/core'; +import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; +import {Observable, of, Subject} from 'rxjs'; +import {map, tap, reduce, mergeMap, mapTo, debounceTime, distinctUntilChanged, merge, filter} from 'rxjs/operators'; + +@Component({ + selector: 'eg-file-reader', + templateUrl: './file-reader.component.html', + providers: [{ + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => FileReaderComponent), + multi: true + }] +}) +export class FileReaderComponent implements ControlValueAccessor, OnInit { + + // Stub functions required by ControlValueAccessor + propagateChange = (_: any) => {}; + propagateTouch = () => {}; + + ngOnInit() { + } + + changeListener($event): void { + const me = this; + if ($event.target.files.length < 1) { + return; + } + const reader = new FileReader(); + reader.onloadend = function(e) { + me.propagateChange(me.parseFileContents(reader.result)); + }; + reader.readAsText($event.target.files[0]); + } + + parseFileContents(contents): Array { + const values = contents.split('\n'); + values.forEach((val, idx) => { + val = val.replace(/\s+$/, ''); + val = val.replace(/^\s+/, ''); + values[idx] = val; + }); + return values; + } + + writeValue(value: any) { + // intentionally empty + } + + registerOnChange(fn) { + this.propagateChange = fn; + } + + registerOnTouched(fn) { + this.propagateTouch = fn; + } +} diff --git a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html index da1155ee99..9a93b3e14d 100644 --- a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html +++ b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html @@ -175,6 +175,15 @@
+

File reader component

+ +
Contents are:
+
    +
  1. {{val}}
  2. +
+
+ +

Cross-tab communications example

To test, open this sandbox in a second browser tab. Enter something in the input box below, then switch to the other tab and click anywhere on the page. You should see the message that you sent to the other browser tab.

diff --git a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts index caf86fa8d2..7e31ec67e8 100644 --- a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts @@ -103,6 +103,9 @@ export class SandboxComponent implements OnInit { // selector field value on metarecord object aMetarecord: string; + // file-reader example + fileContents: Array; + // cross-tab communications example private sbChannel: any; sbChannelText: string; -- 2.11.0