Merge pull request #14017 from ArtemDzhereleiko/AD/imp/api-usage-deff
Add deffinition for api usage widget and fixed dashboard
This commit is contained in:
commit
4269f182dc
@ -50,6 +50,7 @@ $warning-color: #FAA405;
|
||||
color: $enabled-color;
|
||||
}
|
||||
.mat-mdc-progress-bar {
|
||||
--mdc-linear-progress-track-color: #{rgba($enabled-color, 0.06)};
|
||||
--mdc-linear-progress-active-indicator-color: #{$enabled-color};
|
||||
}
|
||||
}
|
||||
@ -58,6 +59,7 @@ $warning-color: #FAA405;
|
||||
color: $disabled-color;
|
||||
}
|
||||
.mat-mdc-progress-bar {
|
||||
--mdc-linear-progress-track-color: #{rgba($disabled-color, 0.06)};
|
||||
--mdc-linear-progress-active-indicator-color: #{$disabled-color};
|
||||
}
|
||||
}
|
||||
@ -66,6 +68,7 @@ $warning-color: #FAA405;
|
||||
color: $warning-color;
|
||||
}
|
||||
.mat-mdc-progress-bar {
|
||||
--mdc-linear-progress-track-color: #{rgba($warning-color, 0.06)};
|
||||
--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 { ImagePipe } from '@shared/pipe/image.pipe';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { DataKey, DatasourceType, widgetType } from "@shared/models/widget.models";
|
||||
import { WidgetSubscriptionOptions } from "@core/api/widget-api.models";
|
||||
import { formattedDataFormDatasourceData } from "@core/utils";
|
||||
import { DatasourceType, widgetType } from '@shared/models/widget.models';
|
||||
import { WidgetSubscriptionOptions } from '@core/api/widget-api.models';
|
||||
import { formattedDataFormDatasourceData } from '@core/utils';
|
||||
|
||||
import { UtilsService } from "@core/services/utils.service";
|
||||
import { UtilsService } from '@core/services/utils.service';
|
||||
import {
|
||||
ApiUsageDataKeysSettings,
|
||||
apiUsageDefaultSettings,
|
||||
ApiUsageWidgetSettings
|
||||
} from "@home/components/widget/lib/settings/cards/api-usage-settings.component.models";
|
||||
ApiUsageWidgetSettings,
|
||||
getUniqueDataKeys
|
||||
} from '@home/components/widget/lib/settings/cards/api-usage-settings.component.models';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-api-usage-widget',
|
||||
@ -80,7 +80,7 @@ export class ApiUsageWidgetComponent implements OnInit, OnDestroy {
|
||||
type: DatasourceType.entity,
|
||||
name: '',
|
||||
entityAliasId: this.settings.dsEntityAliasId,
|
||||
dataKeys: this.getUniqueDataKeys(this.settings.dataKeys)
|
||||
dataKeys: getUniqueDataKeys(this.settings.apiUsageDataKeys)
|
||||
}
|
||||
|
||||
const apiUsageSubscriptionOptions: WidgetSubscriptionOptions = {
|
||||
@ -122,7 +122,7 @@ export class ApiUsageWidgetComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
parseApiUsages() {
|
||||
this.settings.dataKeys.forEach((key) => {
|
||||
this.settings.apiUsageDataKeys.forEach((key) => {
|
||||
this.apiUsages.push({
|
||||
label: this.utils.customTranslation(key.label, key.label),
|
||||
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() {
|
||||
if (this.contentResize$) {
|
||||
this.contentResize$.disconnect();
|
||||
|
||||
@ -17,10 +17,10 @@
|
||||
import { IAliasController } from '@core/api/widget-api.models';
|
||||
import { WidgetConfigCallbacks } from '@home/components/widget/config/widget-config.component.models';
|
||||
import { DataKey, Widget, widgetType } from '@shared/models/widget.models';
|
||||
import { Observable } from "rxjs";
|
||||
import { BackgroundSettings, BackgroundType } from "@shared/models/widget-settings.models";
|
||||
import { DataKeyType } from "@shared/models/telemetry/telemetry.models";
|
||||
import { materialColors } from "@shared/models/material.models";
|
||||
import { Observable } from 'rxjs';
|
||||
import { BackgroundSettings, BackgroundType } from '@shared/models/widget-settings.models';
|
||||
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
|
||||
import { materialColors } from '@shared/models/material.models';
|
||||
|
||||
export interface ApiUsageSettingsContext {
|
||||
aliasController: IAliasController;
|
||||
@ -33,7 +33,7 @@ export interface ApiUsageSettingsContext {
|
||||
|
||||
export interface ApiUsageWidgetSettings {
|
||||
dsEntityAliasId: string;
|
||||
dataKeys: ApiUsageDataKeysSettings[];
|
||||
apiUsageDataKeys: ApiUsageDataKeysSettings[];
|
||||
targetDashboardState: string;
|
||||
background: BackgroundSettings;
|
||||
padding: string;
|
||||
@ -80,7 +80,7 @@ const generateDataKey = (label: string, status: string, maxLimit: string, curren
|
||||
|
||||
export const apiUsageDefaultSettings: ApiUsageWidgetSettings = {
|
||||
dsEntityAliasId: '',
|
||||
dataKeys: [
|
||||
apiUsageDataKeys: [
|
||||
generateDataKey('{i18n:api-usage.transport-messages}', 'transportApiState', 'transportMsgLimit', 'transportMsgCount'),
|
||||
generateDataKey('{i18n:api-usage.transport-data-points}', 'transportApiState', 'transportDataPointsLimit', 'transportDataPointsCount'),
|
||||
generateDataKey('{i18n:api-usage.rule-engine-executions}', 'ruleEngineApiState', 'ruleEngineExecutionLimit', 'ruleEngineExecutionCount'),
|
||||
@ -104,3 +104,15 @@ export const apiUsageDefaultSettings: ApiUsageWidgetSettings = {
|
||||
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,
|
||||
apiUsageDefaultSettings,
|
||||
ApiUsageSettingsContext
|
||||
} from "@home/components/widget/lib/settings/cards/api-usage-settings.component.models";
|
||||
import { deepClone } from "@core/utils";
|
||||
import { Observable, of } from "rxjs";
|
||||
} from '@home/components/widget/lib/settings/cards/api-usage-settings.component.models';
|
||||
import { deepClone } from '@core/utils';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import {
|
||||
DataKeyConfigDialogComponent,
|
||||
DataKeyConfigDialogData
|
||||
} from "@home/components/widget/lib/settings/common/key/data-key-config-dialog.component";
|
||||
import { MatDialog } from "@angular/material/dialog";
|
||||
import { CdkDragDrop } from "@angular/cdk/drag-drop";
|
||||
} from '@home/components/widget/lib/settings/common/key/data-key-config-dialog.component';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-api-usage-widget-settings',
|
||||
@ -82,11 +82,11 @@ export class ApiUsageWidgetSettingsComponent extends WidgetSettingsComponent {
|
||||
}
|
||||
|
||||
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 {
|
||||
return this.apiUsageWidgetSettingsForm.get('dataKeys') as UntypedFormArray;
|
||||
return this.apiUsageWidgetSettingsForm.get('apiUsageDataKeys') as UntypedFormArray;
|
||||
}
|
||||
|
||||
trackByDataKey(index: number): any {
|
||||
@ -104,7 +104,7 @@ export class ApiUsageWidgetSettingsComponent extends WidgetSettingsComponent {
|
||||
}
|
||||
|
||||
removeDataKey(index: number) {
|
||||
(this.apiUsageWidgetSettingsForm.get('dataKeys') as UntypedFormArray).removeAt(index);
|
||||
(this.apiUsageWidgetSettingsForm.get('apiUsageDataKeys') as UntypedFormArray).removeAt(index);
|
||||
}
|
||||
|
||||
addDataKey() {
|
||||
@ -115,7 +115,7 @@ export class ApiUsageWidgetSettingsComponent extends WidgetSettingsComponent {
|
||||
maxLimit: 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()]);
|
||||
dataKeysArray.push(dataKeyControl);
|
||||
}
|
||||
@ -131,7 +131,7 @@ export class ApiUsageWidgetSettingsComponent extends WidgetSettingsComponent {
|
||||
protected prepareInputSettings(settings: WidgetSettings): WidgetSettings {
|
||||
return {
|
||||
dsEntityAliasId: settings?.dsEntityAliasId,
|
||||
dataKeys: settings?.dataKeys,
|
||||
apiUsageDataKeys: settings?.apiUsageDataKeys,
|
||||
targetDashboardState: settings?.targetDashboardState,
|
||||
background: settings?.background,
|
||||
padding: settings.padding
|
||||
@ -141,7 +141,7 @@ export class ApiUsageWidgetSettingsComponent extends WidgetSettingsComponent {
|
||||
protected onSettingsSet(settings: WidgetSettings) {
|
||||
this.apiUsageWidgetSettingsForm = this.fb.group({
|
||||
dsEntityAliasId: [settings?.dsEntityAliasId],
|
||||
dataKeys: this.prepareDataKeysFormArray(settings?.dataKeys),
|
||||
apiUsageDataKeys: this.prepareDataKeysFormArray(settings?.apiUsageDataKeys),
|
||||
targetDashboardState: [settings?.targetDashboardState],
|
||||
background: [settings?.background, []],
|
||||
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 { Filters } from '@shared/models/query/query.models';
|
||||
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> {
|
||||
testWidget(widget: Widget): boolean;
|
||||
@ -29,7 +30,8 @@ export interface WidgetModelDefinition<T = any> {
|
||||
}
|
||||
|
||||
const widgetModelRegistry: WidgetModelDefinition[] = [
|
||||
MapModelDefinition
|
||||
MapModelDefinition,
|
||||
ApiUsageModelDefinition
|
||||
];
|
||||
|
||||
export const findWidgetModelDefinition = (widget: Widget): WidgetModelDefinition => {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -9604,7 +9604,8 @@
|
||||
"add-key": "Add key",
|
||||
"no-key": "No 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": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user