@c8y/ngx-components 1024.19.5 → 1024.20.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.
- package/fesm2022/c8y-ngx-components-ai-agents-html.mjs +0 -9
- package/fesm2022/c8y-ngx-components-ai-agents-html.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-ai-agents-scada.mjs +0 -4
- package/fesm2022/c8y-ngx-components-ai-agents-scada.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-ai.mjs +10 -10
- package/fesm2022/c8y-ngx-components-ai.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-alarm-event-selector.mjs +13 -9
- package/fesm2022/c8y-ngx-components-alarm-event-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-asset-properties.mjs +4 -3
- package/fesm2022/c8y-ngx-components-asset-properties.mjs.map +1 -1
- package/fesm2022/{c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-CG8k844T.mjs → c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-1WsTSnO_.mjs} +9 -5
- package/fesm2022/c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-1WsTSnO_.mjs.map +1 -0
- package/fesm2022/{c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-CTXM7Dkc.mjs → c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-C3KZGqlc.mjs} +2 -2
- package/fesm2022/{c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-CTXM7Dkc.mjs.map → c8y-ngx-components-computed-asset-properties-fieldbus-item-status-config.component-C3KZGqlc.mjs.map} +1 -1
- package/fesm2022/{c8y-ngx-components-computed-asset-properties-last-measurement-config.component-Da3QVvuf.mjs → c8y-ngx-components-computed-asset-properties-last-measurement-config.component-DOmwNU6m.mjs} +2 -2
- package/fesm2022/{c8y-ngx-components-computed-asset-properties-last-measurement-config.component-Da3QVvuf.mjs.map → c8y-ngx-components-computed-asset-properties-last-measurement-config.component-DOmwNU6m.mjs.map} +1 -1
- package/fesm2022/c8y-ngx-components-computed-asset-properties.mjs +1 -1
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs +30 -9
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-library-details.mjs +2 -2
- package/fesm2022/c8y-ngx-components-datapoint-library-details.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-library-list.mjs +12 -5
- package/fesm2022/c8y-ngx-components-datapoint-library-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +41 -12
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +10 -6
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart.mjs +38 -25
- package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +21 -9
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-list.mjs +7 -4
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +9 -5
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-info-gauge.mjs +18 -12
- package/fesm2022/c8y-ngx-components-widgets-implementations-info-gauge.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-kpi.mjs +4 -3
- package/fesm2022/c8y-ngx-components-widgets-implementations-kpi.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-linear-gauge.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-linear-gauge.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-pie-chart.mjs +3 -3
- package/fesm2022/c8y-ngx-components-widgets-implementations-pie-chart.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +166 -29
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/locales/locales.pot +6 -0
- package/package.json +1 -1
- package/types/c8y-ngx-components-ai-agents-html.d.ts.map +1 -1
- package/types/c8y-ngx-components-ai-agents-scada.d.ts.map +1 -1
- package/types/c8y-ngx-components-ai.d.ts +1 -1
- package/types/c8y-ngx-components-ai.d.ts.map +1 -1
- package/types/c8y-ngx-components-alarm-event-selector.d.ts.map +1 -1
- package/types/c8y-ngx-components-asset-properties.d.ts +0 -1
- package/types/c8y-ngx-components-asset-properties.d.ts.map +1 -1
- package/types/c8y-ngx-components-context-dashboard.d.ts +5 -0
- package/types/c8y-ngx-components-context-dashboard.d.ts.map +1 -1
- package/types/c8y-ngx-components-datapoint-library-list.d.ts.map +1 -1
- package/types/c8y-ngx-components-datapoint-selector.d.ts +13 -3
- package/types/c8y-ngx-components-datapoint-selector.d.ts.map +1 -1
- package/types/c8y-ngx-components-datapoints-export-selector.d.ts +2 -0
- package/types/c8y-ngx-components-datapoints-export-selector.d.ts.map +1 -1
- package/types/c8y-ngx-components-echart.d.ts +1 -0
- package/types/c8y-ngx-components-echart.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-datapoints-graph.d.ts +7 -0
- package/types/c8y-ngx-components-widgets-implementations-datapoints-graph.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-datapoints-list.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-datapoints-table.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-info-gauge.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-kpi.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-pie-chart.d.ts.map +1 -1
- package/types/c8y-ngx-components.d.ts +111 -5
- package/types/c8y-ngx-components.d.ts.map +1 -1
- package/fesm2022/c8y-ngx-components-computed-asset-properties-c8y-ngx-components-computed-asset-properties-CG8k844T.mjs.map +0 -1
|
@@ -987,9 +987,11 @@ class ContextDashboardService {
|
|
|
987
987
|
});
|
|
988
988
|
}
|
|
989
989
|
replaceContextInDataPoints(dataPoints, newContext, oldContext) {
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
990
|
+
if (Array.isArray(dataPoints)) {
|
|
991
|
+
dataPoints.forEach(dp => {
|
|
992
|
+
dp.__target = this.replaceContextInObj(dp.__target, newContext, oldContext);
|
|
993
|
+
});
|
|
994
|
+
}
|
|
993
995
|
return dataPoints;
|
|
994
996
|
}
|
|
995
997
|
replaceContextInObj(obj, newContext, oldContext) {
|
|
@@ -1854,6 +1856,14 @@ class DashboardCaretakerService {
|
|
|
1854
1856
|
this.originator.initState(initialItem);
|
|
1855
1857
|
return initialItem;
|
|
1856
1858
|
}
|
|
1859
|
+
/**
|
|
1860
|
+
* Drops both stacks without touching the current state. Used when a different dashboard is
|
|
1861
|
+
* loaded, so its undo history cannot reach back into the previous one.
|
|
1862
|
+
*/
|
|
1863
|
+
clear() {
|
|
1864
|
+
this.undoStack = [];
|
|
1865
|
+
this.redoStack = [];
|
|
1866
|
+
}
|
|
1857
1867
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DashboardCaretakerService, deps: [{ token: DashboardOriginatorService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1858
1868
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DashboardCaretakerService, providedIn: 'root' }); }
|
|
1859
1869
|
}
|
|
@@ -1893,6 +1903,9 @@ class DashboardEditModeService {
|
|
|
1893
1903
|
* @param state Dashboard children initial state.
|
|
1894
1904
|
*/
|
|
1895
1905
|
init(state) {
|
|
1906
|
+
// These services are application scoped, so without this the undo history of the dashboard
|
|
1907
|
+
// shown before this one stays reachable and can be restored onto this one.
|
|
1908
|
+
this.caretaker.clear();
|
|
1896
1909
|
this.originator.initState(state);
|
|
1897
1910
|
}
|
|
1898
1911
|
/**
|
|
@@ -2717,7 +2730,8 @@ class WidgetService {
|
|
|
2717
2730
|
async getWidgetDefinitions(assetMo, dashboardMo) {
|
|
2718
2731
|
const translatedComponents = this.widgets.map(cmp => ({
|
|
2719
2732
|
...cmp,
|
|
2720
|
-
label: this.translateService.instant(cmp.label)
|
|
2733
|
+
label: this.translateService.instant(cmp.label),
|
|
2734
|
+
...(cmp.description ? { description: this.translateService.instant(cmp.description) } : {})
|
|
2721
2735
|
}));
|
|
2722
2736
|
// cloneDeep and injector lead to a performance issue. We removing the injectors here,
|
|
2723
2737
|
// as they are not needed, to avoid use of a lot of CPU for cloning.
|
|
@@ -2922,7 +2936,8 @@ class WidgetConfigComponent {
|
|
|
2922
2936
|
}
|
|
2923
2937
|
search() {
|
|
2924
2938
|
if (this.searchTerm.length > 0) {
|
|
2925
|
-
|
|
2939
|
+
const regex = new RegExp(escapeRegExp(this.searchTerm.trim()), 'i');
|
|
2940
|
+
this.searchResult = this.components.filter(cmp => regex.test(cmp.label) || (!!cmp.description && regex.test(cmp.description)));
|
|
2926
2941
|
}
|
|
2927
2942
|
else {
|
|
2928
2943
|
this.resetSearch();
|
|
@@ -3076,7 +3091,7 @@ class WidgetConfigComponent {
|
|
|
3076
3091
|
return { ...defaults, ...scaled };
|
|
3077
3092
|
}
|
|
3078
3093
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: WidgetConfigComponent, deps: [{ token: WidgetService }, { token: i2.BottomDrawerRef }, { token: ContextDashboardService }, { token: WidgetConfigService }, { token: i2.BottomDrawerService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3079
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: WidgetConfigComponent, isStandalone: true, selector: "c8y-widget-config", host: { listeners: { "document:keydown.escape": "onEscapePress($event)" }, classAttribute: "d-contents" }, viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }, { propertyName: "configForm", first: true, predicate: ["configForm"], descendants: true }], ngImport: i0, template: "<!-- select widget -->\n@if (!(widgetConfigService.selected$ | async)) {\n <div class=\"card-header j-c-center separator\">\n <div\n class=\"h4 text-center\"\n id=\"drawerTitle\"\n >\n {{ 'Select widget' | translate }}\n </div>\n </div>\n <div class=\"card-inner-scroll fit-h bg-level-2\">\n <div\n class=\"bg-level-0 p-l-24 p-r-24 p-t-8 p-b-8 sticky-header-top-0 elevation-md\"\n style=\"z-index: 2\"\n >\n <div class=\"row\">\n <div class=\"col-sm-6 col-sm-offset-3\">\n <div class=\"input-group input-group-search\">\n <input\n class=\"form-control\"\n [attr.aria-label]=\"'Search' | translate\"\n placeholder=\"{{ 'Search\u2026' | translate }}\"\n type=\"text\"\n #searchInput\n data-cy=\"widget-config--Search\"\n [(ngModel)]=\"searchTerm\"\n [ngModelOptions]=\"{ standalone: true }\"\n (keydown)=\"searchChange$.next($event)\"\n />\n <span class=\"input-group-btn\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Search' | translate }}\"\n type=\"button\"\n (click)=\"resetSearch()\"\n >\n <i [c8yIcon]=\"searchTerm.length === 0 ? 'search' : 'close'\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n </div>\n <div class=\"card-block\">\n <div class=\"card-group p-l-24 p-r-24 d-grid grid__col--auto-300 gap-24 card-select m-b-0\">\n @for (cmp of searchResult || components; track cmp) {\n <button\n class=\"btn-clean d-col card m-b-0\"\n [title]=\"cmp.description || cmp.label | translate\"\n type=\"button\"\n data-cy=\"widget-config--widget-list\"\n (click)=\"select(cmp)\"\n >\n <div\n class=\"border-bottom\"\n role=\"presentation\"\n >\n @if (!cmp.previewImage) {\n <div class=\"h1\"><i c8yIcon=\"file-image-o\"></i></div>\n <small translate>Preview not available</small>\n } @else {\n <img\n class=\"widget-thumbnail\"\n alt=\"{{ cmp.label | translate }}\"\n [src]=\"cmp.previewImage\"\n />\n }\n </div>\n <div class=\"card-block\">\n <p class=\"card-title text-truncate text-medium\">\n <c8y-highlight\n text=\"{{ cmp.label | translate }}\"\n [pattern]=\"searchTerm\"\n ></c8y-highlight>\n </p>\n <p\n class=\"small text-default\"\n style=\"white-space: wrap\"\n >\n {{ cmp.description | translate }}\n </p>\n </div>\n </button>\n }\n @if (searchResult && searchResult.length === 0) {\n <c8y-ui-empty-state\n class=\"p-24 grid__col--fullspan\"\n [icon]=\"'search'\"\n [title]=\"'No widgets found.' | translate\"\n [subtitle]=\"'Rephrase your search term.' | translate\"\n >\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Reset search' | translate }}\"\n type=\"button\"\n (click)=\"resetSearch()\"\n >\n {{ 'Reset search' | translate }}\n </button>\n </c8y-ui-empty-state>\n }\n </div>\n </div>\n </div>\n <div class=\"card-footer text-center separator flex-no-shrink\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"widget-config--cancel-widget\"\n (click)=\"close()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n </div>\n}\n\n<!-- widget configuration -->\n@if (!!(widgetConfigService.selected$ | async)) {\n <div class=\"card-header d-block separator-bottom flex-no-shrink\">\n <div\n class=\"h3 p-t-16\"\n title=\"{{ selected?.label | translate }}\"\n >\n <span>{{ selected?.label | translate }}</span>\n <button\n class=\"btn btn-default btn-sm m-l-8\"\n [title]=\"'Change widget' | translate\"\n (click)=\"backToWidgetSelection(); (false)\"\n >\n <i c8yIcon=\"replace\"></i>\n {{ 'Change widget' | translate }}\n </button>\n </div>\n @if (selected) {\n <div class=\"p-t-8\">\n <p>\n {{ selected.description | translate }}\n </p>\n </div>\n }\n </div>\n\n <c8y-resizable-grid\n class=\"min-height-0 flex-grow\"\n [collapsible]=\"false\"\n [trackId]=\"'c8y-widget-resizable-grid-size-' + (widgetConfigService.instanceId$ | async)\"\n [leftColumnWidth]=\"\n (widgetConfigService.currentConfig$ | async)?.settings?.configurationViewGridSize ||\n WIDGET_CONFIGURATION_GRID_SIZE.DEFAULT\n \"\n >\n <div\n class=\"bg-level-1 inner-scroll\"\n left-pane\n >\n <div class=\"p-16 flex-no-shrink separator-bottom bg-level-1\">\n <c8y-form-group>\n <label\n for=\"widgetTitle\"\n translate\n >\n Widget title\n </label>\n <input\n class=\"form-control\"\n id=\"widgetTitle\"\n placeholder=\"{{ 'e.g.' | translate }} {{ componentLabel | translate }}\"\n name=\"widgetTitle\"\n type=\"text\"\n required\n [(ngModel)]=\"widgetTitle\"\n (ngModelChange)=\"onWidgetTitleChange($event)\"\n />\n </c8y-form-group>\n </div>\n\n @if (!(widgetConfigService.hasConfig$ | async)) {\n <c8y-ui-empty-state\n class=\"p-24\"\n [icon]=\"'settings'\"\n [title]=\"'No configuration needed.' | translate\"\n [subtitle]=\"'This widget does not need any specific configuration.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n <div>\n <form\n name=\"form\"\n #configForm=\"ngForm\"\n >\n @if (widgetConfigService.hasConfig$ | async) {\n @if (widgetConfigService.providers$ | async; as providers) {\n <ng-container\n *c8yComponentOutlet=\"widgetConfigRoot; providers: providers\"\n ></ng-container>\n }\n }\n </form>\n </div>\n </div>\n\n <div\n class=\"inner-scroll d-col flex-grow p-32 p-t-0\"\n right-pane\n >\n <c8y-widget-preview [previewClasses]=\"getStyle(true)\"></c8y-widget-preview>\n\n <c8y-appearance-settings\n [(themeClass)]=\"styling.contentClass\"\n [(headerClass)]=\"styling.headerClass\"\n [possibleStylingTheme]=\"possibleStyling.WIDGET_CONTENT_CLASSES\"\n [possibleStylingHeader]=\"possibleStyling.WIDGET_HEADER_CLASSES\"\n [defaultThemeClass]=\"defaultStyling.contentClass\"\n [defaultHeaderClass]=\"defaultStyling.headerClass\"\n [columns]=\"2\"\n ></c8y-appearance-settings>\n </div>\n </c8y-resizable-grid>\n\n <div class=\"card-footer separator text-center\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"widget-config--cancel-widget\"\n (click)=\"close()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n data-cy=\"widget-config--save-widget\"\n (click)=\"save()\"\n [disabled]=\"(contextDashboardService.formDisabled$ | async) || isSaveDisabled()\"\n c8yProductExperience\n [actionName]=\"current ? 'editWidget' : 'createWidget'\"\n [actionData]=\"{ widgetName: selected && selected.id }\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: C8yComponentOutlet, selector: "[c8yComponentOutlet]", inputs: ["c8yComponentOutlet", "c8yComponentOutletInjector", "c8yComponentOutletEnvironmentInjector", "c8yComponentOutletProviders", "c8yComponentOutletInitialState"] }, { kind: "component", type: WidgetPreviewComponent, selector: "c8y-widget-preview", inputs: ["previewClasses"] }, { kind: "component", type: AppearanceSettingsComponent, selector: "c8y-appearance-settings", inputs: ["themeClass", "headerClass", "defaultThemeClass", "defaultHeaderClass", "dashboardSettings", "possibleStylingTheme", "possibleStylingHeader", "columns"], outputs: ["themeClassChange", "headerClassChange", "onChange"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "component", type: ResizableGridComponent, selector: "c8y-resizable-grid", inputs: ["leftColumnWidth", "trackId", "collapseThreshold", "collapsible", "orientation"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
3094
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: WidgetConfigComponent, isStandalone: true, selector: "c8y-widget-config", host: { listeners: { "document:keydown.escape": "onEscapePress($event)" }, classAttribute: "d-contents" }, viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }, { propertyName: "configForm", first: true, predicate: ["configForm"], descendants: true }], ngImport: i0, template: "<!-- select widget -->\n@if (!(widgetConfigService.selected$ | async)) {\n <div class=\"card-header j-c-center separator\">\n <div\n class=\"h4 text-center\"\n id=\"drawerTitle\"\n >\n {{ 'Select widget' | translate }}\n </div>\n </div>\n <div class=\"card-inner-scroll fit-h bg-level-2\">\n <div\n class=\"bg-level-0 p-l-24 p-r-24 p-t-8 p-b-8 sticky-header-top-0 elevation-md\"\n style=\"z-index: 2\"\n >\n <div class=\"row\">\n <div class=\"col-sm-6 col-sm-offset-3\">\n <div class=\"input-group input-group-search\">\n <input\n class=\"form-control\"\n [attr.aria-label]=\"'Search' | translate\"\n placeholder=\"{{ 'Search\u2026' | translate }}\"\n type=\"text\"\n #searchInput\n data-cy=\"widget-config--Search\"\n [(ngModel)]=\"searchTerm\"\n [ngModelOptions]=\"{ standalone: true }\"\n (keydown)=\"searchChange$.next($event)\"\n />\n <span class=\"input-group-btn\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Search' | translate }}\"\n type=\"button\"\n (click)=\"resetSearch()\"\n >\n <i [c8yIcon]=\"searchTerm.length === 0 ? 'search' : 'close'\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n </div>\n <div class=\"card-block\">\n <div class=\"card-group p-l-24 p-r-24 d-grid grid__col--auto-300 gap-24 card-select m-b-0\">\n @for (cmp of searchResult || components; track cmp) {\n <button\n class=\"btn-clean d-col card m-b-0\"\n [title]=\"cmp.description || cmp.label | translate\"\n type=\"button\"\n data-cy=\"widget-config--widget-list\"\n (click)=\"select(cmp)\"\n >\n <div\n class=\"border-bottom\"\n role=\"presentation\"\n >\n @if (!cmp.previewImage) {\n <div class=\"h1\"><i c8yIcon=\"file-image-o\"></i></div>\n <small translate>Preview not available</small>\n } @else {\n <img\n class=\"widget-thumbnail\"\n alt=\"{{ cmp.label | translate }}\"\n [src]=\"cmp.previewImage\"\n />\n }\n </div>\n <div class=\"card-block\">\n <p class=\"card-title text-truncate text-medium\">\n <c8y-highlight\n text=\"{{ cmp.label | translate }}\"\n [pattern]=\"searchTerm\"\n ></c8y-highlight>\n </p>\n <p\n class=\"small text-default\"\n style=\"white-space: wrap\"\n >\n <c8y-highlight\n text=\"{{ cmp.description | translate }}\"\n [pattern]=\"searchTerm\"\n ></c8y-highlight>\n </p>\n </div>\n </button>\n }\n @if (searchResult && searchResult.length === 0) {\n <c8y-ui-empty-state\n class=\"p-24 grid__col--fullspan\"\n [icon]=\"'search'\"\n [title]=\"'No widgets found.' | translate\"\n [subtitle]=\"'Rephrase your search term.' | translate\"\n >\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Reset search' | translate }}\"\n type=\"button\"\n (click)=\"resetSearch()\"\n >\n {{ 'Reset search' | translate }}\n </button>\n </c8y-ui-empty-state>\n }\n </div>\n </div>\n </div>\n <div class=\"card-footer text-center separator flex-no-shrink\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"widget-config--cancel-widget\"\n (click)=\"close()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n </div>\n}\n\n<!-- widget configuration -->\n@if (!!(widgetConfigService.selected$ | async)) {\n <div class=\"card-header d-block separator-bottom flex-no-shrink\">\n <div\n class=\"h3 p-t-16\"\n title=\"{{ selected?.label | translate }}\"\n >\n <span>{{ selected?.label | translate }}</span>\n <button\n class=\"btn btn-default btn-sm m-l-8\"\n [title]=\"'Change widget' | translate\"\n (click)=\"backToWidgetSelection(); (false)\"\n >\n <i c8yIcon=\"replace\"></i>\n {{ 'Change widget' | translate }}\n </button>\n </div>\n @if (selected) {\n <div class=\"p-t-8\">\n <p>\n {{ selected.description | translate }}\n </p>\n </div>\n }\n </div>\n\n <c8y-resizable-grid\n class=\"min-height-0 flex-grow\"\n [collapsible]=\"false\"\n [trackId]=\"'c8y-widget-resizable-grid-size-' + (widgetConfigService.instanceId$ | async)\"\n [leftColumnWidth]=\"\n (widgetConfigService.currentConfig$ | async)?.settings?.configurationViewGridSize ||\n WIDGET_CONFIGURATION_GRID_SIZE.DEFAULT\n \"\n >\n <div\n class=\"bg-level-1 inner-scroll\"\n left-pane\n >\n <div class=\"p-16 flex-no-shrink separator-bottom bg-level-1\">\n <c8y-form-group>\n <label\n for=\"widgetTitle\"\n translate\n >\n Widget title\n </label>\n <input\n class=\"form-control\"\n id=\"widgetTitle\"\n placeholder=\"{{ 'e.g.' | translate }} {{ componentLabel | translate }}\"\n name=\"widgetTitle\"\n type=\"text\"\n required\n [(ngModel)]=\"widgetTitle\"\n (ngModelChange)=\"onWidgetTitleChange($event)\"\n />\n </c8y-form-group>\n </div>\n\n @if (!(widgetConfigService.hasConfig$ | async)) {\n <c8y-ui-empty-state\n class=\"p-24\"\n [icon]=\"'settings'\"\n [title]=\"'No configuration needed.' | translate\"\n [subtitle]=\"'This widget does not need any specific configuration.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n <div>\n <form\n name=\"form\"\n #configForm=\"ngForm\"\n >\n @if (widgetConfigService.hasConfig$ | async) {\n @if (widgetConfigService.providers$ | async; as providers) {\n <ng-container\n *c8yComponentOutlet=\"widgetConfigRoot; providers: providers\"\n ></ng-container>\n }\n }\n </form>\n </div>\n </div>\n\n <div\n class=\"inner-scroll d-col flex-grow p-32 p-t-0\"\n right-pane\n >\n <c8y-widget-preview [previewClasses]=\"getStyle(true)\"></c8y-widget-preview>\n\n <c8y-appearance-settings\n [(themeClass)]=\"styling.contentClass\"\n [(headerClass)]=\"styling.headerClass\"\n [possibleStylingTheme]=\"possibleStyling.WIDGET_CONTENT_CLASSES\"\n [possibleStylingHeader]=\"possibleStyling.WIDGET_HEADER_CLASSES\"\n [defaultThemeClass]=\"defaultStyling.contentClass\"\n [defaultHeaderClass]=\"defaultStyling.headerClass\"\n [columns]=\"2\"\n ></c8y-appearance-settings>\n </div>\n </c8y-resizable-grid>\n\n <div class=\"card-footer separator text-center\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"widget-config--cancel-widget\"\n (click)=\"close()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n data-cy=\"widget-config--save-widget\"\n (click)=\"save()\"\n [disabled]=\"(contextDashboardService.formDisabled$ | async) || isSaveDisabled()\"\n c8yProductExperience\n [actionName]=\"current ? 'editWidget' : 'createWidget'\"\n [actionData]=\"{ widgetName: selected && selected.id }\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: C8yComponentOutlet, selector: "[c8yComponentOutlet]", inputs: ["c8yComponentOutlet", "c8yComponentOutletInjector", "c8yComponentOutletEnvironmentInjector", "c8yComponentOutletProviders", "c8yComponentOutletInitialState"] }, { kind: "component", type: WidgetPreviewComponent, selector: "c8y-widget-preview", inputs: ["previewClasses"] }, { kind: "component", type: AppearanceSettingsComponent, selector: "c8y-appearance-settings", inputs: ["themeClass", "headerClass", "defaultThemeClass", "defaultHeaderClass", "dashboardSettings", "possibleStylingTheme", "possibleStylingHeader", "columns"], outputs: ["themeClassChange", "headerClassChange", "onChange"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "component", type: ResizableGridComponent, selector: "c8y-resizable-grid", inputs: ["leftColumnWidth", "trackId", "collapseThreshold", "collapsible", "orientation"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
3080
3095
|
}
|
|
3081
3096
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: WidgetConfigComponent, decorators: [{
|
|
3082
3097
|
type: Component,
|
|
@@ -3095,7 +3110,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
3095
3110
|
C8yTranslatePipe,
|
|
3096
3111
|
AsyncPipe,
|
|
3097
3112
|
ResizableGridComponent
|
|
3098
|
-
], standalone: true, changeDetection: ChangeDetectionStrategy.Eager, template: "<!-- select widget -->\n@if (!(widgetConfigService.selected$ | async)) {\n <div class=\"card-header j-c-center separator\">\n <div\n class=\"h4 text-center\"\n id=\"drawerTitle\"\n >\n {{ 'Select widget' | translate }}\n </div>\n </div>\n <div class=\"card-inner-scroll fit-h bg-level-2\">\n <div\n class=\"bg-level-0 p-l-24 p-r-24 p-t-8 p-b-8 sticky-header-top-0 elevation-md\"\n style=\"z-index: 2\"\n >\n <div class=\"row\">\n <div class=\"col-sm-6 col-sm-offset-3\">\n <div class=\"input-group input-group-search\">\n <input\n class=\"form-control\"\n [attr.aria-label]=\"'Search' | translate\"\n placeholder=\"{{ 'Search\u2026' | translate }}\"\n type=\"text\"\n #searchInput\n data-cy=\"widget-config--Search\"\n [(ngModel)]=\"searchTerm\"\n [ngModelOptions]=\"{ standalone: true }\"\n (keydown)=\"searchChange$.next($event)\"\n />\n <span class=\"input-group-btn\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Search' | translate }}\"\n type=\"button\"\n (click)=\"resetSearch()\"\n >\n <i [c8yIcon]=\"searchTerm.length === 0 ? 'search' : 'close'\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n </div>\n <div class=\"card-block\">\n <div class=\"card-group p-l-24 p-r-24 d-grid grid__col--auto-300 gap-24 card-select m-b-0\">\n @for (cmp of searchResult || components; track cmp) {\n <button\n class=\"btn-clean d-col card m-b-0\"\n [title]=\"cmp.description || cmp.label | translate\"\n type=\"button\"\n data-cy=\"widget-config--widget-list\"\n (click)=\"select(cmp)\"\n >\n <div\n class=\"border-bottom\"\n role=\"presentation\"\n >\n @if (!cmp.previewImage) {\n <div class=\"h1\"><i c8yIcon=\"file-image-o\"></i></div>\n <small translate>Preview not available</small>\n } @else {\n <img\n class=\"widget-thumbnail\"\n alt=\"{{ cmp.label | translate }}\"\n [src]=\"cmp.previewImage\"\n />\n }\n </div>\n <div class=\"card-block\">\n <p class=\"card-title text-truncate text-medium\">\n <c8y-highlight\n text=\"{{ cmp.label | translate }}\"\n [pattern]=\"searchTerm\"\n ></c8y-highlight>\n </p>\n <p\n class=\"small text-default\"\n style=\"white-space: wrap\"\n >\n {{ cmp.description | translate }}\n </p>\n </div>\n </button>\n }\n @if (searchResult && searchResult.length === 0) {\n <c8y-ui-empty-state\n class=\"p-24 grid__col--fullspan\"\n [icon]=\"'search'\"\n [title]=\"'No widgets found.' | translate\"\n [subtitle]=\"'Rephrase your search term.' | translate\"\n >\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Reset search' | translate }}\"\n type=\"button\"\n (click)=\"resetSearch()\"\n >\n {{ 'Reset search' | translate }}\n </button>\n </c8y-ui-empty-state>\n }\n </div>\n </div>\n </div>\n <div class=\"card-footer text-center separator flex-no-shrink\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"widget-config--cancel-widget\"\n (click)=\"close()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n </div>\n}\n\n<!-- widget configuration -->\n@if (!!(widgetConfigService.selected$ | async)) {\n <div class=\"card-header d-block separator-bottom flex-no-shrink\">\n <div\n class=\"h3 p-t-16\"\n title=\"{{ selected?.label | translate }}\"\n >\n <span>{{ selected?.label | translate }}</span>\n <button\n class=\"btn btn-default btn-sm m-l-8\"\n [title]=\"'Change widget' | translate\"\n (click)=\"backToWidgetSelection(); (false)\"\n >\n <i c8yIcon=\"replace\"></i>\n {{ 'Change widget' | translate }}\n </button>\n </div>\n @if (selected) {\n <div class=\"p-t-8\">\n <p>\n {{ selected.description | translate }}\n </p>\n </div>\n }\n </div>\n\n <c8y-resizable-grid\n class=\"min-height-0 flex-grow\"\n [collapsible]=\"false\"\n [trackId]=\"'c8y-widget-resizable-grid-size-' + (widgetConfigService.instanceId$ | async)\"\n [leftColumnWidth]=\"\n (widgetConfigService.currentConfig$ | async)?.settings?.configurationViewGridSize ||\n WIDGET_CONFIGURATION_GRID_SIZE.DEFAULT\n \"\n >\n <div\n class=\"bg-level-1 inner-scroll\"\n left-pane\n >\n <div class=\"p-16 flex-no-shrink separator-bottom bg-level-1\">\n <c8y-form-group>\n <label\n for=\"widgetTitle\"\n translate\n >\n Widget title\n </label>\n <input\n class=\"form-control\"\n id=\"widgetTitle\"\n placeholder=\"{{ 'e.g.' | translate }} {{ componentLabel | translate }}\"\n name=\"widgetTitle\"\n type=\"text\"\n required\n [(ngModel)]=\"widgetTitle\"\n (ngModelChange)=\"onWidgetTitleChange($event)\"\n />\n </c8y-form-group>\n </div>\n\n @if (!(widgetConfigService.hasConfig$ | async)) {\n <c8y-ui-empty-state\n class=\"p-24\"\n [icon]=\"'settings'\"\n [title]=\"'No configuration needed.' | translate\"\n [subtitle]=\"'This widget does not need any specific configuration.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n <div>\n <form\n name=\"form\"\n #configForm=\"ngForm\"\n >\n @if (widgetConfigService.hasConfig$ | async) {\n @if (widgetConfigService.providers$ | async; as providers) {\n <ng-container\n *c8yComponentOutlet=\"widgetConfigRoot; providers: providers\"\n ></ng-container>\n }\n }\n </form>\n </div>\n </div>\n\n <div\n class=\"inner-scroll d-col flex-grow p-32 p-t-0\"\n right-pane\n >\n <c8y-widget-preview [previewClasses]=\"getStyle(true)\"></c8y-widget-preview>\n\n <c8y-appearance-settings\n [(themeClass)]=\"styling.contentClass\"\n [(headerClass)]=\"styling.headerClass\"\n [possibleStylingTheme]=\"possibleStyling.WIDGET_CONTENT_CLASSES\"\n [possibleStylingHeader]=\"possibleStyling.WIDGET_HEADER_CLASSES\"\n [defaultThemeClass]=\"defaultStyling.contentClass\"\n [defaultHeaderClass]=\"defaultStyling.headerClass\"\n [columns]=\"2\"\n ></c8y-appearance-settings>\n </div>\n </c8y-resizable-grid>\n\n <div class=\"card-footer separator text-center\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"widget-config--cancel-widget\"\n (click)=\"close()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n data-cy=\"widget-config--save-widget\"\n (click)=\"save()\"\n [disabled]=\"(contextDashboardService.formDisabled$ | async) || isSaveDisabled()\"\n c8yProductExperience\n [actionName]=\"current ? 'editWidget' : 'createWidget'\"\n [actionData]=\"{ widgetName: selected && selected.id }\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n}\n" }]
|
|
3113
|
+
], standalone: true, changeDetection: ChangeDetectionStrategy.Eager, template: "<!-- select widget -->\n@if (!(widgetConfigService.selected$ | async)) {\n <div class=\"card-header j-c-center separator\">\n <div\n class=\"h4 text-center\"\n id=\"drawerTitle\"\n >\n {{ 'Select widget' | translate }}\n </div>\n </div>\n <div class=\"card-inner-scroll fit-h bg-level-2\">\n <div\n class=\"bg-level-0 p-l-24 p-r-24 p-t-8 p-b-8 sticky-header-top-0 elevation-md\"\n style=\"z-index: 2\"\n >\n <div class=\"row\">\n <div class=\"col-sm-6 col-sm-offset-3\">\n <div class=\"input-group input-group-search\">\n <input\n class=\"form-control\"\n [attr.aria-label]=\"'Search' | translate\"\n placeholder=\"{{ 'Search\u2026' | translate }}\"\n type=\"text\"\n #searchInput\n data-cy=\"widget-config--Search\"\n [(ngModel)]=\"searchTerm\"\n [ngModelOptions]=\"{ standalone: true }\"\n (keydown)=\"searchChange$.next($event)\"\n />\n <span class=\"input-group-btn\">\n <button\n class=\"btn btn-dot\"\n title=\"{{ 'Search' | translate }}\"\n type=\"button\"\n (click)=\"resetSearch()\"\n >\n <i [c8yIcon]=\"searchTerm.length === 0 ? 'search' : 'close'\"></i>\n </button>\n </span>\n </div>\n </div>\n </div>\n </div>\n <div class=\"card-block\">\n <div class=\"card-group p-l-24 p-r-24 d-grid grid__col--auto-300 gap-24 card-select m-b-0\">\n @for (cmp of searchResult || components; track cmp) {\n <button\n class=\"btn-clean d-col card m-b-0\"\n [title]=\"cmp.description || cmp.label | translate\"\n type=\"button\"\n data-cy=\"widget-config--widget-list\"\n (click)=\"select(cmp)\"\n >\n <div\n class=\"border-bottom\"\n role=\"presentation\"\n >\n @if (!cmp.previewImage) {\n <div class=\"h1\"><i c8yIcon=\"file-image-o\"></i></div>\n <small translate>Preview not available</small>\n } @else {\n <img\n class=\"widget-thumbnail\"\n alt=\"{{ cmp.label | translate }}\"\n [src]=\"cmp.previewImage\"\n />\n }\n </div>\n <div class=\"card-block\">\n <p class=\"card-title text-truncate text-medium\">\n <c8y-highlight\n text=\"{{ cmp.label | translate }}\"\n [pattern]=\"searchTerm\"\n ></c8y-highlight>\n </p>\n <p\n class=\"small text-default\"\n style=\"white-space: wrap\"\n >\n <c8y-highlight\n text=\"{{ cmp.description | translate }}\"\n [pattern]=\"searchTerm\"\n ></c8y-highlight>\n </p>\n </div>\n </button>\n }\n @if (searchResult && searchResult.length === 0) {\n <c8y-ui-empty-state\n class=\"p-24 grid__col--fullspan\"\n [icon]=\"'search'\"\n [title]=\"'No widgets found.' | translate\"\n [subtitle]=\"'Rephrase your search term.' | translate\"\n >\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Reset search' | translate }}\"\n type=\"button\"\n (click)=\"resetSearch()\"\n >\n {{ 'Reset search' | translate }}\n </button>\n </c8y-ui-empty-state>\n }\n </div>\n </div>\n </div>\n <div class=\"card-footer text-center separator flex-no-shrink\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"widget-config--cancel-widget\"\n (click)=\"close()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n </div>\n}\n\n<!-- widget configuration -->\n@if (!!(widgetConfigService.selected$ | async)) {\n <div class=\"card-header d-block separator-bottom flex-no-shrink\">\n <div\n class=\"h3 p-t-16\"\n title=\"{{ selected?.label | translate }}\"\n >\n <span>{{ selected?.label | translate }}</span>\n <button\n class=\"btn btn-default btn-sm m-l-8\"\n [title]=\"'Change widget' | translate\"\n (click)=\"backToWidgetSelection(); (false)\"\n >\n <i c8yIcon=\"replace\"></i>\n {{ 'Change widget' | translate }}\n </button>\n </div>\n @if (selected) {\n <div class=\"p-t-8\">\n <p>\n {{ selected.description | translate }}\n </p>\n </div>\n }\n </div>\n\n <c8y-resizable-grid\n class=\"min-height-0 flex-grow\"\n [collapsible]=\"false\"\n [trackId]=\"'c8y-widget-resizable-grid-size-' + (widgetConfigService.instanceId$ | async)\"\n [leftColumnWidth]=\"\n (widgetConfigService.currentConfig$ | async)?.settings?.configurationViewGridSize ||\n WIDGET_CONFIGURATION_GRID_SIZE.DEFAULT\n \"\n >\n <div\n class=\"bg-level-1 inner-scroll\"\n left-pane\n >\n <div class=\"p-16 flex-no-shrink separator-bottom bg-level-1\">\n <c8y-form-group>\n <label\n for=\"widgetTitle\"\n translate\n >\n Widget title\n </label>\n <input\n class=\"form-control\"\n id=\"widgetTitle\"\n placeholder=\"{{ 'e.g.' | translate }} {{ componentLabel | translate }}\"\n name=\"widgetTitle\"\n type=\"text\"\n required\n [(ngModel)]=\"widgetTitle\"\n (ngModelChange)=\"onWidgetTitleChange($event)\"\n />\n </c8y-form-group>\n </div>\n\n @if (!(widgetConfigService.hasConfig$ | async)) {\n <c8y-ui-empty-state\n class=\"p-24\"\n [icon]=\"'settings'\"\n [title]=\"'No configuration needed.' | translate\"\n [subtitle]=\"'This widget does not need any specific configuration.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n <div>\n <form\n name=\"form\"\n #configForm=\"ngForm\"\n >\n @if (widgetConfigService.hasConfig$ | async) {\n @if (widgetConfigService.providers$ | async; as providers) {\n <ng-container\n *c8yComponentOutlet=\"widgetConfigRoot; providers: providers\"\n ></ng-container>\n }\n }\n </form>\n </div>\n </div>\n\n <div\n class=\"inner-scroll d-col flex-grow p-32 p-t-0\"\n right-pane\n >\n <c8y-widget-preview [previewClasses]=\"getStyle(true)\"></c8y-widget-preview>\n\n <c8y-appearance-settings\n [(themeClass)]=\"styling.contentClass\"\n [(headerClass)]=\"styling.headerClass\"\n [possibleStylingTheme]=\"possibleStyling.WIDGET_CONTENT_CLASSES\"\n [possibleStylingHeader]=\"possibleStyling.WIDGET_HEADER_CLASSES\"\n [defaultThemeClass]=\"defaultStyling.contentClass\"\n [defaultHeaderClass]=\"defaultStyling.headerClass\"\n [columns]=\"2\"\n ></c8y-appearance-settings>\n </div>\n </c8y-resizable-grid>\n\n <div class=\"card-footer separator text-center\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n data-cy=\"widget-config--cancel-widget\"\n (click)=\"close()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n data-cy=\"widget-config--save-widget\"\n (click)=\"save()\"\n [disabled]=\"(contextDashboardService.formDisabled$ | async) || isSaveDisabled()\"\n c8yProductExperience\n [actionName]=\"current ? 'editWidget' : 'createWidget'\"\n [actionData]=\"{ widgetName: selected && selected.id }\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n}\n" }]
|
|
3099
3114
|
}], ctorParameters: () => [{ type: WidgetService }, { type: i2.BottomDrawerRef }, { type: ContextDashboardService }, { type: WidgetConfigService }, { type: i2.BottomDrawerService }, { type: i0.ChangeDetectorRef }], propDecorators: { searchInput: [{
|
|
3100
3115
|
type: ViewChild,
|
|
3101
3116
|
args: ['searchInput', { static: false }]
|
|
@@ -3257,6 +3272,11 @@ class ContextDashboardComponent {
|
|
|
3257
3272
|
* @param child Change object.
|
|
3258
3273
|
*/
|
|
3259
3274
|
positionOrWidgetDimensionChange(child) {
|
|
3275
|
+
// Not an optimisation: GridStack also reports the layout shifts of loading or tearing down a
|
|
3276
|
+
// dashboard, and recording those leaked one dashboard's widgets into the next (MTM-67837).
|
|
3277
|
+
if (!this.widgetsDashboard?.editMode$.value) {
|
|
3278
|
+
return;
|
|
3279
|
+
}
|
|
3260
3280
|
const currentState = this.editModeService.getCurrentState()?.children || {};
|
|
3261
3281
|
const descriptionProp = child.children.length === Object.values(currentState).length ? 'arrangement' : 'added';
|
|
3262
3282
|
let changeName;
|
|
@@ -3264,14 +3284,15 @@ class ContextDashboardComponent {
|
|
|
3264
3284
|
if (descriptionProp === 'added') {
|
|
3265
3285
|
changeName = DASHBOARD_CHILDREN_STATE_NAME.added;
|
|
3266
3286
|
const addedWidget = child.children.find(c => !currentState[c.data.id]);
|
|
3267
|
-
widgetsChanged = [addedWidget.data];
|
|
3287
|
+
widgetsChanged = addedWidget ? [addedWidget.data] : [];
|
|
3268
3288
|
}
|
|
3269
3289
|
else {
|
|
3270
3290
|
changeName = DASHBOARD_CHILDREN_STATE_NAME.arrangement;
|
|
3271
3291
|
widgetsChanged = child.children
|
|
3272
3292
|
.map(c => {
|
|
3273
3293
|
const lastStateChild = currentState[c.data.id];
|
|
3274
|
-
if (
|
|
3294
|
+
if (!lastStateChild ||
|
|
3295
|
+
c.x != lastStateChild._x ||
|
|
3275
3296
|
c.y != lastStateChild._y ||
|
|
3276
3297
|
c.width != lastStateChild._width ||
|
|
3277
3298
|
c.height != lastStateChild._height) {
|