@elderbyte/ngx-starter 18.1.0-beta → 18.2.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/common/utils/input-utils.mjs +6 -0
- package/esm2022/lib/components/data-view/table/activation/elder-table-activation.directive.mjs +14 -7
- package/esm2022/lib/components/files/blob-viewer/elder-blob-viewer.component.mjs +17 -23
- package/esm2022/lib/components/files/elder-file-select.directive.mjs +85 -86
- package/esm2022/lib/components/files/listing/file-entry.mjs +15 -30
- package/esm2022/lib/components/files/listing/file-listing-rx.mjs +70 -27
- package/esm2022/lib/components/forms/directives/validation/validators/elder-multiple-of.validator.mjs +17 -13
- package/fesm2022/elderbyte-ngx-starter.mjs +154 -413
- package/fesm2022/elderbyte-ngx-starter.mjs.map +1 -1
- package/lib/common/utils/input-utils.d.ts +18 -0
- package/lib/components/data-view/table/activation/elder-table-activation.directive.d.ts +4 -1
- package/lib/components/files/blob-viewer/elder-blob-viewer.component.d.ts +3 -3
- package/lib/components/files/elder-file-select.directive.d.ts +23 -15
- package/lib/components/files/listing/file-entry.d.ts +1 -10
- package/lib/components/files/listing/file-listing-rx.d.ts +6 -2
- package/lib/components/forms/directives/validation/validators/elder-multiple-of.validator.d.ts +2 -4
- package/package.json +1 -1
- package/esm2022/lib/components/files/elder-file-select-input.mjs +0 -119
- package/esm2022/lib/components/files/file-system-api.mjs +0 -88
- package/esm2022/lib/components/files/listing/file-listing-system-handle.mjs +0 -35
- package/esm2022/lib/components/files/listing/file-listing-webkit.mjs +0 -77
- package/lib/components/files/elder-file-select-input.d.ts +0 -59
- package/lib/components/files/file-system-api.d.ts +0 -82
- package/lib/components/files/listing/file-listing-system-handle.d.ts +0 -21
- package/lib/components/files/listing/file-listing-webkit.d.ts +0 -26
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as i2$1 from '@angular/common';
|
|
2
2
|
import { formatDate, CommonModule, formatCurrency, getCurrencySymbol, NgIf, AsyncPipe, NgFor, NgClass, NgTemplateOutlet, NgStyle, formatNumber, DecimalPipe, DatePipe, registerLocaleData, CurrencyPipe } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { Pipe, LOCALE_ID, Inject, NgModule, Optional, SkipSelf, Directive, Output, Input, forwardRef, ViewChild, HostBinding, ViewChildren, ContentChild, Injectable, Component, ChangeDetectionStrategy, Host, APP_INITIALIZER, TemplateRef, HostListener, EventEmitter, ViewEncapsulation, InjectionToken, ContentChildren, Self
|
|
4
|
+
import { Pipe, LOCALE_ID, Inject, NgModule, Optional, SkipSelf, Directive, Output, Input, forwardRef, ViewChild, HostBinding, ViewChildren, ContentChild, Injectable, Component, ChangeDetectionStrategy, Host, APP_INITIALIZER, TemplateRef, HostListener, EventEmitter, input, ViewEncapsulation, InjectionToken, ContentChildren, Self } from '@angular/core';
|
|
5
5
|
import * as i1 from '@angular/platform-browser';
|
|
6
6
|
import { Duration, Period, TemporalQueries, LocalTime, Instant, LocalDate, nativeJs, ZoneId, DateTimeFormatter, convert, ZonedDateTime, Temporal } from '@js-joda/core';
|
|
7
7
|
import { LoggerFactory } from '@elderbyte/ts-logger';
|
|
8
|
-
import { timer, defer, ReplaySubject, concat, finalize, exhaustMap, BehaviorSubject, Subject, switchMap, of, combineLatest, EMPTY, merge, throwError, forkJoin, mergeWith, Observable,
|
|
8
|
+
import { timer, defer, ReplaySubject, concat, finalize, exhaustMap, BehaviorSubject, Subject, switchMap, of, combineLatest, EMPTY, merge, throwError, forkJoin, mergeWith, Observable, zip, mergeMap as mergeMap$1, fromEvent, skipUntil, combineLatestWith as combineLatestWith$1, NEVER } from 'rxjs';
|
|
9
9
|
import { tap, takeUntil, takeWhile, map, filter, distinctUntilChanged, debounceTime, catchError, first, take, switchMap as switchMap$1, mergeMap, expand, reduce, startWith, skip, delay, share, combineLatestWith, skipWhile, timeout } from 'rxjs/operators';
|
|
10
10
|
import * as i1$2 from '@angular/common/http';
|
|
11
11
|
import { HttpParams, HttpEventType, HttpRequest, HttpClient, HttpErrorResponse, HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
@@ -36,7 +36,6 @@ import { MatAutocompleteTrigger, MatAutocomplete, MatAutocompleteModule } from '
|
|
|
36
36
|
import * as i1$7 from '@angular/material/chips';
|
|
37
37
|
import { MatChipGrid, MatChipRow, MatChipRemove, MatChipInput, MatChipsModule, MatChip, MatChipAvatar, MatChipSet, MatChipTrailingIcon, MatChipListbox, MatChipOption } from '@angular/material/chips';
|
|
38
38
|
import { MatInput, MatInputModule } from '@angular/material/input';
|
|
39
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
40
39
|
import { MatList, MatListSubheaderCssMatStyler, MatListItem, MatListModule } from '@angular/material/list';
|
|
41
40
|
import { MatProgressBar, MatProgressBarModule } from '@angular/material/progress-bar';
|
|
42
41
|
import * as i1$5 from '@angular/material/snack-bar';
|
|
@@ -51,6 +50,7 @@ import * as i1$6 from '@angular/material/dialog';
|
|
|
51
50
|
import { MatDialogClose, MAT_DIALOG_DATA, MatDialogConfig, MatDialogModule } from '@angular/material/dialog';
|
|
52
51
|
import { MatMenuTrigger, MatMenu, MatMenuItem, MatMenuModule } from '@angular/material/menu';
|
|
53
52
|
import { MatTooltipModule, MatTooltip } from '@angular/material/tooltip';
|
|
53
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
54
54
|
import { MatPaginator, MatPaginatorIntl, MatPaginatorModule } from '@angular/material/paginator';
|
|
55
55
|
import { MatColumnDef, MatRowDef, MatTable, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell, MatFooterCellDef, MatFooterCell, MatHeaderRowDef, MatHeaderRow, MatRow, MatFooterRowDef, MatFooterRow, MatTableModule } from '@angular/material/table';
|
|
56
56
|
import * as i1$8 from '@angular/cdk/table';
|
|
@@ -9715,92 +9715,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
|
|
|
9715
9715
|
}]
|
|
9716
9716
|
}] });
|
|
9717
9717
|
|
|
9718
|
-
/***************************************************************************
|
|
9719
|
-
* *
|
|
9720
|
-
* FileSystem API *
|
|
9721
|
-
* *
|
|
9722
|
-
**************************************************************************/
|
|
9723
|
-
/**
|
|
9724
|
-
* Holds experimental features of the browser `File System API`. No typescript lint checks
|
|
9725
|
-
* are performed here!
|
|
9726
|
-
*/
|
|
9727
|
-
class FileSystemApi {
|
|
9728
|
-
/***************************************************************************
|
|
9729
|
-
* *
|
|
9730
|
-
* DataTransferItem *
|
|
9731
|
-
* *
|
|
9732
|
-
**************************************************************************/
|
|
9733
|
-
static isGetAsFileSystemHandleSupported(transferItem) {
|
|
9734
|
-
// @ts-ignore
|
|
9735
|
-
return transferItem.getAsFileSystemHandle !== undefined;
|
|
9736
|
-
}
|
|
9737
|
-
static getAsFileSystemHandle(transferItem) {
|
|
9738
|
-
// @ts-ignore
|
|
9739
|
-
return from(transferItem.getAsFileSystemHandle());
|
|
9740
|
-
}
|
|
9741
|
-
/***************************************************************************
|
|
9742
|
-
* *
|
|
9743
|
-
* File Picker *
|
|
9744
|
-
* *
|
|
9745
|
-
**************************************************************************/
|
|
9746
|
-
static isFileSystemSupported() {
|
|
9747
|
-
return 'showOpenFilePicker' in window;
|
|
9748
|
-
}
|
|
9749
|
-
static openFilePicker(pickerOpts) {
|
|
9750
|
-
try {
|
|
9751
|
-
// @ts-ignore
|
|
9752
|
-
return from(window.showOpenFilePicker(pickerOpts));
|
|
9753
|
-
}
|
|
9754
|
-
catch (e) {
|
|
9755
|
-
return throwError(() => new Error(e));
|
|
9756
|
-
}
|
|
9757
|
-
}
|
|
9758
|
-
/***************************************************************************
|
|
9759
|
-
* *
|
|
9760
|
-
* Directory Picker *
|
|
9761
|
-
* *
|
|
9762
|
-
**************************************************************************/
|
|
9763
|
-
static isDirectoryPickerSupported() {
|
|
9764
|
-
return 'showDirectoryPicker' in window;
|
|
9765
|
-
}
|
|
9766
|
-
static openDirectoryPicker(pickerOpts) {
|
|
9767
|
-
try {
|
|
9768
|
-
// @ts-ignore
|
|
9769
|
-
return from(window.showDirectoryPicker(pickerOpts));
|
|
9770
|
-
}
|
|
9771
|
-
catch (e) {
|
|
9772
|
-
return throwError(() => new Error(e));
|
|
9773
|
-
}
|
|
9774
|
-
}
|
|
9775
|
-
/***************************************************************************
|
|
9776
|
-
* *
|
|
9777
|
-
* FileSystemDirectoryHandle *
|
|
9778
|
-
* *
|
|
9779
|
-
**************************************************************************/
|
|
9780
|
-
static getHandlesFromDirectory(dirHandle) {
|
|
9781
|
-
return from(FileSystemApi.getHandlesFromDirectoryAsync(dirHandle));
|
|
9782
|
-
}
|
|
9783
|
-
static buildRelativeParent(fileOrDirHandle, rootDirectory) {
|
|
9784
|
-
if (rootDirectory == null) {
|
|
9785
|
-
return of(undefined);
|
|
9786
|
-
}
|
|
9787
|
-
const relativeParents$ = from(rootDirectory.resolve(fileOrDirHandle));
|
|
9788
|
-
return relativeParents$.pipe(map(parents => {
|
|
9789
|
-
const path = parents;
|
|
9790
|
-
path.pop();
|
|
9791
|
-
return path.join('/');
|
|
9792
|
-
}));
|
|
9793
|
-
}
|
|
9794
|
-
static async getHandlesFromDirectoryAsync(dirHandle) {
|
|
9795
|
-
const handles = [];
|
|
9796
|
-
// @ts-ignore
|
|
9797
|
-
for await (const handle of dirHandle.values()) {
|
|
9798
|
-
handles.push(handle);
|
|
9799
|
-
}
|
|
9800
|
-
return handles;
|
|
9801
|
-
}
|
|
9802
|
-
}
|
|
9803
|
-
|
|
9804
9718
|
/**
|
|
9805
9719
|
* Represents a file and the relative path where the user has selected it.
|
|
9806
9720
|
* This is useful if the user has selected a folder and files
|
|
@@ -9815,24 +9729,26 @@ class FileEntry {
|
|
|
9815
9729
|
* which is also supported by this method.
|
|
9816
9730
|
*/
|
|
9817
9731
|
static ofFile(file) {
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
|
|
9826
|
-
|
|
9732
|
+
let relativeParent = null;
|
|
9733
|
+
if (file.webkitRelativePath) {
|
|
9734
|
+
if (file.webkitRelativePath.endsWith(file.name)) {
|
|
9735
|
+
const nameStart = file.webkitRelativePath.length - file.name.length;
|
|
9736
|
+
relativeParent = file.webkitRelativePath.substring(0, nameStart);
|
|
9737
|
+
}
|
|
9738
|
+
else {
|
|
9739
|
+
relativeParent = file.webkitRelativePath;
|
|
9740
|
+
}
|
|
9741
|
+
}
|
|
9742
|
+
return FileEntry.relativeFile(file, relativeParent);
|
|
9827
9743
|
}
|
|
9828
9744
|
/**
|
|
9829
9745
|
* Creates a file Entry with a relative parent path
|
|
9830
9746
|
*/
|
|
9831
|
-
static relativeFile(file, relativeParent
|
|
9747
|
+
static relativeFile(file, relativeParent) {
|
|
9832
9748
|
if (relativeParent && relativeParent.endsWith('/')) {
|
|
9833
9749
|
relativeParent = relativeParent.substring(0, relativeParent.length - 1);
|
|
9834
9750
|
}
|
|
9835
|
-
return new FileEntry(file, relativeParent
|
|
9751
|
+
return new FileEntry(file, relativeParent);
|
|
9836
9752
|
}
|
|
9837
9753
|
static toFileMap(entries) {
|
|
9838
9754
|
const map = new Map();
|
|
@@ -9852,10 +9768,9 @@ class FileEntry {
|
|
|
9852
9768
|
* Contains the relative path from the selected folder
|
|
9853
9769
|
* to this file. Only relevant if the user has selected a folder.
|
|
9854
9770
|
*/
|
|
9855
|
-
relativeParent
|
|
9771
|
+
relativeParent) {
|
|
9856
9772
|
this.file = file;
|
|
9857
9773
|
this.relativeParent = relativeParent;
|
|
9858
|
-
this.fileHandle = fileHandle;
|
|
9859
9774
|
this.relativePath = FileEntry.buildRelativePath(relativeParent, file);
|
|
9860
9775
|
}
|
|
9861
9776
|
/***************************************************************************
|
|
@@ -9874,46 +9789,42 @@ class FileEntry {
|
|
|
9874
9789
|
return file.name;
|
|
9875
9790
|
}
|
|
9876
9791
|
}
|
|
9877
|
-
static buildRelativeParent(file) {
|
|
9878
|
-
let relativeParent = null;
|
|
9879
|
-
if (file.webkitRelativePath) {
|
|
9880
|
-
if (file.webkitRelativePath.endsWith(file.name)) {
|
|
9881
|
-
const nameStart = file.webkitRelativePath.length - file.name.length;
|
|
9882
|
-
relativeParent = file.webkitRelativePath.substring(0, nameStart);
|
|
9883
|
-
}
|
|
9884
|
-
else {
|
|
9885
|
-
relativeParent = file.webkitRelativePath;
|
|
9886
|
-
}
|
|
9887
|
-
}
|
|
9888
|
-
return relativeParent;
|
|
9889
|
-
}
|
|
9890
9792
|
}
|
|
9891
9793
|
|
|
9892
|
-
class
|
|
9794
|
+
class ElderFileSelectDirective {
|
|
9893
9795
|
/***************************************************************************
|
|
9894
9796
|
* *
|
|
9895
9797
|
* Constructor *
|
|
9896
9798
|
* *
|
|
9897
9799
|
**************************************************************************/
|
|
9898
|
-
constructor(
|
|
9899
|
-
this.renderer = renderer;
|
|
9800
|
+
constructor(el, renderer) {
|
|
9900
9801
|
this.el = el;
|
|
9802
|
+
this.renderer = renderer;
|
|
9901
9803
|
/***************************************************************************
|
|
9902
9804
|
* *
|
|
9903
9805
|
* Fields *
|
|
9904
9806
|
* *
|
|
9905
9807
|
**************************************************************************/
|
|
9906
9808
|
this.logger = LoggerFactory.getLogger(this.constructor.name);
|
|
9907
|
-
this.
|
|
9809
|
+
this.elderFileSelectChange = new EventEmitter();
|
|
9810
|
+
this.elderSingleFileSelectChange = new EventEmitter();
|
|
9908
9811
|
}
|
|
9909
9812
|
/***************************************************************************
|
|
9910
9813
|
* *
|
|
9911
|
-
*
|
|
9814
|
+
* Life Cycle *
|
|
9912
9815
|
* *
|
|
9913
9816
|
**************************************************************************/
|
|
9914
|
-
|
|
9915
|
-
|
|
9817
|
+
ngOnInit() {
|
|
9818
|
+
this.createFileSelect();
|
|
9916
9819
|
}
|
|
9820
|
+
ngOnDestroy() {
|
|
9821
|
+
this.removeFileSelect();
|
|
9822
|
+
}
|
|
9823
|
+
/***************************************************************************
|
|
9824
|
+
* *
|
|
9825
|
+
* Properties *
|
|
9826
|
+
* *
|
|
9827
|
+
**************************************************************************/
|
|
9917
9828
|
set elderFileSelect(value) {
|
|
9918
9829
|
this._accept = value;
|
|
9919
9830
|
if (this._fileInput) {
|
|
@@ -9926,6 +9837,11 @@ class ElderFileSelectInput {
|
|
|
9926
9837
|
this.renderer.setProperty(this._fileInput, 'multiple', value);
|
|
9927
9838
|
}
|
|
9928
9839
|
}
|
|
9840
|
+
/**
|
|
9841
|
+
* Allow the user to select a directory. All files that are recursively contained are selected.
|
|
9842
|
+
* However, the user will no longer be able to select individual files if this is enabled.
|
|
9843
|
+
* @param value
|
|
9844
|
+
*/
|
|
9929
9845
|
set elderFileSelectDirectory(value) {
|
|
9930
9846
|
this._directory = coerceBooleanProperty(value);
|
|
9931
9847
|
if (this._fileInput) {
|
|
@@ -9938,6 +9854,17 @@ class ElderFileSelectInput {
|
|
|
9938
9854
|
* Public API *
|
|
9939
9855
|
* *
|
|
9940
9856
|
**************************************************************************/
|
|
9857
|
+
onClick(event) {
|
|
9858
|
+
this.openFileSelectDialog();
|
|
9859
|
+
}
|
|
9860
|
+
openFileSelectDialog() {
|
|
9861
|
+
this._fileInput.click();
|
|
9862
|
+
}
|
|
9863
|
+
/***************************************************************************
|
|
9864
|
+
* *
|
|
9865
|
+
* Private methods *
|
|
9866
|
+
* *
|
|
9867
|
+
**************************************************************************/
|
|
9941
9868
|
/**
|
|
9942
9869
|
* <input type="file"
|
|
9943
9870
|
* hidden #fileInput
|
|
@@ -9961,9 +9888,7 @@ class ElderFileSelectInput {
|
|
|
9961
9888
|
this.renderer.setAttribute(this._fileInput, 'webkitdirectory', 'true');
|
|
9962
9889
|
this.renderer.setAttribute(this._fileInput, 'directory', 'true');
|
|
9963
9890
|
}
|
|
9964
|
-
this._unlisten = this.renderer.listen(this._fileInput, 'change', event =>
|
|
9965
|
-
this.fileInputChanged(this._fileInput.files);
|
|
9966
|
-
});
|
|
9891
|
+
this._unlisten = this.renderer.listen(this._fileInput, 'change', event => this.fileInputChanged(event));
|
|
9967
9892
|
}
|
|
9968
9893
|
removeFileSelect() {
|
|
9969
9894
|
if (this._unlisten) {
|
|
@@ -9975,24 +9900,26 @@ class ElderFileSelectInput {
|
|
|
9975
9900
|
this._fileInput = null;
|
|
9976
9901
|
}
|
|
9977
9902
|
}
|
|
9978
|
-
|
|
9979
|
-
this._fileInput.
|
|
9980
|
-
}
|
|
9981
|
-
/***************************************************************************
|
|
9982
|
-
* *
|
|
9983
|
-
* Private methods *
|
|
9984
|
-
* *
|
|
9985
|
-
**************************************************************************/
|
|
9986
|
-
fileInputChanged(fileList) {
|
|
9903
|
+
fileInputChanged(event) {
|
|
9904
|
+
const fileList = this._fileInput.files;
|
|
9987
9905
|
const files = this.toFileEntries(fileList);
|
|
9988
9906
|
this.logger.debug('fileInputChanged, files:', files);
|
|
9907
|
+
this.emitFileList(files);
|
|
9989
9908
|
this.clearFileList();
|
|
9990
|
-
this._filesSelected.next(files);
|
|
9991
9909
|
}
|
|
9992
9910
|
clearFileList() {
|
|
9993
9911
|
// not nice but works
|
|
9994
9912
|
this._fileInput.value = null;
|
|
9995
9913
|
}
|
|
9914
|
+
emitFileList(files) {
|
|
9915
|
+
if (files.length > 0) {
|
|
9916
|
+
this.elderFileSelectChange.next(files);
|
|
9917
|
+
this.elderSingleFileSelectChange.emit(files[0].file);
|
|
9918
|
+
}
|
|
9919
|
+
else {
|
|
9920
|
+
this.logger.warn('User did not select any File or the Folder was empty.');
|
|
9921
|
+
}
|
|
9922
|
+
}
|
|
9996
9923
|
toFileEntries(fileList) {
|
|
9997
9924
|
const files = [];
|
|
9998
9925
|
for (const key in fileList) {
|
|
@@ -10002,174 +9929,7 @@ class ElderFileSelectInput {
|
|
|
10002
9929
|
}
|
|
10003
9930
|
return files;
|
|
10004
9931
|
}
|
|
10005
|
-
}
|
|
10006
|
-
|
|
10007
|
-
class FileListingSystemHandle {
|
|
10008
|
-
/***************************************************************************
|
|
10009
|
-
* *
|
|
10010
|
-
* Public methods *
|
|
10011
|
-
* *
|
|
10012
|
-
**************************************************************************/
|
|
10013
|
-
/**
|
|
10014
|
-
* Creates a File Entry Array Observable by resolving its FileSystemHandle.
|
|
10015
|
-
* @returns An `Observable<FileEntry[]>` with the FileSystemFileHandle included
|
|
10016
|
-
*/
|
|
10017
|
-
static listFiles(handle, rootDirectory) {
|
|
10018
|
-
switch (handle.kind) {
|
|
10019
|
-
case 'file':
|
|
10020
|
-
return FileEntry.ofFileHandle(handle, rootDirectory).pipe(toArray());
|
|
10021
|
-
case 'directory':
|
|
10022
|
-
return FileListingSystemHandle.listFilesRecursive(handle, rootDirectory);
|
|
10023
|
-
}
|
|
10024
|
-
}
|
|
10025
|
-
/***************************************************************************
|
|
10026
|
-
* *
|
|
10027
|
-
* Private methods *
|
|
10028
|
-
* *
|
|
10029
|
-
**************************************************************************/
|
|
10030
|
-
static listFilesRecursive(dirHandle, rootDirectory) {
|
|
10031
|
-
return FileSystemApi.getHandlesFromDirectory(dirHandle).pipe(map(handles => FileListingSystemHandle.listFilesOfEach(handles, rootDirectory ? rootDirectory : dirHandle)), switchMap(fileEntriesArray$ => zip(fileEntriesArray$)), map(fileEntriesArray => fileEntriesArray.flat()));
|
|
10032
|
-
}
|
|
10033
|
-
static listFilesOfEach(handles, rootDirectory) {
|
|
10034
|
-
return handles.map(fileOrDirHandle => FileListingSystemHandle.listFiles(fileOrDirHandle, rootDirectory));
|
|
10035
|
-
}
|
|
10036
|
-
}
|
|
10037
|
-
|
|
10038
|
-
class ElderFileSelectDirective {
|
|
10039
|
-
/***************************************************************************
|
|
10040
|
-
* *
|
|
10041
|
-
* Constructor *
|
|
10042
|
-
* *
|
|
10043
|
-
**************************************************************************/
|
|
10044
|
-
constructor(renderer, el, destroyRef) {
|
|
10045
|
-
this.renderer = renderer;
|
|
10046
|
-
this.el = el;
|
|
10047
|
-
this.destroyRef = destroyRef;
|
|
10048
|
-
/***************************************************************************
|
|
10049
|
-
* *
|
|
10050
|
-
* Fields *
|
|
10051
|
-
* *
|
|
10052
|
-
**************************************************************************/
|
|
10053
|
-
this.logger = LoggerFactory.getLogger(this.constructor.name);
|
|
10054
|
-
this.elderFileSelectChange = new EventEmitter();
|
|
10055
|
-
this.elderSingleFileSelectChange = new EventEmitter();
|
|
10056
|
-
this._useDirectoryPicker = false;
|
|
10057
|
-
this._legacyInput = new ElderFileSelectInput(this.renderer, this.el);
|
|
10058
|
-
}
|
|
10059
|
-
/***************************************************************************
|
|
10060
|
-
* *
|
|
10061
|
-
* Life Cycle *
|
|
10062
|
-
* *
|
|
10063
|
-
**************************************************************************/
|
|
10064
|
-
ngOnInit() {
|
|
10065
|
-
if (!FileSystemApi.isFileSystemSupported() || !FileSystemApi.isDirectoryPickerSupported()) {
|
|
10066
|
-
this.logger.warn('showOpenFilePicker or showDirectoryPicker is not supported for this browser, falling back to legacy file picker');
|
|
10067
|
-
this._legacyInput.createFileSelect();
|
|
10068
|
-
this._legacyInput.filesSelected.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
|
|
10069
|
-
next: multiFileChange => {
|
|
10070
|
-
this.elderFileSelectChange.next(multiFileChange);
|
|
10071
|
-
const file = multiFileChange[0]?.file;
|
|
10072
|
-
if (file) {
|
|
10073
|
-
this.elderSingleFileSelectChange.next(file);
|
|
10074
|
-
}
|
|
10075
|
-
}
|
|
10076
|
-
});
|
|
10077
|
-
}
|
|
10078
|
-
}
|
|
10079
|
-
ngOnDestroy() {
|
|
10080
|
-
this._legacyInput.removeFileSelect();
|
|
10081
|
-
}
|
|
10082
|
-
/***************************************************************************
|
|
10083
|
-
* *
|
|
10084
|
-
* Properties *
|
|
10085
|
-
* *
|
|
10086
|
-
**************************************************************************/
|
|
10087
|
-
set elderFileSelect(value) {
|
|
10088
|
-
this._filePickerOptions = {
|
|
10089
|
-
excludeAcceptAllOptions: true,
|
|
10090
|
-
id: this._filePickerOptions?.id,
|
|
10091
|
-
multiple: this._filePickerOptions?.multiple,
|
|
10092
|
-
startIn: this._filePickerOptions?.startIn,
|
|
10093
|
-
types: [this.buildTypeOption(value)]
|
|
10094
|
-
};
|
|
10095
|
-
this._legacyInput.elderFileSelect = value;
|
|
10096
|
-
}
|
|
10097
|
-
buildTypeOption(value) {
|
|
10098
|
-
if (this.isFileExtension(value)) {
|
|
10099
|
-
return {
|
|
10100
|
-
accept: {
|
|
10101
|
-
'*/*': value.trim()
|
|
10102
|
-
.replace(/\s+/g, '')
|
|
10103
|
-
.split(',')
|
|
10104
|
-
}
|
|
10105
|
-
};
|
|
10106
|
-
}
|
|
10107
|
-
else if (this.isMimeType(value)) {
|
|
10108
|
-
return {
|
|
10109
|
-
accept: { [value]: [] }
|
|
10110
|
-
};
|
|
10111
|
-
}
|
|
10112
|
-
return null;
|
|
10113
|
-
}
|
|
10114
|
-
isFileExtension(input) {
|
|
10115
|
-
const regex = new RegExp(/^(\.\w+)(, ?\.\w+)*$/);
|
|
10116
|
-
return regex.test(input);
|
|
10117
|
-
}
|
|
10118
|
-
isMimeType(input) {
|
|
10119
|
-
const regex = new RegExp(/^.+\/.+$/);
|
|
10120
|
-
return regex.test(input);
|
|
10121
|
-
}
|
|
10122
|
-
set elderFileSelectMultiple(value) {
|
|
10123
|
-
this._filePickerOptions = {
|
|
10124
|
-
excludeAcceptAllOptions: this._filePickerOptions?.excludeAcceptAllOptions,
|
|
10125
|
-
id: this._filePickerOptions?.id,
|
|
10126
|
-
multiple: coerceBooleanProperty(value),
|
|
10127
|
-
startIn: this._filePickerOptions?.startIn,
|
|
10128
|
-
types: this._filePickerOptions?.types
|
|
10129
|
-
};
|
|
10130
|
-
this._legacyInput.elderFileSelectMultiple = value;
|
|
10131
|
-
}
|
|
10132
|
-
/**
|
|
10133
|
-
* Allow the user to select a directory. All files that are recursively contained are selected.
|
|
10134
|
-
* However, the user will no longer be able to select individual files if this is enabled.
|
|
10135
|
-
* @param value
|
|
10136
|
-
*/
|
|
10137
|
-
set elderFileSelectDirectory(value) {
|
|
10138
|
-
this._useDirectoryPicker = coerceBooleanProperty(value);
|
|
10139
|
-
this._legacyInput.elderFileSelectDirectory = value;
|
|
10140
|
-
}
|
|
10141
|
-
/***************************************************************************
|
|
10142
|
-
* *
|
|
10143
|
-
* Public API *
|
|
10144
|
-
* *
|
|
10145
|
-
**************************************************************************/
|
|
10146
|
-
onClick(event) {
|
|
10147
|
-
if (!this._useDirectoryPicker && FileSystemApi.isFileSystemSupported()) {
|
|
10148
|
-
this.openFilePicker(this._filePickerOptions).subscribe({
|
|
10149
|
-
next: fileList => this.elderFileSelectChange.next(fileList)
|
|
10150
|
-
});
|
|
10151
|
-
}
|
|
10152
|
-
else if (this._useDirectoryPicker && FileSystemApi.isDirectoryPickerSupported()) {
|
|
10153
|
-
this.openDirectoryPicker(this._directoryPickerOptions).subscribe({
|
|
10154
|
-
next: fileList => this.elderFileSelectChange.next(fileList)
|
|
10155
|
-
});
|
|
10156
|
-
}
|
|
10157
|
-
else {
|
|
10158
|
-
this._legacyInput.openFileSelectDialog();
|
|
10159
|
-
}
|
|
10160
|
-
}
|
|
10161
|
-
/***************************************************************************
|
|
10162
|
-
* *
|
|
10163
|
-
* Private methods *
|
|
10164
|
-
* *
|
|
10165
|
-
**************************************************************************/
|
|
10166
|
-
openFilePicker(pickerOpts) {
|
|
10167
|
-
return FileSystemApi.openFilePicker(pickerOpts).pipe(switchMap(files => combineLatest(files.map(file => FileEntry.ofFileHandle(file)))));
|
|
10168
|
-
}
|
|
10169
|
-
openDirectoryPicker(pickerOpts) {
|
|
10170
|
-
return FileSystemApi.openDirectoryPicker(pickerOpts).pipe(switchMap(dir => FileListingSystemHandle.listFiles(dir)));
|
|
10171
|
-
}
|
|
10172
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderFileSelectDirective, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
9932
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderFileSelectDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
10173
9933
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.4", type: ElderFileSelectDirective, isStandalone: true, selector: "[elderFileSelect]", inputs: { elderFileSelect: "elderFileSelect", elderFileSelectMultiple: "elderFileSelectMultiple", elderFileSelectDirectory: "elderFileSelectDirectory" }, outputs: { elderFileSelectChange: "elderFileSelectChange", elderSingleFileSelectChange: "elderSingleFileSelectChange" }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 }); }
|
|
10174
9934
|
}
|
|
10175
9935
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderFileSelectDirective, decorators: [{
|
|
@@ -10178,7 +9938,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
|
|
|
10178
9938
|
selector: '[elderFileSelect]',
|
|
10179
9939
|
standalone: true
|
|
10180
9940
|
}]
|
|
10181
|
-
}], ctorParameters: () => [{ type: i0.
|
|
9941
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { elderFileSelectChange: [{
|
|
10182
9942
|
type: Output
|
|
10183
9943
|
}], elderSingleFileSelectChange: [{
|
|
10184
9944
|
type: Output
|
|
@@ -10298,44 +10058,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
|
|
|
10298
10058
|
type: Input
|
|
10299
10059
|
}] } });
|
|
10300
10060
|
|
|
10301
|
-
class
|
|
10302
|
-
/***************************************************************************
|
|
10303
|
-
* *
|
|
10304
|
-
* Constructor *
|
|
10305
|
-
* *
|
|
10306
|
-
**************************************************************************/
|
|
10061
|
+
class FileListingRx {
|
|
10307
10062
|
constructor() {
|
|
10063
|
+
this.log = LoggerFactory.getLogger(this.constructor.name);
|
|
10308
10064
|
}
|
|
10065
|
+
static { this.INSTANCE = new FileListingRx(); }
|
|
10309
10066
|
/***************************************************************************
|
|
10310
10067
|
* *
|
|
10311
|
-
* Public
|
|
10068
|
+
* Public API *
|
|
10312
10069
|
* *
|
|
10313
10070
|
**************************************************************************/
|
|
10314
|
-
|
|
10315
|
-
|
|
10071
|
+
toFileList(transferItemList) {
|
|
10072
|
+
const obs = [];
|
|
10073
|
+
for (let i = 0; i < transferItemList.length; i++) {
|
|
10074
|
+
const transferItem = transferItemList[i];
|
|
10075
|
+
const entry = transferItem.webkitGetAsEntry();
|
|
10076
|
+
if (entry) {
|
|
10077
|
+
obs.push(this.listFilesRecursive(entry));
|
|
10078
|
+
}
|
|
10079
|
+
else {
|
|
10080
|
+
const itemAsFile = transferItem.getAsFile();
|
|
10081
|
+
if (itemAsFile) {
|
|
10082
|
+
obs.push(of([FileEntry.ofFile(itemAsFile)]));
|
|
10083
|
+
}
|
|
10084
|
+
else {
|
|
10085
|
+
if (transferItem.kind == 'file') {
|
|
10086
|
+
obs.push(of([
|
|
10087
|
+
FileEntry.ofFile(new File([], '', {
|
|
10088
|
+
type: transferItem.type
|
|
10089
|
+
}))
|
|
10090
|
+
]));
|
|
10091
|
+
}
|
|
10092
|
+
else {
|
|
10093
|
+
this.log.warn('Could not handle DataTransferItem!', transferItem);
|
|
10094
|
+
}
|
|
10095
|
+
}
|
|
10096
|
+
}
|
|
10097
|
+
}
|
|
10098
|
+
return zip(obs).pipe(map(files => files.flat()));
|
|
10099
|
+
}
|
|
10100
|
+
listFilesRecursive(entry) {
|
|
10101
|
+
return this.listFilesRecursiveAsync(entry, null);
|
|
10316
10102
|
}
|
|
10317
10103
|
/***************************************************************************
|
|
10318
10104
|
* *
|
|
10319
10105
|
* Private methods *
|
|
10320
10106
|
* *
|
|
10321
10107
|
**************************************************************************/
|
|
10322
|
-
|
|
10108
|
+
listFilesRecursiveAsync(entry, parent) {
|
|
10323
10109
|
if (entry.isDirectory) {
|
|
10324
10110
|
const directoryEntry = entry;
|
|
10325
|
-
return
|
|
10111
|
+
return this.readEntries(directoryEntry).pipe(mergeMap$1(entries => zip(entries.map(entry => this.listFilesRecursiveAsync(entry, directoryEntry)))), map(files => files.flat()));
|
|
10326
10112
|
}
|
|
10327
10113
|
else if (entry.isFile) {
|
|
10328
10114
|
const fileEntry = entry;
|
|
10329
|
-
return
|
|
10115
|
+
return this.observableFile(fileEntry, parent).pipe(map(file => [file]));
|
|
10330
10116
|
}
|
|
10331
10117
|
else {
|
|
10332
10118
|
return EMPTY;
|
|
10333
10119
|
}
|
|
10334
10120
|
}
|
|
10335
|
-
|
|
10121
|
+
observableFile(fileEntry, parent) {
|
|
10336
10122
|
return new Observable(observer => {
|
|
10337
10123
|
fileEntry.file(file => {
|
|
10338
|
-
observer.next(FileEntry.relativeFile(file,
|
|
10124
|
+
observer.next(FileEntry.relativeFile(file, this.trimStaringSlash(parent?.fullPath)));
|
|
10339
10125
|
observer.complete();
|
|
10340
10126
|
}, err => {
|
|
10341
10127
|
observer.error(err);
|
|
@@ -10343,7 +10129,7 @@ class FileListingWebkit {
|
|
|
10343
10129
|
});
|
|
10344
10130
|
});
|
|
10345
10131
|
}
|
|
10346
|
-
|
|
10132
|
+
trimStaringSlash(path) {
|
|
10347
10133
|
if (path) {
|
|
10348
10134
|
if (path.startsWith('/')) {
|
|
10349
10135
|
path = path.substring(1);
|
|
@@ -10351,12 +10137,12 @@ class FileListingWebkit {
|
|
|
10351
10137
|
}
|
|
10352
10138
|
return path;
|
|
10353
10139
|
}
|
|
10354
|
-
|
|
10140
|
+
readEntries(directoryEntry) {
|
|
10355
10141
|
return new Observable(observer => {
|
|
10356
|
-
|
|
10142
|
+
this.consumeReaderToCompletion(observer, directoryEntry.createReader());
|
|
10357
10143
|
});
|
|
10358
10144
|
}
|
|
10359
|
-
|
|
10145
|
+
consumeReaderToCompletion(observer, directoryReader) {
|
|
10360
10146
|
directoryReader.readEntries(entries => {
|
|
10361
10147
|
if (entries && entries.length > 0) {
|
|
10362
10148
|
observer.next(entries);
|
|
@@ -10372,60 +10158,6 @@ class FileListingWebkit {
|
|
|
10372
10158
|
}
|
|
10373
10159
|
}
|
|
10374
10160
|
|
|
10375
|
-
class FileListingRx {
|
|
10376
|
-
constructor() {
|
|
10377
|
-
this.log = LoggerFactory.getLogger(this.constructor.name);
|
|
10378
|
-
}
|
|
10379
|
-
static { this.INSTANCE = new FileListingRx(); }
|
|
10380
|
-
/***************************************************************************
|
|
10381
|
-
* *
|
|
10382
|
-
* Public API *
|
|
10383
|
-
* *
|
|
10384
|
-
**************************************************************************/
|
|
10385
|
-
toFileList(transferItemList) {
|
|
10386
|
-
const obs = [];
|
|
10387
|
-
for (let i = 0; i < transferItemList.length; i++) {
|
|
10388
|
-
const transferItem = transferItemList[i];
|
|
10389
|
-
obs.push(this.resolveTransferItem(transferItem));
|
|
10390
|
-
}
|
|
10391
|
-
return zip(obs).pipe(map(files => files.flat()));
|
|
10392
|
-
}
|
|
10393
|
-
/***************************************************************************
|
|
10394
|
-
* *
|
|
10395
|
-
* Private methods *
|
|
10396
|
-
* *
|
|
10397
|
-
**************************************************************************/
|
|
10398
|
-
resolveTransferItem(transferItem) {
|
|
10399
|
-
if (FileSystemApi.isGetAsFileSystemHandleSupported(transferItem)) {
|
|
10400
|
-
return FileSystemApi.getAsFileSystemHandle(transferItem).pipe(switchMap(handle => FileListingSystemHandle.listFiles(handle)));
|
|
10401
|
-
}
|
|
10402
|
-
const entry = transferItem.webkitGetAsEntry();
|
|
10403
|
-
if (entry) {
|
|
10404
|
-
return FileListingWebkit.listFilesRecursive(entry);
|
|
10405
|
-
}
|
|
10406
|
-
return this.legacyFileListing(transferItem);
|
|
10407
|
-
}
|
|
10408
|
-
legacyFileListing(transferItem) {
|
|
10409
|
-
const itemAsFile = transferItem.getAsFile();
|
|
10410
|
-
if (itemAsFile) {
|
|
10411
|
-
return of([FileEntry.ofFile(itemAsFile)]);
|
|
10412
|
-
}
|
|
10413
|
-
else {
|
|
10414
|
-
if (transferItem.kind == 'file') {
|
|
10415
|
-
return of([
|
|
10416
|
-
FileEntry.ofFile(new File([], '', {
|
|
10417
|
-
type: transferItem.type
|
|
10418
|
-
}))
|
|
10419
|
-
]);
|
|
10420
|
-
}
|
|
10421
|
-
else {
|
|
10422
|
-
this.log.warn('Could not handle DataTransferItem!', transferItem);
|
|
10423
|
-
return of([]);
|
|
10424
|
-
}
|
|
10425
|
-
}
|
|
10426
|
-
}
|
|
10427
|
-
}
|
|
10428
|
-
|
|
10429
10161
|
class ElderFileDropZoneDirective {
|
|
10430
10162
|
/***************************************************************************
|
|
10431
10163
|
* *
|
|
@@ -10979,7 +10711,18 @@ class ElderBlobViewerComponent {
|
|
|
10979
10711
|
this._url$ = new BehaviorSubject(null);
|
|
10980
10712
|
this._mimeType$ = new BehaviorSubject(null);
|
|
10981
10713
|
this.destroy$ = new Subject();
|
|
10982
|
-
|
|
10714
|
+
/***************************************************************************
|
|
10715
|
+
* *
|
|
10716
|
+
* Properties *
|
|
10717
|
+
* *
|
|
10718
|
+
**************************************************************************/
|
|
10719
|
+
/**
|
|
10720
|
+
* Attempt to display unknown blobs as text. (i.e. mime-type is octet-stream)
|
|
10721
|
+
* @param unknownAsText
|
|
10722
|
+
*/
|
|
10723
|
+
this.displayUnknownAsText = input(false, {
|
|
10724
|
+
transform: (input) => coerceBooleanProperty(input)
|
|
10725
|
+
});
|
|
10983
10726
|
}
|
|
10984
10727
|
/***************************************************************************
|
|
10985
10728
|
* *
|
|
@@ -10993,21 +10736,6 @@ class ElderBlobViewerComponent {
|
|
|
10993
10736
|
this.destroy$.next();
|
|
10994
10737
|
this.destroy$.complete();
|
|
10995
10738
|
}
|
|
10996
|
-
/***************************************************************************
|
|
10997
|
-
* *
|
|
10998
|
-
* Properties *
|
|
10999
|
-
* *
|
|
11000
|
-
**************************************************************************/
|
|
11001
|
-
/**
|
|
11002
|
-
* Attempt to display unknown blobs as text. (i.e. mime-type is octet-stream)
|
|
11003
|
-
* @param unknownAsText
|
|
11004
|
-
*/
|
|
11005
|
-
set displayUnknownAsText(unknownAsText) {
|
|
11006
|
-
// TODO FIX RACE CONDITION:
|
|
11007
|
-
// Since this property is not reactive, it must be set first.
|
|
11008
|
-
// Otherwise, it will still be false, even if set to true!
|
|
11009
|
-
this._displayUnknownAsText = coerceBooleanProperty(unknownAsText);
|
|
11010
|
-
}
|
|
11011
10739
|
/**
|
|
11012
10740
|
* Set a in memory blob to display.
|
|
11013
10741
|
* @param blob
|
|
@@ -11086,7 +10814,7 @@ class ElderBlobViewerComponent {
|
|
|
11086
10814
|
});
|
|
11087
10815
|
}
|
|
11088
10816
|
canDisplayAsText(mimeType) {
|
|
11089
|
-
const can = mimeType.isText || (this.
|
|
10817
|
+
const can = mimeType.isText || (this.displayUnknownAsText() && mimeType.isOctetStream);
|
|
11090
10818
|
// TODO _displayUnknownAsText might be null due race condition see todo above.
|
|
11091
10819
|
// this.logger.debug('canDisplayAsText(' + mimeType.value + ') --> '
|
|
11092
10820
|
// + can + ' ---> this._displayUnknownAsText:' + this._displayUnknownAsText, mimeType);
|
|
@@ -11098,14 +10826,12 @@ class ElderBlobViewerComponent {
|
|
|
11098
10826
|
});
|
|
11099
10827
|
}
|
|
11100
10828
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderBlobViewerComponent, deps: [{ token: HttpClientPristine }, { token: i1.DomSanitizer }, { token: ElderToastService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
11101
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
10829
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.0.4", type: ElderBlobViewerComponent, isStandalone: true, selector: "elder-blob-viewer", inputs: { displayUnknownAsText: { classPropertyName: "displayUnknownAsText", publicName: "displayUnknownAsText", isSignal: true, isRequired: false, transformFunction: null }, blob: { classPropertyName: "blob", publicName: "blob", isSignal: false, isRequired: false, transformFunction: null }, blobUrl: { classPropertyName: "blobUrl", publicName: "blobUrl", isSignal: false, isRequired: false, transformFunction: null }, url: { classPropertyName: "url", publicName: "url", isSignal: false, isRequired: false, transformFunction: null }, mimeType: { classPropertyName: "mimeType", publicName: "mimeType", isSignal: false, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"layout-col full place-center-center document-viewer\">\n\n <ng-container *ngIf=\"blobContext$ | async as blobContext\">\n\n <!-- Video -->\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.mimeType.isVideo\">\n <video class=\"video\"\n controls autoplay loop\n\n >\n <source [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\">\n Your browser does not support HTML5 video.\n </video>\n </div>\n\n <!-- Audio -->\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.mimeType.isAudio\">\n <audio class=\"audio\"\n controls autoplay loop\n >\n <source [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\">\n Your browser does not support HTML5 audio.\n </audio>\n </div>\n\n <!-- Image -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.mimeType.isImage\" style=\"overflow: hidden\">\n <img class=\"cover flex\"\n [src]=\"blobContext.safeUrl\" alt=\"blob image\"/>\n </div>\n\n <!-- Embedded (PDFs etc) -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.displayEmbedded\">\n <div class=\"full\">\n <embed class=\"embedded\" [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\" width=\"100%\" height=\"100%\">\n </div>\n </div>\n\n <!-- Plain Text -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.displayAsText\">\n <textarea\n class=\"document-content\"\n placeholder=\"Content\"\n [value]=\"blobContext.text\" wrap=\"off\"\n readonly\n ></textarea>\n </div>\n\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.cantDisplay\">\n <p>Cant display {{blobContext.mimeType.value}}!</p>\n </div>\n\n </ng-container>\n\n <ng-container *ngIf=\"!(blobContext$ | async)\">\n <div class=\"layout-col place-center-center full\">\n <p>No Document.</p>\n </div>\n </ng-container>\n\n\n</div>\n", styles: [":host{overflow:hidden}.document-viewer{background-color:#dedede;color:#1f1e1e}.video,.audio{width:100%;height:auto}.embedded{width:100%;height:100%}.cover{object-fit:scale-down;width:100%;height:auto;overflow:hidden}.document-content{font-family:Courier,monospace;font-size:14px;background-color:#575757;color:#ccc;outline:none;resize:none;width:100%;height:100%;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-border-radius:12px;border-radius:0;-webkit-box-shadow:0px 2px 14px #000;box-shadow:0 2px 14px #000;border-top:1px solid #FFF;border-bottom:1px solid #FFF}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
11102
10830
|
}
|
|
11103
10831
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderBlobViewerComponent, decorators: [{
|
|
11104
10832
|
type: Component,
|
|
11105
10833
|
args: [{ selector: 'elder-blob-viewer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [NgIf, AsyncPipe], template: "<div class=\"layout-col full place-center-center document-viewer\">\n\n <ng-container *ngIf=\"blobContext$ | async as blobContext\">\n\n <!-- Video -->\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.mimeType.isVideo\">\n <video class=\"video\"\n controls autoplay loop\n\n >\n <source [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\">\n Your browser does not support HTML5 video.\n </video>\n </div>\n\n <!-- Audio -->\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.mimeType.isAudio\">\n <audio class=\"audio\"\n controls autoplay loop\n >\n <source [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\">\n Your browser does not support HTML5 audio.\n </audio>\n </div>\n\n <!-- Image -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.mimeType.isImage\" style=\"overflow: hidden\">\n <img class=\"cover flex\"\n [src]=\"blobContext.safeUrl\" alt=\"blob image\"/>\n </div>\n\n <!-- Embedded (PDFs etc) -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.displayEmbedded\">\n <div class=\"full\">\n <embed class=\"embedded\" [src]=\"blobContext.safeUrl\" [type]=\"blobContext.mimeType.value\" width=\"100%\" height=\"100%\">\n </div>\n </div>\n\n <!-- Plain Text -->\n <div class=\"layout-col full\" *ngIf=\"blobContext.displayAsText\">\n <textarea\n class=\"document-content\"\n placeholder=\"Content\"\n [value]=\"blobContext.text\" wrap=\"off\"\n readonly\n ></textarea>\n </div>\n\n <div class=\"layout-col place-center-center full\" *ngIf=\"blobContext.cantDisplay\">\n <p>Cant display {{blobContext.mimeType.value}}!</p>\n </div>\n\n </ng-container>\n\n <ng-container *ngIf=\"!(blobContext$ | async)\">\n <div class=\"layout-col place-center-center full\">\n <p>No Document.</p>\n </div>\n </ng-container>\n\n\n</div>\n", styles: [":host{overflow:hidden}.document-viewer{background-color:#dedede;color:#1f1e1e}.video,.audio{width:100%;height:auto}.embedded{width:100%;height:100%}.cover{object-fit:scale-down;width:100%;height:auto;overflow:hidden}.document-content{font-family:Courier,monospace;font-size:14px;background-color:#575757;color:#ccc;outline:none;resize:none;width:100%;height:100%;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-border-radius:12px;border-radius:0;-webkit-box-shadow:0px 2px 14px #000;box-shadow:0 2px 14px #000;border-top:1px solid #FFF;border-bottom:1px solid #FFF}\n"] }]
|
|
11106
|
-
}], ctorParameters: () => [{ type: HttpClientPristine }, { type: i1.DomSanitizer }, { type: ElderToastService }], propDecorators: {
|
|
11107
|
-
type: Input
|
|
11108
|
-
}], blob: [{
|
|
10834
|
+
}], ctorParameters: () => [{ type: HttpClientPristine }, { type: i1.DomSanitizer }, { type: ElderToastService }], propDecorators: { blob: [{
|
|
11109
10835
|
type: Input
|
|
11110
10836
|
}], blobUrl: [{
|
|
11111
10837
|
type: Input
|
|
@@ -15947,6 +15673,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
|
|
|
15947
15673
|
type: Input
|
|
15948
15674
|
}] } });
|
|
15949
15675
|
|
|
15676
|
+
class InputUtils {
|
|
15677
|
+
static isNoInputArgs(input) {
|
|
15678
|
+
return input === '';
|
|
15679
|
+
}
|
|
15680
|
+
}
|
|
15681
|
+
|
|
15950
15682
|
class ElderMultipleOfUtil {
|
|
15951
15683
|
/***************************************************************************
|
|
15952
15684
|
* *
|
|
@@ -15996,11 +15728,16 @@ class ElderMultipleOfUtil {
|
|
|
15996
15728
|
}
|
|
15997
15729
|
}
|
|
15998
15730
|
class ElderMultipleOfValidator {
|
|
15999
|
-
|
|
16000
|
-
|
|
16001
|
-
|
|
16002
|
-
|
|
16003
|
-
|
|
15731
|
+
constructor() {
|
|
15732
|
+
/***************************************************************************
|
|
15733
|
+
* *
|
|
15734
|
+
* Fields *
|
|
15735
|
+
* *
|
|
15736
|
+
**************************************************************************/
|
|
15737
|
+
this.factor = input(null, {
|
|
15738
|
+
alias: 'elderMultipleOf',
|
|
15739
|
+
transform: (input) => InputUtils.isNoInputArgs(input) ? null : input
|
|
15740
|
+
});
|
|
16004
15741
|
}
|
|
16005
15742
|
/***************************************************************************
|
|
16006
15743
|
* *
|
|
@@ -16008,15 +15745,15 @@ class ElderMultipleOfValidator {
|
|
|
16008
15745
|
* *
|
|
16009
15746
|
**************************************************************************/
|
|
16010
15747
|
validate(control) {
|
|
16011
|
-
if (this.factor) {
|
|
16012
|
-
return ElderMultipleOfUtil.multipleOfValidator(this.factor)(control);
|
|
15748
|
+
if (this.factor()) {
|
|
15749
|
+
return ElderMultipleOfUtil.multipleOfValidator(this.factor())(control);
|
|
16013
15750
|
}
|
|
16014
15751
|
else {
|
|
16015
15752
|
return null;
|
|
16016
15753
|
}
|
|
16017
15754
|
}
|
|
16018
15755
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderMultipleOfValidator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
16019
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
15756
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.0.4", type: ElderMultipleOfValidator, isStandalone: true, selector: "[elderMultipleOf][formControlName],[elderMultipleOf][formControl],[elderMultipleOf][ngModel]", inputs: { factor: { classPropertyName: "factor", publicName: "elderMultipleOf", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
16020
15757
|
{
|
|
16021
15758
|
provide: NG_VALIDATORS,
|
|
16022
15759
|
useExisting: forwardRef(() => ElderMultipleOfValidator),
|
|
@@ -16037,9 +15774,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
|
|
|
16037
15774
|
],
|
|
16038
15775
|
standalone: true
|
|
16039
15776
|
}]
|
|
16040
|
-
}]
|
|
16041
|
-
type: Input
|
|
16042
|
-
}] } });
|
|
15777
|
+
}] });
|
|
16043
15778
|
|
|
16044
15779
|
/**
|
|
16045
15780
|
* This directive redirects the next focus element
|
|
@@ -16903,7 +16638,7 @@ class ElderTableActivationDirective {
|
|
|
16903
16638
|
this._data = [];
|
|
16904
16639
|
this.activeItem$ = new BehaviorSubject(null);
|
|
16905
16640
|
this.rows$ = new BehaviorSubject([]);
|
|
16906
|
-
this.
|
|
16641
|
+
this._activationOptions = {};
|
|
16907
16642
|
}
|
|
16908
16643
|
/***************************************************************************
|
|
16909
16644
|
* *
|
|
@@ -16964,6 +16699,12 @@ class ElderTableActivationDirective {
|
|
|
16964
16699
|
* Properties *
|
|
16965
16700
|
* *
|
|
16966
16701
|
**************************************************************************/
|
|
16702
|
+
set activationOptions(options) {
|
|
16703
|
+
this.activationOptions = InputUtils.isNoInputArgs(options) ? options : {};
|
|
16704
|
+
}
|
|
16705
|
+
get activationOptions() {
|
|
16706
|
+
return this._activationOptions;
|
|
16707
|
+
}
|
|
16967
16708
|
get activeItemEventChange() {
|
|
16968
16709
|
return this.itemActivationEventSubject;
|
|
16969
16710
|
}
|
|
@@ -17161,12 +16902,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
|
|
|
17161
16902
|
exportAs: 'elderTableActivation',
|
|
17162
16903
|
standalone: true
|
|
17163
16904
|
}]
|
|
17164
|
-
}], ctorParameters: () => [{ type: ElderTableComponent }], propDecorators: {
|
|
17165
|
-
type: Input,
|
|
17166
|
-
args: ['elderTableActivation']
|
|
17167
|
-
}], onKeydown: [{
|
|
16905
|
+
}], ctorParameters: () => [{ type: ElderTableComponent }], propDecorators: { onKeydown: [{
|
|
17168
16906
|
type: HostListener,
|
|
17169
16907
|
args: ['keydown', ['$event']]
|
|
16908
|
+
}], activationOptions: [{
|
|
16909
|
+
type: Input,
|
|
16910
|
+
args: ['elderTableActivation']
|
|
17170
16911
|
}], activeItemEventChange: [{
|
|
17171
16912
|
type: Output
|
|
17172
16913
|
}], activeItemChange: [{
|