Skip to content

refactor: [M3-8977] - Replace Autocompletes with Select #12060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tech Stories
---

Replace `Autocomplete`s with `Select` ([#12060](https://github.com/linode/manager/pull/12060))
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Notice,
Radio,
RadioGroup,
Select,
TextField,
Typography,
} from '@linode/ui';
Expand Down Expand Up @@ -78,7 +79,6 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => {
// Set form field errors for each error we have (except "addresses" errors, which are handled
// by IP Error state).
React.useEffect(() => {
// eslint-disable-next-line no-unused-expressions
ruleErrors?.forEach((thisError) => {
if (thisError.formField !== 'addresses') {
setFieldError(thisError.formField, thisError.reason);
Expand Down Expand Up @@ -211,11 +211,6 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => {
/>
)}
<Autocomplete
textFieldProps={{
dataAttrs: {
'data-qa-rule-select': true,
},
}}
aria-label="Preset for firewall rule"
autoHighlight
disableClearable
Expand All @@ -224,6 +219,11 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => {
onChange={(_, selected) => handleTypeChange(selected)}
options={firewallOptionItemsShort}
placeholder="Select a rule preset..."
textFieldProps={{
dataAttrs: {
'data-qa-rule-select': true,
},
}}
/>
<TextField
aria-label="Label for firewall rule"
Expand All @@ -246,27 +246,28 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => {
placeholder="Enter a description..."
value={values.description}
/>
<Autocomplete
textFieldProps={{
InputProps: {
required: true,
},
dataAttrs: {
'data-qa-protocol-select': true,
},
}}
<Select
aria-label="Select rule protocol."
autoHighlight
disableClearable
errorText={errors.protocol}
label="Protocol"
onBlur={handleBlur}
onChange={(_, selected) => handleProtocolChange(selected.value)}
options={protocolOptions}
placeholder="Select a protocol..."
required
value={protocolOptions.find((p) => p.value === values.protocol)}
/>
<Autocomplete
autoHighlight
disabled={['ICMP', 'IPENCAP'].includes(values.protocol)}
disableSelectAll
errorText={generalPortError}
label="Ports"
multiple
onChange={(_, selected) => handlePortPresetChange(selected)}
options={portOptions}
// If options are selected, hide the placeholder
placeholder={presetPorts.length > 0 ? ' ' : 'Select a port...'}
textFieldProps={{
InputProps: {
required: true,
Expand All @@ -278,16 +279,6 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => {
? `Ports are not allowed for ${values.protocol} protocols.`
: undefined,
}}
autoHighlight
disableSelectAll
disabled={['ICMP', 'IPENCAP'].includes(values.protocol)}
errorText={generalPortError}
label="Ports"
multiple
onChange={(_, selected) => handlePortPresetChange(selected)}
options={portOptions}
// If options are selected, hide the placeholder
placeholder={presetPorts.length > 0 ? ' ' : 'Select a port...'}
value={presetPorts}
/>
{hasCustomInput ? (
Expand All @@ -302,10 +293,16 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => {
value={values.ports}
/>
) : null}
<Autocomplete
<Select
aria-label={`Select rule ${addressesLabel}s.`}
errorText={errors.addresses}
label={`${capitalize(addressesLabel)}s`}
onBlur={handleBlur}
onChange={(_, selected) => {
handleAddressesChange(selected.value);
}}
options={addressOptions}
placeholder={`Select ${addressesLabel}s...`}
textFieldProps={{
InputProps: {
required: true,
Expand All @@ -314,14 +311,6 @@ export const FirewallRuleForm = React.memo((props: FirewallRuleFormProps) => {
'data-qa-address-source-select': true,
},
}}
aria-label={`Select rule ${addressesLabel}s.`}
autoHighlight
disableClearable
errorText={errors.addresses}
label={`${capitalize(addressesLabel)}s`}
onBlur={handleBlur}
options={addressOptions}
placeholder={`Select ${addressesLabel}s...`}
value={addressesValue}
/>
{/* Show this field only if "IP / Netmask has been selected." */}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import {
} from '@linode/queries';
import { useIsGeckoEnabled } from '@linode/shared';
import {
Autocomplete,
Box,
ErrorState,
Notice,
Paper,
Select,
Stack,
TextField,
} from '@linode/ui';
Expand Down Expand Up @@ -115,13 +115,10 @@ export const CreateCluster = () => {
const [ipV6Addr, setIPv6Addr] = React.useState<ExtendedIP[]>([
stringToExtendedIP(''),
]);
const [selectedTier, setSelectedTier] = React.useState<KubernetesTier>(
'standard'
);
const [
isACLAcknowledgementChecked,
setIsACLAcknowledgementChecked,
] = React.useState(false);
const [selectedTier, setSelectedTier] =
React.useState<KubernetesTier>('standard');
const [isACLAcknowledgementChecked, setIsACLAcknowledgementChecked] =
React.useState(false);

const {
data: kubernetesHighAvailabilityTypesData,
Expand Down Expand Up @@ -174,18 +171,14 @@ export const CreateCluster = () => {
// Only want to use current types here.
const typesData = filterCurrentTypes(allTypes?.map(extendType));

const {
mutateAsync: createKubernetesCluster,
} = useCreateKubernetesClusterMutation();
const { mutateAsync: createKubernetesCluster } =
useCreateKubernetesClusterMutation();

const {
mutateAsync: createKubernetesClusterBeta,
} = useCreateKubernetesClusterBetaMutation();
const { mutateAsync: createKubernetesClusterBeta } =
useCreateKubernetesClusterBetaMutation();

const {
isLkeEnterpriseLAFeatureEnabled,
isLkeEnterpriseLAFlagEnabled,
} = useIsLkeEnterpriseEnabled();
const { isLkeEnterpriseLAFeatureEnabled, isLkeEnterpriseLAFlagEnabled } =
useIsLkeEnterpriseEnabled();

const {
isLoadingVersions,
Expand Down Expand Up @@ -384,25 +377,25 @@ export const CreateCluster = () => {
)}
{isCreateClusterRestricted && (
<Notice
important
sx={{ marginBottom: 2 }}
text={getRestrictedResourceText({
action: 'create',
isSingular: false,
resourceType: 'LKE Clusters',
})}
important
sx={{ marginBottom: 2 }}
variant="error"
/>
)}
<Paper data-qa-label-header>
<TextField
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
updateLabel(e.target.value)
}
data-qa-label-input
disabled={isCreateClusterRestricted}
errorText={errorMap.label}
label="Cluster Label"
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
updateLabel(e.target.value)
}
value={label || ''}
/>
{isLkeEnterpriseLAFlagEnabled && (
Expand All @@ -425,6 +418,12 @@ export const CreateCluster = () => {
? 'Kubernetes Enterprise'
: 'Kubernetes'
}
disableClearable
disabled={isCreateClusterRestricted}
errorText={errorMap.region}
isGeckoLAEnabled={isGeckoLAEnabled}
onChange={(e, region) => setSelectedRegion(region)}
regions={regionsData}
textFieldProps={{
helperText: <RegionHelperText mb={2} />,
helperTextPosition: 'top',
Expand All @@ -435,12 +434,6 @@ export const CreateCluster = () => {
? 'Only regions that support LKE Enterprise clusters are listed.'
: undefined
}
disableClearable
disabled={isCreateClusterRestricted}
errorText={errorMap.region}
isGeckoLAEnabled={isGeckoLAEnabled}
onChange={(e, region) => setSelectedRegion(region)}
regions={regionsData}
value={selectedRegion?.id}
/>
</Stack>
Expand All @@ -456,15 +449,14 @@ export const CreateCluster = () => {
<Divider sx={{ marginTop: 4 }} />
<StyledStackWithTabletBreakpoint>
<Stack>
<Autocomplete
onChange={(_, selected) => {
setVersion(selected?.value);
}}
disableClearable={!!version}
<Select
disabled={isCreateClusterRestricted}
errorText={errorMap.k8s_version}
label="Kubernetes Version"
loading={isLoadingVersions}
onChange={(_, selected) => {
setVersion(selected?.value);
}}
options={versions}
placeholder={' '}
sx={{ minWidth: 416 }}
Expand Down Expand Up @@ -523,6 +515,8 @@ export const CreateCluster = () => {
sx={{ marginTop: selectedTier === 'enterprise' ? 4 : 1 }}
/>
<ControlPlaneACLPane
enableControlPlaneACL={controlPlaneACL}
errorText={errorMap.control_plane}
handleIPv4Change={(newIpV4Addr: ExtendedIP[]) => {
setIPv4Addr(newIpV4Addr);
}}
Expand All @@ -532,8 +526,6 @@ export const CreateCluster = () => {
handleIsAcknowledgementChecked={(isChecked: boolean) =>
setIsACLAcknowledgementChecked(isChecked)
}
enableControlPlaneACL={controlPlaneACL}
errorText={errorMap.control_plane}
ipV4Addr={ipV4Addr}
ipV6Addr={ipV6Addr}
isAcknowledgementChecked={isACLAcknowledgementChecked}
Expand All @@ -544,14 +536,6 @@ export const CreateCluster = () => {
)}
<Divider sx={{ marginBottom: 4 }} />
<NodePoolPanel
typesError={
typesError
? getAPIErrorOrDefault(
typesError,
'Error loading Linode type information.'
)[0].reason
: undefined
}
addNodePool={(pool: KubeNodePoolResponse) => addPool(pool)}
apiError={errorMap.node_pools}
hasSelectedRegion={hasSelectedRegion}
Expand All @@ -562,6 +546,14 @@ export const CreateCluster = () => {
selectedRegionId={selectedRegion?.id}
selectedTier={selectedTier}
types={typesData || []}
typesError={
typesError
? getAPIErrorOrDefault(
typesError,
'Error loading Linode type information.'
)[0].reason
: undefined
}
typesLoading={typesLoading}
/>
</Paper>
Expand All @@ -571,11 +563,22 @@ export const CreateCluster = () => {
data-testid="kube-checkout-bar"
>
<KubeCheckoutBar
createCluster={createCluster}
enterprisePrice={lkeEnterpriseType?.price.monthly ?? undefined}
hasAgreed={hasAgreed}
highAvailability={highAvailability}
highAvailabilityPrice={
isErrorKubernetesTypes || !highAvailabilityPrice
? UNKNOWN_PRICE
: highAvailabilityPrice
}
pools={nodePools}
region={selectedRegion?.id}
regionsData={regionsData}
removePool={removePool}
showHighAvailability={showHighAvailability}
submitting={submitting}
toggleHasAgreed={toggleHasAgreed}
updateFor={[
hasAgreed,
highAvailability,
Expand All @@ -588,17 +591,6 @@ export const CreateCluster = () => {
createCluster,
classes,
]}
createCluster={createCluster}
enterprisePrice={lkeEnterpriseType?.price.monthly ?? undefined}
hasAgreed={hasAgreed}
highAvailability={highAvailability}
pools={nodePools}
region={selectedRegion?.id}
regionsData={regionsData}
removePool={removePool}
showHighAvailability={showHighAvailability}
submitting={submitting}
toggleHasAgreed={toggleHasAgreed}
updatePool={updatePool}
/>
</Grid>
Expand Down
Loading