Skip to content
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

Firewall rules create/edit modal #630

Merged
merged 27 commits into from Feb 9, 2022
Merged

Firewall rules create/edit modal #630

merged 27 commits into from Feb 9, 2022

Conversation

david-crespo
Copy link
Collaborator

@david-crespo david-crespo commented Feb 1, 2022

Two ways to see it:

  1. https://console-git-firewall-rule-crud.internal.oxide.computer/orgs/maze-war/projects/prod-online/vpcs/vpc1?tab=firewall-rules, click New rule
  2. Run yarn start:msw and go to http://localhost:4000/orgs/maze-war/projects/mock-project/vpcs/mock-vpc?tab=firewall-rules and click New rule

Limitations

  • Doing almost no input validation — only checking that priority is a number between 0 and 65535

Notes

I'm trying out Yup, a schema validation that Formik has a pretty tight built-in integration with. It adds 30kb to our minified vendor bundle. It's pretty cool, though it seems less powerful than Zod, which is really amazing. Zod would add 50kb instead of 30, but it's quite a bit better — does parsing as well as validation. As you can see here in zod-formik-adapter, turning a Zod schema into something that Formik accepts in the validationSchema prop takes less than 40 lines of code.

@vercel
Copy link

vercel bot commented Feb 1, 2022

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/oxidecomputer/console-ui-storybook/AdDfPE3gNhvK1os3tqhgc3VJCpj4
✅ Preview: https://console-ui-storybook-git-firewall-rule-crud-oxidecomputer.vercel.app

@github-actions
Copy link
Contributor

github-actions bot commented Feb 1, 2022

Preview will be deployed at https://console-git-firewall-rule-crud.internal.oxide.computer

@david-crespo david-crespo temporarily deployed to Preview VM February 1, 2022 22:52 Inactive
@david-crespo david-crespo temporarily deployed to Preview VM February 2, 2022 04:06 Inactive
fieldClassName={cn(fieldClassName, 'appearance-textfield')}
/>
)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appearance-textfield hides the up/down buttons

EditFirewallRuleModal,
} from '../modals/firewall-rules'

const columns = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yeah, I definitely don't miss this 😅. Looking forward to figuring out how we can iterate on the QueryTable to preserve our typesafety and hopefully maintain a less verbose API.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly I don't mind it. There's a memoization issue in the QueryTable version — the columns are currently memoized with a dep array of [children] but I don't think that really works because children is not referentially stable, i.e., it gets remade on every render, which triggers unneeded re-renders in the table.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. That's the biggest challenge with JSX APIs is they're ultimately kind of a nightmare for referential integrity. That said imo they greatly improve the legibility of the construct. At the minimum we'd want type safety for this which I could be content with, but broadly speaking I don't really like APIs that are verbose objects or arrays. Sometimes that's just the price of dealing with JavaScript though, so I can deal if that's what we have to do.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v8 gets you typechecking on the column definition with this kind of janky API:

const table = createTable().RowType<Disk>()

const cols = table.createColumns([
  table.createColumn('name', {
    header: 'Name',
    cell: ({ value }) => <div>{value}</div>,
  }),
  table.createColumn((d) => d.state.state, {
    id: 'status',
    header: 'Status',
    cell: ({ value }) => <DiskStatusBadge status={value} />,
  }),
])

https://github.com/oxidecomputer/console/compare/react-table-v8-test

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know what that reminds me of? react.createElement. Just saying 😄

libs/api/util.ts Outdated
Comment on lines 30 to 40
pick(
rule,
'name',
'action',
'description',
'direction',
'filters',
'priority',
'status',
'targets'
) as NoExtraKeys<VpcFirewallRuleUpdate, VpcFirewallRule>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If new keys are added to the VpcFiewallRule will this fail type checks?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, now that it's a pick this is more about accidentally pulling in keys that don't belong. So for example, if we decided a field wasn't editable anymore, like we remove description from the VpcFirewallRuleUpdate, this will fail because description is still on there and it's not supposed to be.

However, as I test this, it's not behaving as I expect in other ways. For example, if I remove 'name' from the list, it should fail because name is required on VpcFirewallRuleUpdate, and it's not there. But it does not fail. Moving the NoExtraKeys to the return type makes it fail in the expected way, so I'll make that change. Guess I have something to learn about as.

export const firewallRuleGetToPut = (
  rule: VpcFirewallRule
): NoExtraKeys<VpcFirewallRuleUpdate, VpcFirewallRule> =>
  pick(
    rule,
    'name',
    'action',
    'description',
    'direction',
    'filters',
    'priority',
    'status',
    'targets'
  )

This will probably become moot once we make our PUTs spec-compliant, which will mean they have the same shape as the GET response.

</Table.HeaderRow>
</Table.Header>
<Table.Body>
{values.targets.map((t) => (
Copy link
Contributor

@zephraph zephraph Feb 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When running this with msw I'm hitting an error here where values.targets is undefined after trying to edit the first item in the rules list. When logging value at the top of the form it shows allow-icmp twice before erroring

Copy link
Contributor

@zephraph zephraph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is some solid work, thanks for taking it on. There's still a lot to follow up with here, but you've got TODOs on basically all of it, ha. Looking forward to the follow up conversation on the QueryTable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants