@dataclouder/ngx-cloud-storage 0.0.34 → 0.0.35

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Injectable, input, output, ViewChild, Component, Pipe, ChangeDetectorRef, Input, signal, InjectionToken, EventEmitter, Output, computed } from '@angular/core';
2
+ import { inject, Injectable, input, output, ViewChild, Component, Pipe, ChangeDetectorRef, Input, InjectionToken, signal, EventEmitter, Output, computed } from '@angular/core';
3
3
  import { ImageCropperComponent } from 'ngx-image-cropper';
4
4
  import * as i1 from '@angular/forms';
5
5
  import { FormsModule } from '@angular/forms';
@@ -18,7 +18,7 @@ import * as i7 from 'primeng/select';
18
18
  import { SelectModule } from 'primeng/select';
19
19
  import * as i8 from 'primeng/inputtext';
20
20
  import { InputTextModule } from 'primeng/inputtext';
21
- import { MoodStateOptions, CharacterEventActions, APP_CONFIG } from '@dataclouder/ngx-core';
21
+ import { MoodStateOptions, APP_CONFIG, CharacterEventActions } from '@dataclouder/ngx-core';
22
22
  import * as i1$1 from '@angular/platform-browser';
23
23
  import * as i3 from 'primeng/api';
24
24
  import * as i1$2 from '@angular/common';
@@ -702,14 +702,206 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
702
702
  args: [{ selector: 'dc-image-storage-preview', standalone: true, imports: [AsyncPipe, CropperComponentModal], template: "<div class=\"image-storage-preview-container\">\n <div class=\"header\">\n <h2>Storage Images</h2>\n <button class=\"refresh-btn\" (click)=\"refreshImages()\" [disabled]=\"loading$ | async\">\n @if (!(loading$ | async)) {\n <span>Refresh</span>\n }\n @if (loading$ | async) {\n <span>Loading...</span>\n }\n </button>\n </div>\n\n @if (loading$ | async) {\n <div class=\"loading-container\">\n <div class=\"spinner\"></div>\n <p>Loading images...</p>\n </div>\n }\n\n @if (error$ | async) {\n <div class=\"error-container\">\n <p class=\"error-message\">{{ error$ | async }}</p>\n <button (click)=\"refreshImages()\">Try Again</button>\n </div>\n }\n\n @if (!(loading$ | async) && !(error$ | async)) {\n <div class=\"images-grid\">\n @if ((images$ | async)?.length) {\n @for (image of images$ | async; track image) {\n <div class=\"image-card\">\n <div class=\"image-container\">\n <img [src]=\"image.url\" [alt]=\"image.name || 'Storage image'\" loading=\"lazy\" />\n </div>\n <div class=\"image-info\">\n <p class=\"image-name\" [title]=\"image.name\">{{ image.name }}</p>\n <div class=\"image-actions\">\n <a [href]=\"image.url\" target=\"_blank\" class=\"action-btn\">View</a>\n <button (click)=\"selectImage(image)\" class=\"action-btn\">Select</button>\n </div>\n </div>\n </div>\n }\n } @else {\n <div class=\"no-images\">\n <p>No images found in the storage path: {{ storagePath }}</p>\n </div>\n }\n <dc-cropper-modal [imgStorageSettings]=\"imgStorageSettings\"></dc-cropper-modal>\n </div>\n }\n</div>\n", styles: [".image-storage-preview-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;padding:20px;max-width:1200px;margin:0 auto}.header{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.header h2{margin:0;color:#333}.refresh-btn{background-color:#4285f4;color:#fff;border:none;border-radius:4px;padding:8px 16px;cursor:pointer;font-size:14px;transition:background-color .2s}.refresh-btn:hover{background-color:#3367d6}.refresh-btn:disabled{background-color:#a9a9a9;cursor:not-allowed}.loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 0}.spinner{border:4px solid rgba(0,0,0,.1);border-radius:50%;border-top:4px solid #4285f4;width:30px;height:30px;animation:spin 1s linear infinite;margin-bottom:15px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.error-container{background-color:#ffebee;border:1px solid #ffcdd2;border-radius:4px;padding:16px;margin:20px 0;text-align:center}.error-message{color:#d32f2f;margin-bottom:10px}.error-container button{background-color:#d32f2f;color:#fff;border:none;border-radius:4px;padding:8px 16px;cursor:pointer;font-size:14px}.images-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:20px}.image-card{border-radius:8px;overflow:hidden;box-shadow:0 2px 10px #0000001a;transition:transform .2s,box-shadow .2s;background-color:#fff}.image-card:hover{transform:translateY(-5px);box-shadow:0 5px 15px #00000026}.image-container{height:200px;overflow:hidden;position:relative;background-color:#f5f5f5}.image-container img{width:100%;height:100%;object-fit:cover;transition:transform .3s}.image-card:hover .image-container img{transform:scale(1.05)}.image-info{padding:15px}.image-name{margin:0 0 10px;font-size:14px;font-weight:500;color:#333;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.image-actions{display:flex;justify-content:flex-end}.action-btn{background-color:#4285f4;color:#fff;text-decoration:none;border-radius:4px;padding:6px 12px;font-size:12px;transition:background-color .2s}.action-btn:hover{background-color:#3367d6}.no-images{grid-column:1 / -1;text-align:center;padding:40px 0;color:#757575;background-color:#f5f5f5;border-radius:8px}\n"] }]
703
703
  }], ctorParameters: () => [], propDecorators: { imageSelected: [{ type: i0.Output, args: ["imageSelected"] }] } });
704
704
 
