Skip to content

Commit 8cb3a38

Browse files
rllyy97Copilot
andauthored
feat(DesignerV2): Workflow assistant v3 backend integration (#9120)
* Switched copilot response api to LA backend * Fix panel content unmounting on re-render Convert Content and LoadingComponent from inline function components to JSX elements so React reconciles in place instead of unmounting and remounting the panel content tree. This fixes workflow parameter expanded state collapsing on autosave. * Added tests * Refactored editor service * Updated dialogs to FluentV9 Co-authored-by: Copilot <copilot@github.com> * fix: guard null content in Dialog children type * PR comment changes Co-authored-by: Copilot <copilot@github.com> * Renamed + moved some files * Fixed test file import path * Fixed bad regex * fix: update dialog snapshot tests for Fluent v9 migration --------- Co-authored-by: Copilot <copilot@github.com>
1 parent b060ee3 commit 8cb3a38

22 files changed

Lines changed: 1212 additions & 1258 deletions

File tree

apps/Standalone/src/designer/app/AzureLogicAppsDesigner/laDesigner.tsx

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ import {
3333
BaseApiManagementService,
3434
BaseAppServiceService,
3535
BaseChatbotService,
36-
BaseCopilotWorkflowEditorService,
37-
InitCopilotWorkflowEditorService,
3836
BaseExperimentationService,
3937
BaseUserPreferenceService,
4038
BaseFunctionService,
@@ -74,9 +72,6 @@ import {
7472
getMissingRoleDefinitions,
7573
roleQueryKeys,
7674
isAgentWorkflow,
77-
setIsWorkflowDirty,
78-
setFocusNode,
79-
changePanelNode,
8075
} from '@microsoft/logic-apps-designer';
8176
import axios from 'axios';
8277
import isEqual from 'lodash.isequal';
@@ -522,26 +517,6 @@ const DesignerEditor = () => {
522517
getUpdatedWorkflow={getUpdatedWorkflow}
523518
openFeedbackPanel={() => openPanel('Azure Feedback Panel has been opened')}
524519
closeChatBot={() => dispatch(setIsChatBotEnabled(false))}
525-
enableWorkflowEditing={true}
526-
autoApply={true}
527-
onWorkflowProposed={(newWorkflow) => {
528-
if (newWorkflow.parameters) {
529-
setCurrentParameters(newWorkflow.parameters as unknown as ParametersData);
530-
}
531-
setWorkflow({
532-
...newWorkflow,
533-
id: guid(),
534-
});
535-
DesignerStore.dispatch(setIsWorkflowDirty(true));
536-
}}
537-
getNodeVisuals={(nodeId) => {
538-
const meta = DesignerStore.getState().operations.operationMetadata[nodeId];
539-
return meta ? { iconUri: meta.iconUri, brandColor: meta.brandColor } : undefined;
540-
}}
541-
onNodeClick={(nodeId) => {
542-
DesignerStore.dispatch(setFocusNode(nodeId));
543-
DesignerStore.dispatch(changePanelNode(nodeId));
544-
}}
545520
/>
546521
) : null}
547522
<div
@@ -947,20 +922,6 @@ const getDesignerServices = (
947922
location,
948923
});
949924

