thingsboard/ui-ngx/src/app/shared/models/widget.models.ts
2021-03-02 13:21:53 +02:00

442 lines
10 KiB
TypeScript

///
/// Copyright © 2016-2021 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { BaseData } from '@shared/models/base-data';
import { TenantId } from '@shared/models/id/tenant-id';
import { WidgetTypeId } from '@shared/models/id/widget-type-id';
import { Timewindow } from '@shared/models/time/time.models';
import { EntityType } from '@shared/models/entity-type.models';
import { AlarmSearchStatus, AlarmSeverity } from '@shared/models/alarm.models';
import { DataKeyType } from './telemetry/telemetry.models';
import { EntityId } from '@shared/models/id/entity-id';
import * as moment_ from 'moment';
import { EntityDataPageLink, EntityFilter, KeyFilter } from '@shared/models/query/query.models';
export enum widgetType {
timeseries = 'timeseries',
latest = 'latest',
rpc = 'rpc',
alarm = 'alarm',
static = 'static'
}
export interface WidgetTypeTemplate {
bundleAlias: string;
alias: string;
}
export interface WidgetTypeData {
name: string;
icon: string;
isMdiIcon?: boolean;
configHelpLinkId: string;
template: WidgetTypeTemplate;
}
export const widgetTypesData = new Map<widgetType, WidgetTypeData>(
[
[
widgetType.timeseries,
{
name: 'widget.timeseries',
icon: 'timeline',
configHelpLinkId: 'widgetsConfigTimeseries',
template: {
bundleAlias: 'charts',
alias: 'basic_timeseries'
}
}
],
[
widgetType.latest,
{
name: 'widget.latest-values',
icon: 'track_changes',
configHelpLinkId: 'widgetsConfigLatest',
template: {
bundleAlias: 'cards',
alias: 'attributes_card'
}
}
],
[
widgetType.rpc,
{
name: 'widget.rpc',
icon: 'mdi:developer-board',
configHelpLinkId: 'widgetsConfigRpc',
isMdiIcon: true,
template: {
bundleAlias: 'gpio_widgets',
alias: 'basic_gpio_control'
}
}
],
[
widgetType.alarm,
{
name: 'widget.alarm',
icon: 'error',
configHelpLinkId: 'widgetsConfigAlarm',
template: {
bundleAlias: 'alarm_widgets',
alias: 'alarms_table'
}
}
],
[
widgetType.static,
{
name: 'widget.static',
icon: 'font_download',
configHelpLinkId: 'widgetsConfigStatic',
template: {
bundleAlias: 'cards',
alias: 'html_card'
}
}
]
]
);
export interface WidgetResource {
url: string;
isModule?: boolean;
}
export interface WidgetActionSource {
name: string;
value: string;
multiple: boolean;
}
export const widgetActionSources: {[acionSourceId: string]: WidgetActionSource} = {
headerButton:
{
name: 'widget-action.header-button',
value: 'headerButton',
multiple: true,
}
};
export interface WidgetTypeDescriptor {
type: widgetType;
resources: Array<WidgetResource>;
templateHtml: string;
templateCss: string;
controllerScript: string;
settingsSchema?: string | any;
dataKeySettingsSchema?: string | any;
defaultConfig: string;
sizeX: number;
sizeY: number;
}
export interface WidgetTypeParameters {
useCustomDatasources?: boolean;
maxDatasources?: number;
maxDataKeys?: number;
dataKeysOptional?: boolean;
stateData?: boolean;
hasDataPageLink?: boolean;
singleEntity?: boolean;
warnOnPageDataOverflow?: boolean;
ignoreDataUpdateOnIntervalTick?: boolean;
}
export interface WidgetControllerDescriptor {
widgetTypeFunction?: any;
settingsSchema?: string | any;
dataKeySettingsSchema?: string | any;
typeParameters?: WidgetTypeParameters;
actionSources?: {[actionSourceId: string]: WidgetActionSource};
}
export interface WidgetType extends BaseData<WidgetTypeId> {
tenantId: TenantId;
bundleAlias: string;
alias: string;
name: string;
descriptor: WidgetTypeDescriptor;
}
export enum LegendDirection {
column = 'column',
row = 'row'
}
export const legendDirectionTranslationMap = new Map<LegendDirection, string>(
[
[ LegendDirection.column, 'direction.column' ],
[ LegendDirection.row, 'direction.row' ]
]
);
export enum LegendPosition {
top = 'top',
bottom = 'bottom',
left = 'left',
right = 'right'
}
export const legendPositionTranslationMap = new Map<LegendPosition, string>(
[
[ LegendPosition.top, 'position.top' ],
[ LegendPosition.bottom, 'position.bottom' ],
[ LegendPosition.left, 'position.left' ],
[ LegendPosition.right, 'position.right' ]
]
);
export interface LegendConfig {
position: LegendPosition;
direction?: LegendDirection;
sortDataKeys: boolean;
showMin: boolean;
showMax: boolean;
showAvg: boolean;
showTotal: boolean;
}
export function defaultLegendConfig(wType: widgetType): LegendConfig {
return {
direction: LegendDirection.column,
position: LegendPosition.bottom,
sortDataKeys: false,
showMin: false,
showMax: false,
showAvg: wType === widgetType.timeseries,
showTotal: false
};
}
export interface KeyInfo {
name: string;
label?: string;
color?: string;
funcBody?: string;
postFuncBody?: string;
units?: string;
decimals?: number;
}
export interface DataKey extends KeyInfo {
type: DataKeyType;
pattern?: string;
settings?: any;
usePostProcessing?: boolean;
hidden?: boolean;
inLegend?: boolean;
isAdditional?: boolean;
origDataKeyIndex?: number;
_hash?: number;
}
export enum DatasourceType {
function = 'function',
entity = 'entity'
}
export const datasourceTypeTranslationMap = new Map<DatasourceType, string>(
[
[ DatasourceType.function, 'function.function' ],
[ DatasourceType.entity, 'entity.entity' ]
]
);
export interface Datasource {
type?: DatasourceType | any;
name?: string;
aliasName?: string;
dataKeys?: Array<DataKey>;
entityType?: EntityType;
entityId?: string;
entityName?: string;
entityAliasId?: string;
filterId?: string;
unresolvedStateEntity?: boolean;
dataReceived?: boolean;
entity?: BaseData<EntityId>;
entityLabel?: string;
entityDescription?: string;
generated?: boolean;
isAdditional?: boolean;
origDatasourceIndex?: number;
pageLink?: EntityDataPageLink;
keyFilters?: Array<KeyFilter>;
entityFilter?: EntityFilter;
dataKeyStartIndex?: number;
[key: string]: any;
}
export type DataSet = [number, any][];
export interface DataSetHolder {
data: DataSet;
}
export interface DatasourceData extends DataSetHolder {
datasource: Datasource;
dataKey: DataKey;
}
export interface LegendKey {
dataKey: DataKey;
dataIndex: number;
}
export interface LegendKeyData {
min: string;
max: string;
avg: string;
total: string;
hidden: boolean;
}
export interface LegendData {
keys: Array<LegendKey>;
data: Array<LegendKeyData>;
}
export enum WidgetActionType {
openDashboardState = 'openDashboardState',
updateDashboardState = 'updateDashboardState',
openDashboard = 'openDashboard',
custom = 'custom',
customPretty = 'customPretty'
}
export const widgetActionTypeTranslationMap = new Map<WidgetActionType, string>(
[
[ WidgetActionType.openDashboardState, 'widget-action.open-dashboard-state' ],
[ WidgetActionType.updateDashboardState, 'widget-action.update-dashboard-state' ],
[ WidgetActionType.openDashboard, 'widget-action.open-dashboard' ],
[ WidgetActionType.custom, 'widget-action.custom' ],
[ WidgetActionType.customPretty, 'widget-action.custom-pretty' ]
]
);
export interface CustomActionDescriptor {
customFunction?: string;
customResources?: Array<WidgetResource>;
customHtml?: string;
customCss?: string;
}
export interface WidgetActionDescriptor extends CustomActionDescriptor {
id: string;
name: string;
icon: string;
displayName?: string;
type: WidgetActionType;
targetDashboardId?: string;
targetDashboardStateId?: string;
openRightLayout?: boolean;
openNewBrowserTab?: boolean;
openInSeparateDialog?: boolean;
dialogTitle?: string;
dialogHideDashboardToolbar?: boolean;
dialogWidth?: number;
dialogHeight?: number;
setEntityId?: boolean;
stateEntityParamName?: string;
}
export interface WidgetComparisonSettings {
comparisonEnabled?: boolean;
timeForComparison?: moment_.unitOfTime.DurationConstructor;
}
export interface WidgetConfig {
title?: string;
titleIcon?: string;
showTitle?: boolean;
showTitleIcon?: boolean;
iconColor?: string;
iconSize?: string;
titleTooltip?: string;
dropShadow?: boolean;
enableFullscreen?: boolean;
useDashboardTimewindow?: boolean;
displayTimewindow?: boolean;
showLegend?: boolean;
legendConfig?: LegendConfig;
timewindow?: Timewindow;
mobileHeight?: number;
mobileOrder?: number;
color?: string;
backgroundColor?: string;
padding?: string;
margin?: string;
widgetStyle?: {[klass: string]: any};
titleStyle?: {[klass: string]: any};
units?: string;
decimals?: number;
actions?: {[actionSourceId: string]: Array<WidgetActionDescriptor>};
settings?: any;
alarmSource?: Datasource;
alarmStatusList?: AlarmSearchStatus[];
alarmSeverityList?: AlarmSeverity[];
alarmTypeList?: string[];
searchPropagatedAlarms?: boolean;
datasources?: Array<Datasource>;
targetDeviceAliasIds?: Array<string>;
[key: string]: any;
}
export interface Widget {
id?: string;
typeId?: WidgetTypeId;
isSystemType: boolean;
bundleAlias: string;
typeAlias: string;
type: widgetType;
title: string;
sizeX: number;
sizeY: number;
row: number;
col: number;
config: WidgetConfig;
}
export interface GroupInfo {
formIndex: number;
GroupTitle: string;
}
export interface JsonSchema {
type: string;
title?: string;
properties: {[key: string]: any};
required?: string[];
}
export interface JsonSettingsSchema {
schema?: JsonSchema;
form?: any[];
groupInfoes?: GroupInfo[]
}
export interface WidgetPosition {
row: number;
column: number;
}
export interface WidgetSize {
sizeX: number;
sizeY: number;
}