705
+ class FirebaseStorageProvider {
706
+ constructor() {
707
+ this.storage = inject(AngularFireStorage);
708
+ }
709
+ async uploadImage(image, path, provider) {
710
+ try {
711
+ const refStorage = this.storage.ref(path);
712
+ const task = await refStorage.put(image);
713
+ const url = await lastValueFrom(refStorage.getDownloadURL());
714
+ return {
715
+ url,
716
+ name: task.metadata.name,
717
+ type: task.metadata.contentType,
718
+ size: task.metadata.size,
719
+ };
720
+ }
721
+ catch (error) {
722
+ console.error('Firebase upload image error:', error);
723
+ return null;
724
+ }
725
+ }
726
+ async uploadGenericFile(file, storagePath, metadata, keepOriginalName, provider) {
727
+ try {
728
+ const fileName = keepOriginalName ? file.name : `${Date.now()}-${file.name}`;
729
+ const fullFilePath = `${storagePath.replace(/\/$/, '')}/${fileName}`;
730
+ const refStorage = this.storage.ref(fullFilePath);
731
+ const task = await refStorage.put(file, { customMetadata: metadata });
732
+ const url = await lastValueFrom(refStorage.getDownloadURL());
733
+ return {
734
+ url,
735
+ name: file.name,
736
+ type: file.type,
737
+ size: file.size,
738
+ metadata: task.metadata,
739
+ };
740
+ }
741
+ catch (error) {
742
+ console.error('Firebase upload generic file error:', error);
743
+ return null;
744
+ }
745
+ }
746
+ async uploadMultipleFiles(files, storagePath, metadata, keepOriginalName, provider) {
747
+ try {
748
+ const uploadPromises = files.map(file => this.uploadGenericFile(file, storagePath, metadata, keepOriginalName));
749
+ const results = await Promise.all(uploadPromises);
750
+ return results.filter((r) => r !== null);
751
+ }
752
+ catch (error) {
753
+ console.error('Firebase upload multiple files error:', error);
754
+ return null;
755
+ }
756
+ }
757
+ async deleteImage(imagePath) {
758
+ const storageRef = this.storage.ref(imagePath);
759
+ await lastValueFrom(storageRef.delete());
760
+ }
761
+ async deleteDirectory(directoryPath) {
762
+ const storage = getStorage();
763
+ const directoryRef = ref(storage, directoryPath);
764
+ const res = await listAll(directoryRef);
765
+ const promises = res.items.map((itemRef) => deleteObject(itemRef));
766
+ await Promise.all(promises);
767
+ }
768
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FirebaseStorageProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
769
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FirebaseStorageProvider, providedIn: 'root' }); }
770
+ }
771
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FirebaseStorageProvider, decorators: [{
772
+ type: Injectable,
773
+ args: [{
774
+ providedIn: 'root',
775
+ }]
776
+ }] });
777
+
778
+ class BackendStorageProvider {
779
+ constructor() {
780
+ this.http = inject(HttpClient);
781
+ this.appConfig = inject(APP_CONFIG);
782
+ this.apiUrl = this.appConfig.backendNodeUrl + '/storage'; // This should ideally come from an environment config
783
+ }
784
+ async uploadImage(image, path, provider = 'GOOGLE') {
785
+ const formData = new FormData();
786
+ formData.append('file', image, 'image.webp');
787
+ const params = {
788
+ path,
789
+ provider
790
+ };
791
+ try {
792
+ return await firstValueFrom(this.http.post(`${this.apiUrl}/upload`, formData, { params }));
793
+ }
794
+ catch (error) {
795
+ console.error('Backend upload image error:', error);
796
+ return null;
797
+ }
798
+ }
799
+ async uploadGenericFile(file, storagePath, metadata, keepOriginalName, provider = 'GOOGLE') {
800
+ const formData = new FormData();
801
+ if (metadata) {
802
+ formData.append('metadata', JSON.stringify(metadata));
803
+ }
804
+ formData.append('file', file);
805
+ const params = {
806
+ path: storagePath,
807
+ provider
808
+ };
809
+ if (keepOriginalName) {
810
+ params.keepOriginalName = 'true';
811
+ }
812
+ try {
813
+ return await firstValueFrom(this.http.post(`${this.apiUrl}/upload`, formData, { params }));
814
+ }
815
+ catch (error) {
816
+ console.error('Backend upload generic file error:', error);
817
+ return null;
818
+ }
819
+ }
820
+ async uploadMultipleFiles(files, storagePath, metadata, keepOriginalName, provider = 'GOOGLE') {
821
+ const formData = new FormData();
822
+ if (metadata) {
823
+ formData.append('metadata', JSON.stringify(metadata));
824
+ }
825
+ files.forEach(file => {
826
+ formData.append('file', file, file.name);
827
+ });
828
+ const params = {
829
+ path: storagePath,
830
+ provider
831
+ };
832
+ if (keepOriginalName) {
833
+ params.keepOriginalName = 'true';
834
+ }
835
+ try {
836
+ return await firstValueFrom(this.http.post(`${this.apiUrl}/upload-multiple`, formData, { params }));
837
+ }
838
+ catch (error) {
839
+ console.error('Backend upload multiple files error:', error);
840
+ return null;
841
+ }
842
+ }
843
+ async deleteImage(imagePath) {
844
+ // Implement delete if the backend controller supports it
845
+ console.warn('Backend delete image not implemented yet');
846
+ }
847
+ async deleteDirectory(directoryPath) {
848
+ // Implement delete directory if the backend controller supports it
849
+ console.warn('Backend delete directory not implemented yet');
850
+ }
851
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BackendStorageProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
852
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BackendStorageProvider, providedIn: 'root' }); }
853
+ }
854
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BackendStorageProvider, decorators: [{
855
+ type: Injectable,
856
+ args: [{
857
+ providedIn: 'root',
858
+ }]
859
+ }] });
860
+
861
+ const STORAGE_PROVIDER_TYPE = new InjectionToken('STORAGE_PROVIDER_TYPE');
862
+ class UniversalStorageService {
863
+ constructor() {
864
+ this.firebaseProvider = inject(FirebaseStorageProvider);
865
+ this.backendProvider = inject(BackendStorageProvider);
866
+ this.providerType = inject(STORAGE_PROVIDER_TYPE, { optional: true }) || 'FIREBASE';
867
+ }
868
+ get provider() {
869
+ return this.providerType === 'BACKEND' ? this.backendProvider : this.firebaseProvider;
870
+ }
871
+ async uploadImage(image, path, provider) {
872
+ return this.provider.uploadImage(image, path, provider);
873
+ }
874
+ uploadGenericFile(file, storagePath, metadata, keepOriginalName, provider) {
875
+ return this.provider.uploadGenericFile(file, storagePath, metadata, keepOriginalName, provider);
876
+ }
877
+ uploadMultipleFiles(files, storagePath, metadata, keepOriginalName, provider) {
878
+ return this.provider.uploadMultipleFiles(files, storagePath, metadata, keepOriginalName, provider);
879
+ }
880
+ async deleteImage(imagePath) {
881
+ return this.provider.deleteImage(imagePath);
882
+ }
883
+ async deleteDirectory(directoryPath) {
884
+ return this.provider.deleteDirectory(directoryPath);
885
+ }
886
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UniversalStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
887
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UniversalStorageService, providedIn: 'root' }); }
888
+ }
889
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UniversalStorageService, decorators: [{
890
+ type: Injectable,
891
+ args: [{
892
+ providedIn: 'root',
893
+ }]
894
+ }] });
895
+
705
896
  class SimpleUploaderComponent {
706
897
  constructor() {
707
- this.multiImagesStorageService = inject(MultiImagesStorageService);
898
+ this.universalStorageService = inject(UniversalStorageService);
708
899
  this.storagePath = input.required(...(ngDevMode ? [{ debugName: "storagePath" }] : []));
709
900
  this.buttonLabel = input('Upload File', ...(ngDevMode ? [{ debugName: "buttonLabel" }] : []));
710
901
  this.accept = input('*/*', ...(ngDevMode ? [{ debugName: "accept" }] : []));
711
902
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
712
903
  this.metadata = input({}, ...(ngDevMode ? [{ debugName: "metadata" }] : []));
904
+ this.provider = input('GOOGLE', ...(ngDevMode ? [{ debugName: "provider" }] : []));
713
905
  this.fileUploaded = output();
714
906
  this.uploadError = output();
715
907
  this.isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
@@ -749,9 +941,9 @@ class SimpleUploaderComponent {
749
941
  event: this.eventSelected(),
750
942
  };
751
943
  try {
752
- const result = await this.multiImagesStorageService.uploadGenericFile(file, this.storagePath(), metadata);
753
- result.metadata = metadata;
944
+ const result = await this.universalStorageService.uploadGenericFile(file, this.storagePath(), metadata, false, this.provider());
754
945
  if (result) {
946
+ result.metadata = metadata;
755
947
  this.fileUploaded.emit(result);
756
948
  }
757
949
  else {
@@ -772,12 +964,12 @@ class SimpleUploaderComponent {
772
964
  }
773
965
  }
774
966
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SimpleUploaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
775
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: SimpleUploaderComponent, isStandalone: true, selector: "dc-simple-uploader", inputs: { storagePath: { classPropertyName: "storagePath", publicName: "storagePath", isSignal: true, isRequired: true, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileUploaded: "fileUploaded", uploadError: "uploadError" }, ngImport: i0, template: "<p-button\n size=\"large\"\n [label]=\"buttonLabel()\"\n (click)=\"openDialog()\"\n [loading]=\"isLoading()\"\n [disabled]=\"disabled() || isLoading()\"\n pTooltip=\"Upload a file with metadata\"></p-button>\n\n@if(displayDialog()){\n<p-dialog\n header=\"Upload File\"\n [(visible)]=\"displayDialog\"\n [modal]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [contentStyle]=\"{ width: '50vw', height: '50vh' }\">\n <div class=\"upload-dialog\">\n @if(!fileSelected()){\n <div class=\"file-input-container\">\n <input #fileInput type=\"file\" [id]=\"fileInputId\" (change)=\"onFileSelected($event)\" [accept]=\"accept()\" style=\"display: none\" />\n <p-button label=\"Select File\" (click)=\"triggerFileInputClick(fileInput)\"></p-button>\n </div>\n } @else {\n <div class=\"file-details\">\n <p>File: {{ fileSelected()?.name }}</p>\n <p>Size: {{ fileSelected()?.size }} bytes</p>\n </div>\n\n <div class=\"metadata-container\">\n <h5>Metadata</h5>\n <div class=\"p-fluid\">\n @for (key of objectKeys(metadata()); track key) {\n <div class=\"p-field\">\n <label [for]=\"key\">{{ key }}</label>\n <input pInputText [id]=\"key\" [(ngModel)]=\"metadataInput[key]\" />\n </div>\n }\n\n <div class=\"p-field\">\n <label for=\"emotion\">Emotion</label>\n <br />\n <p-select [options]=\"MoodStateOptions\" [(ngModel)]=\"moodSelected\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select an emotion\"></p-select>\n </div>\n <div class=\"p-field\">\n <label for=\"emotion\">Event</label>\n <br />\n <p-select\n [options]=\"CharacterEventActions\"\n [(ngModel)]=\"eventSelected\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select an event\"></p-select>\n </div>\n </div>\n </div>\n }\n </div>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"dialog-footer\">\n <p-button label=\"Cancel\" styleClass=\"p-button-secondary\" (click)=\"displayDialog.set(false)\"></p-button>\n <p-button label=\"Upload\" (click)=\"uploadFile()\" [disabled]=\"!fileSelected() || isLoading()\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i7.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
967
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: SimpleUploaderComponent, isStandalone: true, selector: "dc-simple-uploader", inputs: { storagePath: { classPropertyName: "storagePath", publicName: "storagePath", isSignal: true, isRequired: true, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: true, isRequired: false, transformFunction: null }, provider: { classPropertyName: "provider", publicName: "provider", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileUploaded: "fileUploaded", uploadError: "uploadError" }, ngImport: i0, template: "<p-button\n size=\"large\"\n [label]=\"buttonLabel()\"\n (click)=\"openDialog()\"\n [loading]=\"isLoading()\"\n [disabled]=\"disabled() || isLoading()\"\n pTooltip=\"Upload a file with metadata\"></p-button>\n\n@if(displayDialog()){\n<p-dialog\n header=\"Upload File\"\n [(visible)]=\"displayDialog\"\n [modal]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [contentStyle]=\"{ width: '50vw', height: '50vh' }\">\n <div class=\"upload-dialog\">\n @if(!fileSelected()){\n <div class=\"file-input-container\">\n <input #fileInput type=\"file\" [id]=\"fileInputId\" (change)=\"onFileSelected($event)\" [accept]=\"accept()\" style=\"display: none\" />\n <p-button label=\"Select File\" (click)=\"triggerFileInputClick(fileInput)\"></p-button>\n </div>\n } @else {\n <div class=\"file-details\">\n <p>File: {{ fileSelected()?.name }}</p>\n <p>Size: {{ fileSelected()?.size }} bytes</p>\n </div>\n\n <div class=\"metadata-container\">\n <h5>Metadata</h5>\n <div class=\"p-fluid\">\n @for (key of objectKeys(metadata()); track key) {\n <div class=\"p-field\">\n <label [for]=\"key\">{{ key }}</label>\n <input pInputText [id]=\"key\" [(ngModel)]=\"metadataInput[key]\" />\n </div>\n }\n\n <div class=\"p-field\">\n <label for=\"emotion\">Emotion</label>\n <br />\n <p-select [options]=\"MoodStateOptions\" [(ngModel)]=\"moodSelected\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select an emotion\"></p-select>\n </div>\n <div class=\"p-field\">\n <label for=\"emotion\">Event</label>\n <br />\n <p-select\n [options]=\"CharacterEventActions\"\n [(ngModel)]=\"eventSelected\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select an event\"></p-select>\n </div>\n </div>\n </div>\n }\n </div>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"dialog-footer\">\n <p-button label=\"Cancel\" styleClass=\"p-button-secondary\" (click)=\"displayDialog.set(false)\"></p-button>\n <p-button label=\"Upload\" (click)=\"uploadFile()\" [disabled]=\"!fileSelected() || isLoading()\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i7.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
776
968
  }
777
969
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SimpleUploaderComponent, decorators: [{
778
970
  type: Component,
779
971
  args: [{ selector: 'dc-simple-uploader', standalone: true, imports: [CommonModule, FormsModule, ButtonModule, TooltipModule, DialogModule, InputTextModule, SelectModule], template: "<p-button\n size=\"large\"\n [label]=\"buttonLabel()\"\n (click)=\"openDialog()\"\n [loading]=\"isLoading()\"\n [disabled]=\"disabled() || isLoading()\"\n pTooltip=\"Upload a file with metadata\"></p-button>\n\n@if(displayDialog()){\n<p-dialog\n header=\"Upload File\"\n [(visible)]=\"displayDialog\"\n [modal]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n [contentStyle]=\"{ width: '50vw', height: '50vh' }\">\n <div class=\"upload-dialog\">\n @if(!fileSelected()){\n <div class=\"file-input-container\">\n <input #fileInput type=\"file\" [id]=\"fileInputId\" (change)=\"onFileSelected($event)\" [accept]=\"accept()\" style=\"display: none\" />\n <p-button label=\"Select File\" (click)=\"triggerFileInputClick(fileInput)\"></p-button>\n </div>\n } @else {\n <div class=\"file-details\">\n <p>File: {{ fileSelected()?.name }}</p>\n <p>Size: {{ fileSelected()?.size }} bytes</p>\n </div>\n\n <div class=\"metadata-container\">\n <h5>Metadata</h5>\n <div class=\"p-fluid\">\n @for (key of objectKeys(metadata()); track key) {\n <div class=\"p-field\">\n <label [for]=\"key\">{{ key }}</label>\n <input pInputText [id]=\"key\" [(ngModel)]=\"metadataInput[key]\" />\n </div>\n }\n\n <div class=\"p-field\">\n <label for=\"emotion\">Emotion</label>\n <br />\n <p-select [options]=\"MoodStateOptions\" [(ngModel)]=\"moodSelected\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select an emotion\"></p-select>\n </div>\n <div class=\"p-field\">\n <label for=\"emotion\">Event</label>\n <br />\n <p-select\n [options]=\"CharacterEventActions\"\n [(ngModel)]=\"eventSelected\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select an event\"></p-select>\n </div>\n </div>\n </div>\n }\n </div>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"dialog-footer\">\n <p-button label=\"Cancel\" styleClass=\"p-button-secondary\" (click)=\"displayDialog.set(false)\"></p-button>\n <p-button label=\"Upload\" (click)=\"uploadFile()\" [disabled]=\"!fileSelected() || isLoading()\"></p-button>\n </div>\n </ng-template>\n</p-dialog>\n}\n" }]
780
- }], ctorParameters: () => [], propDecorators: { storagePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "storagePath", required: true }] }], buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], metadata: [{ type: i0.Input, args: [{ isSignal: true, alias: "metadata", required: false }] }], fileUploaded: [{ type: i0.Output, args: ["fileUploaded"] }], uploadError: [{ type: i0.Output, args: ["uploadError"] }] } });
972
+ }], ctorParameters: () => [], propDecorators: { storagePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "storagePath", required: true }] }], buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], metadata: [{ type: i0.Input, args: [{ isSignal: true, alias: "metadata", required: false }] }], provider: [{ type: i0.Input, args: [{ isSignal: true, alias: "provider", required: false }] }], fileUploaded: [{ type: i0.Output, args: ["fileUploaded"] }], uploadError: [{ type: i0.Output, args: ["uploadError"] }] } });
781
973
 
