Skip to content

Commit b34518f

Browse files
preetriti1Priti Sambandam
and
Priti Sambandam
authoredMar 17, 2025··
fix(templates): Adding reload handler when resource changes to reload services (#6805)
* Adding a reset state action for templates * fix(templates): Adding a reload handler when a resource changes and services to reload * Adding CITs and also updated standard app template standalone * chore(release): 5.53.1 * Revert "chore(release): 5.53.1" This reverts commit 4fc648d. * Calling handler on every resource change to track resource validity --------- Co-authored-by: Priti Sambandam <[email protected]> Co-authored-by: [email protected] <preetriti1>
1 parent e2b90e6 commit b34518f

24 files changed

+766
-296
lines changed
 

‎apps/Standalone/src/designer/app/AzureLogicAppsDesigner/Services/WorkflowAndArtifacts.tsx

+79-80
Original file line numberDiff line numberDiff line change
@@ -22,33 +22,31 @@ const hybridApiVersion = '2024-02-02-preview';
2222
const consumptionApiVersion = '2019-05-01';
2323

2424
export const useConnectionsData = (appId?: string) => {
25-
return useQuery(
26-
['getConnectionsData', appId],
27-
async () => {
28-
const uri = `${baseUrl}/${appId}/workflowsconfiguration/connections?api-version=2018-11-01`;
29-
try {
30-
const response = await axios.get(uri, {
31-
headers: {
32-
Authorization: `Bearer ${environment.armToken}`,
33-
},
34-
});
35-
const { files, health } = response.data.properties;
36-
if (equals(health.state, 'healthy')) {
37-
return files['connections.json'];
38-
}
39-
const { error } = health;
40-
throw new Error(error.message);
41-
} catch {
42-
return {};
43-
}
44-
},
45-
{
46-
enabled: !!appId,
47-
refetchOnMount: false,
48-
refetchOnReconnect: false,
49-
refetchOnWindowFocus: false,
25+
return useQuery(['getConnectionsData', appId], async () => getConnectionsData(appId as string), {
26+
enabled: !!appId,
27+
refetchOnMount: false,
28+
refetchOnReconnect: false,
29+
refetchOnWindowFocus: false,
30+
});
31+
};
32+
33+
export const getConnectionsData = async (appId: string): Promise<ConnectionsData> => {
34+
const uri = `${baseUrl}/${appId}/workflowsconfiguration/connections?api-version=2018-11-01`;
35+
try {
36+
const response = await axios.get(uri, {
37+
headers: {
38+
Authorization: `Bearer ${environment.armToken}`,
39+
},
40+
});
41+
const { files, health } = response.data.properties;
42+
if (equals(health.state, 'healthy')) {
43+
return files['connections.json'];
5044
}
51-
);
45+
const { error } = health;
46+
throw new Error(error.message);
47+
} catch {
48+
return {};
49+
}
5250
};
5351

5452
export const useWorkflowAndArtifactsStandard = (workflowId: string) => {
@@ -293,66 +291,67 @@ export const listCallbackUrl = async (
293291
};
294292

295293
export const useWorkflowApp = (siteResourceId: string, hostingPlan: HostingPlanTypes) => {
296-
return useQuery(
297-
['workflowApp', siteResourceId],
298-
async () => {
299-
const apiVersions = {
300-
consumption: '2016-10-01',
301-
standard: '2018-11-01',
302-
hybrid: '2023-11-02-preview',
303-
};
304-
const uri = `${baseUrl}${siteResourceId}?api-version=${apiVersions[hostingPlan] || '2018-11-01'}`;
305-
const response = await axios.get(uri, {
306-
headers: {
307-
Authorization: `Bearer ${environment.armToken}`,
308-
},
309-
});
294+
return useQuery(['workflowApp', siteResourceId], async () => getWorkflowApp(siteResourceId, hostingPlan), {
295+
refetchOnMount: false,
296+
refetchOnReconnect: false,
297+
refetchOnWindowFocus: false,
298+
});
299+
};
310300

311-
return response.data;
301+
export const getWorkflowAppFromCache = async (siteResourceId: string, hostingPlan: HostingPlanTypes) => {
302+
const queryClient = getReactQueryClient();
303+
return queryClient.fetchQuery(['workflowApp', siteResourceId], async () => getWorkflowApp(siteResourceId, hostingPlan));
304+
};
305+
306+
const getWorkflowApp = async (siteResourceId: string, hostingPlan: HostingPlanTypes) => {
307+
const apiVersions = {
308+
consumption: '2016-10-01',
309+
standard: '2018-11-01',
310+
hybrid: '2023-11-02-preview',
311+
};
312+
const uri = `${baseUrl}${siteResourceId}?api-version=${apiVersions[hostingPlan] || '2018-11-01'}`;
313+
const response = await axios.get(uri, {
314+
headers: {
315+
Authorization: `Bearer ${environment.armToken}`,
312316
},
313-
{
314-
refetchOnMount: false,
315-
refetchOnReconnect: false,
316-
refetchOnWindowFocus: false,
317-
}
318-
);
317+
});
318+
319+
return response.data;
319320
};
320321

321322
export const useAppSettings = (siteResourceId: string) => {
322-
return useQuery(
323-
['appSettings', siteResourceId],
324-
async () => {
325-
if (HybridAppUtility.isHybridLogicApp(siteResourceId)) {
326-
const containerAppInfo = (
327-
await axios.get(`${baseUrl}${siteResourceId}?api-version=2024-02-02-preview`, {
328-
headers: {
329-
Authorization: `Bearer ${environment.armToken}`,
330-
},
331-
})
332-
).data;
333-
containerAppInfo.properties = containerAppInfo.properties.template.containers[0].env;
334-
containerAppInfo.properties = containerAppInfo.properties.reduce((acc: any, cur: any) => {
335-
acc[cur.name] = cur.value;
336-
return acc;
337-
}, {});
338-
return containerAppInfo;
339-
}
323+
return useQuery(['appSettings', siteResourceId], async () => getAppSettings(siteResourceId), {
324+
refetchOnMount: false,
325+
refetchOnReconnect: false,
326+
refetchOnWindowFocus: false,
327+
});
328+
};
340329

341-
const uri = `${baseUrl}${siteResourceId}/config/appsettings/list?api-version=2018-11-01`;
342-
return (
343-
await axios.post(uri, null, {
344-
headers: {
345-
Authorization: `Bearer ${environment.armToken}`,
346-
},
347-
})
348-
).data;
349-
},
350-
{
351-
refetchOnMount: false,
352-
refetchOnReconnect: false,
353-
refetchOnWindowFocus: false,
354-
}
355-
);
330+
export const getAppSettings = async (siteResourceId: string) => {
331+
if (HybridAppUtility.isHybridLogicApp(siteResourceId)) {
332+
const containerAppInfo = (
333+
await axios.get(`${baseUrl}${siteResourceId}?api-version=2024-02-02-preview`, {
334+
headers: {
335+
Authorization: `Bearer ${environment.armToken}`,
336+
},
337+
})
338+
).data;
339+
containerAppInfo.properties = containerAppInfo.properties.template.containers[0].env;
340+
containerAppInfo.properties = containerAppInfo.properties.reduce((acc: any, cur: any) => {
341+
acc[cur.name] = cur.value;
342+
return acc;
343+
}, {});
344+
return containerAppInfo;
345+
}
346+
347+
const uri = `${baseUrl}${siteResourceId}/config/appsettings/list?api-version=2018-11-01`;
348+
return (
349+
await axios.post(uri, null, {
350+
headers: {
351+
Authorization: `Bearer ${environment.armToken}`,
352+
},
353+
})
354+
).data;
356355
};
357356

358357
export const useCurrentTenantId = () => {

‎apps/Standalone/src/templates/app/LocalTemplates.tsx

+52-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect, useMemo, useState } from 'react';
22
import { TemplatesDataProvider, TemplatesView } from '@microsoft/logic-apps-designer';
33
import type { RootState } from '../state/Store';
4-
import { TemplatesDesigner, TemplatesDesignerProvider } from '@microsoft/logic-apps-designer';
4+
import { TemplatesDesigner, TemplatesDesignerProvider, templateStore, resetStateOnResourceChange } from '@microsoft/logic-apps-designer';
55
import { useSelector } from 'react-redux';
66
import {
77
BaseGatewayService,
@@ -20,10 +20,6 @@ import {
2020
} from '@microsoft/logic-apps-shared';
2121
import { HttpClient } from '../../designer/app/AzureLogicAppsDesigner/Services/HttpClient';
2222

23-
const subscriptionId = 'one';
24-
const resourceGroup = 'SecondRG';
25-
const location = 'eastus';
26-
2723
const loadLocalTemplateFromResourcePath = async (resourcePath: string, artifactType = 'manifest') => {
2824
const paths = resourcePath.split('/');
2925

@@ -33,6 +29,9 @@ const loadLocalTemplateFromResourcePath = async (resourcePath: string, artifactT
3329
};
3430

3531
const localTemplateManifestPaths = ['BasicWorkflowOnly', 'SimpleConnectionParameter', 'SimpleAccelerator', 'SimpleParametersOnly'];
32+
const defaultSubscriptionId = 'one';
33+
const defaultResourceGroup = 'SecondRG';
34+
const defaultLocation = 'eastus';
3635

3736
export const LocalTemplates = () => {
3837
const { theme, templatesView } = useSelector((state: RootState) => ({
@@ -55,19 +54,23 @@ export const LocalTemplates = () => {
5554
}, [useEndpoint]);
5655

5756
const services = useMemo(
58-
() => getServices(isConsumption, !!useEndpoint),
57+
() => getServices(defaultSubscriptionId, defaultResourceGroup, defaultLocation, isConsumption, !!useEndpoint),
5958
// eslint-disable-next-line react-hooks/exhaustive-deps
6059
[isConsumption, useEndpoint]
6160
);
61+
const onReloadServices = () => {
62+
const { subscriptionId, resourceGroup, location } = templateStore.getState().workflow;
63+
templateStore.dispatch(resetStateOnResourceChange(getResourceBasedServices(subscriptionId, resourceGroup, location, isConsumption)));
64+
};
6265
const isSingleTemplateView = useMemo(() => templatesView !== 'gallery', [templatesView]);
6366

6467
return (
6568
<TemplatesDesignerProvider locale="en-US" theme={theme}>
6669
<TemplatesDataProvider
6770
resourceDetails={{
68-
subscriptionId,
69-
resourceGroup,
70-
location,
71+
subscriptionId: defaultSubscriptionId,
72+
resourceGroup: defaultResourceGroup,
73+
location: defaultLocation,
7174
workflowAppName: 'app1',
7275
}}
7376
reload={reload}
@@ -76,6 +79,7 @@ export const LocalTemplates = () => {
7679
isConsumption={isConsumption}
7780
isCreateView={!isConsumption || !!isCreateView}
7881
enableResourceSelection={enableResourceSelection}
82+
onResourceChange={onReloadServices}
7983
existingWorkflowName={undefined}
8084
viewTemplate={
8185
isSingleTemplateView
@@ -167,7 +171,13 @@ export const LocalTemplates = () => {
167171

168172
const httpClient = new HttpClient();
169173

170-
const getServices = (isConsumption: boolean, useEndpoint: boolean): any => {
174+
const getServices = (
175+
subscriptionId: string,
176+
resourceGroup: string,
177+
location: string,
178+
isConsumption: boolean,
179+
useEndpoint: boolean
180+
): any => {
171181
const connectionService = isConsumption
172182
? new ConsumptionConnectionService({
173183
apiVersion: '2018-07-01-preview',
@@ -276,6 +286,38 @@ const getServices = (isConsumption: boolean, useEndpoint: boolean): any => {
276286
};
277287
};
278288

289+
const getResourceBasedServices = (subscriptionId: string, resourceGroup: string, location: string, isConsumption: boolean) => {
290+
const connectionService = isConsumption
291+
? new ConsumptionConnectionService({
292+
apiVersion: '2018-07-01-preview',
293+
baseUrl: '/baseUrl',
294+
subscriptionId,
295+
resourceGroup,
296+
location,
297+
httpClient,
298+
})
299+
: new StandardConnectionService({
300+
baseUrl: '/url',
301+
apiVersion: '2018-11-01',
302+
httpClient,
303+
apiHubServiceDetails: {
304+
apiVersion: '2018-07-01-preview',
305+
baseUrl: '/baseUrl',
306+
subscriptionId,
307+
resourceGroup,
308+
location,
309+
httpClient,
310+
},
311+
workflowAppDetails: {
312+
appName: 'app',
313+
identity: { type: ResourceIdentityType.SYSTEM_ASSIGNED },
314+
},
315+
readConnections: () => Promise.resolve({}),
316+
});
317+
318+
return { connectionService };
319+
};
320+
279321
class LocalTemplateService extends StandardTemplateService {
280322
constructor(private readonly _options: any) {
281323
super(_options);

0 commit comments

Comments
 (0)
Please sign in to comment.