Skip to content

Commit 2aaf69b

Browse files
authored
Merge pull request #924 from axewilledge/configurable-object-editor
Update package configurable view and enhance state machine actions
2 parents 853ff6f + 6701023 commit 2aaf69b

File tree

7 files changed

+73
-23
lines changed

7 files changed

+73
-23
lines changed

workspaces/ballerina/ballerina-core/src/interfaces/extended-lang-client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,6 +1928,7 @@ export interface ProjectInfo {
19281928
name?: string;
19291929
title?: string;
19301930
orgName?: string;
1931+
org?: string;
19311932
version?: string;
19321933
projectPath?: string;
19331934
children?: ProjectInfo[];

workspaces/ballerina/ballerina-extension/src/stateMachine.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
fetchScope,
2020
getOrgPackageName,
2121
UndoRedoManager,
22-
getPackageName
22+
getOrgAndPackageName
2323
} from './utils';
2424
import { buildProjectsStructure } from './utils/project-artifacts';
2525
import { runCommandWithOutput } from './utils/runCommand';
@@ -61,6 +61,15 @@ const stateMachine = createMachine<MachineContext>(
6161
on: {
6262
RESET_TO_EXTENSION_READY: {
6363
target: "extensionReady",
64+
actions: assign({
65+
documentUri: undefined,
66+
position: undefined,
67+
identifier: undefined,
68+
projectPath: undefined,
69+
scope: undefined,
70+
org: undefined,
71+
package: undefined
72+
})
6473
},
6574
UPDATE_PROJECT_STRUCTURE: {
6675
actions: [
@@ -210,8 +219,11 @@ const stateMachine = createMachine<MachineContext>(
210219
OPEN_VIEW: {
211220
target: "viewActive",
212221
actions: assign({
222+
org: (context, event) => event.viewLocation?.org,
223+
package: (context, event) => event.viewLocation?.package,
213224
view: (context, event) => event.viewLocation.view,
214225
documentUri: (context, event) => event.viewLocation.documentUri,
226+
projectPath: (context, event) => event.viewLocation?.projectPath,
215227
position: (context, event) => event.viewLocation.position,
216228
identifier: (context, event) => event.viewLocation.identifier,
217229
serviceType: (context, event) => event.viewLocation.serviceType,
@@ -290,6 +302,7 @@ const stateMachine = createMachine<MachineContext>(
290302
identifier: (context, event) => event.viewLocation.identifier,
291303
serviceType: (context, event) => event.viewLocation.serviceType,
292304
projectPath: (context, event) => event.viewLocation?.projectPath || context?.projectPath,
305+
org: (context, event) => event.viewLocation?.org || context?.org,
293306
package: (context, event) => event.viewLocation?.package || context?.package,
294307
type: (context, event) => event.viewLocation?.type,
295308
isGraphql: (context, event) => event.viewLocation?.isGraphql,
@@ -486,7 +499,7 @@ const stateMachine = createMachine<MachineContext>(
486499
},
487500
findView(context, event): Promise<void> {
488501
return new Promise(async (resolve, reject) => {
489-
const packageName = getPackageName(context.projectInfo, context.projectPath);
502+
const { orgName, packageName } = getOrgAndPackageName(context.projectInfo, context.projectPath);
490503
if (!context.view && context.langClient) {
491504
if (!context.position || ("groupId" in context.position)) {
492505
if (!context.projectPath && context.workspacePath) {
@@ -500,7 +513,8 @@ const stateMachine = createMachine<MachineContext>(
500513
location: {
501514
view: MACHINE_VIEW.PackageOverview,
502515
documentUri: context.documentUri,
503-
package: packageName || context.package
516+
org: orgName || context.org,
517+
package: packageName || context.package,
504518
}
505519
});
506520
}
@@ -518,6 +532,7 @@ const stateMachine = createMachine<MachineContext>(
518532
documentUri: context.documentUri,
519533
position: context.position,
520534
identifier: context.identifier,
535+
org: orgName || context.org,
521536
package: packageName || context.package,
522537
type: context?.type,
523538
isGraphql: context?.isGraphql,
@@ -569,8 +584,8 @@ const stateMachine = createMachine<MachineContext>(
569584
if (!selectedEntry?.location.view) {
570585
return resolve(
571586
context.workspacePath
572-
? { view: MACHINE_VIEW.WorkspaceOverview }
573-
: { view: MACHINE_VIEW.PackageOverview, documentUri: context.documentUri }
587+
? { view: MACHINE_VIEW.WorkspaceOverview }
588+
: { view: MACHINE_VIEW.PackageOverview, documentUri: context.documentUri }
574589
);
575590
}
576591

@@ -697,6 +712,9 @@ export function openView(type: EVENT_TYPE, viewLocation: VisualizerLocation, res
697712
}
698713
extension.hasPullModuleResolved = false;
699714
extension.hasPullModuleNotification = false;
715+
const { orgName, packageName } = getOrgAndPackageName(StateMachine.context().projectInfo, viewLocation.projectPath);
716+
viewLocation.org = orgName;
717+
viewLocation.package = packageName;
700718
stateService.send({ type: type, viewLocation: viewLocation });
701719
}
702720

workspaces/ballerina/ballerina-extension/src/utils/config.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,12 @@ function compareVersions(
136136
if (current.major !== minimum.major) {
137137
return current.major > minimum.major;
138138
}
139-
139+
140140
// Major versions are equal, compare minor
141141
if (current.minor !== minimum.minor) {
142142
return current.minor > minimum.minor;
143143
}
144-
144+
145145
// Major and minor are equal, compare patch
146146
return current.patch >= minimum.patch;
147147
}
@@ -357,20 +357,20 @@ export function setupBIFiles(projectDir: string): void {
357357
});
358358
}
359359

360-
export function getPackageName(projectInfo: ProjectInfo, projectPath: string): string {
360+
export function getOrgAndPackageName(projectInfo: ProjectInfo, projectPath: string): { orgName: string, packageName: string } {
361361
if (!projectPath || !projectInfo) {
362-
return "";
362+
return { orgName: '', packageName: '' };
363363
}
364364

365365
if (projectInfo.children?.length) {
366366
const matchedProject = projectInfo.children.find(
367367
(child) => child.projectPath === projectPath
368368
);
369-
369+
370370
if (matchedProject) {
371-
return matchedProject.title || matchedProject.name;
371+
return { orgName: matchedProject.org || matchedProject.orgName, packageName: matchedProject.name };
372372
}
373373
}
374374

375-
return projectInfo.title || projectInfo.name;
375+
return { orgName: projectInfo.org || projectInfo.orgName, packageName: projectInfo.name || projectInfo.title };
376376
}

workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/ConfigurableItem/ConfigObjectEditor.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,11 +499,17 @@ export function ConfigObjectEditor(props: ObjectEditorProps) {
499499
// If there's an existing config value, parse it and merge with recordConfig
500500
if (configValue) {
501501
try {
502-
let parsedValue;
502+
let parsedValue: any;
503503
if (typeof configValue === 'string') {
504504
// Attempt to fix JSON if it is JavaScript-style (unquoted keys)
505505
const fixedJson = configValue.replace(/([{,]\s*)([a-zA-Z0-9_]+)\s*:/g, '$1"$2":');
506506
parsedValue = JSON.parse(fixedJson);
507+
// Check if there are string values that are not wrapped in quotes
508+
Object.keys(parsedValue).forEach(key => {
509+
if (typeof parsedValue[key] === 'string' && !/^".*"$/.test(parsedValue[key])) {
510+
parsedValue[key] = `"${parsedValue[key]}"`;
511+
}
512+
});
507513
} else {
508514
parsedValue = configValue;
509515
}

workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/ConfigurableItem/index.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,20 @@ export function ConfigurableItem(props: ConfigurableItemProps) {
124124
setEditConfigVariableFormOpen(true);
125125
};
126126

127+
const handleTextAreaChange = (value: any) => {
128+
if (configVariable.properties?.type?.value === 'string' && !/^".*"$/.test(value)) {
129+
value = `"${value}"`;
130+
}
131+
handleUpdateConfigValue(value, configVariable);
132+
}
133+
134+
const getPlainValue = (value: string) => {
135+
if (configVariable.properties?.type?.value === 'string' && /^".*"$/.test(value)) {
136+
return value.replace(/^"|"$/g, '');
137+
}
138+
return value;
139+
}
140+
127141
const handleUpdateConfigValue = async (newValue: string, prevNode: ConfigVariable) => {
128142
const newConfigVarNode: ConfigVariable = {
129143
...prevNode,
@@ -304,13 +318,13 @@ export function ConfigurableItem(props: ConfigurableItemProps) {
304318
return Math.min(5, Math.ceil(value.length / 100));
305319
})()}
306320
resize="vertical"
307-
value={configVariable?.properties?.configValue?.value ? String(configVariable?.properties?.configValue?.value) : ''}
321+
value={configVariable?.properties?.configValue?.value ? getPlainValue(String(configVariable?.properties?.configValue?.value)) : ''}
308322
style={{
309323
width: '100%',
310324
maxWidth: '350px',
311325
minHeight: '20px'
312326
}}
313-
onChange={(e: any) => handleUpdateConfigValue(e.target.value, configVariable)}
327+
onChange={(e: any) => handleTextAreaChange(e.target.value)}
314328
>
315329
<style>{`
316330
vscode-text-area::part(control) {

workspaces/ballerina/ballerina-visualizer/src/views/BI/Configurables/ViewConfigurableVariables/index.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { AddForm } from "../AddConfigurableVariables";
2525
import { TopNavigationBar } from "../../../../components/TopNavigationBar";
2626
import { TitleBar } from "../../../../components/TitleBar";
2727
import ConfigurableItem from "../ConfigurableItem";
28+
import { RelativeLoader } from "../../../../components/RelativeLoader";
2829

2930
const Container = styled.div`
3031
width: 100%;
@@ -118,10 +119,12 @@ export function ViewConfigurableVariables(props?: ConfigProps) {
118119
const [categoriesWithModules, setCategoriesWithModules] = useState<CategoryWithModules[]>([]);
119120
const [selectedModule, setSelectedModule] = useState<PackageModuleState>(null);
120121
const integrationCategory = `${props.org}/${props.package}`;
122+
const [isLoading, setIsLoading] = useState<boolean>(false);
121123

122124
useEffect(() => {
123-
getConfigVariables();
124-
}, [props]);
125+
setIsLoading(true);
126+
getConfigVariables(true);
127+
}, [props.org, props.package]);
125128

126129
useEffect(() => {
127130
if (categoriesWithModules.length > 0 && !selectedModule) {
@@ -266,7 +269,7 @@ export function ViewConfigurableVariables(props?: ConfigProps) {
266269
});
267270
};
268271

269-
const getConfigVariables = async () => {
272+
const getConfigVariables = async (initialLoad: boolean = false) => {
270273

271274
let data: ConfigVariablesState = {};
272275
let errorMsg: string = '';
@@ -279,13 +282,13 @@ export function ViewConfigurableVariables(props?: ConfigProps) {
279282
.then((variables) => {
280283
data = (variables as any).configVariables;
281284
errorMsg = (variables as any).errorMsg;
282-
});
285+
})
283286

284287
setConfigVariables(data);
285288
setErrorMessage(errorMsg);
286289

287290
// Only set initial selected module if none is selected
288-
if (!selectedModule) {
291+
if (!selectedModule || initialLoad) {
289292
// Extract and set the available categories with their modules
290293
const extractedCategories = Object.keys(data).map(category => ({
291294
name: category,
@@ -300,6 +303,7 @@ export function ViewConfigurableVariables(props?: ConfigProps) {
300303
module: initialModule
301304
});
302305
}
306+
setIsLoading(false);
303307
};
304308

305309
const updateErrorMessage = (message: string) => {
@@ -355,7 +359,8 @@ export function ViewConfigurableVariables(props?: ConfigProps) {
355359
/>
356360
</SearchContainer>
357361
<div style={{ width: "auto" }}>
358-
<SplitView defaultWidths={[20, 80]}>
362+
{isLoading && <RelativeLoader message="Loading configurable variables..." />}
363+
{!isLoading && <SplitView defaultWidths={[20, 80]}>
359364
{/* Left side tree view */}
360365
<div id={`package-treeview`} style={{ padding: "10px 0 50px 0" }}>
361366
{/* Display integration category first */}
@@ -670,7 +675,7 @@ export function ViewConfigurableVariables(props?: ConfigProps) {
670675
}
671676
</>
672677
</div>
673-
</SplitView>
678+
</SplitView>}
674679
</div>
675680
</div>
676681
</ViewContent>

workspaces/mi/mi-extension/src/rpc-managers/mi-data-mapper/rpc-manager.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,13 @@ export class MiDataMapperRpcManager implements MIDataMapperAPI {
170170

171171
async formatDMC(documentUri: string): Promise<void> {
172172
const uri = Uri.file(documentUri);
173-
const edits: TextEdit[] = await commands.executeCommand("vscode.executeFormatDocumentProvider", uri);
173+
let edits: TextEdit[];
174+
try {
175+
edits = await commands.executeCommand("vscode.executeFormatDocumentProvider", uri);
176+
} catch (error) {
177+
console.error("Error occurred while formatting DMC file: ", error);
178+
return;
179+
}
174180
const workspaceEdit = new WorkspaceEdit();
175181
workspaceEdit.set(uri, edits);
176182
await workspace.applyEdit(workspaceEdit);

0 commit comments

Comments
 (0)