@stemy/ngx-utils 19.1.3 → 19.2.0

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.
@@ -3,7 +3,7 @@ import { InjectionToken, PLATFORM_ID, Injectable, Inject, Optional, Injector, Ev
3
3
  import 'reflect-metadata';
4
4
  import * as i2 from '@angular/router';
5
5
  import { ActivatedRouteSnapshot, Scroll, NavigationEnd, DefaultUrlSerializer, UrlTree, UrlSegmentGroup, UrlSegment, UrlSerializer } from '@angular/router';
6
- import { BehaviorSubject, Observable, firstValueFrom, Subject, Subscription, from, TimeoutError, combineLatest } from 'rxjs';
6
+ import { BehaviorSubject, Observable, firstValueFrom, Subject, Subscription, from, TimeoutError, combineLatest, lastValueFrom } from 'rxjs';
7
7
  import { skipWhile, debounceTime, distinctUntilChanged, map, filter, mergeMap, timeout } from 'rxjs/operators';
8
8
  import * as i1$3 from '@angular/common';
9
9
  import { isPlatformBrowser, isPlatformServer, DOCUMENT, APP_BASE_HREF, CommonModule } from '@angular/common';
@@ -505,7 +505,7 @@ class AjaxRequestHandler {
505
505
  if (typeof XMLHttpRequest !== "undefined" && !AjaxRequestHandler.isOverridden) {
506
506
  AjaxRequestHandler.isOverridden = true;
507
507
  const originalOpen = XMLHttpRequest.prototype.open;
508
- XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
508
+ XMLHttpRequest.prototype.open = function (method, url) {
509
509
  originalOpen.apply(this, arguments);
510
510
  window.dispatchEvent(new CustomEvent("ajaxRequest", {
511
511
  detail: {
@@ -1589,6 +1589,54 @@ class FileUtils {
1589
1589
  }));
1590
1590
  return FileUtils.readFileAsDataURL(blob);
1591
1591
  }
1592
+ static getVideoCover(file, seekTo = null, quality = .75) {
1593
+ return new Promise((resolve, reject) => {
1594
+ // load the file to a video player
1595
+ const videoPlayer = document.createElement("video");
1596
+ videoPlayer.setAttribute("src", URL.createObjectURL(file));
1597
+ videoPlayer.load();
1598
+ videoPlayer.addEventListener("error", (ex) => {
1599
+ reject("error when loading video file");
1600
+ });
1601
+ // load metadata of the video to get video duration and dimensions
1602
+ videoPlayer.addEventListener("loadedmetadata", () => {
1603
+ if (isNaN(seekTo)) {
1604
+ seekTo = videoPlayer.duration / 2;
1605
+ }
1606
+ // seek to user defined timestamp (in seconds) if possible
1607
+ if (videoPlayer.duration < seekTo) {
1608
+ reject("video is too short.");
1609
+ return;
1610
+ }
1611
+ // delay seeking or else "seeked" event won"t fire on Safari
1612
+ setTimeout(() => {
1613
+ videoPlayer.currentTime = seekTo;
1614
+ }, 200);
1615
+ // extract video thumbnail once seeking is complete
1616
+ videoPlayer.addEventListener("seeked", () => {
1617
+ // define a canvas to have the same dimension as the video
1618
+ const canvas = document.createElement("canvas");
1619
+ canvas.width = videoPlayer.videoWidth;
1620
+ canvas.height = videoPlayer.videoHeight;
1621
+ // draw the video frame to canvas
1622
+ const ctx = canvas.getContext("2d");
1623
+ ctx.drawImage(videoPlayer, 0, 0, canvas.width, canvas.height);
1624
+ // return the canvas image as a blob
1625
+ resolve(ctx.canvas.toDataURL("image/jpeg", quality));
1626
+ });
1627
+ });
1628
+ });
1629
+ }
1630
+ static async getFilePreview(file) {
1631
+ const type = file.type.toLowerCase();
1632
+ if (type.startsWith("image/")) {
1633
+ return URL.createObjectURL(file);
1634
+ }
1635
+ if (type.startsWith("video/")) {
1636
+ return FileUtils.getVideoCover(file);
1637
+ }
1638
+ return null;
1639
+ }
1592
1640
  static readFile(callback) {
1593
1641
  return new Promise(
1594
1642
  // @dynamic
@@ -3809,7 +3857,6 @@ class DragDropHandler {
3809
3857
  this.dropEffect = ev.dataTransfer.dropEffect;
3810
3858
  };
3811
3859
  this.onDragEnter = ev => {
3812
- ev.preventDefault();
3813
3860
  if (this.first) {
3814
3861
  this.second = true;
3815
3862
  }
@@ -3837,7 +3884,6 @@ class DragDropHandler {
3837
3884
  }
3838
3885
  };
3839
3886
  this.onDrop = ev => {
3840
- ev.preventDefault();
3841
3887
  this.first = false;
3842
3888
  this.second = false;
3843
3889
  this.fireEvent("drop", ev);
@@ -5389,12 +5435,14 @@ class DropListComponent {
5389
5435
  this.context = [];
5390
5436
  this.prepareItem = () => { };
5391
5437
  this.checkFn = () => false;
5438
+ this.dropFn = () => false;
5392
5439
  this.valueMap = {};
5393
5440
  this.remove = index => {
5394
5441
  this.changeValue(this.value.filter((_, i) => i !== index));
5395
5442
  };
5396
5443
  }
5397
5444
  onDragEnter(ev, elem, data) {
5445
+ ev.preventDefault();
5398
5446
  if (!elem || !ObjectUtils.isFunction(this.checkFn) || !this.checkFn({ ev, elem, data })) {
5399
5447
  ev.dataTransfer.effectAllowed = "none";
5400
5448
  ev.dataTransfer.dropEffect = "none";
@@ -5415,11 +5463,15 @@ class DropListComponent {
5415
5463
  if (!elem) {
5416
5464
  return;
5417
5465
  }
5418
- const source = JSON.parse(ev.dataTransfer.getData("itemData"));
5466
+ const data = JSON.parse(ev.dataTransfer.getData("itemData") || "{}");
5419
5467
  elem.classList.remove("drop-allowed");
5420
5468
  checkTransitions(elem, () => {
5421
5469
  checkTransitions(elem, () => {
5422
- const id = source[this.idField] || source.id;
5470
+ if (elem && ObjectUtils.isFunction(this.dropFn) && this.dropFn({ ev, elem, data })) {
5471
+ // If drop is handled from outside function
5472
+ return;
5473
+ }
5474
+ const id = data[this.idField] || data.id;
5423
5475
  this.changeValue(this.value.concat([id]));
5424
5476
  });
5425
5477
  elem.classList.remove("dropped");
@@ -5460,7 +5512,7 @@ class DropListComponent {
5460
5512
  this.onTouched?.();
5461
5513
  }
5462
5514
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: DropListComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
5463
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.3", type: DropListComponent, isStandalone: false, selector: "drop-list", inputs: { disabled: "disabled", unique: "unique", idField: "idField", labelField: "labelField", value: "value", context: "context", prepareItem: "prepareItem", checkFn: "checkFn" }, providers: [{
5515
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.3", type: DropListComponent, isStandalone: false, selector: "drop-list", inputs: { disabled: "disabled", unique: "unique", idField: "idField", labelField: "labelField", value: "value", context: "context", prepareItem: "prepareItem", checkFn: "checkFn", dropFn: "dropFn" }, providers: [{
5464
5516
  provide: NG_VALUE_ACCESSOR,
5465
5517
  useExisting: forwardRef(() => DropListComponent),
5466
5518
  multi: true,
@@ -5489,6 +5541,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
5489
5541
  type: Input
5490
5542
  }], checkFn: [{
5491
5543
  type: Input
5544
+ }], dropFn: [{
5545
+ type: Input
5492
5546
  }], itemTemplate: [{
5493
5547
  type: ContentChild,
5494
5548
  args: ["itemTemplate"]
@@ -5670,6 +5724,7 @@ class DynamicTableComponent {
5670
5724
  ev.dataTransfer.setData(item.id, "id");
5671
5725
  }
5672
5726
  onDragEnter(ev, elem, item) {
5727
+ ev.preventDefault();
5673
5728
  if (!elem || !item || !ObjectUtils.isFunction(this.dragEnterFn) || !this.dragEnterFn({ ev, elem, item })) {
5674
5729
  ev.dataTransfer.effectAllowed = "none";
5675
5730
  ev.dataTransfer.dropEffect = "none";
@@ -5895,6 +5950,230 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
5895
5950
  args: ["defaultItemTemplate"]
5896
5951
  }] } });
5897
5952
 
5953
+ class UploadComponent {
5954
+ get http() {
5955
+ return this.api.client;
5956
+ }
5957
+ constructor(cdr, api, toaster) {
5958
+ this.cdr = cdr;
5959
+ this.api = api;
5960
+ this.toaster = toaster;
5961
+ this.value = null;
5962
+ this.disabled = false;
5963
+ this.fileImageCache = [];
5964
+ this.buttonText = "button.select-files";
5965
+ this.onUploaded = new EventEmitter();
5966
+ this.onChange = () => {
5967
+ };
5968
+ this.onTouched = () => {
5969
+ };
5970
+ }
5971
+ onDragEnter(ev) {
5972
+ const types = Array.from(ev.dataTransfer.items || [])
5973
+ .filter(t => t.kind == "file")
5974
+ .map(t => t.type.toLowerCase());
5975
+ types.push(...Array.from(ev.dataTransfer.files || []).map(f => f.type.toLowerCase()));
5976
+ if (!types.some(type => ArrayUtils.has(this.acceptTypes, type))) {
5977
+ ev.preventDefault();
5978
+ return;
5979
+ }
5980
+ ev.dataTransfer.effectAllowed = "copy";
5981
+ ev.dataTransfer.dropEffect = "copy";
5982
+ this.dropAllowed = true;
5983
+ }
5984
+ onDrop() {
5985
+ this.dropAllowed = false;
5986
+ }
5987
+ ngOnChanges() {
5988
+ this.accept = this.accept || "";
5989
+ this.acceptAttr = ObjectUtils.isString(this.accept) ? this.accept : this.accept.join(",");
5990
+ this.acceptTypes = ObjectUtils.isString(this.accept) && this.accept.length > 0
5991
+ ? this.accept.toLowerCase().split(",")
5992
+ : (ObjectUtils.isArray(this.accept) ? this.accept : []);
5993
+ this.isImage = /(png|jpg|jpeg|webp|gif)/gi.test(this.acceptAttr);
5994
+ this.cdr.markForCheck();
5995
+ }
5996
+ registerOnChange(fn) {
5997
+ this.onChange = fn;
5998
+ }
5999
+ registerOnTouched(fn) {
6000
+ this.onTouched = fn;
6001
+ }
6002
+ writeValue(value) {
6003
+ this.value = value;
6004
+ this.cdr.markForCheck();
6005
+ this.onChange(this.value);
6006
+ this.onTouched(this.value);
6007
+ }
6008
+ setDisabledState(val) {
6009
+ this.disabled = val === true;
6010
+ this.cdr.markForCheck();
6011
+ }
6012
+ onInputClick(ev) {
6013
+ const top = document.elementFromPoint(ev.clientX, ev.clientY);
6014
+ if (ev.target !== top && !this.processing)
6015
+ return;
6016
+ ev.preventDefault();
6017
+ }
6018
+ onInputChange(ev) {
6019
+ const input = ev.currentTarget;
6020
+ if (this.processing) {
6021
+ input.value = "";
6022
+ return;
6023
+ }
6024
+ const length = input.files.length;
6025
+ if (length == 0) {
6026
+ this.writeValue(this.multiple ? [] : null);
6027
+ return;
6028
+ }
6029
+ const files = [];
6030
+ for (let i = 0; i < length; i++) {
6031
+ const file = input.files.item(i);
6032
+ if (this.acceptTypes.length == 0) {
6033
+ files.push(file);
6034
+ continue;
6035
+ }
6036
+ const type = file.type.toLowerCase();
6037
+ const ext = FileUtils.getExtension(file);
6038
+ if (!ArrayUtils.has(this.acceptTypes, type, ext))
6039
+ continue;
6040
+ files.push(file);
6041
+ }
6042
+ if (files.length == 0) {
6043
+ this.toaster.error("message.invalid-files.error");
6044
+ return;
6045
+ }
6046
+ this.processFiles(this.multiple ? files : files.slice(0, 1)).then(results => {
6047
+ const ids = results.map(t => t._id || t.id);
6048
+ this.writeValue(this.multiple ? ids : (ids[0] || null));
6049
+ this.onUploaded.emit(results);
6050
+ });
6051
+ input.value = "";
6052
+ }
6053
+ delete(index) {
6054
+ if (this.multiple) {
6055
+ const current = Array.from(this.value || []);
6056
+ current.splice(index, 1);
6057
+ this.writeValue(current);
6058
+ }
6059
+ this.writeValue(null);
6060
+ }
6061
+ getUrl(image) {
6062
+ if (ObjectUtils.isBlob(image)) {
6063
+ let cache = this.fileImageCache.find(t => t.file == image);
6064
+ if (!cache) {
6065
+ cache = { file: image, url: URL.createObjectURL(image) };
6066
+ this.fileImageCache.push(cache);
6067
+ }
6068
+ return cache.url;
6069
+ }
6070
+ const url = !image ? null : image.imageUrl || image;
6071
+ if (!ObjectUtils.isString(url))
6072
+ return null;
6073
+ if (url.startsWith("data:"))
6074
+ return url;
6075
+ const baseUrl = this.baseUrl;
6076
+ const images = this.isImage ? `image/` : ``;
6077
+ if (!baseUrl) {
6078
+ return `${images}${url}`;
6079
+ }
6080
+ return `${baseUrl}/${images}${url}`;
6081
+ }
6082
+ async processFiles(files) {
6083
+ if (this.processing)
6084
+ return null;
6085
+ const headers = this.http.makeHeaders();
6086
+ const makeUpload = ObjectUtils.isFunction(this.makeUpload) ? this.makeUpload : f => {
6087
+ const form = new FormData();
6088
+ form.append("file", f);
6089
+ return form;
6090
+ };
6091
+ const preProcess = ObjectUtils.isFunction(this.preProcess) ? this.preProcess : () => {
6092
+ return false;
6093
+ };
6094
+ this.processing = files.filter(f => !preProcess(f)).map(file => {
6095
+ const process = {
6096
+ file,
6097
+ progress: 0
6098
+ };
6099
+ process.promise = FileUtils.getFilePreview(file).then(preview => {
6100
+ process.preview = `url('${preview}')`;
6101
+ this.cdr.detectChanges();
6102
+ });
6103
+ return process;
6104
+ });
6105
+ const baseUrl = this.baseUrl || this.api.url("assets");
6106
+ const requests = this.processing.map(async (p) => {
6107
+ await p.promise;
6108
+ const request = this.http.post(baseUrl, makeUpload(p.file), {
6109
+ headers, observe: "events", reportProgress: true
6110
+ });
6111
+ request.subscribe(value => {
6112
+ if (value.type === HttpEventType.UploadProgress) {
6113
+ p.progress = Math.round(value.loaded / value.total * 100);
6114
+ this.cdr.detectChanges();
6115
+ }
6116
+ });
6117
+ return lastValueFrom(request)
6118
+ .then((res) => {
6119
+ const body = res.body;
6120
+ if (!ObjectUtils.isObject(body)) {
6121
+ return { id: body };
6122
+ }
6123
+ return body;
6124
+ }, (e) => {
6125
+ this.toaster.error(e.error?.message || e.message || `Can"t upload file: ${p.file.name}`);
6126
+ return null;
6127
+ });
6128
+ });
6129
+ const results = await Promise.all(requests);
6130
+ this.processing = null;
6131
+ this.cdr.detectChanges();
6132
+ return results.filter(r => r !== null);
6133
+ }
6134
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: UploadComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: API_SERVICE }, { token: TOASTER_SERVICE }], target: i0.ɵɵFactoryTarget.Component }); }
6135
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.3", type: UploadComponent, isStandalone: false, selector: "upload", inputs: { value: "value", disabled: "disabled", accept: "accept", baseUrl: "baseUrl", multiple: "multiple", buttonText: "buttonText", makeUpload: "makeUpload", preProcess: "preProcess" }, outputs: { onUploaded: "onUploaded" }, providers: [{
6136
+ provide: NG_VALUE_ACCESSOR,
6137
+ useExisting: forwardRef(() => UploadComponent),
6138
+ multi: true,
6139
+ }], queries: [{ propertyName: "buttonTemplate", first: true, predicate: ["buttonTemplate"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-template #defaultBtn let-loading=\"loading\">\r\n <a class=\"btn btn-primary\" [ngClass]=\"{loading: loading}\">\r\n {{ buttonText | translate }}\r\n </a>\r\n</ng-template>\r\n\r\n<div class=\"upload\">\r\n <div class=\"upload-input\" [ngClass]=\"{'drop-allowed': dropAllowed}\">\r\n <input type=\"file\"\r\n #input\r\n [multiple]=\"multiple\"\r\n [accept]=\"acceptAttr\"\r\n (dragenter)=\"onDragEnter($event)\"\r\n (dragleave)=\"onDrop()\"\r\n (drop)=\"onDrop()\"\r\n (click)=\"onInputClick($event)\"\r\n (blur)=\"onTouched($event)\"\r\n (change)=\"onInputChange($event)\"/>\r\n <div class=\"process-container\">\r\n <div class=\"upload-process\"\r\n [ngStyle]=\"!proc.preview ? {} : {backgroundImage: proc.preview}\"\r\n *ngFor=\"let proc of processing\">\r\n <div class=\"upload-progress\">\r\n <div class=\"upload-progress-num\">{{ proc.progress }}%</div>\r\n <div class=\"upload-progress-bar\" [ngStyle]=\"{width: proc.progress + '%'}\">\r\n\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"btn-container\" (click)=\"input.click()\">\r\n <ng-container [ngTemplateOutlet]=\"buttonTemplate || defaultBtn\"\r\n [ngTemplateOutletContext]=\"{loading: !!processing, buttonText: buttonText}\">\r\n </ng-container>\r\n </div>\r\n </div>\r\n <ng-template #defaultTemplate>\r\n <ul class=\"files\" *ngIf=\"!multiple\">\r\n <li class=\"file\" *ngIf=\"value\">\r\n <a [href]=\"getUrl(value) | safe: 'url'\" target=\"target\">\r\n <i class=\"fas fa-download\"></i>\r\n </a>\r\n <a class=\"btn btn-danger btn-delete\" (click)=\"delete()\">\r\n <mat-icon>delete</mat-icon>\r\n </a>\r\n </li>\r\n </ul>\r\n <ul class=\"files\" *ngIf=\"multiple\">\r\n <li class=\"file\" *ngFor=\"let file of value; let i = index\">\r\n <a [href]=\"getUrl(file) | safe: 'url'\" [target]=\"'target_' + i\">\r\n <i class=\"fas fa-download\"></i>\r\n </a>\r\n <a class=\"btn btn-danger btn-delete\" (click)=\"delete(i)\">x</a>\r\n </li>\r\n </ul>\r\n </ng-template>\r\n <ng-container *ngIf=\"isImage; else defaultTemplate\">\r\n <ul class=\"images\" *ngIf=\"!multiple\">\r\n <li class=\"image\" *ngIf=\"value\">\r\n <img alt=\"file image\" [src]=\"getUrl(value) | safe: 'url'\"/>\r\n <a mat-mini-fab (click)=\"delete()\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n </li>\r\n </ul>\r\n <ul class=\"images\" *ngIf=\"multiple\">\r\n <li class=\"image\" *ngFor=\"let image of value; let i = index\">\r\n <img alt=\"file image\" [src]=\"getUrl(image) | safe: 'url'\"/>\r\n <a mat-mini-fab (click)=\"delete(i)\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n </li>\r\n </ul>\r\n </ng-container>\r\n</div>\r\n", styles: [".upload{--background: var(--primary-color, var(--mat-sys-primary, black));--text: var(--text-color, var(--mat-sys-on-primary, white))}.upload .upload-input{width:100%;border:2px #bfbfbf dashed;border-radius:10px;background-color:#0000000d;transition:.2s;flex-wrap:wrap;position:relative;padding:0 10px 10px}.upload .upload-input.drop-allowed{background-color:#00000080;border-color:#a9a9a9}.upload .upload-input input{display:block;position:absolute;inset:0;opacity:0}.upload .upload-input .process-container{min-height:120px;display:flex;gap:10px;flex-wrap:wrap;margin-bottom:8px}.upload .upload-input .upload-process{margin-top:10px;width:120px;height:120px;background:#00000080 center center no-repeat;background-size:cover;display:flex;align-items:center;justify-content:center}.upload .upload-input .upload-progress{position:relative;width:90%;height:15px;border:1px solid darkgrey;background:#ffffff80}.upload .upload-input .upload-progress-bar{position:absolute;height:15px;background:var(--background);top:0}.upload .upload-input .upload-progress-num{position:relative;z-index:1;font-size:12px;line-height:15px;text-align:center;color:var(--text)}.upload .images,.upload .files{list-style-type:none;margin:10px 0;padding:0;display:flex;gap:5px}.upload .images li,.upload .files li{position:relative}.upload .images li a,.upload .files li a{position:absolute;right:8px;top:8px}.upload .images img,.upload .files img{max-width:100%;max-height:200px;margin:2px;border-radius:5px}.upload .btn-select{display:inline-block;position:relative;cursor:pointer}.upload .btn-select button{display:inline-block;position:relative;z-index:1}\n"], dependencies: [{ kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: SafeHtmlPipe, name: "safe" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
6140
+ }
6141
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: UploadComponent, decorators: [{
6142
+ type: Component,
6143
+ args: [{ standalone: false, selector: "upload", encapsulation: ViewEncapsulation.None, providers: [{
6144
+ provide: NG_VALUE_ACCESSOR,
6145
+ useExisting: forwardRef(() => UploadComponent),
6146
+ multi: true,
6147
+ }], template: "<ng-template #defaultBtn let-loading=\"loading\">\r\n <a class=\"btn btn-primary\" [ngClass]=\"{loading: loading}\">\r\n {{ buttonText | translate }}\r\n </a>\r\n</ng-template>\r\n\r\n<div class=\"upload\">\r\n <div class=\"upload-input\" [ngClass]=\"{'drop-allowed': dropAllowed}\">\r\n <input type=\"file\"\r\n #input\r\n [multiple]=\"multiple\"\r\n [accept]=\"acceptAttr\"\r\n (dragenter)=\"onDragEnter($event)\"\r\n (dragleave)=\"onDrop()\"\r\n (drop)=\"onDrop()\"\r\n (click)=\"onInputClick($event)\"\r\n (blur)=\"onTouched($event)\"\r\n (change)=\"onInputChange($event)\"/>\r\n <div class=\"process-container\">\r\n <div class=\"upload-process\"\r\n [ngStyle]=\"!proc.preview ? {} : {backgroundImage: proc.preview}\"\r\n *ngFor=\"let proc of processing\">\r\n <div class=\"upload-progress\">\r\n <div class=\"upload-progress-num\">{{ proc.progress }}%</div>\r\n <div class=\"upload-progress-bar\" [ngStyle]=\"{width: proc.progress + '%'}\">\r\n\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"btn-container\" (click)=\"input.click()\">\r\n <ng-container [ngTemplateOutlet]=\"buttonTemplate || defaultBtn\"\r\n [ngTemplateOutletContext]=\"{loading: !!processing, buttonText: buttonText}\">\r\n </ng-container>\r\n </div>\r\n </div>\r\n <ng-template #defaultTemplate>\r\n <ul class=\"files\" *ngIf=\"!multiple\">\r\n <li class=\"file\" *ngIf=\"value\">\r\n <a [href]=\"getUrl(value) | safe: 'url'\" target=\"target\">\r\n <i class=\"fas fa-download\"></i>\r\n </a>\r\n <a class=\"btn btn-danger btn-delete\" (click)=\"delete()\">\r\n <mat-icon>delete</mat-icon>\r\n </a>\r\n </li>\r\n </ul>\r\n <ul class=\"files\" *ngIf=\"multiple\">\r\n <li class=\"file\" *ngFor=\"let file of value; let i = index\">\r\n <a [href]=\"getUrl(file) | safe: 'url'\" [target]=\"'target_' + i\">\r\n <i class=\"fas fa-download\"></i>\r\n </a>\r\n <a class=\"btn btn-danger btn-delete\" (click)=\"delete(i)\">x</a>\r\n </li>\r\n </ul>\r\n </ng-template>\r\n <ng-container *ngIf=\"isImage; else defaultTemplate\">\r\n <ul class=\"images\" *ngIf=\"!multiple\">\r\n <li class=\"image\" *ngIf=\"value\">\r\n <img alt=\"file image\" [src]=\"getUrl(value) | safe: 'url'\"/>\r\n <a mat-mini-fab (click)=\"delete()\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n </li>\r\n </ul>\r\n <ul class=\"images\" *ngIf=\"multiple\">\r\n <li class=\"image\" *ngFor=\"let image of value; let i = index\">\r\n <img alt=\"file image\" [src]=\"getUrl(image) | safe: 'url'\"/>\r\n <a mat-mini-fab (click)=\"delete(i)\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n </li>\r\n </ul>\r\n </ng-container>\r\n</div>\r\n", styles: [".upload{--background: var(--primary-color, var(--mat-sys-primary, black));--text: var(--text-color, var(--mat-sys-on-primary, white))}.upload .upload-input{width:100%;border:2px #bfbfbf dashed;border-radius:10px;background-color:#0000000d;transition:.2s;flex-wrap:wrap;position:relative;padding:0 10px 10px}.upload .upload-input.drop-allowed{background-color:#00000080;border-color:#a9a9a9}.upload .upload-input input{display:block;position:absolute;inset:0;opacity:0}.upload .upload-input .process-container{min-height:120px;display:flex;gap:10px;flex-wrap:wrap;margin-bottom:8px}.upload .upload-input .upload-process{margin-top:10px;width:120px;height:120px;background:#00000080 center center no-repeat;background-size:cover;display:flex;align-items:center;justify-content:center}.upload .upload-input .upload-progress{position:relative;width:90%;height:15px;border:1px solid darkgrey;background:#ffffff80}.upload .upload-input .upload-progress-bar{position:absolute;height:15px;background:var(--background);top:0}.upload .upload-input .upload-progress-num{position:relative;z-index:1;font-size:12px;line-height:15px;text-align:center;color:var(--text)}.upload .images,.upload .files{list-style-type:none;margin:10px 0;padding:0;display:flex;gap:5px}.upload .images li,.upload .files li{position:relative}.upload .images li a,.upload .files li a{position:absolute;right:8px;top:8px}.upload .images img,.upload .files img{max-width:100%;max-height:200px;margin:2px;border-radius:5px}.upload .btn-select{display:inline-block;position:relative;cursor:pointer}.upload .btn-select button{display:inline-block;position:relative;z-index:1}\n"] }]
6148
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
6149
+ type: Inject,
6150
+ args: [API_SERVICE]
6151
+ }] }, { type: undefined, decorators: [{
6152
+ type: Inject,
6153
+ args: [TOASTER_SERVICE]
6154
+ }] }], propDecorators: { value: [{
6155
+ type: Input
6156
+ }], disabled: [{
6157
+ type: Input
6158
+ }], accept: [{
6159
+ type: Input
6160
+ }], baseUrl: [{
6161
+ type: Input
6162
+ }], multiple: [{
6163
+ type: Input
6164
+ }], buttonText: [{
6165
+ type: Input
6166
+ }], makeUpload: [{
6167
+ type: Input
6168
+ }], preProcess: [{
6169
+ type: Input
6170
+ }], onUploaded: [{
6171
+ type: Output
6172
+ }], buttonTemplate: [{
6173
+ type: ContentChild,
6174
+ args: ["buttonTemplate"]
6175
+ }] } });
6176
+
5898
6177
  // --- Pipes ---
5899
6178
  const pipes = [
5900
6179
  ChunkPipe,
@@ -5948,7 +6227,8 @@ const components = [
5948
6227
  DropListComponent,
5949
6228
  DynamicTableComponent,
5950
6229
  PaginationMenuComponent,
5951
- UnorderedListComponent
6230
+ UnorderedListComponent,
6231
+ UploadComponent
5952
6232
  ];
5953
6233
  const providers = [
5954
6234
  ...pipes,
@@ -6285,8 +6565,8 @@ class NgxUtilsModule {
6285
6565
  constructor() {
6286
6566
  }
6287
6567
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: NgxUtilsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
6288
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: NgxUtilsModule, declarations: [ChunkPipe, EntriesPipe, ExtraItemPropertiesPipe, FilterPipe, FindPipe, FormatNumberPipe, GetOffsetPipe, GetTypePipe, GetValuePipe, GlobalTemplatePipe, GroupByPipe, IsTypePipe, JoinPipe, KeysPipe, MapPipe, MaxPipe, MinPipe, PopPipe, ReducePipe, RemapPipe, ReplacePipe, ReversePipe, RoundPipe, SafeHtmlPipe, ShiftPipe, SplitPipe, TranslatePipe, ValuesPipe, AsyncMethodBase, AsyncMethodDirective, BackgroundDirective, DynamicTableTemplateDirective, GlobalTemplateDirective, IconDirective, NgxTemplateOutletDirective, PaginationDirective, PaginationItemDirective, ResourceIfDirective, StickyDirective, StickyClassDirective, UnorderedListItemDirective, UnorderedListTemplateDirective, DropListComponent, DynamicTableComponent, PaginationMenuComponent, UnorderedListComponent], imports: [CommonModule,
6289
- FormsModule], exports: [ChunkPipe, EntriesPipe, ExtraItemPropertiesPipe, FilterPipe, FindPipe, FormatNumberPipe, GetOffsetPipe, GetTypePipe, GetValuePipe, GlobalTemplatePipe, GroupByPipe, IsTypePipe, JoinPipe, KeysPipe, MapPipe, MaxPipe, MinPipe, PopPipe, ReducePipe, RemapPipe, ReplacePipe, ReversePipe, RoundPipe, SafeHtmlPipe, ShiftPipe, SplitPipe, TranslatePipe, ValuesPipe, AsyncMethodBase, AsyncMethodDirective, BackgroundDirective, DynamicTableTemplateDirective, GlobalTemplateDirective, IconDirective, NgxTemplateOutletDirective, PaginationDirective, PaginationItemDirective, ResourceIfDirective, StickyDirective, StickyClassDirective, UnorderedListItemDirective, UnorderedListTemplateDirective, DropListComponent, DynamicTableComponent, PaginationMenuComponent, UnorderedListComponent, FormsModule] }); }
6568
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: NgxUtilsModule, declarations: [ChunkPipe, EntriesPipe, ExtraItemPropertiesPipe, FilterPipe, FindPipe, FormatNumberPipe, GetOffsetPipe, GetTypePipe, GetValuePipe, GlobalTemplatePipe, GroupByPipe, IsTypePipe, JoinPipe, KeysPipe, MapPipe, MaxPipe, MinPipe, PopPipe, ReducePipe, RemapPipe, ReplacePipe, ReversePipe, RoundPipe, SafeHtmlPipe, ShiftPipe, SplitPipe, TranslatePipe, ValuesPipe, AsyncMethodBase, AsyncMethodDirective, BackgroundDirective, DynamicTableTemplateDirective, GlobalTemplateDirective, IconDirective, NgxTemplateOutletDirective, PaginationDirective, PaginationItemDirective, ResourceIfDirective, StickyDirective, StickyClassDirective, UnorderedListItemDirective, UnorderedListTemplateDirective, DropListComponent, DynamicTableComponent, PaginationMenuComponent, UnorderedListComponent, UploadComponent], imports: [CommonModule,
6569
+ FormsModule], exports: [ChunkPipe, EntriesPipe, ExtraItemPropertiesPipe, FilterPipe, FindPipe, FormatNumberPipe, GetOffsetPipe, GetTypePipe, GetValuePipe, GlobalTemplatePipe, GroupByPipe, IsTypePipe, JoinPipe, KeysPipe, MapPipe, MaxPipe, MinPipe, PopPipe, ReducePipe, RemapPipe, ReplacePipe, ReversePipe, RoundPipe, SafeHtmlPipe, ShiftPipe, SplitPipe, TranslatePipe, ValuesPipe, AsyncMethodBase, AsyncMethodDirective, BackgroundDirective, DynamicTableTemplateDirective, GlobalTemplateDirective, IconDirective, NgxTemplateOutletDirective, PaginationDirective, PaginationItemDirective, ResourceIfDirective, StickyDirective, StickyClassDirective, UnorderedListItemDirective, UnorderedListTemplateDirective, DropListComponent, DynamicTableComponent, PaginationMenuComponent, UnorderedListComponent, UploadComponent, FormsModule] }); }
6290
6570
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: NgxUtilsModule, providers: pipes, imports: [CommonModule,
6291
6571
  FormsModule, FormsModule] }); }
