UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

163 lines (158 loc) • 6.74 kB
import { gettext } from '@c8y/ngx-components/gettext'; import { DynamicComponentErrorStrategy, DynamicDatapointsResolver, hookWidget } from '@c8y/ngx-components'; import { defaultWidgetIds } from '@c8y/ngx-components/widgets/definitions'; import { importConfigWithTargets, exportConfigWithTargets } from '@c8y/ngx-components/widgets/import-export-config'; import { hookWidgetConfig } from '@c8y/ngx-components/context-dashboard'; import { FormGroup } from '@angular/forms'; const AT_LEAST_ONE_ACTIVE_ERROR_KEY = 'noActiveDataPoint'; function atLeastOneDataPointActive(dataPointsControlNames) { const validatorFn = (formGroup) => { if (!(formGroup instanceof FormGroup)) return null; const errorKey = AT_LEAST_ONE_ACTIVE_ERROR_KEY; let anyActive = false; for (const controlName of dataPointsControlNames) { const control = formGroup.get(controlName); const value = control?.value; if (Array.isArray(value) && value.some(item => item?.__active)) { anyActive = true; break; } } // If none are active if (!anyActive) { // Set error on all specified controls for (const controlName of dataPointsControlNames) { const control = formGroup.get(controlName); if (control) { const errors = { ...(control.errors || {}) }; errors[errorKey] = true; control.setErrors(errors); } } // Set error on the group return { [errorKey]: true }; } else { // Remove error from all specified controls if present for (const controlName of dataPointsControlNames) { const control = formGroup.get(controlName); if (control?.errors?.[errorKey]) { const errors = { ...control.errors }; delete errors[errorKey]; control.setErrors(Object.keys(errors).length ? errors : null); } } // Validation passes for the group return null; } }; // Attach metadata to the validator function validatorFn.controlNames = dataPointsControlNames; return validatorFn; } const DEFAULT_FORM_CONFIG = { showRedRange: true, showYellowRange: true, showRange: true, selectableChartRenderTypes: [] }; const DATAPOINTS_GAUGE_CONTROL_NAME = 'datapointsGauge'; const DATAPOINTS_LABELS_CONTROL_NAME = 'datapointsLabels'; const MISSING_RANGE_ERROR_KEY = 'gaugeDatapointMissingRange'; function gaugeDatapointHasRange(controlName) { const validatorFn = (formGroup) => { if (!(formGroup instanceof FormGroup)) return null; const control = formGroup.get(controlName); const datapoints = control?.value; if (!Array.isArray(datapoints)) return null; const activeGauge = datapoints.find(dp => dp?.__active); if (!activeGauge) return null; const min = Number(activeGauge.min); const max = Number(activeGauge.max); const hasRange = Number.isFinite(min) && Number.isFinite(max) && min !== max; return hasRange ? null : { [MISSING_RANGE_ERROR_KEY]: true }; }; validatorFn.controlNames = [controlName]; return validatorFn; } const minActiveDataPointError = { [AT_LEAST_ONE_ACTIVE_ERROR_KEY]: gettext('At least 1 data point must be selected and active for the gauge or the labels.') }; const gaugeRangeError = { [MISSING_RANGE_ERROR_KEY]: gettext('The gauge data point has no min/max range configured. The gauge bar will not display correctly.') }; const infoGaugeWidgetDefinition = { id: defaultWidgetIds.INFO_GAUGE, label: gettext('Info gauge'), description: gettext('Radial gauge and multiple label and value pairs for data points'), loadComponent: () => import('@c8y/ngx-components/widgets/implementations/info-gauge').then(m => m.InfoGaugeWidgetViewComponent), loadConfigComponent: () => import('@c8y/ngx-components/widgets/implementations/info-gauge').then(m => m.InfoGaugeWidgetConfigComponent), previewImage: 'c8y-style-assets/info-gauge-widget-pr.png', resolve: { datapointsLabels: DynamicDatapointsResolver, datapointsGauge: DynamicDatapointsResolver }, errorStrategy: DynamicComponentErrorStrategy.OVERLAY_ERROR, data: { schema: () => import('c8y-schema-loader?interfaceName=InfoGaugeWidgetConfig&type=widget-config!@c8y/ngx-components/widgets/implementations/info-gauge'), export: exportConfigWithTargets, import: importConfigWithTargets, settings: { noNewWidgets: false, widgetDefaults: { _width: 6, _height: 5 }, ng1: { options: { noDeviceTarget: true, groupsSelectable: false } } } } }; const infoGaugeWidgetProviders = [ hookWidget(infoGaugeWidgetDefinition), hookWidgetConfig({ widgetId: defaultWidgetIds.INFO_GAUGE, label: gettext('Gauge`display`'), loadComponent: () => import('@c8y/ngx-components/datapoint-selector').then(m => m.WidgetDatapointsSelectorComponent), initialState: { minActiveCount: 0, defaultFormOptions: DEFAULT_FORM_CONFIG, controlName: DATAPOINTS_GAUGE_CONTROL_NAME }, expanded: true, validators: [ atLeastOneDataPointActive([DATAPOINTS_GAUGE_CONTROL_NAME, DATAPOINTS_LABELS_CONTROL_NAME]), gaugeDatapointHasRange(DATAPOINTS_GAUGE_CONTROL_NAME) ], validationErrors: { ...minActiveDataPointError, ...gaugeRangeError }, priority: 80 }), hookWidgetConfig({ widgetId: defaultWidgetIds.INFO_GAUGE, label: gettext('Multiple label and value pairs'), loadComponent: () => import('@c8y/ngx-components/datapoint-selector').then(m => m.WidgetDatapointsSelectorComponent), initialState: { minActiveCount: 0, defaultFormOptions: DEFAULT_FORM_CONFIG, controlName: DATAPOINTS_LABELS_CONTROL_NAME }, validators: [ atLeastOneDataPointActive([DATAPOINTS_GAUGE_CONTROL_NAME, DATAPOINTS_LABELS_CONTROL_NAME]) ], validationErrors: minActiveDataPointError, priority: 80 }) ]; /** * Generated bundle index. Do not edit. */ export { infoGaugeWidgetDefinition, infoGaugeWidgetProviders }; //# sourceMappingURL=c8y-ngx-components-widgets-definitions-info-gauge.mjs.map