diff --git a/webview-ui/src/AzureServiceOperator/AzureServiceOperator.tsx b/webview-ui/src/AzureServiceOperator/AzureServiceOperator.tsx index 347a4791d..621650290 100644 --- a/webview-ui/src/AzureServiceOperator/AzureServiceOperator.tsx +++ b/webview-ui/src/AzureServiceOperator/AzureServiceOperator.tsx @@ -1,4 +1,3 @@ -import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"; import styles from "./AzureServiceOperator.module.css"; import { InitialState } from "../../../src/webview-contract/webviewDefinitions/azureServiceOperator"; import { useEffect } from "react"; @@ -64,7 +63,7 @@ export function AzureServiceOperator(initialState: InitialState) {

The Azure Service Operator helps you provision Azure resources and connect your applications to them from within Kubernetes. -  Learn more +  Learn more

diff --git a/webview-ui/src/AzureServiceOperator/Inputs.tsx b/webview-ui/src/AzureServiceOperator/Inputs.tsx index 3a9529e2f..e45bf3f08 100644 --- a/webview-ui/src/AzureServiceOperator/Inputs.tsx +++ b/webview-ui/src/AzureServiceOperator/Inputs.tsx @@ -1,10 +1,3 @@ -import { - VSCodeButton, - VSCodeDropdown, - VSCodeLink, - VSCodeOption, - VSCodeTextField, -} from "@vscode/webview-ui-toolkit/react"; import styles from "./AzureServiceOperator.module.css"; import { ASOState, EventDef, InstallStepStatus } from "./helpers/state"; import { EventHandlers } from "../utilities/state"; @@ -14,6 +7,8 @@ import { MessageSink } from "../../../src/webview-contract/messaging"; import { getRequiredInputs } from "./helpers/inputs"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faInfoCircle } from "@fortawesome/free-solid-svg-icons"; +import { CustomDropdown } from "../components/CustomDropdown"; +import { CustomDropdownOption } from "../components/CustomDropdownOption"; type ChangeEvent = Event | FormEvent; @@ -45,10 +40,8 @@ export function Inputs(props: InputsProps) { props.handlers.onSetCheckingSP(); } - function handleSubscriptionChanged(e: Event | FormEvent) { - const elem = e.target as HTMLInputElement; - const subscriptionId = elem.value || null; - props.handlers.onSetSelectedSubscriptionId(subscriptionId); + function handleSubscriptionChanged(value: string) { + props.handlers.onSetSelectedSubscriptionId(value); } function handleSubmit(e: FormEvent) { @@ -74,15 +67,16 @@ export function Inputs(props: InputsProps) { Provide the App ID and password of a Service Principal with Contributor permissions for your subscription. This allows ASO to create resources in your subscription on your behalf. - +   Learn more - +

- - - +
{canViewSubscriptions && (
@@ -121,31 +114,28 @@ export function Inputs(props: InputsProps) { The supplied service principal has some role assignments on the following subscriptions. Please ensure these are adequate for the Azure resources that ASO will be creating in your selected subscription. - -   Learn more - +   Learn more

- - {subscriptions.length !== 1 && Select} + {subscriptions.length !== 1 && } {subscriptions.map((s) => ( - - {s.name} - + ))} - - + +
)} diff --git a/webview-ui/src/CreateCluster/CreateCluster.tsx b/webview-ui/src/CreateCluster/CreateCluster.tsx index 539611294..d75265898 100644 --- a/webview-ui/src/CreateCluster/CreateCluster.tsx +++ b/webview-ui/src/CreateCluster/CreateCluster.tsx @@ -38,10 +38,11 @@ export function CreateCluster(initialState: InitialState) { /> ); case Stage.Creating: + console.log("Creating cluster"); return ( <>

- Creating Cluster {state.createParams!.name} in {state.createParams!.location} + Creating Cluster {state.createParams?.name} in {state.createParams?.location}

{state.deploymentPortalUrl && (

@@ -62,7 +63,10 @@ export function CreateCluster(initialState: InitialState) { ); case Stage.Succeeded: return ( - + ); default: throw new Error(`Unexpected stage ${state.stage}`); diff --git a/webview-ui/src/CreateCluster/CreateClusterInput.tsx b/webview-ui/src/CreateCluster/CreateClusterInput.tsx index 7fee7a644..a30492f67 100644 --- a/webview-ui/src/CreateCluster/CreateClusterInput.tsx +++ b/webview-ui/src/CreateCluster/CreateClusterInput.tsx @@ -1,6 +1,6 @@ import { faTimesCircle } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react"; +// import { VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react"; import { FormEvent, useState } from "react"; import { MessageSink } from "../../../src/webview-contract/messaging"; import { @@ -16,9 +16,9 @@ import styles from "./CreateCluster.module.css"; import { CreateClusterPresetInput } from "./CreateClusterPresetInput"; import { CreateResourceGroupDialog } from "./CreateResourceGroup"; import { EventDef } from "./helpers/state"; - -type ChangeEvent = Event | FormEvent; - +import { CustomDropdown } from "../components/CustomDropdown"; +import { CustomDropdownOption } from "../components/CustomDropdownOption"; +import { MouseEvent } from "react"; interface CreateClusterInputProps { locations: string[]; resourceGroups: ResourceGroup[]; @@ -32,7 +32,7 @@ export function CreateClusterInput(props: CreateClusterInputProps) { const [isNewResourceGroupDialogShown, setIsNewResourceGroupDialogShown] = useState(false); const [newResourceGroupName, setNewResourceGroupName] = useState(null); const [presetSelected, setPresetSelected] = useState(PresetType.Automatic); - const [selectedIndex, setSelectedIndex] = useState(0); + const [selectedResourceGroup, setSelectedResourceGroup] = useState(""); const [location, setLocation] = useState>(unset()); const newResourceGroup = newResourceGroupName @@ -51,26 +51,30 @@ export function CreateClusterInput(props: CreateClusterInputProps) { setIsNewResourceGroupDialogShown(false); setExistingResourceGroup(valid(null)); setNewResourceGroupName(groupName); - setSelectedIndex(1); // this is the index of the new resource group and the first option is "Select" + setSelectedResourceGroup(groupName); } function handlePresetSelection(presetSelected: PresetType) { setPresetSelected(presetSelected); } - function handleValidationAndIndex(e: ChangeEvent) { - handleExistingResourceGroupChange(e); - const ele = e.currentTarget as HTMLSelectElement; - setSelectedIndex(ele.selectedIndex); + function handleValidationAndIndex(value: string) { + handleExistingResourceGroupChange(value); + setSelectedResourceGroup(value); } - function handleExistingResourceGroupChange(e: ChangeEvent) { - const elem = e.currentTarget as HTMLSelectElement; - const resourceGroup = elem.selectedIndex <= 0 ? null : allResourceGroups[elem.selectedIndex - 1]; + function handleExistingResourceGroupChange(value: string) { + const resourceGroup = value ? allResourceGroups.find((group) => group.name === value) : null; const validatable = resourceGroup ? valid(resourceGroup) : invalid(null, "Resource Group is required."); setExistingResourceGroup(validatable); } + const handleCreateNewRG = (event: MouseEvent) => { + setIsNewResourceGroupDialogShown(true); + event.preventDefault(); + event.stopPropagation(); + }; + function getValidatedName(name: string): Validatable { if (!name) return invalid(name, "Cluster name must be at least 1 character long."); if (name.length > 63) return invalid(name, "Cluster name must be at most 63 characters long."); @@ -84,15 +88,14 @@ export function CreateClusterInput(props: CreateClusterInputProps) { return valid(name); } - function handleNameChange(e: ChangeEvent) { - const name = (e.currentTarget as HTMLInputElement).value; + function handleNameChange(e: FormEvent) { + const name = e.currentTarget.value; const validated = getValidatedName(name); setName(validated); } - function handleLocationChange(e: ChangeEvent) { - const elem = e.currentTarget as HTMLSelectElement; - const location = elem.selectedIndex <= 0 ? null : props.locations[elem.selectedIndex - 1]; + function handleLocationChange(value: string) { + const location = value ? props.locations.find((loc) => loc === value) : null; const validated = location ? valid(location) : missing("Location is required."); setLocation(validated); } @@ -139,32 +142,32 @@ export function CreateClusterInput(props: CreateClusterInputProps) { + - - - Select - + {allResourceGroups.length > 0 ? ( allResourceGroups.map((group) => ( - - {group === newResourceGroup ? "(New)" : ""} {group.name} - + )) ) : ( - No resource groups available + )} - + - {hasMessage(existingResourceGroup) && ( @@ -195,19 +198,17 @@ export function CreateClusterInput(props: CreateClusterInputProps) { - - Select + {props.locations.map((location) => ( - - {location} - + ))} - + {hasMessage(location) && ( diff --git a/webview-ui/src/CreateFleet/CreateFleetInput.tsx b/webview-ui/src/CreateFleet/CreateFleetInput.tsx index c74442bb3..ccd0c587e 100644 --- a/webview-ui/src/CreateFleet/CreateFleetInput.tsx +++ b/webview-ui/src/CreateFleet/CreateFleetInput.tsx @@ -5,7 +5,6 @@ import { ResourceGroup, ToVsCodeMsgDef, } from "../../../src/webview-contract/webviewDefinitions/createFleet"; -import { VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react"; import { hasMessage, invalid, @@ -25,6 +24,8 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faTimesCircle } from "@fortawesome/free-solid-svg-icons"; import styles from "./CreateFleet.module.css"; import { CreateFleetModeInput } from "./CreateFleetModeInput"; +import { CustomDropdown } from "../components/CustomDropdown"; +import { CustomDropdownOption } from "../components/CustomDropdownOption"; type ChangeEvent = Event | FormEvent; @@ -39,22 +40,21 @@ interface CreateFleetInputProps { export function CreateFleetInput(props: CreateFleetInputProps) { const [existingResourceGroup, setExistingResourceGroup] = useState>(unset()); const [fleetName, setFleetName] = useState>(unset()); - const [selectedResourceGroupIndex, setselectedResourceGroupIndex] = useState(0); + // const [selectedResourceGroupIndex, setselectedResourceGroupIndex] = useState(0); const [location, setLocation] = useState>(unset()); const [hubModeSelected, setHubModeSelected] = useState(HubMode.With); const [dnsPrefix, setDnsPrefix] = useState>(unset()); + const [selectedResourceGroup, setSelectedResourceGroup] = useState(""); const allResourcesGroups = props.resourceGroups; // All available resource groups fetched from the portal - function handleValidationAndIndex(e: ChangeEvent) { - handleExistingResourceGroupChange(e); - const ele = e.currentTarget as HTMLSelectElement; - setselectedResourceGroupIndex(ele.selectedIndex); + function handleValidationAndIndex(value: string) { + handleExistingResourceGroupChange(value); + setSelectedResourceGroup(value); } - function handleExistingResourceGroupChange(e: ChangeEvent) { - const elem = e.currentTarget as HTMLSelectElement; - const resourceGroup = elem.selectedIndex <= 0 ? null : allResourcesGroups[elem.selectedIndex - 1]; + function handleExistingResourceGroupChange(value: string) { + const resourceGroup = value ? allResourcesGroups.find((group) => group.name === value) : null; const validatable = resourceGroup ? valid(resourceGroup) : invalid(null, "Resource Group is required."); setExistingResourceGroup(validatable); } @@ -80,9 +80,8 @@ export function CreateFleetInput(props: CreateFleetInputProps) { return valid(name); } - function handleLocationChange(e: ChangeEvent) { - const elem = e.currentTarget as HTMLSelectElement; - const location = elem.selectedIndex <= 0 ? null : props.locations[elem.selectedIndex - 1]; + function handleLocationChange(value: string) { + const location = value ? props.locations.find((loc) => loc === value) : null; const validated = location ? valid(location) : missing("Location is required."); setLocation(validated); } @@ -151,27 +150,22 @@ export function CreateFleetInput(props: CreateFleetInputProps) { - - - Select - + {allResourcesGroups.length > 0 ? ( allResourcesGroups.map((group) => ( - - {""} {group.name} - + )) ) : ( - No resource groups available + )} - + {hasMessage(existingResourceGroup) && ( @@ -182,19 +176,17 @@ export function CreateFleetInput(props: CreateFleetInputProps) { - - Select + {props.locations.map((location) => ( - - {location} - + ))} - + {hasMessage(location) && ( diff --git a/webview-ui/src/Detector/Detector.tsx b/webview-ui/src/Detector/Detector.tsx index e2bdce31c..c7f86322a 100644 --- a/webview-ui/src/Detector/Detector.tsx +++ b/webview-ui/src/Detector/Detector.tsx @@ -1,4 +1,3 @@ -import { VSCodeDivider, VSCodeLink } from "@vscode/webview-ui-toolkit/react"; import { InitialState } from "../../../src/webview-contract/webviewDefinitions/detector"; import { SingleDetector } from "./SingleDetector"; import { useStateManagement } from "../utilities/state"; @@ -11,9 +10,8 @@ export function Detector(initialState: InitialState) { <>

{state.name}

{state.description && state.description !== "test" &&

{state.description}

} - To perform more checks on your cluster, visit{" "} - AKS Diagnostics. - + To perform more checks on your cluster, visit AKS Diagnostics. +
{state.detectors.map((detector) => ( ))} diff --git a/webview-ui/src/InspektorGadget/GadgetSelector.tsx b/webview-ui/src/InspektorGadget/GadgetSelector.tsx index 18f5dfa2e..a84e22b88 100644 --- a/webview-ui/src/InspektorGadget/GadgetSelector.tsx +++ b/webview-ui/src/InspektorGadget/GadgetSelector.tsx @@ -1,8 +1,8 @@ -import { VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react"; -import { FormEvent } from "react"; import { GadgetCategory } from "./helpers/gadgets/types"; import { configuredGadgetResources } from "./helpers/gadgets"; - +import { CustomDropdown } from "../components/CustomDropdown"; +import { CustomDropdownOption } from "../components/CustomDropdownOption"; +import { useState } from "react"; export interface GadgetSelectorProps { category: GadgetCategory; id: string; @@ -12,27 +12,21 @@ export interface GadgetSelectorProps { } export function GadgetSelector(props: GadgetSelectorProps) { - function handleResourceChange(e: Event | FormEvent) { - const elem = e.target as HTMLInputElement; - const resource = elem.value ? elem.value : null; + function handleResourceChange(value: string) { + const resource = value ? value : null; + setSelectedNode(value); props.onResourceChanged(resource); } const configuredResources = configuredGadgetResources[props.category]; + const [selectedNode, setSelectedNode] = useState(""); return ( - - Select + + {Object.keys(configuredResources).map((resource) => ( - - {configuredResources[resource]!.name} - + ))} - + ); } diff --git a/webview-ui/src/InspektorGadget/Overview.tsx b/webview-ui/src/InspektorGadget/Overview.tsx index 5febcf2c1..2f1a02778 100644 --- a/webview-ui/src/InspektorGadget/Overview.tsx +++ b/webview-ui/src/InspektorGadget/Overview.tsx @@ -47,7 +47,6 @@ export function Overview(props: OverviewProps) { )} -
{props.version && (isVersionStringOrNull(props.version.client) || isVersionStringOrNull(props.version.server)) && ( + {!props.matchesExisting && }
); diff --git a/webview-ui/src/Kubectl/Kubectl.tsx b/webview-ui/src/Kubectl/Kubectl.tsx index e2a81e586..847ddb5c2 100644 --- a/webview-ui/src/Kubectl/Kubectl.tsx +++ b/webview-ui/src/Kubectl/Kubectl.tsx @@ -1,4 +1,3 @@ -import { VSCodeDivider } from "@vscode/webview-ui-toolkit/react"; import { CommandCategory, InitialState, PresetCommand } from "../../../src/webview-contract/webviewDefinitions/kubectl"; import styles from "./Kubectl.module.css"; import { CommandList } from "./CommandList"; @@ -75,7 +74,7 @@ export function Kubectl(initialState: InitialState) {

Kubectl Command Run for {state.clusterName}

- +