782
974
  class DCFilesCacheService {
783
975
  constructor() {
@@ -923,203 +1115,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
923
1115
  }]
924
1116
  }] });
925
1117
 
926
- class FirebaseStorageProvider {
927
- constructor() {
928
- this.storage = inject(AngularFireStorage);
929
- }
930
- async uploadImage(image, path) {
931
- try {
932
- const refStorage = this.storage.ref(path);
933
- const task = await refStorage.put(image);
934
- const url = await lastValueFrom(refStorage.getDownloadURL());
935
- return {
936
- url,
937
- name: task.metadata.name,
938
- type: task.metadata.contentType,
939
- size: task.metadata.size,
940
- };
941
- }
942
- catch (error) {
943
- console.error('Firebase upload image error:', error);
944
- return null;
945
- }
946
- }
947
- async uploadGenericFile(file, storagePath, metadata, keepOriginalName) {
948
- try {
949
- const fileName = keepOriginalName ? file.name : `${Date.now()}-${file.name}`;
950
- const fullFilePath = `${storagePath.replace(/\/$/, '')}/${fileName}`;
951
- const refStorage = this.storage.ref(fullFilePath);
952
- const task = await refStorage.put(file, { customMetadata: metadata });
953
- const url = await lastValueFrom(refStorage.getDownloadURL());
954
- return {
955
- url,
956
- name: file.name,
957
- type: file.type,
958
- size: file.size,
959
- metadata: task.metadata,
960
- };
961
- }
962
- catch (error) {
963
- console.error('Firebase upload generic file error:', error);
964
- return null;
965
- }
966
- }
967
- async uploadMultipleFiles(files, storagePath, metadata, keepOriginalName) {
968
- try {
969
- const uploadPromises = files.map(file => this.uploadGenericFile(file, storagePath, metadata, keepOriginalName));
970
- const results = await Promise.all(uploadPromises);
971
- return results.filter((r) => r !== null);
972
- }
973
- catch (error) {
974
- console.error('Firebase upload multiple files error:', error);
975
- return null;
976
- }
977
- }
978
- async deleteImage(imagePath) {
979
- const storageRef = this.storage.ref(imagePath);
980
- await lastValueFrom(storageRef.delete());
981
- }
982
- async deleteDirectory(directoryPath) {
983
- const storage = getStorage();
984
- const directoryRef = ref(storage, directoryPath);
985
- const res = await listAll(directoryRef);
986
- const promises = res.items.map((itemRef) => deleteObject(itemRef));
987
- await Promise.all(promises);
988
- }
989
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FirebaseStorageProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
990
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FirebaseStorageProvider, providedIn: 'root' }); }
991
- }
992
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FirebaseStorageProvider, decorators: [{
993
- type: Injectable,
994
- args: [{
995
- providedIn: 'root',
996
- }]
997
- }] });
998
-
999
- class BackendStorageProvider {
1000
- constructor() {
1001
- this.http = inject(HttpClient);
1002
- this.appConfig = inject(APP_CONFIG);
1003
- this.apiUrl = this.appConfig.backendNodeUrl + '/storage'; // This should ideally come from an environment config
1004
- }
1005
- async uploadImage(image, path) {
1006
- const formData = new FormData();
1007
- formData.append('file', image, 'image.webp');
1008
- const params = {
1009
- path,
1010
- provider: 'GOOGLE'
1011
- };
1012
- try {
1013
- return await firstValueFrom(this.http.post(`${this.apiUrl}/upload`, formData, { params }));
1014
- }
1015
- catch (error) {
1016
- console.error('Backend upload image error:', error);
1017
- return null;
1018
- }
1019
- }
1020
- async uploadGenericFile(file, storagePath, metadata, keepOriginalName) {
1021
- const formData = new FormData();
1022
- if (metadata) {
1023
- formData.append('metadata', JSON.stringify(metadata));
1024
- }
1025
- formData.append('file', file);
1026
- const params = {
1027
- path: storagePath,
1028
- provider: 'GOOGLE'
1029
- };
1030
- if (keepOriginalName) {
1031
- params.keepOriginalName = 'true';
1032
- }
1033
- try {
1034
- return await firstValueFrom(this.http.post(`${this.apiUrl}/upload`, formData, { params }));
1035
- }
1036
- catch (error) {
1037
- console.error('Backend upload generic file error:', error);
1038
- return null;
1039
- }
1040
- }
1041
- async uploadMultipleFiles(files, storagePath, metadata, keepOriginalName) {
1042
- const formData = new FormData();
1043
- if (metadata) {
1044
- formData.append('metadata', JSON.stringify(metadata));
1045
- }
1046
- files.forEach(file => {
1047
- formData.append('file', file, file.name);
1048
- });
1049
- const params = {
1050
- path: storagePath,
1051
- provider: 'GOOGLE'
1052
- };
1053
- if (keepOriginalName) {
1054
- params.keepOriginalName = 'true';
1055
- }
1056
- try {
1057
- return await firstValueFrom(this.http.post(`${this.apiUrl}/upload-multiple`, formData, { params }));
1058
- }
1059
- catch (error) {
1060
- console.error('Backend upload multiple files error:', error);
1061
- return null;
1062
- }
1063
- }
1064
- async deleteImage(imagePath) {
1065
- // Implement delete if the backend controller supports it
1066
- console.warn('Backend delete image not implemented yet');
1067
- }
1068
- async deleteDirectory(directoryPath) {
1069
- // Implement delete directory if the backend controller supports it
1070
- console.warn('Backend delete directory not implemented yet');
1071
- }
1072
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BackendStorageProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1073
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BackendStorageProvider, providedIn: 'root' }); }
1074
- }
1075
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BackendStorageProvider, decorators: [{
1076
- type: Injectable,
1077
- args: [{
1078
- providedIn: 'root',
1079
- }]
1080
- }] });
1081
-
1082
- const STORAGE_PROVIDER_TYPE = new InjectionToken('STORAGE_PROVIDER_TYPE');
1083
- class UniversalStorageService {
1084
- constructor() {
1085
- this.firebaseProvider = inject(FirebaseStorageProvider);
1086
- this.backendProvider = inject(BackendStorageProvider);
1087
- this.providerType = inject(STORAGE_PROVIDER_TYPE, { optional: true }) || 'FIREBASE';
1088
- }
1089
- get provider() {
1090
- return this.providerType === 'BACKEND' ? this.backendProvider : this.firebaseProvider;
1091
- }
1092
- async uploadImage(image, path) {
1093
- return this.provider.uploadImage(image, path);
1094
- }
1095
- uploadGenericFile(file, storagePath, metadata, keepOriginalName) {
1096
- return this.provider.uploadGenericFile(file, storagePath, metadata, keepOriginalName);
1097
- }
1098
- uploadMultipleFiles(files, storagePath, metadata, keepOriginalName) {
1099
- return this.provider.uploadMultipleFiles(files, storagePath, metadata, keepOriginalName);
1100
- }
1101
- async deleteImage(imagePath) {
1102
- return this.provider.deleteImage(imagePath);
1103
- }
1104
- async deleteDirectory(directoryPath) {
1105
- return this.provider.deleteDirectory(directoryPath);
1106
- }
1107
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UniversalStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1108
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UniversalStorageService, providedIn: 'root' }); }
1109
- }
1110
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UniversalStorageService, decorators: [{
1111
- type: Injectable,
1112
- args: [{
1113
- providedIn: 'root',
1114
- }]
1115
- }] });
1116
-
1117
1118
  class BackendUploadComponent {
1118
1119
  constructor() {
1119
1120
  this.storageService = inject(UniversalStorageService);
1120
1121
  this.onUploadFinish = new EventEmitter();
1121
1122
  this.storagePath = 'test-uploads';
1122
1123
  this.keepOriginalNames = true;
1124
+ this.provider = 'GOOGLE';
1123
1125
  this.uploading = signal(false, ...(ngDevMode ? [{ debugName: "uploading" }] : []));
1124
1126
  this.status = signal(null, ...(ngDevMode ? [{ debugName: "status" }] : []));
1125
1127
  this.message = signal('', ...(ngDevMode ? [{ debugName: "message" }] : []));
@@ -1152,7 +1154,7 @@ class BackendUploadComponent {
1152
1154
  groupedFiles[uploadPath].push(file);
1153
1155
  });
1154
1156
  const uploadPromises = Object.entries(groupedFiles).map(([path, pathFiles]) => {
1155
- return this.storageService.uploadMultipleFiles(pathFiles, path, null, this.keepOriginalNames);
1157
+ return this.storageService.uploadMultipleFiles(pathFiles, path, null, this.keepOriginalNames, this.provider);
1156
1158
  });
1157
1159
  const results = await Promise.all(uploadPromises);
1158
1160
  const flattenedResults = results.flat().filter(result => result && result.url);
@@ -1222,7 +1224,7 @@ class BackendUploadComponent {
1222
1224
  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
1223
1225
  }
1224
1226
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BackendUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1225
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: BackendUploadComponent, isStandalone: true, selector: "dc-backend-upload", inputs: { storagePath: "storagePath", keepOriginalNames: "keepOriginalNames" }, outputs: { onUploadFinish: "onUploadFinish" }, providers: [
1227
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: BackendUploadComponent, isStandalone: true, selector: "dc-backend-upload", inputs: { storagePath: "storagePath", keepOriginalNames: "keepOriginalNames", provider: "provider" }, outputs: { onUploadFinish: "onUploadFinish" }, providers: [
1226
1228
  { provide: STORAGE_PROVIDER_TYPE, useValue: 'BACKEND' },
1227
1229
  UniversalStorageService
1228
1230
  ], viewQueries: [{ propertyName: "fileUpload", first: true, predicate: ["fu"], descendants: true }], ngImport: i0, template: "<div class=\"card p-4\">\n <p-toast />\n \n <p-fileupload \n #fu\n name=\"file\" \n [customUpload]=\"true\" \n (uploadHandler)=\"onUpload($event)\"\n (onSelect)=\"onSelect($event)\"\n (onRemove)=\"onRemove($event)\"\n (onClear)=\"onClear()\"\n [multiple]=\"true\" \n [maxFileSize]=\"10000000\" \n mode=\"advanced\">\n \n <ng-template #header let-files let-chooseCallback=\"chooseCallback\" let-clearCallback=\"clearCallback\" let-uploadCallback=\"uploadCallback\">\n <div class=\"flex flex-wrap justify-between items-center flex-1 gap-4\">\n <div class=\"flex gap-2\">\n <p-button (onClick)=\"choose($event, chooseCallback)\" icon=\"pi pi-plus\" [rounded]=\"true\" [outlined]=\"true\" label=\"Choose\" />\n <input #folderInput type=\"file\" webkitdirectory directory multiple style=\"display: none\" (change)=\"onFolderSelect($event)\">\n <p-button (onClick)=\"folderInput.click()\" icon=\"pi pi-folder-open\" [rounded]=\"true\" [outlined]=\"true\" label=\"Upload Folder\" severity=\"secondary\" />\n <p-button (onClick)=\"uploadCallback()\" icon=\"pi pi-cloud-upload\" [rounded]=\"true\" [outlined]=\"true\" severity=\"success\" [disabled]=\"!files || files.length === 0\" label=\"Upload\" />\n <p-button (onClick)=\"clearCallback()\" icon=\"pi pi-times\" [rounded]=\"true\" [outlined]=\"true\" severity=\"danger\" [disabled]=\"!files || files.length === 0\" label=\"Clear\" />\n </div>\n <div class=\"flex items-center gap-3 ml-auto\">\n <p-progressbar [value]=\"totalSizePercent()\" [showValue]=\"false\" class=\"w-full md:w-20rem h-1\">\n </p-progressbar>\n <span class=\"whitespace-nowrap text-sm text-secondary\">{{ formatSize(totalSize()) }} / 10MB</span>\n </div>\n </div>\n </ng-template>\n\n <ng-template #content let-files let-uploadedFiles=\"uploadedFiles\" let-removeFileCallback=\"removeFileCallback\" let-removeUploadedFileCallback=\"removeUploadedFileCallback\">\n <div class=\"flex flex-col gap-4 pt-4\">\n @if (files?.length > 0) {\n <div>\n <h5 class=\"mb-3 text-lg font-medium\">Pending Uploads</h5>\n <div class=\"flex flex-wrap gap-4\">\n @for (file of files; track file.name; let i = $index) {\n <div class=\"p-4 border rounded-lg border-surface-200 dark:border-surface-700 flex flex-col items-center gap-3 bg-surface-50 dark:bg-surface-900 w-48\">\n <div class=\"w-full h-24 flex items-center justify-center bg-surface-100 dark:bg-surface-800 rounded\">\n @if (file.objectURL) {\n <img role=\"presentation\" [alt]=\"file.name\" [src]=\"file.objectURL\" class=\"max-w-full max-h-full object-contain\" />\n } @else {\n <i class=\"pi pi-file text-4xl text-surface-400\"></i>\n }\n </div>\n <span class=\"font-semibold text-sm truncate w-full text-center\" [title]=\"file.webkitRelativePath || file.name\">\n {{ file.webkitRelativePath || file.name }}\n </span>\n <div class=\"text-xs text-secondary\">{{ formatSize(file.size) }}</div>\n <p-badge value=\"Pending\" severity=\"warn\" />\n <p-button icon=\"pi pi-times\" (onClick)=\"removeFileCallback($event, i)\" [outlined]=\"true\" [rounded]=\"true\" severity=\"danger\" size=\"small\" />\n </div>\n }\n </div>\n </div>\n }\n\n @if (uploadedFileUrls().length > 0) {\n <div class=\"mt-4\">\n <h5 class=\"mb-3 text-lg font-medium text-green-600\">Completed Uploads</h5>\n <div class=\"flex flex-wrap gap-4\">\n @for (url of uploadedFileUrls(); track url; let i = $index) {\n <div class=\"p-4 border rounded-lg border-green-200 dark:border-green-800 flex flex-col items-center gap-3 bg-green-50 dark:bg-green-900/20 w-48\">\n <div class=\"w-full h-24 flex items-center justify-center bg-surface-100 dark:bg-surface-800 rounded\">\n @if (url.toLowerCase().endsWith('.png') || url.toLowerCase().endsWith('.jpg') || url.toLowerCase().endsWith('.jpeg') || url.toLowerCase().endsWith('.webp')) {\n <img [src]=\"url\" class=\"max-w-full max-h-full object-contain\" />\n } @else {\n <i class=\"pi pi-check-circle text-4xl text-green-500\"></i>\n }\n </div>\n <span class=\"font-semibold text-sm truncate w-full text-center\">Uploaded File {{ i + 1 }}</span>\n <p-badge value=\"Completed\" severity=\"success\" />\n <a [href]=\"url\" target=\"_blank\" class=\"text-xs text-primary underline\">View File</a>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </ng-template>\n\n <ng-template #empty>\n <div class=\"flex items-center justify-center flex-col py-8 border-2 border-dashed border-surface-300 dark:border-surface-600 rounded-xl bg-surface-50 dark:bg-surface-900/50\">\n <i class=\"pi pi-cloud-upload text-5xl text-surface-400 mb-4\"></i>\n <p class=\"text-surface-600 dark:text-surface-400 font-medium\">Drag and drop files here to upload</p>\n <p class=\"text-surface-500 dark:text-surface-500 text-sm\">Any file type up to 10MB</p>\n </div>\n </ng-template>\n </p-fileupload>\n\n @if (status()) {\n <div class=\"mt-4 p-3 rounded-lg flex items-center gap-3\" [ngClass]=\"status() === 'success' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'\">\n <i [class]=\"status() === 'success' ? 'pi pi-check-circle' : 'pi pi-exclamation-circle'\"></i>\n <span>{{ message() }}</span>\n </div>\n }\n</div>\n", styles: [":host{display:block;margin:1rem 0}.upload-container{padding:1rem;border:1px dashed #ccc;border-radius:8px}.status-message{margin-top:1rem;padding:.5rem;border-radius:4px}.status-message.success{background-color:#d4edda;color:#155724}.status-message.error{background-color:#f8d7da;color:#721c24}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "component", type: i2$1.FileUpload, selector: "p-fileupload, p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "chooseButtonProps", "uploadButtonProps", "cancelButtonProps", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i3$1.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "motionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i4$1.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "unit", "mode", "color"] }, { kind: "ngmodule", type: BadgeModule }, { kind: "component", type: i5$1.Badge, selector: "p-badge", inputs: ["styleClass", "badgeSize", "size", "severity", "value", "badgeDisabled"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }] }); }
@@ -1242,6 +1244,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
1242
1244
  type: Input
1243
1245
  }], keepOriginalNames: [{
1244
1246
  type: Input
1247
+ }], provider: [{
1248
+ type: Input
1245
1249
  }] } });
