@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
258 lines (250 loc) • 28.7 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, Component, Input, Optional, NgModule } from '@angular/core';
import { BehaviorSubject, Subject, merge } from 'rxjs';
import { distinctUntilChanged, tap, switchMap, shareReplay, filter, map, takeUntil } from 'rxjs/operators';
import * as i1 from '@c8y/client';
import * as i2 from '@c8y/ngx-components';
import { gettext, LoadingComponent, EmptyStateComponent, C8yValidators, FormGroupComponent, MessagesComponent, MessageDirective, C8yTranslatePipe, DropAreaComponent } from '@c8y/ngx-components';
import * as i3 from '@ngx-translate/core';
import { NgIf, NgClass, AsyncPipe, NgStyle, NgForOf } from '@angular/common';
import * as i4 from '@c8y/ngx-components/context-dashboard';
import { get } from 'lodash-es';
import * as i1$1 from '@angular/forms';
import { Validators, ReactiveFormsModule, ControlContainer, NgForm } from '@angular/forms';
const defaultObjectFitValue = 'contain';
const defaultObjectPositionValue = 'center';
class ImageWidgetService {
constructor(inventory, fileService, alert, translate, binary) {
this.inventory = inventory;
this.fileService = fileService;
this.alert = alert;
this.translate = translate;
this.binary = binary;
}
async getImageDetails(imageBinaryId) {
if (!imageBinaryId) {
return null;
}
try {
const { data: imageBinaryMo } = await this.inventory.detail(imageBinaryId);
const file = await this.fileService.getFile(imageBinaryMo);
const base64 = await this.fileService.toBase64(file);
return {
file,
base64: base64
};
}
catch (e) {
const text = this.translate.instant(gettext('Unable to retrieve image with id: {{ imageBinaryId }}'), { imageBinaryId });
this.alert.danger(text, e?.data);
}
return null;
}
async uploadFile(file, options = {}) {
const hash = await this.fileService.getHashSumOfFile(file);
const fileDetails = { c8y_SHA256: hash };
const globalImage = !options?.dashboardMoId || options?.isDeviceTypeDashboard;
const partialBinaryMo = !globalImage
? { ...fileDetails }
: { ...fileDetails, c8y_Global: {} };
const { data: mo } = await this.binary.create(file, partialBinaryMo);
if (options?.dashboardMoId) {
await this.inventory.childAdditionsAdd(mo, options?.dashboardMoId);
}
return mo.id;
}
getStyling(config) {
if (!config.styling?.objectFit || config.styling?.objectFit === 'full-width') {
return null;
}
return {
'object-fit': config.styling.objectFit,
'object-position': `${config.styling?.objectPositionX || defaultObjectPositionValue} ${config.styling?.objectPositionY || defaultObjectPositionValue}`
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageWidgetService, deps: [{ token: i1.InventoryService }, { token: i2.FilesService }, { token: i2.AlertService }, { token: i3.TranslateService }, { token: i1.InventoryBinaryService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageWidgetService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageWidgetService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: i1.InventoryService }, { type: i2.FilesService }, { type: i2.AlertService }, { type: i3.TranslateService }, { type: i1.InventoryBinaryService }] });
class ImageWidgetViewComponent {
constructor(imageWidget) {
this.imageWidget = imageWidget;
this.imageBinaryId$ = new BehaviorSubject(null);
this.loading = true;
this.imageDetails$ = this.imageBinaryId$.pipe(distinctUntilChanged(), tap(() => (this.loading = true)), switchMap(imageBinaryId => this.imageWidget.getImageDetails(imageBinaryId)), tap(() => (this.loading = false)), shareReplay(1));
}
ngOnChanges(changes) {
if (changes.config) {
const value = changes.config.currentValue;
this.imageBinaryId$.next(value.imageBinaryId);
this.setStyling(value);
}
}
setStyling(config) {
this.styling = this.imageWidget.getStyling(config);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageWidgetViewComponent, deps: [{ token: ImageWidgetService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ImageWidgetViewComponent, isStandalone: true, selector: "c8y-image-widget-view", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"imageDetails$ | async as details; else empty\">\n <img\n [src]=\"details.base64\"\n [title]=\"details.file.name\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n</ng-container>\n\n<ng-template #empty>\n <div class=\"d-flex fit-h fit-w j-c-center a-i-center\" *ngIf=\"!loading\">\n <c8y-ui-empty-state\n class=\"fit-w\"\n [icon]=\"'no-image'\"\n [title]=\"'No image to display.' | translate\"\n [subtitle]=\"'Upload an image.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n<div class=\"d-flex fit-h fit-w j-c-center a-i-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageWidgetViewComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-image-widget-view', standalone: true, imports: [NgIf, NgClass, AsyncPipe, NgStyle, LoadingComponent, EmptyStateComponent], template: "<ng-container *ngIf=\"imageDetails$ | async as details; else empty\">\n <img\n [src]=\"details.base64\"\n [title]=\"details.file.name\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n</ng-container>\n\n<ng-template #empty>\n <div class=\"d-flex fit-h fit-w j-c-center a-i-center\" *ngIf=\"!loading\">\n <c8y-ui-empty-state\n class=\"fit-w\"\n [icon]=\"'no-image'\"\n [title]=\"'No image to display.' | translate\"\n [subtitle]=\"'Upload an image.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n<div class=\"d-flex fit-h fit-w j-c-center a-i-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n</div>\n" }]
}], ctorParameters: () => [{ type: ImageWidgetService }], propDecorators: { config: [{
type: Input
}] } });
class ImageWidgetConfigComponent {
constructor(formBuilder, form, fileService, alert, imageWidget, widgetConfig) {
this.formBuilder = formBuilder;
this.form = form;
this.fileService = fileService;
this.alert = alert;
this.imageWidget = imageWidget;
this.widgetConfig = widgetConfig;
this.imageBinaryId$ = new BehaviorSubject(null);
this.loading = false;
this.destroyed$ = new Subject();
this.objectFitOptions = [
{
label: gettext('Contain`verb, image fitting option`'),
value: 'contain',
description: gettext('The image is entirely displayed within the widget while preserving the aspect ratio.')
},
{
label: gettext('Cover`verb, image fitting option`'),
value: 'cover',
description: gettext('The image is resized to fill the widget while preserving the aspect ratio. Overflowing areas are clipped.')
},
{
label: gettext('Fill`verb, image fitting option`'),
value: 'fill',
description: gettext('The image is stretched to fill the widget, overriding the aspect-ratio.')
},
{
label: gettext('Full width`image fitting option`'),
value: 'full-width',
description: gettext(`The image is resized to fit the widget's width while preserving the aspect ratio. Overflowing area is scrollable.`)
}
];
}
async onBeforeSave(config) {
if (this.formGroup.invalid) {
return false;
}
const fileFromForm = this.getFileFromFormValue(this.formGroup.value);
if (fileFromForm && fileFromForm !== this.fileFromConfig) {
try {
const imageBinaryId = await this.imageWidget.uploadFile(fileFromForm, {
dashboardMoId: this.getDashboardMoId(),
isDeviceTypeDashboard: this.widgetConfig?.isDeviceTypeDashboard
});
Object.assign(config, { imageBinaryId });
}
catch (e) {
this.alert.danger(gettext('Unable to upload image.'), e?.data);
return false;
}
}
const styling = this.formGroup.value.styling;
Object.assign(config, { styling });
return true;
}
ngOnInit() {
this.initForm();
const imageFromConfig = this.imageBinaryId$.pipe(filter(id => !!id), distinctUntilChanged(), tap(() => (this.loading = true)), switchMap(imageBinaryId => this.imageWidget.getImageDetails(imageBinaryId)), tap(details => {
this.loading = false;
this.fileFromConfig = details.file;
if (details) {
this.formGroup.patchValue({ images: [{ file: details.file, name: details.file.name }] });
}
}), map(details => details?.base64), shareReplay(1));
const selectedFile = this.formGroup.valueChanges.pipe(map(value => this.getFileFromFormValue(value)), distinctUntilChanged(), switchMap(file => (file ? this.fileService.toBase64(file) : Promise.resolve(''))));
this.imageSrc$ = merge(imageFromConfig, selectedFile).pipe(map(base64 => (base64 ? base64 : '')));
this.imageBinaryId$.next(this.config?.imageBinaryId);
}
ngOnDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
}
getDashboardMoId() {
return get(this.widgetConfig, 'mo.id', null);
}
async initForm() {
const stylingFormGroup = this.formBuilder.group({
objectFit: [
// fallback to 'full-width' for old legacy widgets, newly created widgets should use defaultObjectFitValue
this.config.imageBinaryId && !this.config.styling ? 'full-width' : defaultObjectFitValue,
[Validators.required]
],
objectPositionX: [defaultObjectPositionValue, [Validators.required]],
objectPositionY: [defaultObjectPositionValue, [Validators.required]]
});
this.formGroup = this.formBuilder.group({
images: [
null,
[
Validators.required,
Validators.minLength(1),
Validators.maxLength(1),
C8yValidators.filesValidator({ maximumFileSizeInKb: 1000, typePrefix: 'image/' })
]
],
styling: stylingFormGroup
});
this.form.form.addControl('config', this.formGroup);
this.formGroup.patchValue(this.config);
this.formGroup.valueChanges
.pipe(takeUntil(this.destroyed$))
.subscribe(changes => this.setStyling(changes));
}
getFileFromFormValue(formValue) {
const images = formValue?.images || [];
return images[0]?.file || null;
}
setStyling(config) {
this.styling = this.imageWidget.getStyling(config);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageWidgetConfigComponent, deps: [{ token: i1$1.FormBuilder }, { token: i1$1.NgForm }, { token: i2.FilesService }, { token: i2.AlertService }, { token: ImageWidgetService }, { token: i4.WidgetConfigComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ImageWidgetConfigComponent, isStandalone: true, selector: "c8y-image-widget-config", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"p-l-24 p-r-24\">\n <div [formGroup]=\"formGroup\" class=\"row p-t-8\">\n <div class=\"col-md-12\">\n <c8y-form-group>\n <label>{{ 'Image' | translate }}</label>\n <c8y-drop-area\n formControlName=\"images\"\n class=\"drop-area-sm\"\n [icon]=\"'upload'\"\n [accept]=\"'image'\"\n [maxAllowedFiles]=\"1\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message\n name=\"maxFileSizeReached\"\n [text]=\"\n 'The maximum image size is {{ maxFileSize }} kB. The selected image has a size of {{ actualFileSize }} kB.'\n | translate\n \"\n ></c8y-message>\n <c8y-message\n name=\"wrongFileType\"\n [text]=\"'Wrong file type, select an image.' | translate\"\n ></c8y-message>\n <c8y-message name=\"maxlength\" [text]=\"'Only select one image.' | translate\"></c8y-message>\n <c8y-message name=\"required\" [text]=\"'An image is required.' | translate\"></c8y-message>\n <c8y-message name=\"minlength\" [text]=\"'An image is required.' | translate\"></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <ng-container *ngIf=\"imageSrc$ | async as src\">\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">\n {{ 'Size and alignment' | translate }}\n </div>\n <div [formGroupName]=\"'styling'\">\n <c8y-form-group>\n <label>\n {{ 'Image display' | translate }}\n </label>\n <ul class=\"list-group separator-top-bottom\">\n <li\n class=\"list-group-item d-flex a-i-center p-l-0\"\n *ngFor=\"let objectFitOption of objectFitOptions; let i = index\"\n >\n <label class=\"c8y-radio\">\n <input\n type=\"radio\"\n [id]=\"'groupradiocontentclass' + i\"\n formControlName=\"objectFit\"\n [value]=\"objectFitOption.value\"\n />\n <span></span>\n <span class=\"l-h-1\">\n {{ objectFitOption.label | translate }}\n <br />\n <small class=\"text-muted\">\n {{ objectFitOption.description | translate }}\n </small>\n </span>\n </label>\n </li>\n </ul>\n </c8y-form-group>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Horizontal alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionX\">\n <option [ngValue]=\"'left'\">\n {{ 'left`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'right'\">\n {{ 'right`horizontal alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Vertical alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionY\">\n <option [ngValue]=\"'top'\">\n {{ 'top`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'bottom'\">\n {{ 'bottom`vertical alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">{{ 'Preview' | translate }}</div>\n <div class=\"form-group\">\n <div\n class=\"border-top border-right border-bottom border-left inner-scroll\"\n style=\"height: 300px\"\n >\n <img\n [src]=\"src\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"col-md-12 d-flex j-c-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.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$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "maxFileSizeInMegaBytes", "accept"], outputs: ["dropped"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageWidgetConfigComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-image-widget-config', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], standalone: true, imports: [
ReactiveFormsModule,
FormGroupComponent,
MessagesComponent,
MessageDirective,
C8yTranslatePipe,
AsyncPipe,
NgIf,
NgStyle,
NgClass,
NgForOf,
DropAreaComponent
], template: "<div class=\"p-l-24 p-r-24\">\n <div [formGroup]=\"formGroup\" class=\"row p-t-8\">\n <div class=\"col-md-12\">\n <c8y-form-group>\n <label>{{ 'Image' | translate }}</label>\n <c8y-drop-area\n formControlName=\"images\"\n class=\"drop-area-sm\"\n [icon]=\"'upload'\"\n [accept]=\"'image'\"\n [maxAllowedFiles]=\"1\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message\n name=\"maxFileSizeReached\"\n [text]=\"\n 'The maximum image size is {{ maxFileSize }} kB. The selected image has a size of {{ actualFileSize }} kB.'\n | translate\n \"\n ></c8y-message>\n <c8y-message\n name=\"wrongFileType\"\n [text]=\"'Wrong file type, select an image.' | translate\"\n ></c8y-message>\n <c8y-message name=\"maxlength\" [text]=\"'Only select one image.' | translate\"></c8y-message>\n <c8y-message name=\"required\" [text]=\"'An image is required.' | translate\"></c8y-message>\n <c8y-message name=\"minlength\" [text]=\"'An image is required.' | translate\"></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <ng-container *ngIf=\"imageSrc$ | async as src\">\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">\n {{ 'Size and alignment' | translate }}\n </div>\n <div [formGroupName]=\"'styling'\">\n <c8y-form-group>\n <label>\n {{ 'Image display' | translate }}\n </label>\n <ul class=\"list-group separator-top-bottom\">\n <li\n class=\"list-group-item d-flex a-i-center p-l-0\"\n *ngFor=\"let objectFitOption of objectFitOptions; let i = index\"\n >\n <label class=\"c8y-radio\">\n <input\n type=\"radio\"\n [id]=\"'groupradiocontentclass' + i\"\n formControlName=\"objectFit\"\n [value]=\"objectFitOption.value\"\n />\n <span></span>\n <span class=\"l-h-1\">\n {{ objectFitOption.label | translate }}\n <br />\n <small class=\"text-muted\">\n {{ objectFitOption.description | translate }}\n </small>\n </span>\n </label>\n </li>\n </ul>\n </c8y-form-group>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Horizontal alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionX\">\n <option [ngValue]=\"'left'\">\n {{ 'left`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'right'\">\n {{ 'right`horizontal alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Vertical alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionY\">\n <option [ngValue]=\"'top'\">\n {{ 'top`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'bottom'\">\n {{ 'bottom`vertical alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">{{ 'Preview' | translate }}</div>\n <div class=\"form-group\">\n <div\n class=\"border-top border-right border-bottom border-left inner-scroll\"\n style=\"height: 300px\"\n >\n <img\n [src]=\"src\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"col-md-12 d-flex j-c-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n </div>\n </div>\n</div>\n" }]
}], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i1$1.NgForm }, { type: i2.FilesService }, { type: i2.AlertService }, { type: ImageWidgetService }, { type: i4.WidgetConfigComponent, decorators: [{
type: Optional
}] }], propDecorators: { config: [{
type: Input
}] } });
/**
* @deprecated
*/
class ImageWidgetModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageWidgetModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: ImageWidgetModule, imports: [ImageWidgetViewComponent, ImageWidgetConfigComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageWidgetModule, imports: [ImageWidgetViewComponent, ImageWidgetConfigComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ImageWidgetModule, decorators: [{
type: NgModule,
args: [{
imports: [ImageWidgetViewComponent, ImageWidgetConfigComponent]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { ImageWidgetConfigComponent, ImageWidgetModule, ImageWidgetService, ImageWidgetViewComponent, defaultObjectFitValue, defaultObjectPositionValue };
//# sourceMappingURL=c8y-ngx-components-widgets-implementations-image.mjs.map