diff --git a/docs/third-party-licenses.json b/docs/third-party-licenses.json
index 1701814d..503d61b7 100644
--- a/docs/third-party-licenses.json
+++ b/docs/third-party-licenses.json
@@ -27,13 +27,6 @@
"url": "https://github.com/microsoft/vscode-codicons",
"license": "https://github.com/microsoft/vscode-codicons/blob/main/LICENSE"
},
- {
- "name": "@vscode/webview-ui-toolkit",
- "version": "1.4.0",
- "spdx": "MIT",
- "url": "https://github.com/microsoft/vscode-webview-ui-toolkit",
- "license": "https://github.com/microsoft/vscode-webview-ui-toolkit/blob/main/LICENSE"
- },
{
"name": "async-mutex",
"version": "0.5.0",
diff --git a/package-lock.json b/package-lock.json
index 58b862c4..36902ea3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,7 +16,6 @@
"@lydell/node-pty": "^1.1.0",
"@microsoft/vscode-serial-monitor-api": "^0.1.7",
"@vscode/codicons": "^0.0.44",
- "@vscode/webview-ui-toolkit": "^1.4.0",
"antd": "^5.29.3",
"async-mutex": "^0.5.0",
"eta": "^4.5.1",
@@ -5138,47 +5137,6 @@
"win32"
]
},
- "node_modules/@microsoft/fast-element": {
- "version": "1.14.0",
- "integrity": "sha512-zXvuSOzvsu8zDTy9eby8ix8VqLop2rwKRgp++ZN2kTCsoB3+QJVoaGD2T/Cyso2ViZQFXNpiNCVKfnmxBvmWkQ==",
- "license": "MIT"
- },
- "node_modules/@microsoft/fast-foundation": {
- "version": "2.50.0",
- "integrity": "sha512-8mFYG88Xea1jZf2TI9Lm/jzZ6RWR8x29r24mGuLojNYqIR2Bl8+hnswoV6laApKdCbGMPKnsAL/O68Q0sRxeVg==",
- "license": "MIT",
- "dependencies": {
- "@microsoft/fast-element": "^1.14.0",
- "@microsoft/fast-web-utilities": "^5.4.1",
- "tabbable": "^5.2.0",
- "tslib": "^1.13.0"
- }
- },
- "node_modules/@microsoft/fast-foundation/node_modules/tslib": {
- "version": "1.14.1",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "license": "0BSD"
- },
- "node_modules/@microsoft/fast-react-wrapper": {
- "version": "0.3.25",
- "integrity": "sha512-jKzmk2xJV93RL/jEFXEZgBvXlKIY4N4kXy3qrjmBfFpqNi3VjY+oUTWyMnHRMC5EUhIFxD+Y1VD4u9uIPX3jQw==",
- "license": "MIT",
- "dependencies": {
- "@microsoft/fast-element": "^1.14.0",
- "@microsoft/fast-foundation": "^2.50.0"
- },
- "peerDependencies": {
- "react": ">=16.9.0"
- }
- },
- "node_modules/@microsoft/fast-web-utilities": {
- "version": "5.4.1",
- "integrity": "sha512-ReWYncndjV3c8D8iq9tp7NcFNc1vbVHvcBFPME2nNFKNbS1XCesYZGlIlf3ot5EmuOXPlrzUHOWzQ2vFpIkqDg==",
- "license": "MIT",
- "dependencies": {
- "exenv-es6": "^1.1.1"
- }
- },
"node_modules/@microsoft/vscode-serial-monitor-api": {
"version": "0.1.7",
"integrity": "sha512-ROmxRIryoE1ZKAcrO3xS9NaUcLimihjT63b6Sh3YEQ4qZ6zC5QwysP6zUDM6W0jalQxoJuDH0hac4A8TTl5quQ==",
@@ -7191,21 +7149,6 @@
"concat-map": "0.0.1"
}
},
- "node_modules/@vscode/webview-ui-toolkit": {
- "version": "1.4.0",
- "integrity": "sha512-modXVHQkZLsxgmd5yoP3ptRC/G8NBDD+ob+ngPiWNQdlrH6H1xR/qgOBD85bfU3BhOB5sZzFWBwwhp9/SfoHww==",
- "deprecated": "This package has been deprecated, https://github.com/microsoft/vscode-webview-ui-toolkit/issues/561",
- "license": "MIT",
- "dependencies": {
- "@microsoft/fast-element": "^1.12.0",
- "@microsoft/fast-foundation": "^2.49.4",
- "@microsoft/fast-react-wrapper": "^0.3.22",
- "tslib": "^2.6.2"
- },
- "peerDependencies": {
- "react": ">=16.9.0"
- }
- },
"node_modules/@webassemblyjs/ast": {
"version": "1.14.1",
"integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
@@ -10998,11 +10941,6 @@
"dev": true,
"license": "ISC"
},
- "node_modules/exenv-es6": {
- "version": "1.1.1",
- "integrity": "sha512-vlVu3N8d6yEMpMsEm+7sUBAI81aqYYuEvfK0jNqmdb/OPXzzH7QWDDnVjMvDSY47JdHEqx/dfC/q8WkfoTmpGQ==",
- "license": "MIT"
- },
"node_modules/exit": {
"version": "0.1.2",
"integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
@@ -21074,11 +21012,6 @@
"node": ">=18"
}
},
- "node_modules/tabbable": {
- "version": "5.3.3",
- "integrity": "sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA==",
- "license": "MIT"
- },
"node_modules/table": {
"version": "6.9.0",
"integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==",
diff --git a/package.json b/package.json
index 7d389cb7..c3cce2b4 100644
--- a/package.json
+++ b/package.json
@@ -79,7 +79,6 @@
"@lydell/node-pty": "^1.1.0",
"@microsoft/vscode-serial-monitor-api": "^0.1.7",
"@vscode/codicons": "^0.0.44",
- "@vscode/webview-ui-toolkit": "^1.4.0",
"antd": "^5.29.3",
"async-mutex": "^0.5.0",
"eta": "^4.5.1",
@@ -1553,7 +1552,7 @@
]
},
"transformIgnorePatterns": [
- "/node_modules/(?!(@vscode/webview-ui-toolkit|@microsoft|exenv-es6|yaml)/)"
+ "/node_modules/(?!(@microsoft|yaml)/)"
],
"testPathIgnorePatterns": [
"/node_modules/",
diff --git a/src/views/common/components/compact-dropdown.tsx b/src/views/common/components/compact-dropdown.tsx
index 91529847..f13ddb81 100644
--- a/src/views/common/components/compact-dropdown.tsx
+++ b/src/views/common/components/compact-dropdown.tsx
@@ -115,7 +115,7 @@ export const CompactDropdown = (props: CompactDropdownProps) => {
{props.addonBefore &&
{props.addonBefore}
}
-
+
{props.displayText ? props.displayText(props.selected) : props.selected || props.unselectedLabel} {props.tag}
{props.warning && }
{props.available.length > 1 && }
diff --git a/src/views/common/components/file-path-picker.test.tsx b/src/views/common/components/file-path-picker.test.tsx
index 01028250..065fbb25 100644
--- a/src/views/common/components/file-path-picker.test.tsx
+++ b/src/views/common/components/file-path-picker.test.tsx
@@ -45,12 +45,15 @@ describe('FileLocationPicker', () => {
openFilePicker={mockOpenFilePicker}
/>);
});
- const browseBtn = container.querySelector('.file-location-picker vscode-button') as HTMLButtonElement;
+ const browseBtn = container.querySelector('.file-location-picker button') as HTMLButtonElement;
expect(mockOpenFilePicker).toHaveBeenCalledTimes(0);
React.act(() => {
- browseBtn!.click();
+ if (!browseBtn) {
+ throw new Error('Browse button not found. Check the selector or component rendering.');
+ }
+ browseBtn.click();
});
expect(mockOpenFilePicker).toHaveBeenCalledTimes(1);
@@ -76,6 +79,6 @@ describe('FileLocationPicker', () => {
simulateChangeEvent(inputBox, 'my-location');
expect(dispatch).toHaveBeenCalledTimes(1);
- expect(dispatch).toHaveBeenCalledWith({ type: 'SET_SOLUTION_LOCATION' , solutionLocation: 'my-location' });
+ expect(dispatch).toHaveBeenCalledWith({ type: 'SET_SOLUTION_LOCATION', solutionLocation: 'my-location' });
});
});
diff --git a/src/views/common/components/file-path-picker.tsx b/src/views/common/components/file-path-picker.tsx
index 8cfb749b..13aa4d13 100644
--- a/src/views/common/components/file-path-picker.tsx
+++ b/src/views/common/components/file-path-picker.tsx
@@ -16,8 +16,8 @@
import './file-path-picker.css';
import * as React from 'react';
-import { VSCodeButton } from '@vscode/webview-ui-toolkit/react';
import { CreateSolutionAction } from '../../create-solutions/view/state/reducer';
+import { Button } from 'antd';
export interface FileLocationPickerProps {
disabled: boolean;
@@ -41,12 +41,13 @@ export const FileLocationPicker = ({ id, disabled, location, dispatch, openFileP
})}
value={location}
disabled={disabled} />
- openFilePicker()}
>
Browse
-
+
);
diff --git a/src/views/config-wizard/confwiz-webview-main.ts b/src/views/config-wizard/confwiz-webview-main.ts
index 8495b6c8..aa79ecec 100644
--- a/src/views/config-wizard/confwiz-webview-main.ts
+++ b/src/views/config-wizard/confwiz-webview-main.ts
@@ -152,13 +152,6 @@ export class ConfWizWebview implements vscode.CustomTextEditorProvider {
}
protected _getWebviewContent(webview: vscode.Webview, extensionUri: vscode.Uri): string {
- const toolkitUri = webview.asWebviewUri(vscode.Uri.joinPath(
- extensionUri,
- 'dist',
- 'views',
- 'toolkit.min.js'
- ));
-
const mainUri = webview.asWebviewUri(vscode.Uri.joinPath(
extensionUri,
'dist',
@@ -194,7 +187,6 @@ export class ConfWizWebview implements vscode.CustomTextEditorProvider {
-
diff --git a/src/views/config-wizard/confwiz-webview-view-component.test.tsx b/src/views/config-wizard/confwiz-webview-view-component.test.tsx
index 7d6b344c..5b1b022e 100644
--- a/src/views/config-wizard/confwiz-webview-view-component.test.tsx
+++ b/src/views/config-wizard/confwiz-webview-view-component.test.tsx
@@ -29,6 +29,12 @@ import {
const sendNotificationMock = jest.fn();
const notificationHandlers = new Map
void>();
+const mockVsCodeApi = {
+ postMessage: jest.fn(),
+ setState: jest.fn(),
+ getState: jest.fn(),
+};
+const acquireVsCodeApiMock = jest.fn(() => mockVsCodeApi);
const getNotificationKey = (type: unknown): string => {
if (typeof type === 'string') {
@@ -42,13 +48,6 @@ const getNotificationKey = (type: unknown): string => {
return String(type);
};
-// Mock acquireVsCodeApi
-global.acquireVsCodeApi = jest.fn(() => ({
- postMessage: jest.fn(),
- setState: jest.fn(),
- getState: jest.fn(),
-}));
-
jest.mock('vscode-messenger-webview', () => ({
Messenger: jest.fn().mockImplementation(() => ({
start: jest.fn(),
@@ -59,22 +58,11 @@ jest.mock('vscode-messenger-webview', () => ({
}))
}));
-jest.mock('@vscode/webview-ui-toolkit/react', () => ({
- VSCodeTextField: ({ children: _children, ...props }: React.InputHTMLAttributes) => (
-
- ),
- VSCodeCheckbox: ({ onChange, onClick, ...props }: React.InputHTMLAttributes) => (
- undefined)} onClick={onClick} {...props} />
- ),
- VSCodeDropdown: (props: React.SelectHTMLAttributes) => ,
- VSCodeOption: (props: React.OptionHTMLAttributes) => ,
-}));
-
jest.mock('primereact/treetable', () => ({
TreeTable: ({ value, header, children }: { value: unknown[]; header: React.ReactNode; children: React.ReactNode }) => {
const columns = React.Children.toArray(children) as React.ReactElement[];
return (
-
+ <>
{header}
{value?.map((node: unknown, index: number) => (
@@ -83,7 +71,7 @@ jest.mock('primereact/treetable', () => ({
))}
))}
-
+ >
);
},
}));
@@ -130,10 +118,19 @@ const makeRoot = (children: TreeNodeElement[]): TreeNodeElement => ({
describe('ConfWiz functional component', () => {
beforeEach(() => {
+ (globalThis as { acquireVsCodeApi?: () => unknown }).acquireVsCodeApi = acquireVsCodeApiMock;
+ acquireVsCodeApiMock.mockClear();
sendNotificationMock.mockClear();
+ mockVsCodeApi.postMessage.mockClear();
+ mockVsCodeApi.setState.mockClear();
+ mockVsCodeApi.getState.mockClear();
notificationHandlers.clear();
});
+ afterEach(() => {
+ delete (globalThis as { acquireVsCodeApi?: () => unknown }).acquireVsCodeApi;
+ });
+
it('marks dirty on first edit and saves on blur', () => {
const editElement: TreeNodeElement = {
guiId: 1,
@@ -175,8 +172,8 @@ describe('ConfWiz functional component', () => {
render( );
emitWizardData({ element: makeRoot([checkboxElement]), documentPath: 'test.c', noAnnotationsFound: false });
- const checkbox = document.querySelector('input[type="checkbox"]') as HTMLInputElement;
- expect(checkbox.className).toContain('checkbox-inconsistent');
+ const checkbox = document.querySelector('input[type="checkbox"]')?.parentElement as HTMLInputElement;
+ expect(checkbox.parentElement?.className).toContain('checkbox-inconsistent');
expect(checkbox.getAttribute('title')).toContain('Inconsistent comment state detected');
expect(checkbox.getAttribute('title')).toContain('Original tooltip info');
});
@@ -270,8 +267,8 @@ describe('ConfWiz dropdown overflow tooltips', () => {
const { getByRole } = render(confWiz.getCreateCombobox(element));
const dropdown = getByRole('combobox') as HTMLSelectElement;
- expect(dropdown.title).toBe("Value '256' overflows 8 bits");
- expect(dropdown.className).toContain('dropdown-invalid');
+ expect(dropdown.title).toBe('Value \'256\' overflows 8 bits');
+ expect(dropdown.className).toContain('compact-dropdown-trigger');
});
it('should show not-in-list tooltip when value is missing and no overflow', () => {
@@ -295,6 +292,6 @@ describe('ConfWiz dropdown overflow tooltips', () => {
const dropdown = getByRole('combobox') as HTMLSelectElement;
expect(dropdown.title).toBe("Value '0' is not in the list");
- expect(dropdown.className).toContain('dropdown-invalid');
+ expect(dropdown.className).toContain('compact-dropdown-trigger');
});
});
diff --git a/src/views/config-wizard/confwiz-webview-view-component.tsx b/src/views/config-wizard/confwiz-webview-view-component.tsx
index 0b918082..378851d6 100644
--- a/src/views/config-wizard/confwiz-webview-view-component.tsx
+++ b/src/views/config-wizard/confwiz-webview-view-component.tsx
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-import { VSCodeCheckbox, VSCodeDropdown, VSCodeOption, VSCodeTextField } from '@vscode/webview-ui-toolkit/react';
import { Column, ColumnBodyOptions } from 'primereact/column';
import { TreeNode } from 'primereact/treenode';
import { TreeTable } from 'primereact/treetable';
@@ -32,8 +31,12 @@ import {
setPanelActiveType,
setWizardDataType
} from './confwiz-webview-common';
+import { Input, Checkbox, ConfigProvider, theme } from 'antd';
import { filterTree } from './../filterTree';
import './confwiz-webview.css';
+import { CompactDropdown } from '../common/components/compact-dropdown';
+
+const { Search } = Input;
// Render-only helper flag for dimming
type DTreeNode = TreeNode & { dimmed?: boolean };
@@ -77,8 +80,8 @@ export class ConfWiz extends React.Component, State> {
};
protected get messenger(): Messenger {
if (!this._messenger) {
- const vscode = acquireVsCodeApi();
- this._messenger = new Messenger(vscode);
+ const vscodeApi = acquireVsCodeApi();
+ this._messenger = new Messenger(vscodeApi);
this._messenger.start();
}
@@ -382,86 +385,81 @@ export class ConfWiz extends React.Component, State> {
const errorsText = this.getErrorsText(rootNode);
const header =
- {
+ this.setState({ filter: '' });
+ }}
onInput={(event): void => {
const element = event.target as HTMLInputElement;
this.setState({ filter: element.value });
}}
- >
-
-
+ />
;
const filteredChildren = filterTree(rootNode.children, this.state.filter);
+ const isDarkTheme = document.body.classList.contains('vscode-dark');
- return
- }) => {
- this.pendingRefocus = true;
- this.pendingRefocusKey = this.state.activeKey;
- this.setState({ expandedKeys: event.value });
- }}
- // Apply dimming to the row itself; no extra wrappers in cells (keeps expanders aligned)
- rowClassName={(node: DTreeNode) => {
- const key = this.getNodeKey(node);
- const lastTouchedKey = this.state.lastTouchedKey ?? this.state.activeKey;
- const isLastTouched = key !== '' && key === lastTouchedKey;
- const isInactive = isLastTouched && (!this.state.panelIsActive || !this.state.hasUserFocus);
- const isActive = key !== '' && key === this.state.activeKey && this.state.panelIsActive && this.state.hasUserFocus;
- return {
- 'tree-dimmed': !!node?.dimmed,
- 'cw-row-active': isActive,
- 'cw-row-inactive': isInactive,
- };
- }}
- >
- {
- return this.createTextName(data.data as TreeNodeElement);
- }}
- />
- {
- const treeNodeData = data.data as TreeNodeElement;
- const isDimmed = (data as DTreeNode).dimmed || false;
-
- // Only disable children of unchecked checkboxes, not the unchecked checkbox itself
- const isUncheckedCheckbox = this.isUncheckedCheckbox(treeNodeData);
- const shouldDisable = isDimmed && !isUncheckedCheckbox;
-
- return this.createGuiElement(treeNodeData, shouldDisable);
- }}
- />
-
- {errorsText}
-
;
- }
-
- protected getComboDropItems(element: TreeNodeElement): React.JSX.Element[] {
- if (element.dropItems == undefined) {
- return [];
- }
-
- const options: React.JSX.Element[] = [];
- for (const val of element.dropItems) {
- const sel = (element.value.value == val) ? true : false;
- options.push({val} );
- }
-
- return options;
+ return (
+
+
+ }) => {
+ this.pendingRefocus = true;
+ this.pendingRefocusKey = this.state.activeKey;
+ this.setState({ expandedKeys: event.value });
+ }}
+ // Apply dimming to the row itself; no extra wrappers in cells (keeps expanders aligned)
+ rowClassName={(node: DTreeNode) => {
+ const key = this.getNodeKey(node);
+ const lastTouchedKey = this.state.lastTouchedKey ?? this.state.activeKey;
+ const isLastTouched = key !== '' && key === lastTouchedKey;
+ const isInactive = isLastTouched && (!this.state.panelIsActive || !this.state.hasUserFocus);
+ const isActive = key !== '' && key === this.state.activeKey && this.state.panelIsActive && this.state.hasUserFocus;
+ return {
+ 'tree-dimmed': !!node?.dimmed,
+ 'cw-row-active': isActive,
+ 'cw-row-inactive': isInactive,
+ };
+ }}
+ >
+ {
+ return this.createTextName(data.data as TreeNodeElement);
+ }}
+ />
+ {
+ const treeNodeData = data.data as TreeNodeElement;
+ const isDimmed = (data as DTreeNode).dimmed || false;
+
+ // Only disable children of unchecked checkboxes, not the unchecked checkbox itself
+ const isUncheckedCheckbox = this.isUncheckedCheckbox(treeNodeData);
+ const shouldDisable = isDimmed && !isUncheckedCheckbox;
+
+ return this.createGuiElement(treeNodeData, shouldDisable);
+ }}
+ />
+
+ {errorsText}
+
+
+ );
}
protected getInfoItems(element: TreeNodeElement): string {
@@ -475,7 +473,7 @@ export class ConfWiz extends React.Component, State> {
}
protected createCombobox(element: TreeNodeElement, shouldDisable: boolean = false): React.ReactElement {
- const options = this.getComboDropItems(element);
+ // const options = this.getComboDropItems(element);
const infos = this.getInfoItems(element);
const key = this.getElementKey(element);
@@ -491,11 +489,11 @@ export class ConfWiz extends React.Component, State> {
// If there's no matching option, inject a temporary "missing" option so the selection is visible
if (isInvalid) {
- options.unshift(
-
- {`${selectedValue} (not in list)`}
-
- );
+ // options.unshift(
+ //
+ // {`${selectedValue} (not in list)`}
+ //
+ // );
}
let tooltipMessage = infos;
@@ -509,24 +507,25 @@ export class ConfWiz extends React.Component, State> {
return (
this.handleUserFocus(key)}>
- {
- const selectElement = event.target as HTMLSelectElement;
- this.inputDropdown(selectElement, element);
- }}
- onKeyDown={(event) => {
- if (this.keyboardNav.onValueKeyDown(event, key)) {
- return;
- }
- this.onKeyDownFilter(event);
+ selected={selectedValue}
+ available={dropItems}
+ style={{ width: '100%' }}
+ onChange={(value) => {
+ // const selectElement = event.target as HTMLSelectElement;
+ // this.inputDropdown(selectElement, element);
+ element.newValue.value = value;
+ // Immediate local update for consistent behavior with checkbox and text field
+ element.value.value = value;
+ this.forceUpdate();
+ // Toggle forceRender to trigger React re-render
+ this.setState(prevState => ({ forceRender: !prevState.forceRender }));
+ this.messenger.sendNotification(saveElement, HOST_EXTENSION, { documentPath: this.state.documentPath, element, noAnnotationsFound: false });
}}
title={tooltipMessage}
- >
- {options}
-
+ warning={isInvalid || hasOverflow ? tooltipMessage : undefined}
+ />
);
}
@@ -553,11 +552,11 @@ export class ConfWiz extends React.Component, State> {
: infos;
const option = (
- {
- const inputElement = event.currentTarget as HTMLInputElement;
+ onChange={(event) => {
+ const inputElement = event.target as HTMLInputElement;
this.toggleChecked(inputElement, element);
}}
onKeyDown={(event) => {
@@ -584,11 +583,15 @@ export class ConfWiz extends React.Component, State> {
protected createEdit(element: TreeNodeElement, shouldDisable: boolean = false): React.ReactElement {
const infos = this.getInfoItems(element);
const key = this.getElementKey(element);
- const option = {
+ element.value.value = (e.target as HTMLInputElement).value;
+ this.forceUpdate();
+ }}
onInput={(event) => {
const inputElement = event.target as HTMLInputElement;
// Update local state immediately for UI responsiveness
@@ -687,7 +690,7 @@ export class ConfWiz extends React.Component, State> {
this.messenger.sendNotification(saveElement, HOST_EXTENSION, { documentPath: this.state.documentPath, element, noAnnotationsFound: false });
}
- private onEditChange(edit: HTMLInputElement, element: TreeNodeElement) {
+ private onEditChange(edit: HTMLInputElement | HTMLTextAreaElement, element: TreeNodeElement) {
// - element.newValue.value: used for backend save logic
element.newValue.value = edit.value;
// - element.value.value: used for immediate UI update (VSCodeTextField value property)
@@ -695,15 +698,6 @@ export class ConfWiz extends React.Component, State> {
this.messenger.sendNotification(saveElement, HOST_EXTENSION, { documentPath: this.state.documentPath, element, noAnnotationsFound: false });
}
- private inputDropdown(selected: HTMLSelectElement, element: TreeNodeElement) {
- element.newValue.value = selected.value;
- // Immediate local update for consistent behavior with checkbox and text field
- element.value.value = selected.value;
- // Toggle forceRender to trigger React re-render
- this.setState(prevState => ({ forceRender: !prevState.forceRender }));
- this.messenger.sendNotification(saveElement, HOST_EXTENSION, { documentPath: this.state.documentPath, element, noAnnotationsFound: false });
- }
-
/**
* Filters 'keydown' event for navigation keys and stops event propagation if matches.
* This keeps TreeTable to avoid using them for navigation through the tree while for
diff --git a/src/views/create-solutions/view/components/create-solution.test.tsx b/src/views/create-solutions/view/components/create-solution.test.tsx
index 8591e9de..e1fdfec3 100644
--- a/src/views/create-solutions/view/components/create-solution.test.tsx
+++ b/src/views/create-solutions/view/components/create-solution.test.tsx
@@ -17,7 +17,6 @@
import 'jest';
import * as React from 'react';
import { createRoot } from 'react-dom/client';
-import { act } from 'react-dom/test-utils';
import { simulateChangeEvent } from '../../../../__test__/dom-events';
import { refAppFactory } from '../../../../core-tools/core-tools-service.factories';
import { cSolutionExampleFactory } from '../../../../solar-search/solar-search-client.factories';
@@ -25,33 +24,36 @@ import { MockMessageHandler } from '../../../__test__/mock-message-handler';
import { boardHardwareOptionFactory, deviceHardwareOptionFactory } from '../../cmsis-solution-types.factories';
import { IncomingMessage, OutgoingMessage } from '../../messages';
import { CreationActions } from '../actions';
-import { CreateSolutionState } from '../state/reducer';
import { CreateSolution } from './create-solution';
+import { act } from 'react';
+import { CreateSolutionState } from '../state/reducer';
-const targetDataWindowMessage: IncomingMessage = { type: 'TARGET_DATA', data: {
- devices: [
- {
- header: 'Test Header',
- categories: [],
- items: ['A', 'B', 'C'].map(i => ({
- label: `Item ${i}`,
- value: deviceHardwareOptionFactory(),
- }))
- }
- ],
- boards: [
- {
- header: 'Test Header',
- categories: [],
- items: ['A', 'B', 'C'].map(i => ({
- label: `Item ${i}`,
- value: boardHardwareOptionFactory(),
- }))
- }
- ]
-}, errors: [] };
+const targetDataWindowMessage: IncomingMessage = {
+ type: 'TARGET_DATA', data: {
+ devices: [
+ {
+ header: 'Test Header',
+ categories: [],
+ items: ['A', 'B', 'C'].map(i => ({
+ label: `Item ${i}`,
+ value: deviceHardwareOptionFactory(),
+ }))
+ }
+ ],
+ boards: [
+ {
+ header: 'Test Header',
+ categories: [],
+ items: ['A', 'B', 'C'].map(i => ({
+ label: `Item ${i}`,
+ value: boardHardwareOptionFactory(),
+ }))
+ }
+ ]
+ }, errors: []
+};
describe('CreateSolution', () => {
let container: Element;
@@ -60,8 +62,8 @@ describe('CreateSolution', () => {
let creationActions: { [key in keyof CreationActions]: jest.Mock, Parameters> };
const getElements = () => ({
- createBtn: container.querySelector('vscode-button[title="Create Solution"]') as HTMLButtonElement,
- cancelBtn: container.querySelector('vscode-button[title="Cancel"]') as HTMLButtonElement,
+ createBtn: container.querySelector('button[title="Create Solution"]') as HTMLButtonElement,
+ cancelBtn: container.querySelector('button[title="Cancel"]') as HTMLButtonElement,
fInput: container.querySelector('#create-solution-solution-folder') as HTMLInputElement,
boardDropdown: container.querySelector('#create-solution-board-target') as HTMLElement,
deviceDropdown: container.querySelector('#create-solution-device-target') as HTMLElement,
@@ -79,6 +81,11 @@ describe('CreateSolution', () => {
await act(async () => firstOption.click());
};
+ const confirmTargetSelection = async () => {
+ const selectButton = container.querySelector('button[title="Select"]:not([disabled])') as HTMLButtonElement;
+ await act(async () => selectButton.click());
+ };
+
const selectFirstTemplate = async () => {
const firstTemplate = container.querySelector('.template') as HTMLElement;
await act(async () => firstTemplate.click());
@@ -94,6 +101,7 @@ describe('CreateSolution', () => {
await openDropdown(elements.boardDropdown);
await selectFirstTarget();
+ await confirmTargetSelection();
await openDropdown(elements.templateDropdown);
await selectFirstTemplate();
@@ -120,6 +128,17 @@ describe('CreateSolution', () => {
case 'GET_PLATFORM':
messageHandler.postWindowMessage({ type: 'PLATFORM', data: { name: 'vscode' } });
break;
+ case 'DATA_GET_BOARD_INFO':
+ messageHandler.postWindowMessage({
+ type: 'HARDWARE_INFO',
+ data: {
+ memoryInfo: {},
+ image: '',
+ debugInterfacesList: [],
+ boardInfo: boardHardwareOptionFactory(),
+ },
+ });
+ break;
}
messageHandler.postWindowMessage({ type: 'REQUEST_SUCCESSFUL', requestType: message.type });
});
@@ -153,10 +172,10 @@ describe('CreateSolution', () => {
it('requests closure of the webview on the cancel button', async () => {
await renderCreateSolution();
const expectedMessage: OutgoingMessage = { type: 'WEBVIEW_CLOSE' };
- const cancelBtn = Array.from(container.querySelectorAll('#create-solution-form vscode-button'))
+ const cancelBtn = Array.from(container.querySelectorAll('#create-solution-form button'))
.find(button => button.innerHTML.includes('Cancel')) as HTMLButtonElement;
- await act(async() => cancelBtn!.click());
+ await act(async () => cancelBtn!.click());
expect(listener).toHaveBeenLastCalledWith(expectedMessage);
});
@@ -178,7 +197,7 @@ describe('CreateSolution', () => {
const example = cSolutionExampleFactory();
messageHandler.postWindowMessage({
type: 'BOARD_EXAMPLE_DATA',
- data: [ example ],
+ data: [example],
});
await openDropdown(getElements().templateDropdown);
@@ -239,7 +258,7 @@ describe('CreateSolution', () => {
it('requests the directory path when the browse button is clicked', async () => {
await renderCreateSolution();
- const browseBtn = container.querySelector('#create-solution-file-locator ~ vscode-button') as HTMLButtonElement;
+ const browseBtn = container.querySelector('#create-solution-file-locator ~ button') as HTMLButtonElement;
await act(async () => browseBtn!.click());
@@ -275,7 +294,7 @@ describe('CreateSolution', () => {
expect(errorMessageElement.innerHTML.includes('already exists at this location'));
});
- it ('auto selects a board if it is connected', async () => {
+ it('auto selects a board if it is connected', async () => {
const connectedBoard = targetDataWindowMessage.data.boards[0].items[1].value;
listener.mockImplementation(async (message: OutgoingMessage) => {
switch (message.type) {
@@ -300,7 +319,7 @@ describe('CreateSolution', () => {
messageHandler.postWindowMessage({
type: 'BOARD_EXAMPLE_DATA',
- data: [ example ],
+ data: [example],
});
const templateDropdown = getElements().templateDropdown;
diff --git a/src/views/create-solutions/view/components/create-solution.tsx b/src/views/create-solutions/view/components/create-solution.tsx
index 1ca54222..b3d2727f 100644
--- a/src/views/create-solutions/view/components/create-solution.tsx
+++ b/src/views/create-solutions/view/components/create-solution.tsx
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-import { VSCodeButton, VSCodeCheckbox } from '@vscode/webview-ui-toolkit/react';
import * as React from 'react';
import { FileLocationPicker } from '../../../common/components/file-path-picker';
import { TooltipQuestion } from '../../../common/components/tooltip-question';
@@ -29,7 +28,7 @@ import { ExampleDropdownTree } from './example-dropdown-tree';
import { HardwareRow } from './hardware-row';
import { ProjectConfiguration } from './project-configuration';
import { validationError } from './validation-message';
-import { ConfigProvider, theme, Tooltip } from 'antd';
+import { Button, Checkbox, ConfigProvider, theme, Tooltip } from 'antd';
import { useVSCodeTheme } from '../../../hooks/use-vscode-theme';
import { SettingOutlined } from '@ant-design/icons';
@@ -47,12 +46,12 @@ export interface CreateSolutionProps {
const SettingsLink = ({ setting, children }: { setting: string, children?: React.ReactNode }) => (
<>
- { children }
-
-
+
>
);
@@ -217,7 +216,7 @@ export const CreateSolution = ({ creationActions, messageHandler }: CreateSoluti
<>
Templates, Reference Applications, and Examples
- dispatch({ type: 'TOGGLE_ALL_PACK_VERSIONS' })} disabled={disabled} />
+ dispatch({ type: 'TOGGLE_ALL_PACK_VERSIONS' })} disabled={disabled} />
All pack versions
@@ -283,31 +282,31 @@ export const CreateSolution = ({ creationActions, messageHandler }: CreateSoluti
{validationError(validationErrors.solutionLocation)}
)}
- dispatch({ type: 'TOGGLE_INIT_GIT' })} disabled={disabled} />
+ dispatch({ type: 'TOGGLE_INIT_GIT' })} disabled={disabled} />
Initialize Git repository
- dispatch({ type: 'TOGGLE_OPEN_MODAL' })} disabled={disabled} />
+ dispatch({ type: 'TOGGLE_OPEN_MODAL' })} disabled={disabled} />
Show project opening options
- {
messageHandler.push({ type: 'WEBVIEW_CLOSE' });
}}
>
- Cancel
-
- creationActions.createSolution(dispatch, state, messageHandler)}>
+ Cancel
+
+ creationActions.createSolution(dispatch, state, messageHandler)}>
{state.createProgress === 'checking' ? 'Checking…' : state.createProgress === 'creating' ? 'Creating…' : 'Create'}
-
+
diff --git a/src/views/create-solutions/view/components/hardware-panel.test.tsx b/src/views/create-solutions/view/components/hardware-panel.test.tsx
index 0293327c..682e7daa 100644
--- a/src/views/create-solutions/view/components/hardware-panel.test.tsx
+++ b/src/views/create-solutions/view/components/hardware-panel.test.tsx
@@ -40,7 +40,7 @@ describe('Hardware Panel', () => {
const hardwareInfo: HardwareInfo = {
image: faker.internet.url(),
memoryInfo: { 'IROM1': { size: 32768, count: 2 } },
- debugInterfacesList: [{ adapter: 'JTAG', connector: '20 pin JTAG' } , { adapter: 'JTAG', connector: '30000 pin Micro USB' }],
+ debugInterfacesList: [{ adapter: 'JTAG', connector: '20 pin JTAG' }, { adapter: 'JTAG', connector: '30000 pin Micro USB' }],
};
beforeEach(() => {
@@ -69,7 +69,7 @@ describe('Hardware Panel', () => {
it('render hardware info panel for the selected Board/Device', () => {
React.act(() => {
- createRoot(container).render();
+ createRoot(container).render( );
});
const HardwareInfoTitlesEntry = container.querySelector('.details-header-item');
expect(HardwareInfoTitlesEntry!.querySelector('#board-device')?.innerHTML).toBe(labelForHardwareOption(boardHardwareOption));
@@ -86,7 +86,7 @@ describe('Hardware Panel', () => {
it('requests board/device hardwareInfo data on startup', () => {
React.act(() => {
- createRoot(container).render();
+ createRoot(container).render( );
});
const expectedMessage: OutgoingMessage = { type: 'DATA_GET_BOARD_INFO', boardId: { ...boardHardwareOption.id, key: boardHardwareOption.key } };
expect(listener).toHaveBeenCalledWith(expectedMessage);
@@ -95,9 +95,9 @@ describe('Hardware Panel', () => {
it('dispatches a SET_BOARD_SELECTION action when the select button is clicked and a board is selected', () => {
React.act(() => {
- createRoot(container).render();
+ createRoot(container).render( );
});
- const selectBtn = container.querySelector('.select-button vscode-button') as HTMLButtonElement;
+ const selectBtn = container.querySelector('.select-button button') as HTMLButtonElement;
React.act(() => {
Simulate.click(selectBtn);
@@ -110,9 +110,9 @@ describe('Hardware Panel', () => {
const deviceHardwareOption = deviceHardwareOptionFactory();
const deviceSelection: HardwareSelection = { type: 'Devices', value: deviceHardwareOption };
React.act(() => {
- createRoot(container).render();
+ createRoot(container).render( );
});
- const selectBtn = container.querySelector('.select-button vscode-button') as HTMLButtonElement;
+ const selectBtn = container.querySelector('.select-button button') as HTMLButtonElement;
React.act(() => {
Simulate.click(selectBtn);
diff --git a/src/views/create-solutions/view/components/hardware-panel.tsx b/src/views/create-solutions/view/components/hardware-panel.tsx
index f9ec5b21..eb0d854e 100644
--- a/src/views/create-solutions/view/components/hardware-panel.tsx
+++ b/src/views/create-solutions/view/components/hardware-panel.tsx
@@ -22,12 +22,12 @@ import { MessageHandler } from '../../../message-handler';
import { IncomingMessage, OutgoingMessage } from '../../messages';
import { formatBytes } from '../../units-conversion';
import { HardwareSelection } from '../state/hardware-selection';
-import { VSCodeButton, VSCodeProgressRing } from '@vscode/webview-ui-toolkit/react';
import * as Messages from '../../messages';
import { dedupe } from '../../../../array';
import { DebugInterface } from '../../../../core-tools/client/packs_pb';
import { CreateSolutionAction } from '../state/reducer';
import { serialisePackId } from '../../../../packs/pack-id';
+import { Button, Spin } from 'antd';
interface HardwarePanelProps {
hardwareInfo: HardwareInfo | undefined;
@@ -77,7 +77,7 @@ export const HardwarePanel = (props: HardwarePanelProps) => {
previewHardware.value.mountedDevices.flatMap(device => device.processors) :
previewHardware.value.processors;
- const coreCounts: {[key in string]: number} = {};
+ const coreCounts: { [key in string]: number } = {};
processorList.forEach(processorInfo => {
coreCounts[processorInfo.core] = (coreCounts[processorInfo.core] ?? 0) + 1;
});
@@ -119,51 +119,54 @@ export const HardwarePanel = (props: HardwarePanelProps) => {
.map(debugInterface => debugInterface.adapter);
content = (
- <>
-
-
{headingText}
-
{previewHardware.value.id.vendor}
- {enableWebsiteLinks && (
-
Product page
- )}
+ <>
+
+
+
{headingText}
+
{previewHardware.value.id.vendor}
+ {enableWebsiteLinks && (
+
Product page
+ )}
+
+
+
+
+ {coreElement}
+ {(previewHardware.type === 'Boards' && previewHardware.value.mountedDevices.length) ? (
+ <>
Mounted Devices
+
{previewHardware.value.mountedDevices.map((p, i) => (
+ {p.id.name}
+ ))}
+ >
+ ) : undefined}
+ {debugAdapters?.length ? (
+ <>
Debug Interface
+
{debugAdapters.map((adapter, i) => (
+ {adapter}
+ ))}
+ >
+ ) : undefined}
+ {memoryElement}
+ {packInfoElement}
+
+ {
+ dispatchSelect(previewHardware);
+ onClick();
+ }}>Select
-
-
- {coreElement}
- {(previewHardware.type === 'Boards' && previewHardware.value.mountedDevices.length) ? (
- <>
Mounted Devices
-
{previewHardware.value.mountedDevices.map((p, i) => (
- {p.id.name}
- ))}
- >
- ) : undefined}
- {debugAdapters?.length ? (
- <>
Debug Interface
-
{debugAdapters.map((adapter, i) => (
- {adapter}
- ))}
- >
- ) : undefined}
- {memoryElement}
- {packInfoElement}
-
- {
- dispatchSelect(previewHardware);
- onClick();
- } }>Select
-
>
+ >
);
} else if (previewHardware && !hardwareInfo) {
- content =
;
+ content =
;
} else {
content = (
Please select a target
- Select
+ Select
);
diff --git a/src/views/create-solutions/view/components/hardware-row.test.tsx b/src/views/create-solutions/view/components/hardware-row.test.tsx
index 53f37dcc..bdcd7973 100644
--- a/src/views/create-solutions/view/components/hardware-row.test.tsx
+++ b/src/views/create-solutions/view/components/hardware-row.test.tsx
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-import { TextField } from '@vscode/webview-ui-toolkit';
import * as React from 'react';
import { createRoot } from 'react-dom/client';
import { Simulate } from 'react-dom/test-utils';
@@ -40,13 +39,13 @@ describe('HardwareRow', () => {
const getElements = () => ({
boardDropdown: container.querySelector('#create-solution-board-target') as HTMLElement,
deviceDropdown: container.querySelector('#create-solution-device-target') as HTMLElement,
- targetType: container.querySelector('#create-solution-target-type') as TextField,
+ targetType: container.querySelector('#create-solution-target-type') as HTMLInputElement,
hardwareRowHeaders: container.querySelector('#create-solution-hardware') as HTMLElement
});
const makeTargetCategories =
(param: A) => {
- return {
+ return {
header: 'Test Header',
categories: [],
items: ['A', 'B', 'C'].map(i => ({
@@ -61,7 +60,7 @@ describe('HardwareRow', () => {
const devices: TreeViewCategory[] = ([makeTargetCategories(deviceHardwareOptionFactory())]);
const hardwareLists: AsyncStatus = asyncLoaded({ boards, devices });
- beforeEach(async() => {
+ beforeEach(async () => {
container = document.createElement('div');
jest.clearAllMocks();
listener = jest.fn();
@@ -85,7 +84,7 @@ describe('HardwareRow', () => {
validationErrors={validationErrors}
webServicesEnabled={state.webServicesEnabled}
messageHandler={messageHandler}
- dispatch={dispatch}/>
+ dispatch={dispatch} />
));
const input = container.querySelector('#create-solution-target-type') as HTMLElement;
@@ -101,7 +100,7 @@ describe('HardwareRow', () => {
validationErrors={validationErrors}
webServicesEnabled={state.webServicesEnabled}
messageHandler={messageHandler}
- dispatch={dispatch}/>
+ dispatch={dispatch} />
));
const elements = getElements();
@@ -120,7 +119,7 @@ describe('HardwareRow', () => {
validationErrors={validationErrors}
webServicesEnabled={state.webServicesEnabled}
messageHandler={messageHandler}
- dispatch={dispatch}/>
+ dispatch={dispatch} />
));
const elements = getElements();
@@ -140,7 +139,7 @@ describe('HardwareRow', () => {
validationErrors={validationErrors}
webServicesEnabled={state.webServicesEnabled}
messageHandler={messageHandler}
- dispatch={dispatch}/>
+ dispatch={dispatch} />
));
const clearButton = container.querySelector('[title="clear-selection"]') as HTMLButtonElement;
@@ -160,7 +159,7 @@ describe('HardwareRow', () => {
validationErrors={validationErrors}
webServicesEnabled={state.webServicesEnabled}
messageHandler={messageHandler}
- dispatch={dispatch}/>
+ dispatch={dispatch} />
));
const clearButton = container.querySelector('[title="clear-selection"]');
diff --git a/src/views/create-solutions/view/components/hardware-row.tsx b/src/views/create-solutions/view/components/hardware-row.tsx
index 3c9d80e9..a2a5f007 100644
--- a/src/views/create-solutions/view/components/hardware-row.tsx
+++ b/src/views/create-solutions/view/components/hardware-row.tsx
@@ -216,7 +216,9 @@ const HardwareDropdown = (
searchValue={treeViewSearch}
topLevelCategories={props.treeViewList}
itemPredicate={itemPredicate}
- onSelect={item => onSelect(item.value)}
+ onSelect={item => {
+ onSelect(item.value);
+ }}
noEntriesMessage={noEntriesMessage}
>
diff --git a/src/views/create-solutions/view/components/project-configuration.css b/src/views/create-solutions/view/components/project-configuration.css
index ab7ebea4..308c98c7 100644
--- a/src/views/create-solutions/view/components/project-configuration.css
+++ b/src/views/create-solutions/view/components/project-configuration.css
@@ -28,3 +28,7 @@
.add-project-config-row {
margin-top: 5px;
}
+
+.compact-dropdown-inner {
+ height: 100%;
+}
\ No newline at end of file
diff --git a/src/views/create-solutions/view/components/project-configuration.test.tsx b/src/views/create-solutions/view/components/project-configuration.test.tsx
index 0db289bb..3c4cf428 100644
--- a/src/views/create-solutions/view/components/project-configuration.test.tsx
+++ b/src/views/create-solutions/view/components/project-configuration.test.tsx
@@ -38,13 +38,14 @@ describe('ProjectConfiguration', () => {
});
it('renders the project configuration info for device reference', () => {
- const projects: FieldAndInteraction[] = [{
+ const projects: FieldAndInteraction[] = [{
value: newProjectFactory({
trustzone: 'secure',
processorName: '',
name: 'IO6-Alen',
}),
- hadInteraction: false }
+ hadInteraction: false
+ }
];
const device = {
id: { name: 'blast-blast-2000', vendor: 'c7-mark12-intergalatic' },
@@ -137,7 +138,7 @@ describe('ProjectConfiguration', () => {
expect(dispatch).toHaveBeenCalledWith({ type: 'MODIFY_PROJECT', request: { type: 'UPDATE_PROJECT_NAME', index: 0, name: 'NewValue' } });
});
- it('update to the core selected in the dropdown', () => {
+ it('update to the core selected in the dropdown', async () => {
const projects = [
{ value: newProjectFactory({ name: '', processorName: 'core1' }), hadInteraction: false },
{ value: newProjectFactory(), hadInteraction: false }
@@ -159,21 +160,24 @@ describe('ProjectConfiguration', () => {
/>);
});
- const targetElement = container.querySelectorAll('.dropdownCore');
- const dropdownList = targetElement[0].querySelectorAll('vscode-option');
+ const targetElement = container.querySelector('.dropdownCore');
+ await React.act(async () => { // Open the dropdown
+ Simulate.click(targetElement!.querySelector('.compact-dropdown-trigger')!);
+ });
- React.act(() => {
+ const dropdownList = targetElement!.querySelectorAll('li');
+ await React.act(async () => { // Click the first option in the dropdown
Simulate.click(dropdownList[0]!);
});
expect(dispatch).toHaveBeenCalledWith({ type: 'MODIFY_PROJECT', request: { type: 'UPDATE_PROJECT_CORE', index: 0, processorName: 'the-core' } });
});
- it('update to the trustzone selected in the dropdown', () => {
+ it('update to the trustzone selected in the dropdown', async () => {
const projects = [{ value: newProjectFactory({ processorName: 'coreA', trustzone: 'secure' }), hadInteraction: false }];
const device = deviceHardwareOptionFactory({
id: { name: 'some-device', vendor: 'some-vendor' },
- processors: [ { name: 'coreA', core: 'Cortex-M', tz: Tz.TZ }]
+ processors: [{ name: 'coreA', core: 'Cortex-M', tz: Tz.TZ }]
});
React.act(() => {
@@ -184,10 +188,13 @@ describe('ProjectConfiguration', () => {
errors={[]}
/>);
});
- const targetElement = container.querySelectorAll('.dropdownTrustzone');
- const dropdownList = targetElement[0].querySelectorAll('vscode-option');
+ const targetElement = container.querySelector('.dropdownTrustzone');
+ await React.act(async () => { // Open the dropdown
+ Simulate.click(targetElement!.querySelector('.compact-dropdown-trigger')!);
+ });
- React.act(() => {
+ const dropdownList = targetElement!.querySelectorAll('li');
+ await React.act(async () => { // Click the second option in the dropdown
Simulate.click(dropdownList[1]!);
});
diff --git a/src/views/create-solutions/view/components/project-configuration.tsx b/src/views/create-solutions/view/components/project-configuration.tsx
index 743c92d2..b2a46d73 100644
--- a/src/views/create-solutions/view/components/project-configuration.tsx
+++ b/src/views/create-solutions/view/components/project-configuration.tsx
@@ -17,10 +17,12 @@
import * as React from 'react';
import './project-configuration.css';
import { DeviceHardwareOption, NewProject, ProcessorInfo, Trustzone, validTrustZone } from '../../cmsis-solution-types';
-import { VSCodeButton, VSCodeDropdown, VSCodeOption } from '@vscode/webview-ui-toolkit/react';
import { CreateSolutionAction } from '../state/reducer';
import { validationError } from './validation-message';
import { FieldAndInteraction } from '../state/field-and-interaction';
+import { Button } from 'antd';
+import { CompactDropdown } from '../../../common/components/compact-dropdown';
+import { CmsisCodicon } from '../../../common/components/cmsis-codicon';
type ProjectConfigurationProps = {
device: DeviceHardwareOption;
@@ -40,18 +42,18 @@ export const ProjectConfiguration = (props: ProjectConfigurationProps) => {
Core
TrustZone
- {projects.map((project, index) =>
)}
-
)}
+ dispatch({ type: 'MODIFY_PROJECT', request: { type: 'ADD_PROJECT' } })}
>
- Add Project
-
+ Add Project
+
{showTrustZoneText && (
- Some TrustZone devices will be shipped with secure firmware by the manufacturer. Please check your device's specification before adding your own secure project.
+ Some TrustZone devices will be shipped with secure firmware by the manufacturer. Please check your device's specification before adding your own secure project.
)}
@@ -76,28 +78,7 @@ const ProjectConfigurationRow = (props: ProjectConfigurationRowProps) => {
? ['secure', 'non-secure', 'off']
: ['off'];
- const coreDropdownOptions = device.processors.length === 1
- ? [
{processor?.core} ]
- : device.processors.map(processor => (
-
dispatch({
- type: 'MODIFY_PROJECT',
- request: { type: 'UPDATE_PROJECT_CORE', index: index, processorName: (e.target as HTMLInputElement).value },
- })}
- >{processor.name}
- ));
-
- const trustZoneDropdownOptions = trustzoneOptions.map(option =>
-
dispatch({
- type: 'MODIFY_PROJECT',
- request: { type: 'UPDATE_PROJECT_TRUSTZONE', index: index, trustzone: option as Trustzone },
- })}
- >{option} );
+ const coreDropdownOptions = device.processors.map(p => p.name);
return (
@@ -112,27 +93,43 @@ const ProjectConfigurationRow = (props: ProjectConfigurationRowProps) => {
title='Provide a descriptive name for each project contained in your solution'
>
- 1 ? false : true}
title={coreDropdownOptions.length > 1 ? 'The Arm core that the project will run on, as determined by the cores on the selected microcontroller (MCU) device' : 'No additional core options to select from the dropdown'}
- value={device.processors.length === 1 ? processor?.core : rowInfo.processorName}
- >{coreDropdownOptions}
- {
+ dispatch({
+ type: 'MODIFY_PROJECT',
+ request: { type: 'UPDATE_PROJECT_CORE', index: index, processorName: option },
+ });
+ }}
+ />
+ 1)}
- title={trustZoneDropdownOptions.length > 1 ? 'TrustZone reduces the potential for attack by isolating the critical security firmware, assets and private information from the rest of the application' : 'No additional trustzone options to select from the dropdown'}
- value={rowInfo.trustzone}
- >{trustZoneDropdownOptions}
- 1 ? 'TrustZone reduces the potential for attack by isolating the critical security firmware, assets and private information from the rest of the application' : 'No additional trustzone options to select from the dropdown'}
+ selected={rowInfo.trustzone}
+ available={trustzoneOptions.map(option => option)}
+ style={{ width: 'auto' }}
+ className='dropdownTrustzone'
+ onChange={(option) => {
+ dispatch({
+ type: 'MODIFY_PROJECT',
+ request: { type: 'UPDATE_PROJECT_TRUSTZONE', index: index, trustzone: option as Trustzone },
+ });
+ }}
+ />
+ }
+ type="default"
+ variant="text"
aria-label="Delete"
disabled={removeDisabled}
onClick={() => dispatch({ type: 'MODIFY_PROJECT', request: { type: 'REMOVE_PROJECT', index: index } })}
title='Remove the current project configuration row'
- >
-
-
+ />
{validationError(error)}
);
diff --git a/src/views/manage-layers/manage-layers-webview-view.ts b/src/views/manage-layers/manage-layers-webview-view.ts
index 94c23569..4bc66608 100644
--- a/src/views/manage-layers/manage-layers-webview-view.ts
+++ b/src/views/manage-layers/manage-layers-webview-view.ts
@@ -18,7 +18,7 @@ import '../webpack-globals';
import { MessageHandlerImpl } from '../message-handler';
import * as Messages from './messages';
-// Const function created by webview iframe script
+// Acquire the VS Code webview API via vscode-messenger-webview.
const api = acquireVsCodeApi();
const messageHandler = new MessageHandlerImpl
(
diff --git a/src/views/manage-layers/view/components/create-layer.tsx b/src/views/manage-layers/view/components/create-layer.tsx
index 95ea1cbb..93c550ee 100644
--- a/src/views/manage-layers/view/components/create-layer.tsx
+++ b/src/views/manage-layers/view/components/create-layer.tsx
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-import { VSCodeButton } from '@vscode/webview-ui-toolkit/react';
import * as React from 'react';
import { ConfigurationVariable, ManageLayersAction, TargetConfiguration, VariableSet } from '../state/reducer';
import { ValidationErrors } from '../state/validation';
import './manage-layers.css';
import { validationError } from './validation-message';
+import { Button } from 'antd';
export type CreateLayerProps = {
@@ -43,7 +43,7 @@ export function CreateLayer(props: CreateLayerProps): React.ReactElement {
function createVariable(curVariable: ConfigurationVariable, errStr: string, idx: number, props: CreateLayerProps): React.ReactElement {
const settings = curVariable.settings;
- const variableName = curVariable.variableName ;
+ const variableName = curVariable.variableName;
const variableValue = curVariable.variableValue;
const description = curVariable.description;
const copyTo = curVariable.copyTo;
@@ -112,14 +112,14 @@ function createEdit(name: string, value: string, idx: number, props: CreateLayer
function createDefaultSelection(idx: number, props: CreateLayerProps, disabled: boolean): React.ReactElement {
- return {
- props.dispatch({ type: 'CURRENT_LAYER_PATH_COPYTO_DEFAULT', variableId: idx });
- }}
- >
- Default
-
- ;
+ return (
+ {
+ props.dispatch({ type: 'CURRENT_LAYER_PATH_COPYTO_DEFAULT', variableId: idx });
+ }}>
+ Default
+
+ );
}
diff --git a/src/views/manage-layers/view/components/manage-layers.tsx b/src/views/manage-layers/view/components/manage-layers.tsx
index d411638d..12dfa516 100644
--- a/src/views/manage-layers/view/components/manage-layers.tsx
+++ b/src/views/manage-layers/view/components/manage-layers.tsx
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-import { VSCodeButton } from '@vscode/webview-ui-toolkit/react';
import * as React from 'react';
import { LayerErrors } from '../../../common/components/layer-errors';
import { RadioButton } from '../../../common/components/radio-button';
@@ -25,6 +24,8 @@ import { initialState, manageLayersReducer } from '../state/reducer';
import { hasErrors, validate } from '../state/validation';
import { CreateLayer } from './create-layer';
import './manage-layers.css';
+import { Button, ConfigProvider, theme } from 'antd';
+import { useVSCodeTheme } from '../../../hooks/use-vscode-theme';
export interface ManageLayersProps {
/**
@@ -57,7 +58,7 @@ export const ManageLayers = ({ changeLayerActions, messageHandler }: ManageLayer
if (currentLayer) {
for (let idx = 0; idx < currentLayer.variables.length; idx++) {
const variable = currentLayer.variables[idx];
- if (!variable.disabled) {
+ if (!variable.disabled) {
messageHandler.push({ type: 'CHECK_LAYER_DOES_NOT_EXIST', layerFolder: variable.copyTo, variableId: idx });
}
}
@@ -76,128 +77,136 @@ export const ManageLayers = ({ changeLayerActions, messageHandler }: ManageLayer
const layerErrors = state.layerErrors;
const showLayer = !!numOfLayers || loading || !!layerErrors.length;
const activeTargetName = state.activeTargetType?.length ? state.activeTargetType : 'unknown';
+ const isDarkTheme = useVSCodeTheme();
return (
-