-
Notifications
You must be signed in to change notification settings - Fork 332
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
upcoming: [M3-8028]: Linode Create Refactor - User Defined Fields #10395
upcoming: [M3-8028]: Linode Create Refactor - User Defined Fields #10395
Conversation
Coverage Report: β
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got a 500 trying to submit this one βοΈ
Tried in prod with exact same specs and it went through
{
"authorized_users": [],
"backups_enabled": false,
"booted": true,
"image": "linode/almalinux8",
"label": "setup-ipsec-vpn-us-east",
"private_ip": false,
"region": "us-east",
"root_pass": "[pass]",
"stackscript_data": {
"VPN_PASSWORD": "dfasdf4534",
"VPN_USER": "dddesdfgd",
"VPN_IPSEC_PSK": "dfgsdfg564"
},
"stackscript_id": 37239,
"tags": [],
"type": "g6-nanode-1"
}
one thing i noticed is the stackscript_id
seems to be missing in the v2 flow but unsure if that's the root cause
|
||
if (getIsUDFMultiSelect(userDefinedField)) { | ||
const options = userDefinedField | ||
.manyof!.split(',') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can have have better type safety around manyof
& oneof
(or safer conditionals)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What approach would you recommend here? Changing the condition to if (udf.manyof)
? I can't think of a way to make getIsUDFMultiSelect
more typesafe without writing lots more typescript types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the condition to if (udf.manyof)
yeah i don't have a better solution. maybe not crucial cause we know, but always in favor of being extra verbose to avoid non-null assertions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can probably accomplish what you're looking for using a nifty feature of TypeScript: type predicates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about that, but wouldn't that require a new type?
interface UserDefinedFieldMulti extends UserDefinedField {
manyof: string;
}
/**
* @returns true if a user defined field should be treated as a multi-select
*/
export const getIsUDFMultiSelect = (udf: UserDefinedField): udf is UserDefinedFieldMulti => {
return !!udf.manyof;
}
Is there a way to do it cleaner? I'm not sure having a bunch of extra types is worth it
@abailly-akamai I wasn't able to replicate the 500 error, but I'm assuming the empty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested well on my end with various payloads and stackscripts. β
Thanks for the extra care of unit testing thoroughly β€οΈ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
packages/manager/src/features/Linodes/LinodeCreatev2/utilities.ts
Outdated
Show resolved
Hide resolved
...manager/src/features/Linodes/LinodeCreatev2/Tabs/StackScripts/UserDefinedFields/utilities.ts
Outdated
Show resolved
Hide resolved
...manager/src/features/Linodes/LinodeCreatev2/Tabs/StackScripts/UserDefinedFields/utilities.ts
Outdated
Show resolved
Hide resolved
{formState.errors.stackscript_id && ( | ||
<Notice | ||
spacingBottom={0} | ||
spacingTop={8} | ||
text={formState.errors.stackscript_id.message} | ||
variant="error" | ||
/> | ||
)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
out of curiosity, how can we hit this error? You have to select a StackScript in order to select an image, and submitting the form with neither just gets you the Image is required.
error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was able to trigger formState.errors.stackscript_id
by sending a UDF that was super long
.oneof!.split(',') | ||
.map((option) => ({ label: option })); | ||
|
||
if (options.length > 4) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the condition be >= here? Storybook says we use radio buttons if there are 3 or fewer options
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going to retain > 4
because that's what the existing create flow uses (see packages/manager/src/features/StackScripts/UserDefinedFieldsPanel/FieldTypes/UserDefinedSelect.tsx
)
@dwiley-akamai There should be full parity with StackScript UDF fields. Your screenshot shows two different StackScripts selected, so I'm not sure if you were referring to UDFs. The icon missing in the new ImageSelect is expected. That hasn't been implemented yet |
Whoops, you can disregard that comment. I definitely honed in on "Shadowsocks" in the StackScript name and overlooked that the two StackScripts weren't the same π€¦πΎββοΈ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good and I tested deploying some linodes from stackscripts with UDFs. Left some suggestions.
@@ -15,7 +15,7 @@ interface Props { | |||
disabled?: boolean; | |||
isSelected: boolean; | |||
onOpenDetails: () => void; | |||
onSelect: () => void; | |||
onSelect?: () => void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious as to when this prop would not be passed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the prop optional because in the case of a pre-selected StackScript, the row is disabled and doesn't really need an onClick
. I could revert this, but I felt wrong to have a "dummy" onSelect for a row that should never be selected. Happy do go either way on this change
|
||
if (getIsUDFMultiSelect(userDefinedField)) { | ||
const options = userDefinedField | ||
.manyof!.split(',') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can probably accomplish what you're looking for using a nifty feature of TypeScript: type predicates.
...manager/src/features/Linodes/LinodeCreatev2/Tabs/StackScripts/UserDefinedFields/utilities.ts
Outdated
Show resolved
Hide resolved
return udfs.reduce( | ||
(accum, udf) => { | ||
if (getIsUDFOptional(udf)) { | ||
return [[...accum[0]], [...accum[1], udf]]; | ||
} else { | ||
return [[...accum[0], udf], [...accum[1]]]; | ||
} | ||
}, | ||
[[], []] | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also might be more tersely expressed as two filters:
return udfs.reduce( | |
(accum, udf) => { | |
if (getIsUDFOptional(udf)) { | |
return [[...accum[0]], [...accum[1], udf]]; | |
} else { | |
return [[...accum[0], udf], [...accum[1]]]; | |
} | |
}, | |
[[], []] | |
); | |
return [udfs.filter(getIsUDFRequired), udfs.filter(getIsUDFOptional)]; |
...manager/src/features/Linodes/LinodeCreatev2/Tabs/StackScripts/UserDefinedFields/utilities.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been brought up previously but worth mentioning: if we want to match prod behavior with autofilling the Linode label, we would also want to prefill the stackscript name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review β
Functionality of UDFs for various StackScripts β
Description π
Adds initial User Defined Field support to the Linode Create flow when deploying from a StackScript
Changes π
Preview π·
How to test π§ͺ
Prerequisites
Linode Create v2
feature flagVerification steps
As an Author I have considered π€