950-
// Initialize CopilotWorkflowEditorService if API key is configured
951-
const copilotEditorApiKey = import.meta.env.VITE_COPILOT_EDITOR_API_KEY;
952-
const copilotEditorEndpoint = import.meta.env.VITE_COPILOT_EDITOR_ENDPOINT;
953-
if (copilotEditorApiKey && copilotEditorEndpoint) {
954-
const copilotEditorService = new BaseCopilotWorkflowEditorService({
955-
endpoint: copilotEditorEndpoint,
956-
apiKey: copilotEditorApiKey,
957-
model: import.meta.env.VITE_COPILOT_EDITOR_MODEL || undefined,
958-
deploymentName: import.meta.env.VITE_COPILOT_EDITOR_DEPLOYMENT || undefined,
959-
apiVersion: import.meta.env.VITE_COPILOT_EDITOR_API_VERSION || undefined,
960-
});
961-
InitCopilotWorkflowEditorService(copilotEditorService);
962-
}
963-
964925
const customCodeService = new StandardCustomCodeService({
965926
apiVersion: '2018-11-01',
966927
baseUrl: armUrl,

apps/Standalone/src/designer/app/AzureLogicAppsDesigner/laDesignerConsumptionV2.tsx

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ import {
3131
ConsumptionSearchService,
3232
BaseChatbotService,
3333
BaseCopilotWorkflowEditorService,
34-
InitCopilotWorkflowEditorService,
35-
CONSUMPTION_SYSTEM_PROMPT,
3634
ConsumptionRunService,
3735
guid,
3836
startsWith,
@@ -794,20 +792,14 @@ const getDesignerServices = (
794792
location: 'westcentralus',
795793
});
796794

797-
// Initialize CopilotWorkflowEditorService if API key is configured
798-
const copilotEditorApiKey = import.meta.env.VITE_COPILOT_EDITOR_API_KEY;
799-
const copilotEditorEndpoint = import.meta.env.VITE_COPILOT_EDITOR_ENDPOINT;
800-
if (copilotEditorApiKey && copilotEditorEndpoint) {
801-
const copilotEditorService = new BaseCopilotWorkflowEditorService({
802-
endpoint: copilotEditorEndpoint,
803-
apiKey: copilotEditorApiKey,
804-
model: import.meta.env.VITE_COPILOT_EDITOR_MODEL || undefined,
805-
deploymentName: import.meta.env.VITE_COPILOT_EDITOR_DEPLOYMENT || undefined,
806-
apiVersion: import.meta.env.VITE_COPILOT_EDITOR_API_VERSION || undefined,
807-
systemPrompt: CONSUMPTION_SYSTEM_PROMPT,
808-
});
809-
InitCopilotWorkflowEditorService(copilotEditorService);
810-
}
795+
// Initialize CopilotWorkflowEditorService
796+
const copilotWorkflowEditorService = new BaseCopilotWorkflowEditorService({
797+
baseUrl,
798+
subscriptionId,
799+
location,
800+
apiVersion: '2026-03-01-preview',
801+
getAccessToken: async () => (environment?.armToken ? `Bearer ${environment.armToken}` : ''),
802+
});
811803

812804
// This isn't correct but without it I was getting errors
813805
// It's fine just to unblock standalone consumption
@@ -844,6 +836,7 @@ const getDesignerServices = (
844836
roleService,
845837
hostService,
846838
chatbotService,
839+
copilotWorkflowEditorService,
847840
customCodeService,
848841
cognitiveServiceService,
849842
userPreferenceService: new BaseUserPreferenceService(),

apps/Standalone/src/designer/app/AzureLogicAppsDesigner/laDesignerV2.tsx

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import {
3333
BaseAppServiceService,
3434
BaseChatbotService,
3535
BaseCopilotWorkflowEditorService,
36-
InitCopilotWorkflowEditorService,
3736
BaseExperimentationService,
3837
BaseUserPreferenceService,
3938
BaseFunctionService,
@@ -81,7 +80,6 @@ import isEqual from 'lodash.isequal';
8180
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8281
import type { QueryClient } from '@tanstack/react-query';
8382
import { useDispatch, useSelector } from 'react-redux';
84-
import { useHostingPlan } from '../../state/workflowLoadingSelectors';
8583
import CodeViewEditor from './CodeViewV2';
8684
import { CustomConnectionParameterEditorService } from './Services/customConnectionParameterEditorService';
8785
import { CustomEditorService } from './Services/customEditorService';
@@ -121,7 +119,7 @@ const DesignerEditor = () => {
121119
} = useAllCustomCodeFiles(appId, workflowName, isHybridLogicApp);
122120
const { data: artifactData, isLoading: artifactsLoading, isError, error } = useWorkflowAndArtifactsStandard(workflowId);
123121
const { data: settingsData, isLoading: settingsLoading, isError: settingsIsError, error: settingsError } = useAppSettings(siteResourceId);
124-
const { data: workflowAppData, isLoading: appLoading } = useWorkflowApp(siteResourceId, useHostingPlan());
122+
const { data: workflowAppData, isLoading: appLoading } = useWorkflowApp(siteResourceId, hostingPlan);
125123
const { data: tenantId } = useCurrentTenantId();
126124
const { data: objectId } = useCurrentObjectId();
127125

@@ -307,7 +305,6 @@ const DesignerEditor = () => {
307305
);
308306

309307
// Services
310-
311308
const canonicalLocation = WorkflowUtility.convertToCanonicalFormat(workflowAppData?.location ?? '');
312309
const supportsStateful = !equals(workflow?.kind, 'stateless');
313310
const services = useMemo(
@@ -1119,19 +1116,14 @@ const getDesignerServices = (
11191116
location,
11201117
});
11211118

1122-
// Initialize CopilotWorkflowEditorService if API key is configured
1123-
const copilotEditorApiKey = import.meta.env.VITE_COPILOT_EDITOR_API_KEY;
1124-
const copilotEditorEndpoint = import.meta.env.VITE_COPILOT_EDITOR_ENDPOINT;
1125-
if (copilotEditorApiKey && copilotEditorEndpoint) {
1126-
const copilotEditorService = new BaseCopilotWorkflowEditorService({
1127-
endpoint: copilotEditorEndpoint,
1128-
apiKey: copilotEditorApiKey,
1129-
model: import.meta.env.VITE_COPILOT_EDITOR_MODEL || undefined,
1130-
deploymentName: import.meta.env.VITE_COPILOT_EDITOR_DEPLOYMENT || undefined,
1131-
apiVersion: import.meta.env.VITE_COPILOT_EDITOR_API_VERSION || undefined,
1132-
});
1133-
InitCopilotWorkflowEditorService(copilotEditorService);
1134-
}
1119+
// Initialize CopilotWorkflowEditorService
1120+
const copilotWorkflowEditorService = new BaseCopilotWorkflowEditorService({
1121+
baseUrl: armUrl,
1122+
subscriptionId,
1123+
location,
1124+
apiVersion: '2026-03-01-preview',
1125+
getAccessToken: async () => (environment?.armToken ? `Bearer ${environment.armToken}` : ''),
1126+
});
11351127

11361128
const customCodeService = new StandardCustomCodeService({
11371129
apiVersion: '2018-11-01',
@@ -1173,6 +1165,7 @@ const getDesignerServices = (
11731165
roleService,
11741166
hostService,
11751167
chatbotService,
1168+
copilotWorkflowEditorService,
11761169
customCodeService,
11771170
cognitiveServiceService,
11781171
connectionParameterEditorService,
Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,60 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

33
exports[`ui/dialogs/_alert > should render 1`] = `
4-
<Dialog
5-
dialogContentProps={
6-
{
7-
"title": "Title",
8-
}
9-
}
10-
hidden={false}
11-
modalProps={
12-
{
13-
"firstFocusableSelector": "dialog-ok-button",
14-
"isBlocking": true,
15-
}
16-
}
17-
onDismiss={[MockFunction spy]}
4+
<body
5+
data-tabster="{"root":{}}"
186
>
19-
Message
20-
<StyledDialogFooterBase>
21-
<CustomizedPrimaryButton
22-
className="dialog-ok-button"
23-
onClick={[MockFunction spy]}
7+
<div>
8+
<span
9+
hidden=""
10+
/>
11+
</div>
12+
<div
13+
class="___1uxlrft_djprso0 f1euv43f f15twtuk f1vgc2s3 f1e31b4d f494woh"
14+
data-portal-node="true"
15+
dir="ltr"
16+
>
17+
<div
18+
aria-hidden="true"
19+
class="fui-DialogSurface__backdrop r1e18s3l"
20+
/>
21+
<div
22+
aria-labelledby="dialog-title-r1"
23+
aria-modal="true"
24+
class="fui-DialogSurface r1u3t6p6"
25+
data-tabster="{"restorer":{"type":0},"modalizer":{"id":"modal-r0","isOthersAccessible":false,"isTrapped":true}}"
26+
role="alertdialog"
27+
tabindex="-1"
2428
>
25-
OK
26-
</CustomizedPrimaryButton>
27-
</StyledDialogFooterBase>
28-
</Dialog>
29+
<div
30+
class="fui-DialogBody rhwx3p8"
31+
>
32+
<h2
33+
class="fui-DialogTitle rxjm636 ___mh25s00_kwrsjh0 fsyjsko"
34+
id="dialog-title-r1"
35+
>
36+
Title
37+
</h2>
38+
<div
39+
class="fui-DialogContent r1v5zwsm"
40+
>
41+
Message
42+
</div>
43+
<div
44+
class="fui-DialogActions rhfpeu0 ___pj8zjl0_1y84z0u f1a7i8kp fd46tj4 fsyjsko f1f41i0t f1jaqex3 f2ao6jk"
45+
>
46+
<button
47+
class="fui-Button r1alrhcs ___1akj6hk_ih97uj0 ffp7eso f1p3nwhy f11589ue f1q5o8ev f1pdflbu f1phragk f15wkkf3 f1s2uweq fr80ssc f1ukrpxl fecsdlb f1rq72xc fnp9lpt f1h0usnq fs4ktlq f16h9ulv fx2bmrt f1d6v5y2 f1rirnrt f1uu00uk fkvaka8 f1ux7til f9a0qzu f1lkg8j3 fkc42ay fq7113v ff1wgvm fiob0tu f1j6scgf f1x4h75k f4xjyn1 fbgcvur f1ks1yx8 f1o6qegi fcnxywj fmxjhhp f9ddjv3 f17t0x8g f194v5ow f1qgg65p fk7jm04 fhgccpy f32wu9k fu5nqqq f13prjl2 f1czftr5 f1nl83rv f12k37oa fr96u23"
48+
type="button"
49+
>
50+
OK
51+
</button>
52+
</div>
53+
</div>
54+
</div>
55+
<span
56+
hidden=""
57+
/>
58+
</div>
59+
</body>
2960
`;
Lines changed: 60 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,66 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

33
exports[`ui/dialogs/_confirm > should render 1`] = `
4-
<Dialog
5-
dialogContentProps={
6-
{
7-
"title": "Title",
8-
}
9-
}
10-
hidden={false}
11-
modalProps={
12-
{
13-
"firstFocusableSelector": "dialog-ok-button",
14-
"isBlocking": true,
15-
}
16-
}
17-
onDismiss={[MockFunction spy]}
4+
<body
5+
data-tabster="{"root":{}}"
186
>
19-
Message
20-
<StyledDialogFooterBase>
21-
<CustomizedPrimaryButton
22-
className="dialog-ok-button"
23-
onClick={[MockFunction spy]}
7+
<div>
8+
<span
9+
hidden=""
10+
/>
11+
</div>
12+
<div
13+
class="___1uxlrft_djprso0 f1euv43f f15twtuk f1vgc2s3 f1e31b4d f494woh"
14+
data-portal-node="true"
15+
dir="ltr"
16+
>
17+
<div
18+
aria-hidden="true"
19+
class="fui-DialogSurface__backdrop r1e18s3l"
20+
/>
21+
<div
22+
aria-labelledby="dialog-title-r1"
23+
aria-modal="true"
24+
class="fui-DialogSurface r1u3t6p6"
25+
data-tabster="{"restorer":{"type":0},"modalizer":{"id":"modal-r0","isOthersAccessible":false,"isTrapped":true}}"
26+
role="alertdialog"
27+
tabindex="-1"
2428
>
25-
OK
26-
</CustomizedPrimaryButton>
27-
<CustomizedDefaultButton
28-
onClick={[MockFunction spy]}
29-
>
30-
Cancel
31-
</CustomizedDefaultButton>
32-
</StyledDialogFooterBase>
33-
</Dialog>
29+
<div
30+
class="fui-DialogBody rhwx3p8"
31+
>
32+
<h2
33+
class="fui-DialogTitle rxjm636 ___mh25s00_kwrsjh0 fsyjsko"
34+
id="dialog-title-r1"
35+
>
36+
Title
37+
</h2>
38+
<div
39+
class="fui-DialogContent r1v5zwsm"
40+
>
41+
Message
42+
</div>
43+
<div
44+
class="fui-DialogActions rhfpeu0 ___pj8zjl0_1y84z0u f1a7i8kp fd46tj4 fsyjsko f1f41i0t f1jaqex3 f2ao6jk"
45+
>
46+
<button
47+
class="fui-Button r1alrhcs"
48+
type="button"
49+
>
50+
Cancel
51+
</button>
52+
<button
53+
class="fui-Button r1alrhcs ___1akj6hk_ih97uj0 ffp7eso f1p3nwhy f11589ue f1q5o8ev f1pdflbu f1phragk f15wkkf3 f1s2uweq fr80ssc f1ukrpxl fecsdlb f1rq72xc fnp9lpt f1h0usnq fs4ktlq f16h9ulv fx2bmrt f1d6v5y2 f1rirnrt f1uu00uk fkvaka8 f1ux7til f9a0qzu f1lkg8j3 fkc42ay fq7113v ff1wgvm fiob0tu f1j6scgf f1x4h75k f4xjyn1 fbgcvur f1ks1yx8 f1o6qegi fcnxywj fmxjhhp f9ddjv3 f17t0x8g f194v5ow f1qgg65p fk7jm04 fhgccpy f32wu9k fu5nqqq f13prjl2 f1czftr5 f1nl83rv f12k37oa fr96u23"
54+
type="button"
55+
>
56+
OK
57+
</button>
58+
</div>
59+
</div>
60+
</div>
61+
<span
62+
hidden=""
63+
/>
64+
</div>
65+
</body>
3466
`;
Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
1+
/**
2+
* @vitest-environment jsdom
3+
*/
14
import type { AlertProps } from '../alert';
25
import { Alert } from '../alert';
36
import * as React from 'react';
4-
import * as ReactShallowRenderer from 'react-test-renderer/shallow';
5-
import { describe, vi, beforeEach, afterEach, beforeAll, afterAll, it, test, expect } from 'vitest';
7+
import { render } from '@testing-library/react';
8+
import { IntlProvider } from 'react-intl';
9+
import { describe, vi, beforeEach, it, expect } from 'vitest';
10+
611
describe('ui/dialogs/_alert', () => {
712
let minimal: AlertProps;
8-
let renderer: ReactShallowRenderer.ShallowRenderer;
13+
914
beforeEach(() => {
1015
minimal = {
1116
hidden: false,
1217
message: 'Message',
1318
title: 'Title',
1419
onDismiss: vi.fn(),
1520
};
16-
renderer = ReactShallowRenderer.createRenderer();
1721
});
1822

1923
it('should render', () => {
20-
const alert = renderer.render(<Alert {...minimal} />);
21-
expect(alert).toMatchSnapshot();
24+
const { baseElement } = render(
25+
<IntlProvider locale="en">
26+
<Alert {...minimal} />
27+
</IntlProvider>
28+
);
29+
expect(baseElement).toMatchSnapshot();
2230
});
2331
});

0 commit comments

Comments
 (0)