@elderbyte/ngx-starter 18.1.0-beta2 → 18.2.0-beta2
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 +83 -85
- package/esm2022/lib/components/files/listing/file-entry.mjs +15 -30
- package/esm2022/lib/components/files/listing/file-listing-rx.mjs +70 -30
- package/esm2022/lib/components/forms/directives/validation/validators/elder-multiple-of.validator.mjs +24 -9
- package/fesm2022/elderbyte-ngx-starter.mjs +162 -422
- 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 -16
- package/lib/components/files/listing/file-entry.d.ts +1 -10
- package/lib/components/files/listing/file-listing-rx.d.ts +6 -3
- package/lib/components/forms/directives/validation/validators/elder-multiple-of.validator.d.ts +9 -3
- 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 -96
- 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 -86
- 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,100 +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
|
-
/**
|
|
9738
|
-
* Returns an FileSystemHandle Observable of the given DataTransferItem. The FileSystemHandle can only be accessed in the `dragstart`
|
|
9739
|
-
* or `drop` event. Otherwise, it will return null!
|
|
9740
|
-
*/
|
|
9741
|
-
static getAsFileSystemHandle(transferItem) {
|
|
9742
|
-
// @ts-ignore
|
|
9743
|
-
return from(transferItem.getAsFileSystemHandle());
|
|
9744
|
-
}
|
|
9745
|
-
/***************************************************************************
|
|
9746
|
-
* *
|
|
9747
|
-
* File Picker *
|
|
9748
|
-
* *
|
|
9749
|
-
**************************************************************************/
|
|
9750
|
-
static isFileSystemSupported() {
|
|
9751
|
-
return 'showOpenFilePicker' in window;
|
|
9752
|
-
}
|
|
9753
|
-
static openFilePicker(pickerOpts) {
|
|
9754
|
-
try {
|
|
9755
|
-
// @ts-ignore
|
|
9756
|
-
return from(window.showOpenFilePicker(pickerOpts));
|
|
9757
|
-
}
|
|
9758
|
-
catch (e) {
|
|
9759
|
-
return throwError(() => new Error(e));
|
|
9760
|
-
}
|
|
9761
|
-
}
|
|
9762
|
-
/***************************************************************************
|
|
9763
|
-
* *
|
|
9764
|
-
* Directory Picker *
|
|
9765
|
-
* *
|
|
9766
|
-
**************************************************************************/
|
|
9767
|
-
static isDirectoryPickerSupported() {
|
|
9768
|
-
return 'showDirectoryPicker' in window;
|
|
9769
|
-
}
|
|
9770
|
-
static openDirectoryPicker(pickerOpts) {
|
|
9771
|
-
try {
|
|
9772
|
-
// @ts-ignore
|
|
9773
|
-
return from(window.showDirectoryPicker(pickerOpts));
|
|
9774
|
-
}
|
|
9775
|
-
catch (e) {
|
|
9776
|
-
return throwError(() => new Error(e));
|
|
9777
|
-
}
|
|
9778
|
-
}
|
|
9779
|
-
/***************************************************************************
|
|
9780
|
-
* *
|
|
9781
|
-
* FileSystemDirectoryHandle *
|
|
9782
|
-
* *
|
|
9783
|
-
**************************************************************************/
|
|
9784
|
-
static getHandlesFromDirectory(dirHandle) {
|
|
9785
|
-
return from(FileSystemApi.getHandlesFromDirectoryAsync(dirHandle));
|
|
9786
|
-
}
|
|
9787
|
-
static buildRelativeParent(fileOrDirHandle, rootDirectory) {
|
|
9788
|
-
if (rootDirectory == null) {
|
|
9789
|
-
return of(undefined);
|
|
9790
|
-
}
|
|
9791
|
-
const relativeParents$ = from(rootDirectory.resolve(fileOrDirHandle));
|
|
9792
|
-
return relativeParents$.pipe(map(parents => {
|
|
9793
|
-
// path/to/folder/file.jpg
|
|
9794
|
-
const path = parents;
|
|
9795
|
-
// root/path/to/folder/file.jpg
|
|
9796
|
-
path.unshift(rootDirectory.name);
|
|
9797
|
-
// root/path/to/folder
|
|
9798
|
-
path.pop();
|
|
9799
|
-
return path.join('/');
|
|
9800
|
-
}));
|
|
9801
|
-
}
|
|
9802
|
-
static async getHandlesFromDirectoryAsync(dirHandle) {
|
|
9803
|
-
const handles = [];
|
|
9804
|
-
// @ts-ignore
|
|
9805
|
-
for await (const handle of dirHandle.values()) {
|
|
9806
|
-
handles.push(handle);
|
|
9807
|
-
}
|
|
9808
|
-
return handles;
|
|
9809
|
-
}
|
|
9810
|
-
}
|
|
9811
|
-
|
|
9812
9718
|
/**
|
|
9813
9719
|
* Represents a file and the relative path where the user has selected it.
|
|
9814
9720
|
* This is useful if the user has selected a folder and files
|
|
@@ -9823,24 +9729,26 @@ class FileEntry {
|
|
|
9823
9729
|
* which is also supported by this method.
|
|
9824
9730
|
*/
|
|
9825
9731
|
static ofFile(file) {
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
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);
|
|
9835
9743
|
}
|
|
9836
9744
|
/**
|
|
9837
9745
|
* Creates a file Entry with a relative parent path
|
|
9838
9746
|
*/
|
|
9839
|
-
static relativeFile(file, relativeParent
|
|
9747
|
+
static relativeFile(file, relativeParent) {
|
|
9840
9748
|
if (relativeParent && relativeParent.endsWith('/')) {
|
|
9841
9749
|
relativeParent = relativeParent.substring(0, relativeParent.length - 1);
|
|
9842
9750
|
}
|
|
9843
|
-
return new FileEntry(file, relativeParent
|
|
9751
|
+
return new FileEntry(file, relativeParent);
|
|
9844
9752
|
}
|
|
9845
9753
|
static toFileMap(entries) {
|
|
9846
9754
|
const map = new Map();
|
|
@@ -9860,10 +9768,9 @@ class FileEntry {
|
|
|
9860
9768
|
* Contains the relative path from the selected folder
|
|
9861
9769
|
* to this file. Only relevant if the user has selected a folder.
|
|
9862
9770
|
*/
|
|
9863
|
-
relativeParent
|
|
9771
|
+
relativeParent) {
|
|
9864
9772
|
this.file = file;
|
|
9865
9773
|
this.relativeParent = relativeParent;
|
|
9866
|
-
this.fileHandle = fileHandle;
|
|
9867
9774
|
this.relativePath = FileEntry.buildRelativePath(relativeParent, file);
|
|
9868
9775
|
}
|
|
9869
9776
|
/***************************************************************************
|
|
@@ -9882,46 +9789,42 @@ class FileEntry {
|
|
|
9882
9789
|
return file.name;
|
|
9883
9790
|
}
|
|
9884
9791
|
}
|
|
9885
|
-
static buildRelativeParent(file) {
|
|
9886
|
-
let relativeParent = null;
|
|
9887
|
-
if (file.webkitRelativePath) {
|
|
9888
|
-
if (file.webkitRelativePath.endsWith(file.name)) {
|
|
9889
|
-
const nameStart = file.webkitRelativePath.length - file.name.length;
|
|
9890
|
-
relativeParent = file.webkitRelativePath.substring(0, nameStart);
|
|
9891
|
-
}
|
|
9892
|
-
else {
|
|
9893
|
-
relativeParent = file.webkitRelativePath;
|
|
9894
|
-
}
|
|
9895
|
-
}
|
|
9896
|
-
return relativeParent;
|
|
9897
|
-
}
|
|
9898
9792
|
}
|
|
9899
9793
|
|
|
9900
|
-
class
|
|
9794
|
+
class ElderFileSelectDirective {
|
|
9901
9795
|
/***************************************************************************
|
|
9902
9796
|
* *
|
|
9903
9797
|
* Constructor *
|
|
9904
9798
|
* *
|
|
9905
9799
|
**************************************************************************/
|
|
9906
|
-
constructor(
|
|
9907
|
-
this.renderer = renderer;
|
|
9800
|
+
constructor(el, renderer) {
|
|
9908
9801
|
this.el = el;
|
|
9802
|
+
this.renderer = renderer;
|
|
9909
9803
|
/***************************************************************************
|
|
9910
9804
|
* *
|
|
9911
9805
|
* Fields *
|
|
9912
9806
|
* *
|
|
9913
9807
|
**************************************************************************/
|
|
9914
9808
|
this.logger = LoggerFactory.getLogger(this.constructor.name);
|
|
9915
|
-
this.
|
|
9809
|
+
this.elderFileSelectChange = new EventEmitter();
|
|
9810
|
+
this.elderSingleFileSelectChange = new EventEmitter();
|
|
9916
9811
|
}
|
|
9917
9812
|
/***************************************************************************
|
|
9918
9813
|
* *
|
|
9919
|
-
*
|
|
9814
|
+
* Life Cycle *
|
|
9920
9815
|
* *
|
|
9921
9816
|
**************************************************************************/
|
|
9922
|
-
|
|
9923
|
-
|
|
9817
|
+
ngOnInit() {
|
|
9818
|
+
this.createFileSelect();
|
|
9819
|
+
}
|
|
9820
|
+
ngOnDestroy() {
|
|
9821
|
+
this.removeFileSelect();
|
|
9924
9822
|
}
|
|
9823
|
+
/***************************************************************************
|
|
9824
|
+
* *
|
|
9825
|
+
* Properties *
|
|
9826
|
+
* *
|
|
9827
|
+
**************************************************************************/
|
|
9925
9828
|
set elderFileSelect(value) {
|
|
9926
9829
|
this._accept = value;
|
|
9927
9830
|
if (this._fileInput) {
|
|
@@ -9934,6 +9837,11 @@ class ElderFileSelectInput {
|
|
|
9934
9837
|
this.renderer.setProperty(this._fileInput, 'multiple', value);
|
|
9935
9838
|
}
|
|
9936
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
|
+
*/
|
|
9937
9845
|
set elderFileSelectDirectory(value) {
|
|
9938
9846
|
this._directory = coerceBooleanProperty(value);
|
|
9939
9847
|
if (this._fileInput) {
|
|
@@ -9946,6 +9854,17 @@ class ElderFileSelectInput {
|
|
|
9946
9854
|
* Public API *
|
|
9947
9855
|
* *
|
|
9948
9856
|
**************************************************************************/
|
|
9857
|
+
onClick(event) {
|
|
9858
|
+
this.openFileSelectDialog();
|
|
9859
|
+
}
|
|
9860
|
+
openFileSelectDialog() {
|
|
9861
|
+
this._fileInput.click();
|
|
9862
|
+
}
|
|
9863
|
+
/***************************************************************************
|
|
9864
|
+
* *
|
|
9865
|
+
* Private methods *
|
|
9866
|
+
* *
|
|
9867
|
+
**************************************************************************/
|
|
9949
9868
|
/**
|
|
9950
9869
|
* <input type="file"
|
|
9951
9870
|
* hidden #fileInput
|
|
@@ -9969,9 +9888,7 @@ class ElderFileSelectInput {
|
|
|
9969
9888
|
this.renderer.setAttribute(this._fileInput, 'webkitdirectory', 'true');
|
|
9970
9889
|
this.renderer.setAttribute(this._fileInput, 'directory', 'true');
|
|
9971
9890
|
}
|
|
9972
|
-
this._unlisten = this.renderer.listen(this._fileInput, 'change', event =>
|
|
9973
|
-
this.fileInputChanged(this._fileInput.files);
|
|
9974
|
-
});
|
|
9891
|
+
this._unlisten = this.renderer.listen(this._fileInput, 'change', event => this.fileInputChanged(event));
|
|
9975
9892
|
}
|
|
9976
9893
|
removeFileSelect() {
|
|
9977
9894
|
if (this._unlisten) {
|
|
@@ -9983,24 +9900,26 @@ class ElderFileSelectInput {
|
|
|
9983
9900
|
this._fileInput = null;
|
|
9984
9901
|
}
|
|
9985
9902
|
}
|
|
9986
|
-
|
|
9987
|
-
this._fileInput.
|
|
9988
|
-
}
|
|
9989
|
-
/***************************************************************************
|
|
9990
|
-
* *
|
|
9991
|
-
* Private methods *
|
|
9992
|
-
* *
|
|
9993
|
-
**************************************************************************/
|
|
9994
|
-
fileInputChanged(fileList) {
|
|
9903
|
+
fileInputChanged(event) {
|
|
9904
|
+
const fileList = this._fileInput.files;
|
|
9995
9905
|
const files = this.toFileEntries(fileList);
|
|
9996
9906
|
this.logger.debug('fileInputChanged, files:', files);
|
|
9907
|
+
this.emitFileList(files);
|
|
9997
9908
|
this.clearFileList();
|
|
9998
|
-
this._filesSelected.next(files);
|
|
9999
9909
|
}
|
|
10000
9910
|
clearFileList() {
|
|
10001
9911
|
// not nice but works
|
|
10002
9912
|
this._fileInput.value = null;
|
|
10003
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
|
+
}
|
|
10004
9923
|
toFileEntries(fileList) {
|
|
10005
9924
|
const files = [];
|
|
10006
9925
|
for (const key in fileList) {
|
|
@@ -10010,175 +9929,7 @@ class ElderFileSelectInput {
|
|
|
10010
9929
|
}
|
|
10011
9930
|
return files;
|
|
10012
9931
|
}
|
|
10013
|
-
}
|
|
10014
|
-
|
|
10015
|
-
class FileListingSystemHandle {
|
|
10016
|
-
/***************************************************************************
|
|
10017
|
-
* *
|
|
10018
|
-
* Public methods *
|
|
10019
|
-
* *
|
|
10020
|
-
**************************************************************************/
|
|
10021
|
-
/**
|
|
10022
|
-
* Creates a File Entry Array Observable by resolving its FileSystemHandle.
|
|
10023
|
-
* @returns An `Observable<FileEntry[]>` with the FileSystemFileHandle included
|
|
10024
|
-
*/
|
|
10025
|
-
static listFiles(handle, rootDirectory) {
|
|
10026
|
-
switch (handle.kind) {
|
|
10027
|
-
case 'file':
|
|
10028
|
-
return FileEntry.ofFileHandle(handle, rootDirectory).pipe(toArray());
|
|
10029
|
-
case 'directory':
|
|
10030
|
-
return FileListingSystemHandle.listFilesRecursive(handle, rootDirectory);
|
|
10031
|
-
}
|
|
10032
|
-
}
|
|
10033
|
-
/***************************************************************************
|
|
10034
|
-
* *
|
|
10035
|
-
* Private methods *
|
|
10036
|
-
* *
|
|
10037
|
-
**************************************************************************/
|
|
10038
|
-
static listFilesRecursive(dirHandle, rootDirectory) {
|
|
10039
|
-
return FileSystemApi.getHandlesFromDirectory(dirHandle).pipe(map(handles => FileListingSystemHandle.listFilesOfEach(handles, rootDirectory ? rootDirectory : dirHandle)), switchMap(fileEntriesArray$ => zip(fileEntriesArray$)), map(fileEntriesArray => fileEntriesArray.flat()));
|
|
10040
|
-
}
|
|
10041
|
-
static listFilesOfEach(handles, rootDirectory) {
|
|
10042
|
-
return handles.map(fileOrDirHandle => FileListingSystemHandle.listFiles(fileOrDirHandle, rootDirectory));
|
|
10043
|
-
}
|
|
10044
|
-
}
|
|
10045
|
-
|
|
10046
|
-
class ElderFileSelectDirective {
|
|
10047
|
-
/***************************************************************************
|
|
10048
|
-
* *
|
|
10049
|
-
* Constructor *
|
|
10050
|
-
* *
|
|
10051
|
-
**************************************************************************/
|
|
10052
|
-
constructor(renderer, el, destroyRef) {
|
|
10053
|
-
this.renderer = renderer;
|
|
10054
|
-
this.el = el;
|
|
10055
|
-
this.destroyRef = destroyRef;
|
|
10056
|
-
/***************************************************************************
|
|
10057
|
-
* *
|
|
10058
|
-
* Fields *
|
|
10059
|
-
* *
|
|
10060
|
-
**************************************************************************/
|
|
10061
|
-
this.logger = LoggerFactory.getLogger(this.constructor.name);
|
|
10062
|
-
this.elderFileSelectChange = new EventEmitter();
|
|
10063
|
-
this.elderSingleFileSelectChange = new EventEmitter();
|
|
10064
|
-
this._useDirectoryPicker = false;
|
|
10065
|
-
this._legacyInput = new ElderFileSelectInput(this.renderer, this.el);
|
|
10066
|
-
}
|
|
10067
|
-
/***************************************************************************
|
|
10068
|
-
* *
|
|
10069
|
-
* Life Cycle *
|
|
10070
|
-
* *
|
|
10071
|
-
**************************************************************************/
|
|
10072
|
-
ngOnInit() {
|
|
10073
|
-
if (!FileSystemApi.isFileSystemSupported() || !FileSystemApi.isDirectoryPickerSupported()) {
|
|
10074
|
-
this.logger.warn('showOpenFilePicker or showDirectoryPicker is not supported for this browser, falling back to legacy file picker');
|
|
10075
|
-
this._legacyInput.createFileSelect();
|
|
10076
|
-
this._legacyInput.filesSelected.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
|
|
10077
|
-
next: multiFileChange => this.pushFileChanges(multiFileChange)
|
|
10078
|
-
});
|
|
10079
|
-
}
|
|
10080
|
-
}
|
|
10081
|
-
ngOnDestroy() {
|
|
10082
|
-
this._legacyInput.removeFileSelect();
|
|
10083
|
-
}
|
|
10084
|
-
/***************************************************************************
|
|
10085
|
-
* *
|
|
10086
|
-
* Properties *
|
|
10087
|
-
* *
|
|
10088
|
-
**************************************************************************/
|
|
10089
|
-
set elderFileSelect(value) {
|
|
10090
|
-
this._filePickerOptions = {
|
|
10091
|
-
excludeAcceptAllOptions: true,
|
|
10092
|
-
id: this._filePickerOptions?.id,
|
|
10093
|
-
multiple: this._filePickerOptions?.multiple,
|
|
10094
|
-
startIn: this._filePickerOptions?.startIn,
|
|
10095
|
-
types: [this.buildTypeOption(value)]
|
|
10096
|
-
};
|
|
10097
|
-
this._legacyInput.elderFileSelect = value;
|
|
10098
|
-
}
|
|
10099
|
-
buildTypeOption(value) {
|
|
10100
|
-
if (this.isFileExtension(value)) {
|
|
10101
|
-
return {
|
|
10102
|
-
accept: {
|
|
10103
|
-
'*/*': value.trim()
|
|
10104
|
-
.replace(/\s+/g, '')
|
|
10105
|
-
.split(',')
|
|
10106
|
-
}
|
|
10107
|
-
};
|
|
10108
|
-
}
|
|
10109
|
-
else if (this.isMimeType(value)) {
|
|
10110
|
-
return {
|
|
10111
|
-
accept: { [value]: [] }
|
|
10112
|
-
};
|
|
10113
|
-
}
|
|
10114
|
-
return null;
|
|
10115
|
-
}
|
|
10116
|
-
isFileExtension(input) {
|
|
10117
|
-
const regex = new RegExp(/^(\.\w+)(, ?\.\w+)*$/);
|
|
10118
|
-
return regex.test(input);
|
|
10119
|
-
}
|
|
10120
|
-
isMimeType(input) {
|
|
10121
|
-
const regex = new RegExp(/^.+\/.+$/);
|
|
10122
|
-
return regex.test(input);
|
|
10123
|
-
}
|
|
10124
|
-
set elderFileSelectMultiple(value) {
|
|
10125
|
-
this._filePickerOptions = {
|
|
10126
|
-
excludeAcceptAllOptions: this._filePickerOptions?.excludeAcceptAllOptions,
|
|
10127
|
-
id: this._filePickerOptions?.id,
|
|
10128
|
-
multiple: coerceBooleanProperty(value),
|
|
10129
|
-
startIn: this._filePickerOptions?.startIn,
|
|
10130
|
-
types: this._filePickerOptions?.types
|
|
10131
|
-
};
|
|
10132
|
-
this._legacyInput.elderFileSelectMultiple = value;
|
|
10133
|
-
}
|
|
10134
|
-
/**
|
|
10135
|
-
* Allow the user to select a directory. All files that are recursively contained are selected.
|
|
10136
|
-
* However, the user will no longer be able to select individual files if this is enabled.
|
|
10137
|
-
* @param value
|
|
10138
|
-
*/
|
|
10139
|
-
set elderFileSelectDirectory(value) {
|
|
10140
|
-
this._useDirectoryPicker = coerceBooleanProperty(value);
|
|
10141
|
-
this._legacyInput.elderFileSelectDirectory = value;
|
|
10142
|
-
}
|
|
10143
|
-
/***************************************************************************
|
|
10144
|
-
* *
|
|
10145
|
-
* Public API *
|
|
10146
|
-
* *
|
|
10147
|
-
**************************************************************************/
|
|
10148
|
-
onClick(event) {
|
|
10149
|
-
if (!this._useDirectoryPicker && FileSystemApi.isFileSystemSupported()) {
|
|
10150
|
-
this.openFilePicker(this._filePickerOptions).subscribe({
|
|
10151
|
-
next: multiFileChange => this.pushFileChanges(multiFileChange)
|
|
10152
|
-
});
|
|
10153
|
-
}
|
|
10154
|
-
else if (this._useDirectoryPicker && FileSystemApi.isDirectoryPickerSupported()) {
|
|
10155
|
-
this.openDirectoryPicker(this._directoryPickerOptions).subscribe({
|
|
10156
|
-
next: multiFileChange => this.pushFileChanges(multiFileChange)
|
|
10157
|
-
});
|
|
10158
|
-
}
|
|
10159
|
-
else {
|
|
10160
|
-
this._legacyInput.openFileSelectDialog();
|
|
10161
|
-
}
|
|
10162
|
-
}
|
|
10163
|
-
/***************************************************************************
|
|
10164
|
-
* *
|
|
10165
|
-
* Private methods *
|
|
10166
|
-
* *
|
|
10167
|
-
**************************************************************************/
|
|
10168
|
-
pushFileChanges(multiFileChange) {
|
|
10169
|
-
this.elderFileSelectChange.next(multiFileChange);
|
|
10170
|
-
const file = multiFileChange[0]?.file;
|
|
10171
|
-
if (file) {
|
|
10172
|
-
this.elderSingleFileSelectChange.next(file);
|
|
10173
|
-
}
|
|
10174
|
-
}
|
|
10175
|
-
openFilePicker(pickerOpts) {
|
|
10176
|
-
return FileSystemApi.openFilePicker(pickerOpts).pipe(switchMap(files => combineLatest(files.map(file => FileEntry.ofFileHandle(file)))));
|
|
10177
|
-
}
|
|
10178
|
-
openDirectoryPicker(pickerOpts) {
|
|
10179
|
-
return FileSystemApi.openDirectoryPicker(pickerOpts).pipe(switchMap(dir => FileListingSystemHandle.listFiles(dir)));
|
|
10180
|
-
}
|
|
10181
|
-
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 }); }
|
|
10182
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 }); }
|
|
10183
9934
|
}
|
|
10184
9935
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderFileSelectDirective, decorators: [{
|
|
@@ -10187,7 +9938,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
|
|
|
10187
9938
|
selector: '[elderFileSelect]',
|
|
10188
9939
|
standalone: true
|
|
10189
9940
|
}]
|
|
10190
|
-
}], ctorParameters: () => [{ type: i0.
|
|
9941
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { elderFileSelectChange: [{
|
|
10191
9942
|
type: Output
|
|
10192
9943
|
}], elderSingleFileSelectChange: [{
|
|
10193
9944
|
type: Output
|
|
@@ -10307,44 +10058,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
|
|
|
10307
10058
|
type: Input
|
|
10308
10059
|
}] } });
|
|
10309
10060
|
|
|
10310
|
-
class
|
|
10311
|
-
/***************************************************************************
|
|
10312
|
-
* *
|
|
10313
|
-
* Constructor *
|
|
10314
|
-
* *
|
|
10315
|
-
**************************************************************************/
|
|
10061
|
+
class FileListingRx {
|
|
10316
10062
|
constructor() {
|
|
10063
|
+
this.log = LoggerFactory.getLogger(this.constructor.name);
|
|
10317
10064
|
}
|
|
10065
|
+
static { this.INSTANCE = new FileListingRx(); }
|
|
10318
10066
|
/***************************************************************************
|
|
10319
10067
|
* *
|
|
10320
|
-
* Public
|
|
10068
|
+
* Public API *
|
|
10321
10069
|
* *
|
|
10322
10070
|
**************************************************************************/
|
|
10323
|
-
|
|
10324
|
-
|
|
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);
|
|
10325
10102
|
}
|
|
10326
10103
|
/***************************************************************************
|
|
10327
10104
|
* *
|
|
10328
10105
|
* Private methods *
|
|
10329
10106
|
* *
|
|
10330
10107
|
**************************************************************************/
|
|
10331
|
-
|
|
10108
|
+
listFilesRecursiveAsync(entry, parent) {
|
|
10332
10109
|
if (entry.isDirectory) {
|
|
10333
10110
|
const directoryEntry = entry;
|
|
10334
|
-
return
|
|
10111
|
+
return this.readEntries(directoryEntry).pipe(mergeMap$1(entries => zip(entries.map(entry => this.listFilesRecursiveAsync(entry, directoryEntry)))), map(files => files.flat()));
|
|
10335
10112
|
}
|
|
10336
10113
|
else if (entry.isFile) {
|
|
10337
10114
|
const fileEntry = entry;
|
|
10338
|
-
return
|
|
10115
|
+
return this.observableFile(fileEntry, parent).pipe(map(file => [file]));
|
|
10339
10116
|
}
|
|
10340
10117
|
else {
|
|
10341
10118
|
return EMPTY;
|
|
10342
10119
|
}
|
|
10343
10120
|
}
|
|
10344
|
-
|
|
10121
|
+
observableFile(fileEntry, parent) {
|
|
10345
10122
|
return new Observable(observer => {
|
|
10346
10123
|
fileEntry.file(file => {
|
|
10347
|
-
observer.next(FileEntry.relativeFile(file,
|
|
10124
|
+
observer.next(FileEntry.relativeFile(file, this.trimStaringSlash(parent?.fullPath)));
|
|
10348
10125
|
observer.complete();
|
|
10349
10126
|
}, err => {
|
|
10350
10127
|
observer.error(err);
|
|
@@ -10352,7 +10129,7 @@ class FileListingWebkit {
|
|
|
10352
10129
|
});
|
|
10353
10130
|
});
|
|
10354
10131
|
}
|
|
10355
|
-
|
|
10132
|
+
trimStaringSlash(path) {
|
|
10356
10133
|
if (path) {
|
|
10357
10134
|
if (path.startsWith('/')) {
|
|
10358
10135
|
path = path.substring(1);
|
|
@@ -10360,12 +10137,12 @@ class FileListingWebkit {
|
|
|
10360
10137
|
}
|
|
10361
10138
|
return path;
|
|
10362
10139
|
}
|
|
10363
|
-
|
|
10140
|
+
readEntries(directoryEntry) {
|
|
10364
10141
|
return new Observable(observer => {
|
|
10365
|
-
|
|
10142
|
+
this.consumeReaderToCompletion(observer, directoryEntry.createReader());
|
|
10366
10143
|
});
|
|
10367
10144
|
}
|
|
10368
|
-
|
|
10145
|
+
consumeReaderToCompletion(observer, directoryReader) {
|
|
10369
10146
|
directoryReader.readEntries(entries => {
|
|
10370
10147
|
if (entries && entries.length > 0) {
|
|
10371
10148
|
observer.next(entries);
|
|
@@ -10381,63 +10158,6 @@ class FileListingWebkit {
|
|
|
10381
10158
|
}
|
|
10382
10159
|
}
|
|
10383
10160
|
|
|
10384
|
-
class FileListingRx {
|
|
10385
|
-
constructor() {
|
|
10386
|
-
this.log = LoggerFactory.getLogger(this.constructor.name);
|
|
10387
|
-
}
|
|
10388
|
-
static { this.INSTANCE = new FileListingRx(); }
|
|
10389
|
-
/***************************************************************************
|
|
10390
|
-
* *
|
|
10391
|
-
* Public API *
|
|
10392
|
-
* *
|
|
10393
|
-
**************************************************************************/
|
|
10394
|
-
toFileList(transferItemList) {
|
|
10395
|
-
const obs = [];
|
|
10396
|
-
for (let i = 0; i < transferItemList.length; i++) {
|
|
10397
|
-
const transferItem = transferItemList[i];
|
|
10398
|
-
obs.push(this.resolveTransferItem(transferItem));
|
|
10399
|
-
}
|
|
10400
|
-
return zip(obs).pipe(map(files => files.flat()));
|
|
10401
|
-
}
|
|
10402
|
-
/***************************************************************************
|
|
10403
|
-
* *
|
|
10404
|
-
* Private methods *
|
|
10405
|
-
* *
|
|
10406
|
-
**************************************************************************/
|
|
10407
|
-
resolveTransferItem(transferItem) {
|
|
10408
|
-
if (FileSystemApi.isGetAsFileSystemHandleSupported(transferItem)) {
|
|
10409
|
-
return FileSystemApi.getAsFileSystemHandle(transferItem).pipe(switchMap(handle => handle ? FileListingSystemHandle.listFiles(handle) : this.legacyFileListing(transferItem)));
|
|
10410
|
-
}
|
|
10411
|
-
return this.legacyFileListing(transferItem);
|
|
10412
|
-
}
|
|
10413
|
-
legacyFileListing(transferItem) {
|
|
10414
|
-
const entry = transferItem.webkitGetAsEntry();
|
|
10415
|
-
if (entry) {
|
|
10416
|
-
return FileListingWebkit.listFilesRecursive(entry);
|
|
10417
|
-
}
|
|
10418
|
-
return this.fallbackFileListing(transferItem);
|
|
10419
|
-
}
|
|
10420
|
-
fallbackFileListing(transferItem) {
|
|
10421
|
-
const itemAsFile = transferItem.getAsFile();
|
|
10422
|
-
if (itemAsFile) {
|
|
10423
|
-
return of([FileEntry.ofFile(itemAsFile)]);
|
|
10424
|
-
}
|
|
10425
|
-
else {
|
|
10426
|
-
if (transferItem.kind == 'file') {
|
|
10427
|
-
return of([
|
|
10428
|
-
FileEntry.ofFile(new File([], '', {
|
|
10429
|
-
type: transferItem.type
|
|
10430
|
-
}))
|
|
10431
|
-
]);
|
|
10432
|
-
}
|
|
10433
|
-
else {
|
|
10434
|
-
this.log.warn('Could not handle DataTransferItem!', transferItem);
|
|
10435
|
-
return of([]);
|
|
10436
|
-
}
|
|
10437
|
-
}
|
|
10438
|
-
}
|
|
10439
|
-
}
|
|
10440
|
-
|
|
10441
10161
|
class ElderFileDropZoneDirective {
|
|
10442
10162
|
/***************************************************************************
|
|
10443
10163
|
* *
|
|
@@ -10991,7 +10711,18 @@ class ElderBlobViewerComponent {
|
|
|
10991
10711
|
this._url$ = new BehaviorSubject(null);
|
|
10992
10712
|
this._mimeType$ = new BehaviorSubject(null);
|
|
10993
10713
|
this.destroy$ = new Subject();
|
|
10994
|
-
|
|
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
|
+
});
|
|
10995
10726
|
}
|
|
10996
10727
|
/***************************************************************************
|
|
10997
10728
|
* *
|
|
@@ -11005,21 +10736,6 @@ class ElderBlobViewerComponent {
|
|
|
11005
10736
|
this.destroy$.next();
|
|
11006
10737
|
this.destroy$.complete();
|
|
11007
10738
|
}
|
|
11008
|
-
/***************************************************************************
|
|
11009
|
-
* *
|
|
11010
|
-
* Properties *
|
|
11011
|
-
* *
|
|
11012
|
-
**************************************************************************/
|
|
11013
|
-
/**
|
|
11014
|
-
* Attempt to display unknown blobs as text. (i.e. mime-type is octet-stream)
|
|
11015
|
-
* @param unknownAsText
|
|
11016
|
-
*/
|
|
11017
|
-
set displayUnknownAsText(unknownAsText) {
|
|
11018
|
-
// TODO FIX RACE CONDITION:
|
|
11019
|
-
// Since this property is not reactive, it must be set first.
|
|
11020
|
-
// Otherwise, it will still be false, even if set to true!
|
|
11021
|
-
this._displayUnknownAsText = coerceBooleanProperty(unknownAsText);
|
|
11022
|
-
}
|
|
11023
10739
|
/**
|
|
11024
10740
|
* Set a in memory blob to display.
|
|
11025
10741
|
* @param blob
|
|
@@ -11098,7 +10814,7 @@ class ElderBlobViewerComponent {
|
|
|
11098
10814
|
});
|
|
11099
10815
|
}
|
|
11100
10816
|
canDisplayAsText(mimeType) {
|
|
11101
|
-
const can = mimeType.isText || (this.
|
|
10817
|
+
const can = mimeType.isText || (this.displayUnknownAsText() && mimeType.isOctetStream);
|
|
11102
10818
|
// TODO _displayUnknownAsText might be null due race condition see todo above.
|
|
11103
10819
|
// this.logger.debug('canDisplayAsText(' + mimeType.value + ') --> '
|
|
11104
10820
|
// + can + ' ---> this._displayUnknownAsText:' + this._displayUnknownAsText, mimeType);
|
|
@@ -11110,14 +10826,12 @@ class ElderBlobViewerComponent {
|
|
|
11110
10826
|
});
|
|
11111
10827
|
}
|
|
11112
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 }); }
|
|
11113
|
-
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 }); }
|
|
11114
10830
|
}
|
|
11115
10831
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderBlobViewerComponent, decorators: [{
|
|
11116
10832
|
type: Component,
|
|
11117
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"] }]
|
|
11118
|
-
}], ctorParameters: () => [{ type: HttpClientPristine }, { type: i1.DomSanitizer }, { type: ElderToastService }], propDecorators: {
|
|
11119
|
-
type: Input
|
|
11120
|
-
}], blob: [{
|
|
10834
|
+
}], ctorParameters: () => [{ type: HttpClientPristine }, { type: i1.DomSanitizer }, { type: ElderToastService }], propDecorators: { blob: [{
|
|
11121
10835
|
type: Input
|
|
11122
10836
|
}], blobUrl: [{
|
|
11123
10837
|
type: Input
|
|
@@ -15959,6 +15673,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
|
|
|
15959
15673
|
type: Input
|
|
15960
15674
|
}] } });
|
|
15961
15675
|
|
|
15676
|
+
class InputUtils {
|
|
15677
|
+
static isNoInputArgs(input) {
|
|
15678
|
+
return input === '';
|
|
15679
|
+
}
|
|
15680
|
+
}
|
|
15681
|
+
|
|
15962
15682
|
class ElderMultipleOfUtil {
|
|
15963
15683
|
/***************************************************************************
|
|
15964
15684
|
* *
|
|
@@ -16008,11 +15728,13 @@ class ElderMultipleOfUtil {
|
|
|
16008
15728
|
}
|
|
16009
15729
|
}
|
|
16010
15730
|
class ElderMultipleOfValidator {
|
|
16011
|
-
|
|
16012
|
-
|
|
16013
|
-
|
|
16014
|
-
|
|
16015
|
-
|
|
15731
|
+
constructor() {
|
|
15732
|
+
/***************************************************************************
|
|
15733
|
+
* *
|
|
15734
|
+
* Fields *
|
|
15735
|
+
* *
|
|
15736
|
+
**************************************************************************/
|
|
15737
|
+
this._factor = null;
|
|
16016
15738
|
}
|
|
16017
15739
|
/***************************************************************************
|
|
16018
15740
|
* *
|
|
@@ -16027,8 +15749,19 @@ class ElderMultipleOfValidator {
|
|
|
16027
15749
|
return null;
|
|
16028
15750
|
}
|
|
16029
15751
|
}
|
|
15752
|
+
/***************************************************************************
|
|
15753
|
+
* *
|
|
15754
|
+
* Properties *
|
|
15755
|
+
* *
|
|
15756
|
+
**************************************************************************/
|
|
15757
|
+
set factor(input) {
|
|
15758
|
+
this._factor = InputUtils.isNoInputArgs(input) ? null : input;
|
|
15759
|
+
}
|
|
15760
|
+
get factor() {
|
|
15761
|
+
return this._factor;
|
|
15762
|
+
}
|
|
16030
15763
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.4", ngImport: i0, type: ElderMultipleOfValidator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
16031
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.4", type: ElderMultipleOfValidator, isStandalone: true, selector: "[elderMultipleOf][formControlName],[elderMultipleOf][formControl],[elderMultipleOf][ngModel]", inputs: {
|
|
15764
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.4", type: ElderMultipleOfValidator, isStandalone: true, selector: "[elderMultipleOf][formControlName],[elderMultipleOf][formControl],[elderMultipleOf][ngModel]", inputs: { factor: ["elderMultipleOf", "factor"] }, providers: [
|
|
16032
15765
|
{
|
|
16033
15766
|
provide: NG_VALIDATORS,
|
|
16034
15767
|
useExisting: forwardRef(() => ElderMultipleOfValidator),
|
|
@@ -16049,8 +15782,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
|
|
|
16049
15782
|
],
|
|
16050
15783
|
standalone: true
|
|
16051
15784
|
}]
|
|
16052
|
-
}], propDecorators: {
|
|
16053
|
-
type: Input
|
|
15785
|
+
}], propDecorators: { factor: [{
|
|
15786
|
+
type: Input,
|
|
15787
|
+
args: ['elderMultipleOf']
|
|
16054
15788
|
}] } });
|
|
16055
15789
|
|
|
16056
15790
|
/**
|
|
@@ -16915,7 +16649,7 @@ class ElderTableActivationDirective {
|
|
|
16915
16649
|
this._data = [];
|
|
16916
16650
|
this.activeItem$ = new BehaviorSubject(null);
|
|
16917
16651
|
this.rows$ = new BehaviorSubject([]);
|
|
16918
|
-
this.
|
|
16652
|
+
this._activationOptions = {};
|
|
16919
16653
|
}
|
|
16920
16654
|
/***************************************************************************
|
|
16921
16655
|
* *
|
|
@@ -16976,6 +16710,12 @@ class ElderTableActivationDirective {
|
|
|
16976
16710
|
* Properties *
|
|
16977
16711
|
* *
|
|
16978
16712
|
**************************************************************************/
|
|
16713
|
+
set activationOptions(options) {
|
|
16714
|
+
this.activationOptions = InputUtils.isNoInputArgs(options) ? options : {};
|
|
16715
|
+
}
|
|
16716
|
+
get activationOptions() {
|
|
16717
|
+
return this._activationOptions;
|
|
16718
|
+
}
|
|
16979
16719
|
get activeItemEventChange() {
|
|
16980
16720
|
return this.itemActivationEventSubject;
|
|
16981
16721
|
}
|
|
@@ -17173,12 +16913,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.4", ngImpor
|
|
|
17173
16913
|
exportAs: 'elderTableActivation',
|
|
17174
16914
|
standalone: true
|
|
17175
16915
|
}]
|
|
17176
|
-
}], ctorParameters: () => [{ type: ElderTableComponent }], propDecorators: {
|
|
17177
|
-
type: Input,
|
|
17178
|
-
args: ['elderTableActivation']
|
|
17179
|
-
}], onKeydown: [{
|
|
16916
|
+
}], ctorParameters: () => [{ type: ElderTableComponent }], propDecorators: { onKeydown: [{
|
|
17180
16917
|
type: HostListener,
|
|
17181
16918
|
args: ['keydown', ['$event']]
|
|
16919
|
+
}], activationOptions: [{
|
|
16920
|
+
type: Input,
|
|
16921
|
+
args: ['elderTableActivation']
|
|
17182
16922
|
}], activeItemEventChange: [{
|
|
17183
16923
|
type: Output
|
|
17184
16924
|
}], activeItemChange: [{
|