Browse Source

feat(iot-hub): add ${entity.url} template variable for all entity steps

Each entity output now includes a url field:
- deviceProfile: /profiles/deviceProfiles/{id}
- device: /entities/devices/{id}
- gateway: /entities/gateways (generic, no ID)
- dashboard: /dashboards/{id}
- ruleChain: /ruleChains/{id}

Available in templates as ${device.url}, ${dashboard.url}, etc.
pull/15508/head
Andrii Shvaika 3 months ago
parent
commit
84c2ea2f2f
  1. 13
      ui-ngx/src/app/modules/home/components/iot-hub/device-install-dialog/device-install-dialog.component.ts
  2. 1
      ui-ngx/src/app/shared/models/iot-hub/device-package.models.ts

13
ui-ngx/src/app/modules/home/components/iot-hub/device-install-dialog/device-install-dialog.component.ts

@ -456,12 +456,12 @@ export class TbDeviceInstallDialogComponent extends DialogComponent<TbDeviceInst
return existing; return existing;
} }
const result = await firstValueFrom(this.deviceProfileService.saveDeviceProfile(template, {ignoreErrors: true})); const result = await firstValueFrom(this.deviceProfileService.saveDeviceProfile(template, {ignoreErrors: true}));
return { id: result.id.id, name: result.name }; return { id: result.id.id, name: result.name, url: `/profiles/deviceProfiles/${result.id.id}` };
} }
case InstallStepType.DEVICE: { case InstallStepType.DEVICE: {
const result = await firstValueFrom(this.deviceService.saveDevice(template, {ignoreErrors: true})); const result = await firstValueFrom(this.deviceService.saveDevice(template, {ignoreErrors: true}));
const creds = await firstValueFrom(this.deviceService.getDeviceCredentials(result.id.id, false, {ignoreErrors: true})); const creds = await firstValueFrom(this.deviceService.getDeviceCredentials(result.id.id, false, {ignoreErrors: true}));
return { id: result.id.id, name: result.name, token: creds.credentialsId }; return { id: result.id.id, name: result.name, url: `/entities/devices/${result.id.id}`, token: creds.credentialsId };
} }
case InstallStepType.GATEWAY: { case InstallStepType.GATEWAY: {
const result = await firstValueFrom(this.deviceService.saveDevice(template, {ignoreErrors: true})); const result = await firstValueFrom(this.deviceService.saveDevice(template, {ignoreErrors: true}));
@ -469,6 +469,7 @@ export class TbDeviceInstallDialogComponent extends DialogComponent<TbDeviceInst
return { return {
id: result.id.id, id: result.id.id,
name: result.name, name: result.name,
url: '/entities/gateways',
token: creds.credentialsId, token: creds.credentialsId,
dockerComposeUrl: `/api/device-connectivity/gateway-launch/${result.id.id}/docker-compose/download` dockerComposeUrl: `/api/device-connectivity/gateway-launch/${result.id.id}/docker-compose/download`
}; };
@ -514,7 +515,7 @@ export class TbDeviceInstallDialogComponent extends DialogComponent<TbDeviceInst
} }
case InstallStepType.DASHBOARD: { case InstallStepType.DASHBOARD: {
const result = await firstValueFrom(this.dashboardService.saveDashboard(template, {ignoreErrors: true})); const result = await firstValueFrom(this.dashboardService.saveDashboard(template, {ignoreErrors: true}));
return { id: result.id.id, name: result.title }; return { id: result.id.id, name: result.title, url: `/dashboards/${result.id.id}` };
} }
case InstallStepType.RULE_CHAIN: { case InstallStepType.RULE_CHAIN: {
const ruleChain = template.ruleChain || template; const ruleChain = template.ruleChain || template;
@ -528,7 +529,7 @@ export class TbDeviceInstallDialogComponent extends DialogComponent<TbDeviceInst
metadata.ruleChainId = saved.id; metadata.ruleChainId = saved.id;
await firstValueFrom(this.ruleChainService.saveRuleChainMetadata(metadata, {ignoreErrors: true})); await firstValueFrom(this.ruleChainService.saveRuleChainMetadata(metadata, {ignoreErrors: true}));
} }
return { id: saved.id.id, name: saved.name }; return { id: saved.id.id, name: saved.name, url: `/ruleChains/${saved.id.id}` };
} }
default: default:
throw new Error(`Unsupported entity step type: ${step.type}`); throw new Error(`Unsupported entity step type: ${step.type}`);
@ -538,13 +539,13 @@ export class TbDeviceInstallDialogComponent extends DialogComponent<TbDeviceInst
private async findDeviceProfileByName(name: string): Promise<EntityStepOutput | null> { private async findDeviceProfileByName(name: string): Promise<EntityStepOutput | null> {
const profiles = await firstValueFrom(this.deviceProfileService.getDeviceProfileNames()); const profiles = await firstValueFrom(this.deviceProfileService.getDeviceProfileNames());
const match = profiles.find(p => p.name === name); const match = profiles.find(p => p.name === name);
return match ? { id: match.id.id, name: match.name } : null; return match ? { id: match.id.id, name: match.name, url: `/profiles/deviceProfiles/${match.id.id}` } : null;
} }
private async findRuleChainByName(name: string): Promise<EntityStepOutput | null> { private async findRuleChainByName(name: string): Promise<EntityStepOutput | null> {
const page = await firstValueFrom(this.ruleChainService.getRuleChains(new PageLink(100, 0, name))); const page = await firstValueFrom(this.ruleChainService.getRuleChains(new PageLink(100, 0, name)));
const match = page.data.find(rc => rc.name === name); const match = page.data.find(rc => rc.name === name);
return match ? { id: match.id.id, name: match.name } : null; return match ? { id: match.id.id, name: match.name, url: `/ruleChains/${match.id.id}` } : null;
} }
private collectCreatedEntityIds(): { entityType: string; id: string }[] { private collectCreatedEntityIds(): { entityType: string; id: string }[] {

1
ui-ngx/src/app/shared/models/iot-hub/device-package.models.ts

@ -128,6 +128,7 @@ export interface FormFieldDefinition {
export interface EntityStepOutput { export interface EntityStepOutput {
id: string; id: string;
name: string; name: string;
url?: string;
token?: string; token?: string;
dockerComposeUrl?: string; dockerComposeUrl?: string;
} }

Loading…
Cancel
Save