6292
6572
  }
@@ -6316,5 +6596,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
6316
6596
  * Generated bundle index. Do not edit.
6317
6597
  */
6318
6598
 
6319
- export { API_SERVICE, APP_BASE_URL, AUTH_SERVICE, AclService, AjaxRequestHandler, ApiService, ArrayUtils, AsyncMethodBase, AsyncMethodDirective, AuthGuard, BASE_CONFIG, BackgroundDirective, BaseDialogService, BaseHttpClient, BaseHttpService, BaseToasterService, CONFIG_SERVICE, CanvasColor, CanvasUtils, ChunkPipe, Circle, ConfigService, DIALOG_SERVICE, DateUtils, DragDropEventPlugin, DropListComponent, DynamicTableComponent, DynamicTableTemplateDirective, ERROR_HANDLER, EXPRESS_REQUEST, EntriesPipe, ErrorHandlerService, EventsService, ExtraItemPropertiesPipe, FactoryDependencies, FileSystemEntry, FileUtils, FilterPipe, FindPipe, FormatNumberPipe, FormatterService, GenericValue, GetOffsetPipe, GetTypePipe, GetValuePipe, GlobalTemplateDirective, GlobalTemplatePipe, GlobalTemplateService, GroupByPipe, HttpPromise, ICON_SERVICE, IConfiguration, IconDirective, IconService, Initializer, IsTypePipe, JSONfn, JoinPipe, KeysPipe, LANGUAGE_SERVICE, LanguageService, LoaderUtils, LocalHttpService, MapPipe, MathUtils, MaxPipe, MinPipe, NgxTemplateOutletDirective, NgxUtilsModule, OPTIONS_TOKEN, ObjectType, ObjectUtils, ObservableUtils, OpenApiService, PROMISE_SERVICE, PaginationDirective, PaginationItemContext, PaginationItemDirective, PaginationMenuComponent, Point, PopPipe, PromiseService, RESIZE_DELAY, RESIZE_STRATEGY, ROOT_ELEMENT, Rect, ReducePipe, ReflectUtils, RemapPipe, ReplacePipe, ResizeEventPlugin, ResourceIfContext, ResourceIfDirective, ReversePipe, RoundPipe, SCRIPT_PARAMS, SafeHtmlPipe, ScrollEventPlugin, SetUtils, ShiftPipe, SplitPipe, StateService, StaticAuthService, StaticLanguageService, StickyClassDirective, StickyDirective, StorageMode, StorageService, StringUtils, TOASTER_SERVICE, TimerUtils, TranslatePipe, TranslatedUrlSerializer, UniqueUtils, UniversalService, UnorderedListComponent, UnorderedListItemDirective, UnorderedListTemplateDirective, ValuedPromise, ValuesPipe, Vector, WASI_IMPLEMENTATION, WasmService, cachedFactory, cancelablePromise, checkTransitions, impatientPromise, provideWithOptions };
6599
+ export { API_SERVICE, APP_BASE_URL, AUTH_SERVICE, AclService, AjaxRequestHandler, ApiService, ArrayUtils, AsyncMethodBase, AsyncMethodDirective, AuthGuard, BASE_CONFIG, BackgroundDirective, BaseDialogService, BaseHttpClient, BaseHttpService, BaseToasterService, CONFIG_SERVICE, CanvasColor, CanvasUtils, ChunkPipe, Circle, ConfigService, DIALOG_SERVICE, DateUtils, DragDropEventPlugin, DropListComponent, DynamicTableComponent, DynamicTableTemplateDirective, ERROR_HANDLER, EXPRESS_REQUEST, EntriesPipe, ErrorHandlerService, EventsService, ExtraItemPropertiesPipe, FactoryDependencies, FileSystemEntry, FileUtils, FilterPipe, FindPipe, FormatNumberPipe, FormatterService, GenericValue, GetOffsetPipe, GetTypePipe, GetValuePipe, GlobalTemplateDirective, GlobalTemplatePipe, GlobalTemplateService, GroupByPipe, HttpPromise, ICON_SERVICE, IConfiguration, IconDirective, IconService, Initializer, IsTypePipe, JSONfn, JoinPipe, KeysPipe, LANGUAGE_SERVICE, LanguageService, LoaderUtils, LocalHttpService, MapPipe, MathUtils, MaxPipe, MinPipe, NgxTemplateOutletDirective, NgxUtilsModule, OPTIONS_TOKEN, ObjectType, ObjectUtils, ObservableUtils, OpenApiService, PROMISE_SERVICE, PaginationDirective, PaginationItemContext, PaginationItemDirective, PaginationMenuComponent, Point, PopPipe, PromiseService, RESIZE_DELAY, RESIZE_STRATEGY, ROOT_ELEMENT, Rect, ReducePipe, ReflectUtils, RemapPipe, ReplacePipe, ResizeEventPlugin, ResourceIfContext, ResourceIfDirective, ReversePipe, RoundPipe, SCRIPT_PARAMS, SafeHtmlPipe, ScrollEventPlugin, SetUtils, ShiftPipe, SplitPipe, StateService, StaticAuthService, StaticLanguageService, StickyClassDirective, StickyDirective, StorageMode, StorageService, StringUtils, TOASTER_SERVICE, TimerUtils, TranslatePipe, TranslatedUrlSerializer, UniqueUtils, UniversalService, UnorderedListComponent, UnorderedListItemDirective, UnorderedListTemplateDirective, UploadComponent, ValuedPromise, ValuesPipe, Vector, WASI_IMPLEMENTATION, WasmService, cachedFactory, cancelablePromise, checkTransitions, impatientPromise, provideWithOptions };
6320
6600
  //# sourceMappingURL=stemy-ngx-utils.mjs.map