1246
1250
 
1247
1251
  class AssetsLoaderComponent {
@@ -1362,7 +1366,7 @@ class AssetsLoaderComponent {
1362
1366
  }
1363
1367
  }
1364
1368
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AssetsLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1365
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: AssetsLoaderComponent, isStandalone: true, selector: "assets-loader", inputs: { assets: { classPropertyName: "assets", publicName: "assets", isSignal: true, isRequired: true, transformFunction: null }, storagePath: { classPropertyName: "storagePath", publicName: "storagePath", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { assetsChange: "assetsChange", assetUpdate: "assetUpdate", onFileSelected: "onFileSelected" }, ngImport: i0, template: "<div class=\"assets-container\">\n <div class=\"assets-card\">\n <p-message severity=\"info\">\n <div class=\"upload-buttons\">\n <div>\n <dc-cropper-modal\n id=\"cropperCardImage\"\n #cropperCardImage\n [buttonLabel]=\"assets()?.image?.url ? 'Cambiar imagen' : 'Cargar una imagen'\"\n [imgStorageSettings]=\"imageStorageSettings()\"\n [currentStorage]=\"assets()?.image\"\n (imageUploaded)=\"onImageUploaded($event, 'image')\"\n (onFileSelected)=\"onFileSelected.emit($event)\"></dc-cropper-modal>\n </div>\n\n <dc-simple-uploader\n [buttonLabel]=\"assets()?.motion?.url ? 'Cambiar video principal' : 'Agregar video principal'\"\n (fileUploaded)=\"onMotionUploaded($event)\"\n [storagePath]=\"storagePath() + '/motions/file'\"\n [accept]=\"'video/*'\"></dc-simple-uploader>\n\n <dc-simple-uploader\n [buttonLabel]=\"'Agregar Movimientos'\"\n (fileUploaded)=\"onMotionAdded($event)\"\n [storagePath]=\"storagePath() + '/motions/file'\"\n [accept]=\"'video/*'\"></dc-simple-uploader>\n\n <dc-cropper-modal\n #cropperBanner\n id=\"cropperBanner\"\n [buttonLabel]=\"assets()?.banner?.url ? 'Cambiar el banner' : 'Cargar un banner'\"\n [imgStorageSettings]=\"bannerImgSettings()\"\n [currentStorage]=\"assets()?.banner\"\n (imageUploaded)=\"onImageUploaded($event, 'banner')\"></dc-cropper-modal>\n\n <dc-cropper-modal\n id=\"cropperStickers\"\n #cropperStickers\n [buttonLabel]=\"'Agregar sticker'\"\n [imgStorageSettings]=\"stickerStorageSettings()\"\n (imageUploaded)=\"onImageUploaded($event, 'sticker')\"></dc-cropper-modal>\n </div>\n </p-message>\n <!-- Banner -->\n\n <div class=\"preview-container\">\n <img [src]=\"assets()?.banner?.url || 'defaults/images/default_banner.webp'\" class=\"main-banner-image-card\" />\n <div class=\"main-image-card\">\n <img [src]=\"assets()?.image?.url || 'defaults/images/default_2_3.webp'\" />\n </div>\n\n <div class=\"motion-container\">\n <video #videoPlayer class=\"main-motion-card\" [src]=\"assets()?.motion?.url\" (ended)=\"onVideoEnded(videoPlayer)\" autoplay muted playsinline></video>\n @if(assets()?.motion?.url){\n <p-button class=\"remove-main-motion-button\" (click)=\"removeMainMotion()\" [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-trash\" severity=\"danger\"></p-button>\n }\n </div>\n </div>\n\n <div class=\"stickers-container\">\n @for (sticker of assets()?.stickers; track sticker.url) {\n <div class=\"sticker-wrapper\">\n <img width=\"100\" [src]=\"sticker.url\" alt=\"\" />\n <p-button (click)=\"removeSticker(sticker)\" class=\"remove-sticker\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" />\n </div>\n }\n </div>\n\n <div class=\"motions-container\">\n @for (motion of assets()?.motions; track motion.url) {\n <div class=\"motion-wrapper\">\n <video width=\"150\" [src]=\"motion.url\" controls playsinline preload=\"none\"></video>\n <p-button (click)=\"removeMotion(motion)\" class=\"remove-motion-button\" icon=\"pi pi-trash\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\"></p-button>\n @if(motion.metadata?.moodState){\n <p-tag style=\"position: absolute; top: 4px; left: 4px\" severity=\"secondary\" [value]=\"motion.metadata?.moodState\" />\n } @if(motion.metadata?.event){\n <p-tag style=\"position: absolute; top: 4px; left: 4px\" severity=\"warn\" [value]=\"motion.metadata?.event\" />\n }\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".main-image-card{max-width:220px;display:block;border-radius:8px;position:absolute;bottom:-100px;left:20px;transform:none;z-index:1;box-shadow:0 4px 8px #0003;overflow:hidden}@media(max-width:1300px){.main-image-card{max-width:170px}}@media(max-width:768px){.main-image-card{max-width:130px}}.main-motion-card{max-width:100%;display:block;border-radius:8px}.main-banner-image-card{display:block;width:100%;max-height:400px;object-fit:cover;border-radius:8px}.remove-sticker{position:absolute;top:5px;right:5px}.assets-container{position:relative;min-height:60px}.assets-card{border:1px dashed rgba(12,19,142,.1215686275);padding:4px;border-radius:15px}.upload-buttons{display:flex;gap:10px}.preview-container{position:relative;margin-bottom:100px}.stickers-container{display:flex;flex-wrap:wrap;gap:10px}.sticker-wrapper{position:relative}.motion-container{position:absolute;bottom:-100px;right:20px;z-index:1;box-shadow:0 4px 8px #0003;max-width:220px;border-radius:8px;overflow:hidden}@media(max-width:1300px){.motion-container{max-width:170px}}@media(max-width:768px){.motion-container{max-width:130px}}.remove-main-motion-button{position:absolute;top:10px;right:10px;z-index:2}.motions-container{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px}.motion-wrapper{position:relative;width:150px;border-radius:8px;overflow:hidden;box-shadow:0 2px 4px #0000001a}.motion-wrapper video{min-height:220px;display:block;background-color:#f0f0f0}.remove-motion-button{position:absolute;top:5px;right:5px;z-index:2}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }, { kind: "component", type: SimpleUploaderComponent, selector: "dc-simple-uploader", inputs: ["storagePath", "buttonLabel", "accept", "disabled", "metadata"], outputs: ["fileUploaded", "uploadError"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i6.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i3$2.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }] }); }
1369
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: AssetsLoaderComponent, isStandalone: true, selector: "assets-loader", inputs: { assets: { classPropertyName: "assets", publicName: "assets", isSignal: true, isRequired: true, transformFunction: null }, storagePath: { classPropertyName: "storagePath", publicName: "storagePath", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { assetsChange: "assetsChange", assetUpdate: "assetUpdate", onFileSelected: "onFileSelected" }, ngImport: i0, template: "<div class=\"assets-container\">\n <div class=\"assets-card\">\n <p-message severity=\"info\">\n <div class=\"upload-buttons\">\n <div>\n <dc-cropper-modal\n id=\"cropperCardImage\"\n #cropperCardImage\n [buttonLabel]=\"assets()?.image?.url ? 'Cambiar imagen' : 'Cargar una imagen'\"\n [imgStorageSettings]=\"imageStorageSettings()\"\n [currentStorage]=\"assets()?.image\"\n (imageUploaded)=\"onImageUploaded($event, 'image')\"\n (onFileSelected)=\"onFileSelected.emit($event)\"></dc-cropper-modal>\n </div>\n\n <dc-simple-uploader\n [buttonLabel]=\"assets()?.motion?.url ? 'Cambiar video principal' : 'Agregar video principal'\"\n (fileUploaded)=\"onMotionUploaded($event)\"\n [storagePath]=\"storagePath() + '/motions/file'\"\n [accept]=\"'video/*'\"></dc-simple-uploader>\n\n <dc-simple-uploader\n [buttonLabel]=\"'Agregar Movimientos'\"\n (fileUploaded)=\"onMotionAdded($event)\"\n [storagePath]=\"storagePath() + '/motions/file'\"\n [accept]=\"'video/*'\"></dc-simple-uploader>\n\n <dc-cropper-modal\n #cropperBanner\n id=\"cropperBanner\"\n [buttonLabel]=\"assets()?.banner?.url ? 'Cambiar el banner' : 'Cargar un banner'\"\n [imgStorageSettings]=\"bannerImgSettings()\"\n [currentStorage]=\"assets()?.banner\"\n (imageUploaded)=\"onImageUploaded($event, 'banner')\"></dc-cropper-modal>\n\n <dc-cropper-modal\n id=\"cropperStickers\"\n #cropperStickers\n [buttonLabel]=\"'Agregar sticker'\"\n [imgStorageSettings]=\"stickerStorageSettings()\"\n (imageUploaded)=\"onImageUploaded($event, 'sticker')\"></dc-cropper-modal>\n </div>\n </p-message>\n <!-- Banner -->\n\n <div class=\"preview-container\">\n <img [src]=\"assets()?.banner?.url || 'defaults/images/default_banner.webp'\" class=\"main-banner-image-card\" />\n <div class=\"main-image-card\">\n <img [src]=\"assets()?.image?.url || 'defaults/images/default_2_3.webp'\" />\n </div>\n\n <div class=\"motion-container\">\n <video #videoPlayer class=\"main-motion-card\" [src]=\"assets()?.motion?.url\" (ended)=\"onVideoEnded(videoPlayer)\" autoplay muted playsinline></video>\n @if(assets()?.motion?.url){\n <p-button class=\"remove-main-motion-button\" (click)=\"removeMainMotion()\" [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-trash\" severity=\"danger\"></p-button>\n }\n </div>\n </div>\n\n <div class=\"stickers-container\">\n @for (sticker of assets()?.stickers; track sticker.url) {\n <div class=\"sticker-wrapper\">\n <img width=\"100\" [src]=\"sticker.url\" alt=\"\" />\n <p-button (click)=\"removeSticker(sticker)\" class=\"remove-sticker\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" />\n </div>\n }\n </div>\n\n <div class=\"motions-container\">\n @for (motion of assets()?.motions; track motion.url) {\n <div class=\"motion-wrapper\">\n <video width=\"150\" [src]=\"motion.url\" controls playsinline preload=\"none\"></video>\n <p-button (click)=\"removeMotion(motion)\" class=\"remove-motion-button\" icon=\"pi pi-trash\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\"></p-button>\n @if(motion.metadata?.moodState){\n <p-tag style=\"position: absolute; top: 4px; left: 4px\" severity=\"secondary\" [value]=\"motion.metadata?.moodState\" />\n } @if(motion.metadata?.event){\n <p-tag style=\"position: absolute; top: 4px; left: 4px\" severity=\"warn\" [value]=\"motion.metadata?.event\" />\n }\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".main-image-card{max-width:220px;display:block;border-radius:8px;position:absolute;bottom:-100px;left:20px;transform:none;z-index:1;box-shadow:0 4px 8px #0003;overflow:hidden}@media(max-width:1300px){.main-image-card{max-width:170px}}@media(max-width:768px){.main-image-card{max-width:130px}}.main-motion-card{max-width:100%;display:block;border-radius:8px}.main-banner-image-card{display:block;width:100%;max-height:400px;object-fit:cover;border-radius:8px}.remove-sticker{position:absolute;top:5px;right:5px}.assets-container{position:relative;min-height:60px}.assets-card{border:1px dashed rgba(12,19,142,.1215686275);padding:4px;border-radius:15px}.upload-buttons{display:flex;gap:10px}.preview-container{position:relative;margin-bottom:100px}.stickers-container{display:flex;flex-wrap:wrap;gap:10px}.sticker-wrapper{position:relative}.motion-container{position:absolute;bottom:-100px;right:20px;z-index:1;box-shadow:0 4px 8px #0003;max-width:220px;border-radius:8px;overflow:hidden}@media(max-width:1300px){.motion-container{max-width:170px}}@media(max-width:768px){.motion-container{max-width:130px}}.remove-main-motion-button{position:absolute;top:10px;right:10px;z-index:2}.motions-container{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px}.motion-wrapper{position:relative;width:150px;border-radius:8px;overflow:hidden;box-shadow:0 2px 4px #0000001a}.motion-wrapper video{min-height:220px;display:block;background-color:#f0f0f0}.remove-motion-button{position:absolute;top:5px;right:5px;z-index:2}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }, { kind: "component", type: SimpleUploaderComponent, selector: "dc-simple-uploader", inputs: ["storagePath", "buttonLabel", "accept", "disabled", "metadata", "provider"], outputs: ["fileUploaded", "uploadError"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i6.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i3$2.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }] }); }
1366
1370
  }
1367
1371
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AssetsLoaderComponent, decorators: [{
1368
1372
  type: Component,