UI: Add deffinition for api usage
This commit is contained in:
parent
1bfb969245
commit
3d0f643e7a
@ -50,6 +50,7 @@ $warning-color: #FAA405;
|
|||||||
color: $enabled-color;
|
color: $enabled-color;
|
||||||
}
|
}
|
||||||
.mat-mdc-progress-bar {
|
.mat-mdc-progress-bar {
|
||||||
|
--mdc-linear-progress-track-color: #{rgba($enabled-color, 0.06)};
|
||||||
--mdc-linear-progress-active-indicator-color: #{$enabled-color};
|
--mdc-linear-progress-active-indicator-color: #{$enabled-color};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,6 +59,7 @@ $warning-color: #FAA405;
|
|||||||
color: $disabled-color;
|
color: $disabled-color;
|
||||||
}
|
}
|
||||||
.mat-mdc-progress-bar {
|
.mat-mdc-progress-bar {
|
||||||
|
--mdc-linear-progress-track-color: #{rgba($disabled-color, 0.06)};
|
||||||
--mdc-linear-progress-active-indicator-color: #{$disabled-color};
|
--mdc-linear-progress-active-indicator-color: #{$disabled-color};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,6 +68,7 @@ $warning-color: #FAA405;
|
|||||||
color: $warning-color;
|
color: $warning-color;
|
||||||
}
|
}
|
||||||
.mat-mdc-progress-bar {
|
.mat-mdc-progress-bar {
|
||||||
|
--mdc-linear-progress-track-color: #{rgba($warning-color, 0.06)};
|
||||||
--mdc-linear-progress-active-indicator-color: #{$warning-color};
|
--mdc-linear-progress-active-indicator-color: #{$warning-color};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,16 +20,16 @@ import { backgroundStyle, ComponentStyle, overlayStyle } from '@shared/models/wi
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { ImagePipe } from '@shared/pipe/image.pipe';
|
import { ImagePipe } from '@shared/pipe/image.pipe';
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
import { DataKey, DatasourceType, widgetType } from "@shared/models/widget.models";
|
import { DatasourceType, widgetType } from '@shared/models/widget.models';
|
||||||
import { WidgetSubscriptionOptions } from "@core/api/widget-api.models";
|
import { WidgetSubscriptionOptions } from '@core/api/widget-api.models';
|
||||||
import { formattedDataFormDatasourceData } from "@core/utils";
|
import { formattedDataFormDatasourceData } from '@core/utils';
|
||||||
|
|
||||||
import { UtilsService } from "@core/services/utils.service";
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
import {
|
import {
|
||||||
ApiUsageDataKeysSettings,
|
|
||||||
apiUsageDefaultSettings,
|
apiUsageDefaultSettings,
|
||||||
ApiUsageWidgetSettings
|
ApiUsageWidgetSettings,
|
||||||
} from "@home/components/widget/lib/settings/cards/api-usage-settings.component.models";
|
getUniqueDataKeys
|
||||||
|
} from '@home/components/widget/lib/settings/cards/api-usage-settings.component.models';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-api-usage-widget',
|
selector: 'tb-api-usage-widget',
|
||||||
@ -80,7 +80,7 @@ export class ApiUsageWidgetComponent implements OnInit, OnDestroy {
|
|||||||
type: DatasourceType.entity,
|
type: DatasourceType.entity,
|
||||||
name: '',
|
name: '',
|
||||||
entityAliasId: this.settings.dsEntityAliasId,
|
entityAliasId: this.settings.dsEntityAliasId,
|
||||||
dataKeys: this.getUniqueDataKeys(this.settings.dataKeys)
|
dataKeys: getUniqueDataKeys(this.settings.apiUsageDataKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiUsageSubscriptionOptions: WidgetSubscriptionOptions = {
|
const apiUsageSubscriptionOptions: WidgetSubscriptionOptions = {
|
||||||
@ -122,7 +122,7 @@ export class ApiUsageWidgetComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parseApiUsages() {
|
parseApiUsages() {
|
||||||
this.settings.dataKeys.forEach((key) => {
|
this.settings.apiUsageDataKeys.forEach((key) => {
|
||||||
this.apiUsages.push({
|
this.apiUsages.push({
|
||||||
label: this.utils.customTranslation(key.label, key.label),
|
label: this.utils.customTranslation(key.label, key.label),
|
||||||
state: key.state,
|
state: key.state,
|
||||||
@ -134,20 +134,6 @@ export class ApiUsageWidgetComponent implements OnInit, OnDestroy {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getUniqueDataKeys(data: ApiUsageDataKeysSettings[]): DataKey[] {
|
|
||||||
const seenNames = new Set<string>();
|
|
||||||
return data
|
|
||||||
.flatMap(item => [item.status, item.maxLimit, item.current])
|
|
||||||
.filter(key => {
|
|
||||||
if (seenNames.has(key.name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
seenNames.add(key.name);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
if (this.contentResize$) {
|
if (this.contentResize$) {
|
||||||
this.contentResize$.disconnect();
|
this.contentResize$.disconnect();
|
||||||
|
|||||||
@ -17,10 +17,10 @@
|
|||||||
import { IAliasController } from '@core/api/widget-api.models';
|
import { IAliasController } from '@core/api/widget-api.models';
|
||||||
import { WidgetConfigCallbacks } from '@home/components/widget/config/widget-config.component.models';
|
import { WidgetConfigCallbacks } from '@home/components/widget/config/widget-config.component.models';
|
||||||
import { DataKey, Widget, widgetType } from '@shared/models/widget.models';
|
import { DataKey, Widget, widgetType } from '@shared/models/widget.models';
|
||||||
import { Observable } from "rxjs";
|
import { Observable } from 'rxjs';
|
||||||
import { BackgroundSettings, BackgroundType } from "@shared/models/widget-settings.models";
|
import { BackgroundSettings, BackgroundType } from '@shared/models/widget-settings.models';
|
||||||
import { DataKeyType } from "@shared/models/telemetry/telemetry.models";
|
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
|
||||||
import { materialColors } from "@shared/models/material.models";
|
import { materialColors } from '@shared/models/material.models';
|
||||||
|
|
||||||
export interface ApiUsageSettingsContext {
|
export interface ApiUsageSettingsContext {
|
||||||
aliasController: IAliasController;
|
aliasController: IAliasController;
|
||||||
@ -33,7 +33,7 @@ export interface ApiUsageSettingsContext {
|
|||||||
|
|
||||||
export interface ApiUsageWidgetSettings {
|
export interface ApiUsageWidgetSettings {
|
||||||
dsEntityAliasId: string;
|
dsEntityAliasId: string;
|
||||||
dataKeys: ApiUsageDataKeysSettings[];
|
apiUsageDataKeys: ApiUsageDataKeysSettings[];
|
||||||
targetDashboardState: string;
|
targetDashboardState: string;
|
||||||
background: BackgroundSettings;
|
background: BackgroundSettings;
|
||||||
padding: string;
|
padding: string;
|
||||||
@ -80,7 +80,7 @@ const generateDataKey = (label: string, status: string, maxLimit: string, curren
|
|||||||
|
|
||||||
export const apiUsageDefaultSettings: ApiUsageWidgetSettings = {
|
export const apiUsageDefaultSettings: ApiUsageWidgetSettings = {
|
||||||
dsEntityAliasId: '',
|
dsEntityAliasId: '',
|
||||||
dataKeys: [
|
apiUsageDataKeys: [
|
||||||
generateDataKey('{i18n:api-usage.transport-messages}', 'transportApiState', 'transportMsgLimit', 'transportMsgCount'),
|
generateDataKey('{i18n:api-usage.transport-messages}', 'transportApiState', 'transportMsgLimit', 'transportMsgCount'),
|
||||||
generateDataKey('{i18n:api-usage.transport-data-points}', 'transportApiState', 'transportDataPointsLimit', 'transportDataPointsCount'),
|
generateDataKey('{i18n:api-usage.transport-data-points}', 'transportApiState', 'transportDataPointsLimit', 'transportDataPointsCount'),
|
||||||
generateDataKey('{i18n:api-usage.rule-engine-executions}', 'ruleEngineApiState', 'ruleEngineExecutionLimit', 'ruleEngineExecutionCount'),
|
generateDataKey('{i18n:api-usage.rule-engine-executions}', 'ruleEngineApiState', 'ruleEngineExecutionLimit', 'ruleEngineExecutionCount'),
|
||||||
@ -104,3 +104,15 @@ export const apiUsageDefaultSettings: ApiUsageWidgetSettings = {
|
|||||||
padding: '0'
|
padding: '0'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getUniqueDataKeys = (data: ApiUsageDataKeysSettings[]): DataKey[] => {
|
||||||
|
const seenNames = new Set<string>();
|
||||||
|
return data
|
||||||
|
.flatMap(item => [item.status, item.maxLimit, item.current])
|
||||||
|
.filter(key => {
|
||||||
|
if (seenNames.has(key.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seenNames.add(key.name);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@ -37,15 +37,15 @@ import {
|
|||||||
ApiUsageDataKeysSettings,
|
ApiUsageDataKeysSettings,
|
||||||
apiUsageDefaultSettings,
|
apiUsageDefaultSettings,
|
||||||
ApiUsageSettingsContext
|
ApiUsageSettingsContext
|
||||||
} from "@home/components/widget/lib/settings/cards/api-usage-settings.component.models";
|
} from '@home/components/widget/lib/settings/cards/api-usage-settings.component.models';
|
||||||
import { deepClone } from "@core/utils";
|
import { deepClone } from '@core/utils';
|
||||||
import { Observable, of } from "rxjs";
|
import { Observable, of } from 'rxjs';
|
||||||
import {
|
import {
|
||||||
DataKeyConfigDialogComponent,
|
DataKeyConfigDialogComponent,
|
||||||
DataKeyConfigDialogData
|
DataKeyConfigDialogData
|
||||||
} from "@home/components/widget/lib/settings/common/key/data-key-config-dialog.component";
|
} from '@home/components/widget/lib/settings/common/key/data-key-config-dialog.component';
|
||||||
import { MatDialog } from "@angular/material/dialog";
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { CdkDragDrop } from "@angular/cdk/drag-drop";
|
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-api-usage-widget-settings',
|
selector: 'tb-api-usage-widget-settings',
|
||||||
@ -82,11 +82,11 @@ export class ApiUsageWidgetSettingsComponent extends WidgetSettingsComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected doUpdateSettings(settingsForm: UntypedFormGroup, settings: WidgetSettings) {
|
protected doUpdateSettings(settingsForm: UntypedFormGroup, settings: WidgetSettings) {
|
||||||
settingsForm.setControl('dataKeys', this.prepareDataKeysFormArray(settings?.dataKeys), {emitEvent: false});
|
settingsForm.setControl('apiUsageDataKeys', this.prepareDataKeysFormArray(settings?.apiUsageDataKeys), {emitEvent: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
dataKeysFormArray(): UntypedFormArray {
|
dataKeysFormArray(): UntypedFormArray {
|
||||||
return this.apiUsageWidgetSettingsForm.get('dataKeys') as UntypedFormArray;
|
return this.apiUsageWidgetSettingsForm.get('apiUsageDataKeys') as UntypedFormArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
trackByDataKey(index: number): any {
|
trackByDataKey(index: number): any {
|
||||||
@ -104,7 +104,7 @@ export class ApiUsageWidgetSettingsComponent extends WidgetSettingsComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeDataKey(index: number) {
|
removeDataKey(index: number) {
|
||||||
(this.apiUsageWidgetSettingsForm.get('dataKeys') as UntypedFormArray).removeAt(index);
|
(this.apiUsageWidgetSettingsForm.get('apiUsageDataKeys') as UntypedFormArray).removeAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
addDataKey() {
|
addDataKey() {
|
||||||
@ -115,7 +115,7 @@ export class ApiUsageWidgetSettingsComponent extends WidgetSettingsComponent {
|
|||||||
maxLimit: null,
|
maxLimit: null,
|
||||||
current: null
|
current: null
|
||||||
};
|
};
|
||||||
const dataKeysArray = this.apiUsageWidgetSettingsForm.get('dataKeys') as UntypedFormArray;
|
const dataKeysArray = this.apiUsageWidgetSettingsForm.get('apiUsageDataKeys') as UntypedFormArray;
|
||||||
const dataKeyControl = this.fb.control(dataKey, [this.apiUsageDataKeyValidator()]);
|
const dataKeyControl = this.fb.control(dataKey, [this.apiUsageDataKeyValidator()]);
|
||||||
dataKeysArray.push(dataKeyControl);
|
dataKeysArray.push(dataKeyControl);
|
||||||
}
|
}
|
||||||
@ -131,7 +131,7 @@ export class ApiUsageWidgetSettingsComponent extends WidgetSettingsComponent {
|
|||||||
protected prepareInputSettings(settings: WidgetSettings): WidgetSettings {
|
protected prepareInputSettings(settings: WidgetSettings): WidgetSettings {
|
||||||
return {
|
return {
|
||||||
dsEntityAliasId: settings?.dsEntityAliasId,
|
dsEntityAliasId: settings?.dsEntityAliasId,
|
||||||
dataKeys: settings?.dataKeys,
|
apiUsageDataKeys: settings?.apiUsageDataKeys,
|
||||||
targetDashboardState: settings?.targetDashboardState,
|
targetDashboardState: settings?.targetDashboardState,
|
||||||
background: settings?.background,
|
background: settings?.background,
|
||||||
padding: settings.padding
|
padding: settings.padding
|
||||||
@ -141,7 +141,7 @@ export class ApiUsageWidgetSettingsComponent extends WidgetSettingsComponent {
|
|||||||
protected onSettingsSet(settings: WidgetSettings) {
|
protected onSettingsSet(settings: WidgetSettings) {
|
||||||
this.apiUsageWidgetSettingsForm = this.fb.group({
|
this.apiUsageWidgetSettingsForm = this.fb.group({
|
||||||
dsEntityAliasId: [settings?.dsEntityAliasId],
|
dsEntityAliasId: [settings?.dsEntityAliasId],
|
||||||
dataKeys: this.prepareDataKeysFormArray(settings?.dataKeys),
|
apiUsageDataKeys: this.prepareDataKeysFormArray(settings?.apiUsageDataKeys),
|
||||||
targetDashboardState: [settings?.targetDashboardState],
|
targetDashboardState: [settings?.targetDashboardState],
|
||||||
background: [settings?.background, []],
|
background: [settings?.background, []],
|
||||||
padding: [settings.padding, []]
|
padding: [settings.padding, []]
|
||||||
|
|||||||
@ -0,0 +1,88 @@
|
|||||||
|
///
|
||||||
|
/// Copyright © 2016-2025 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 { EntityAliases, EntityAliasInfo, getEntityAliasId } from '@shared/models/alias.models';
|
||||||
|
import { FilterInfo, Filters } from '@shared/models/query/query.models';
|
||||||
|
import { Dashboard } from '@shared/models/dashboard.models';
|
||||||
|
import { Datasource, DatasourceType, Widget } from '@shared/models/widget.models';
|
||||||
|
import { WidgetModelDefinition } from '@shared/models/widget/widget-model.definition';
|
||||||
|
import {
|
||||||
|
ApiUsageWidgetSettings,
|
||||||
|
getUniqueDataKeys
|
||||||
|
} from '@home/components/widget/lib/settings/cards/api-usage-settings.component.models';
|
||||||
|
|
||||||
|
interface AliasFilterPair {
|
||||||
|
alias?: EntityAliasInfo;
|
||||||
|
filter?: FilterInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ApiUsageDatasourcesInfo {
|
||||||
|
ds?: AliasFilterPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ApiUsageModelDefinition: WidgetModelDefinition<ApiUsageDatasourcesInfo> = {
|
||||||
|
testWidget(widget: Widget): boolean {
|
||||||
|
if (widget?.config?.settings) {
|
||||||
|
const settings = widget.config.settings;
|
||||||
|
if (settings.apiUsageDataKeys && Array.isArray(settings.apiUsageDataKeys)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
prepareExportInfo(dashboard: Dashboard, widget: Widget): ApiUsageDatasourcesInfo {
|
||||||
|
const settings: ApiUsageWidgetSettings = widget.config.settings as ApiUsageWidgetSettings;
|
||||||
|
const info: ApiUsageDatasourcesInfo = {};
|
||||||
|
if (settings.dsEntityAliasId) {
|
||||||
|
info.ds = prepareExportDataSourcesInfo(dashboard, settings.dsEntityAliasId);
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
},
|
||||||
|
updateFromExportInfo(widget: Widget, entityAliases: EntityAliases, filters: Filters, info: ApiUsageDatasourcesInfo): void {
|
||||||
|
const settings: ApiUsageWidgetSettings = widget.config.settings as ApiUsageWidgetSettings;
|
||||||
|
if (info?.ds?.alias) {
|
||||||
|
settings.dsEntityAliasId = getEntityAliasId(entityAliases, info.ds.alias);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
datasources(widget: Widget): Datasource[] {
|
||||||
|
const settings: ApiUsageWidgetSettings = widget.config.settings as ApiUsageWidgetSettings;
|
||||||
|
const datasources: Datasource[] = [];
|
||||||
|
if (settings.apiUsageDataKeys?.length && settings.dsEntityAliasId) {
|
||||||
|
datasources.push({
|
||||||
|
type: DatasourceType.entity,
|
||||||
|
name: '',
|
||||||
|
entityAliasId: settings.dsEntityAliasId,
|
||||||
|
dataKeys: getUniqueDataKeys(settings.apiUsageDataKeys)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return datasources;
|
||||||
|
},
|
||||||
|
hasTimewindow(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const prepareExportDataSourcesInfo = (dashboard: Dashboard, settings: string): AliasFilterPair => {
|
||||||
|
const aliasAndFilter: AliasFilterPair = {};
|
||||||
|
const entityAlias = dashboard.configuration.entityAliases[settings];
|
||||||
|
if (entityAlias) {
|
||||||
|
aliasAndFilter.alias = {
|
||||||
|
alias: entityAlias.alias,
|
||||||
|
filter: entityAlias.filter
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return aliasAndFilter;
|
||||||
|
}
|
||||||
@ -19,6 +19,7 @@ import { Dashboard } from '@shared/models/dashboard.models';
|
|||||||
import { EntityAliases } from '@shared/models/alias.models';
|
import { EntityAliases } from '@shared/models/alias.models';
|
||||||
import { Filters } from '@shared/models/query/query.models';
|
import { Filters } from '@shared/models/query/query.models';
|
||||||
import { MapModelDefinition } from '@shared/models/widget/maps/map-model.definition';
|
import { MapModelDefinition } from '@shared/models/widget/maps/map-model.definition';
|
||||||
|
import { ApiUsageModelDefinition } from '@shared/models/widget/home-widgets/api-usage-model.definition';
|
||||||
|
|
||||||
export interface WidgetModelDefinition<T = any> {
|
export interface WidgetModelDefinition<T = any> {
|
||||||
testWidget(widget: Widget): boolean;
|
testWidget(widget: Widget): boolean;
|
||||||
@ -29,7 +30,8 @@ export interface WidgetModelDefinition<T = any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const widgetModelRegistry: WidgetModelDefinition[] = [
|
const widgetModelRegistry: WidgetModelDefinition[] = [
|
||||||
MapModelDefinition
|
MapModelDefinition,
|
||||||
|
ApiUsageModelDefinition
|
||||||
];
|
];
|
||||||
|
|
||||||
export const findWidgetModelDefinition = (widget: Widget): WidgetModelDefinition => {
|
export const findWidgetModelDefinition = (widget: Widget): WidgetModelDefinition => {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -9544,7 +9544,8 @@
|
|||||||
"add-key": "Add key",
|
"add-key": "Add key",
|
||||||
"no-key": "No key",
|
"no-key": "No key",
|
||||||
"delete-key": "Delete key",
|
"delete-key": "Delete key",
|
||||||
"target-dashboard-state": "Target dashboard state"
|
"target-dashboard-state": "Target dashboard state",
|
||||||
|
"go-to-main-state": "Go to default view"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"color": {
|
"color": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user