From 389d8684d319f6523df6d3ffe8a7541224dccc91 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Wed, 1 Apr 2026 17:09:29 +0300 Subject: [PATCH] feat(iot-hub): add find-or-create for rule chains in device install Reuse existing rule chains by name (same pattern as device profiles). Shared entities (device profile, rule chain) are looked up before creation. Per-install entities (device, dashboard) are always created fresh. --- .../device-install-dialog.component.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ui-ngx/src/app/modules/home/pages/iot-hub/device-install-dialog/device-install-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/iot-hub/device-install-dialog/device-install-dialog.component.ts index e622b8ccba..e5d69e2fbb 100644 --- a/ui-ngx/src/app/modules/home/pages/iot-hub/device-install-dialog/device-install-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/pages/iot-hub/device-install-dialog/device-install-dialog.component.ts @@ -18,6 +18,7 @@ import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; import { firstValueFrom } from 'rxjs'; +import { PageLink } from '@shared/models/page/page-link'; import { MpItemVersionView } from '@shared/models/iot-hub/iot-hub-version.models'; import { IotHubApiService } from '@core/http/iot-hub-api.service'; import { DeviceProfileService } from '@core/http/device-profile.service'; @@ -356,6 +357,10 @@ export class TbDeviceInstallDialogComponent implements OnInit { case InstallStepType.RULE_CHAIN: { const ruleChain = template.ruleChain || template; const metadata = template.metadata; + const existing = await this.findRuleChainByName(ruleChain.name); + if (existing) { + return existing; + } const saved = await firstValueFrom(this.ruleChainService.saveRuleChain(ruleChain)); if (metadata) { metadata.ruleChainId = saved.id; @@ -373,4 +378,10 @@ export class TbDeviceInstallDialogComponent implements OnInit { const match = profiles.find(p => p.name === name); return match ? { id: match.id.id, name: match.name } : null; } + + private async findRuleChainByName(name: string): Promise { + const page = await firstValueFrom(this.ruleChainService.getRuleChains(new PageLink(100, 0, name))); + const match = page.data.find(rc => rc.name === name); + return match ? { id: match.id.id, name: match.name } : null; + } }