diff --git a/ui-ngx/src/app/core/auth/auth.models.ts b/ui-ngx/src/app/core/auth/auth.models.ts
index 55af791156..1944c693ac 100644
--- a/ui-ngx/src/app/core/auth/auth.models.ts
+++ b/ui-ngx/src/app/core/auth/auth.models.ts
@@ -28,6 +28,8 @@ export interface SysParamsState {
userSettings: UserSettings;
maxResourceSize: number;
maxDebugModeDurationMinutes: number;
+ maxDataPointsPerRollingArg: number;
+ maxArgumentsPerCF: number;
ruleChainDebugPerTenantLimitsConfiguration?: string;
}
diff --git a/ui-ngx/src/app/core/auth/auth.reducer.ts b/ui-ngx/src/app/core/auth/auth.reducer.ts
index a460cf35bb..3ecf70074c 100644
--- a/ui-ngx/src/app/core/auth/auth.reducer.ts
+++ b/ui-ngx/src/app/core/auth/auth.reducer.ts
@@ -31,6 +31,8 @@ const emptyUserAuthState: AuthPayload = {
persistDeviceStateToTelemetry: false,
mobileQrEnabled: false,
maxResourceSize: 0,
+ maxArgumentsPerCF: 0,
+ maxDataPointsPerRollingArg: 0,
maxDebugModeDurationMinutes: 0,
userSettings: initialUserSettings
};
diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.html b/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.html
index 96dff1c1be..5510aeb2c2 100644
--- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.html
+++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.html
@@ -119,9 +119,22 @@
}
-
-
diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.scss b/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.scss
index c4efe323c6..877a749afa 100644
--- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.scss
+++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.scss
@@ -30,6 +30,12 @@
}
}
+ .max-args-warning {
+ .mat-icon {
+ color: #FAA405;
+ }
+ }
+
.tb-form-table-row-cell-buttons {
--mat-badge-legacy-small-size-container-size: 8px;
--mat-badge-small-size-container-overlap-offset: -5px;
diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.ts b/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.ts
index 2537f34059..e3b19503af 100644
--- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.ts
+++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.ts
@@ -55,6 +55,9 @@ import { TbPopoverComponent } from '@shared/components/popover.component';
import { TbTableDatasource } from '@shared/components/table/table-datasource.abstract';
import { EntityService } from '@core/http/entity.service';
import { MatSort } from '@angular/material/sort';
+import { getCurrentAuthState } from '@core/auth/auth.selectors';
+import { Store } from '@ngrx/store';
+import { AppState } from '@core/core.state';
@Component({
selector: 'tb-calculated-field-arguments-table',
@@ -93,6 +96,7 @@ export class CalculatedFieldArgumentsTableComponent implements ControlValueAcces
readonly ArgumentEntityType = ArgumentEntityType;
readonly ArgumentType = ArgumentType;
readonly CalculatedFieldType = CalculatedFieldType;
+ readonly maxArgumentsPerCF = getCurrentAuthState(this.store).maxArgumentsPerCF;
private popoverComponent: TbPopoverComponent;
private propagateChange: (argumentsObj: Record) => void = () => {};
@@ -105,6 +109,7 @@ export class CalculatedFieldArgumentsTableComponent implements ControlValueAcces
private renderer: Renderer2,
private entityService: EntityService,
private destroyRef: DestroyRef,
+ private store: Store
) {
this.argumentsFormArray.valueChanges.pipe(takeUntilDestroyed()).subscribe(value => {
this.updateEntityNameMap(value);
diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.html b/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.html
index 72bc85a48f..566a433545 100644
--- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.html
+++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.html
@@ -166,10 +166,19 @@
formControlName="timeWindow"
/>
-
+ @if (maxDataPointsPerRollingArg) {
+
+ }
}
diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.scss b/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.scss
index 1f7c084d08..773489ee60 100644
--- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.scss
+++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.scss
@@ -28,9 +28,7 @@ $panel-width: 520px;
min-width: 120px;
}
}
-}
-:host ::ng-deep {
.limit-field-row {
@media screen and (max-width: $panel-width) {
display: flex;
@@ -42,7 +40,9 @@ $panel-width: 520px;
}
}
}
+}
+:host ::ng-deep {
.time-interval-field {
.advanced-input {
flex-direction: column;
diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.ts b/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.ts
index 93b8f897ce..9d9614ba28 100644
--- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.ts
+++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/panel/calculated-field-argument-panel.component.ts
@@ -38,7 +38,9 @@ import { EntityFilter } from '@shared/models/query/query.models';
import { AliasFilterType } from '@shared/models/alias.models';
import { merge } from 'rxjs';
import { MINUTE } from '@shared/models/time/time.models';
-import { TimeService } from '@core/services/time.service';
+import { getCurrentAuthState } from '@core/auth/auth.selectors';
+import { AppState } from '@core/core.state';
+import { Store } from '@ngrx/store';
@Component({
selector: 'tb-calculated-field-argument-panel',
@@ -58,7 +60,8 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit {
argumentsDataApplied = output<{ value: CalculatedFieldArgumentValue, index: number }>();
- readonly defaultLimit = Math.max(this.timeService.getMinDatapointsLimit(), Math.floor(this.timeService.getMaxDatapointsLimit() / 10));
+ readonly maxDataPointsPerRollingArg = getCurrentAuthState(this.store).maxDataPointsPerRollingArg;
+ readonly defaultLimit = Math.floor(this.maxDataPointsPerRollingArg / 10);
argumentFormGroup = this.fb.group({
argumentName: ['', [Validators.required, this.uniqNameRequired(), Validators.pattern(charsWithNumRegex), Validators.maxLength(255)]],
@@ -72,7 +75,7 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit {
scope: [{ value: AttributeScope.SERVER_SCOPE, disabled: true }, [Validators.required]],
}),
defaultValue: ['', [Validators.pattern(noLeadTrailSpacesRegex)]],
- limit: [this.defaultLimit],
+ limit: [{ value: this.defaultLimit, disabled: !this.maxDataPointsPerRollingArg }],
timeWindow: [MINUTE * 15],
});
@@ -96,7 +99,7 @@ export class CalculatedFieldArgumentPanelComponent implements OnInit {
private fb: FormBuilder,
private cd: ChangeDetectorRef,
private popover: TbPopoverComponent,
- private timeService: TimeService
+ private store: Store
) {
this.observeEntityFilterChanges();
this.observeEntityTypeChanges()
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html
index 9f1839afec..64d5039914 100644
--- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html
+++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.html
@@ -229,6 +229,92 @@
+
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts
index 4cce34c502..b1d6652e4a 100644
--- a/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts
+++ b/ui-ngx/src/app/modules/home/components/profile/tenant/default-tenant-profile-configuration.component.ts
@@ -118,7 +118,13 @@ export class DefaultTenantProfileConfigurationComponent implements ControlValueA
edgeEventRateLimits: [null, []],
edgeEventRateLimitsPerEdge: [null, []],
edgeUplinkMessagesRateLimits: [null, []],
- edgeUplinkMessagesRateLimitsPerEdge: [null, []]
+ edgeUplinkMessagesRateLimitsPerEdge: [null, []],
+ maxCalculatedFieldsPerEntity: [null, [Validators.required, Validators.min(0)]],
+ maxArgumentsPerCF: [null, [Validators.required, Validators.min(0)]],
+ maxDataPointsPerRollingArg: [null, [Validators.required, Validators.min(0)]],
+ maxStateSizeInKBytes: [null, [Validators.required, Validators.min(0)]],
+ calculatedFieldDebugEventsRateLimit: [null, []],
+ maxSingleValueArgumentSizeInKBytes: [null, [Validators.required, Validators.min(0)]],
});
this.defaultTenantProfileConfigurationFormGroup.get('smsEnabled').valueChanges.pipe(
diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.models.ts b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.models.ts
index ab50c967bf..f09f950ee7 100644
--- a/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.models.ts
+++ b/ui-ngx/src/app/modules/home/components/profile/tenant/rate-limits/rate-limits.models.ts
@@ -45,7 +45,8 @@ export enum RateLimitsType {
EDGE_EVENTS_RATE_LIMIT = 'EDGE_EVENTS_RATE_LIMIT',
EDGE_EVENTS_PER_EDGE_RATE_LIMIT = 'EDGE_EVENTS_PER_EDGE_RATE_LIMIT',
EDGE_UPLINK_MESSAGES_RATE_LIMIT = 'EDGE_UPLINK_MESSAGES_RATE_LIMIT',
- EDGE_UPLINK_MESSAGES_PER_EDGE_RATE_LIMIT = 'EDGE_UPLINK_MESSAGES_PER_EDGE_RATE_LIMIT'
+ EDGE_UPLINK_MESSAGES_PER_EDGE_RATE_LIMIT = 'EDGE_UPLINK_MESSAGES_PER_EDGE_RATE_LIMIT',
+ CALCULATED_FIELD_DEBUG_EVENT_RATE_LIMIT = 'CALCULATED_FIELD_DEBUG_EVENT_RATE_LIMIT',
}
export const rateLimitsLabelTranslationMap = new Map(
@@ -74,6 +75,7 @@ export const rateLimitsLabelTranslationMap = new Map(
[RateLimitsType.EDGE_EVENTS_PER_EDGE_RATE_LIMIT, 'tenant-profile.rate-limits.edge-events-per-edge-rate-limit'],
[RateLimitsType.EDGE_UPLINK_MESSAGES_RATE_LIMIT, 'tenant-profile.rate-limits.edge-uplink-messages-rate-limit'],
[RateLimitsType.EDGE_UPLINK_MESSAGES_PER_EDGE_RATE_LIMIT, 'tenant-profile.rate-limits.edge-uplink-messages-per-edge-rate-limit'],
+ [RateLimitsType.CALCULATED_FIELD_DEBUG_EVENT_RATE_LIMIT, 'tenant-profile.rate-limits.calculated-field-debug-event-rate-limit'],
]
);
@@ -103,6 +105,7 @@ export const rateLimitsDialogTitleTranslationMap = new Map