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

UI for Create Postgres Peer #456

Merged
merged 12 commits into from
Oct 3, 2023
Merged

UI for Create Postgres Peer #456

merged 12 commits into from
Oct 3, 2023

Conversation

Amogh-Bharadwaj
Copy link
Contributor

@Amogh-Bharadwaj Amogh-Bharadwaj commented Sep 29, 2023

  • UI for Create Peer step where user enters configuration details
  • Wired validate peer API to the UI
  • Wired create peer API to the UI
  • Form validation, loading text
  • Written in a way where adding new peers is easy
  • Tested the create peer flow (including psql-ing the peer) for postgres

APIs for create peer and validate peer are present in app/api/peers/validate and app/api/peers/create respectively.

Makes progress towards #431

@Jobandeep2417
Copy link

Jobandeep2417 commented Sep 29, 2023

image

Hey Team, Peer overview page simply crashes if the PeerDB instance is not up, Should this be handled gracefully with an error message. I have confirmed by removing the fetchPeer() call and replacing it with an empty array the page loads fine in that case as shown below

image

label: 'Port',
stateHandler: (value: string, setter: PeerSetter) =>
setter((curr) => ({ ...curr, port: parseInt(value, 10) })),
type: 'number', // type for textfield
Copy link

@Jobandeep2417 Jobandeep2417 Sep 29, 2023

Choose a reason for hiding this comment

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

The Port should have a min max range, it should not allow negative values. Although we are validating it in validation helper, thought of adding for better UI experience

image

The way PgConfig and Config form components are setup there is no way to send this info from the settings props.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could prevent typing of non-numbers but right now I personally think it's fine. Happy to discuss though

return (
<>
{props.settings.map((setting, id) => {
return (

Choose a reason for hiding this comment

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

I think making the form config-driven is a good idea. But we maybe need to revisit things like how default values can be set. For Example port default value is 5432 in config state variable, but we are not using it anywhere. perhaps a crude way to do it could be as shown below by adding a default value


export default function PgConfig(props: ConfigProps) {
  return (
    <>
      {props.settings.map((setting, id) => {
        let _defaultValue = setting.type === "number" && setting.label === "Port" ? "5432" : "";
        return (
          <RowWithTextField
            key={id}
            label={<Label as='label'>{setting.label}</Label>}
            action={
              <TextField
                variant='simple'
                type={setting.type}
                defaultValue={_defaultValue}
                onChange={(e) =>
                  setting.stateHandler(e.target.value, props.setter)
                }
              />
            }
          />
        );
      })}
    </>
  );

image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The default values are not really meant to be used in UI, but rather because protobuf-grpc doesn't seem to allow undefined values so we need dummies.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also thanks for the catch: the config value for the state here should be made generic to peer. fixed.

<Button as={Link} href='/peers'>
Cancel
</Button>
<Button

Choose a reason for hiding this comment

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

This is confusing we should block at Data source selection only or grey out the unavailable datasource types

image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup. Singled out postgres (for now) as the only option in the data source selection step.

target='_blank'
>
Learn about peers
</Action>
</Panel>
<Panel>
<Label colorName='lowContrast' variant='subheadline'>

Choose a reason for hiding this comment

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

I think both source and Datasource is not required any one is sufficient
image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup. Changed. Thanks

}).then((res) => res.text());

if (statusMessage !== 'created') {
setMessage({ ok: false, msg: statusMessage });

Choose a reason for hiding this comment

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

Is this supposed to show an error message on UI? Coz even for 500 code I am not seeing any error message?

image

Choose a reason for hiding this comment

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

The same issue for validate button

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey Joban. Couldn't reproduce this. Maybe we could investigate separately if this persists

export const checkFormFields = (peerType: string, config: PeerConfig) => {
switch (peerType) {
case 'POSTGRES':
return pgSchema.validate(config);

Choose a reason for hiding this comment

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

nit: we are showing extra double quotes for error field
image

Copy link
Contributor Author

@Amogh-Bharadwaj Amogh-Bharadwaj Sep 29, 2023

Choose a reason for hiding this comment

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

I think this is fine as the quotes does make the error more clear in a way

Choose a reason for hiding this comment

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

For the Name field double quotes were not there, which is why I pointed it out. Looks a bit inconsistent

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey Joban there are no quotes now. Thanks

export async function POST(request: Request) {
let body = await request.json();
let name = body.name;
let type = body.type;

Choose a reason for hiding this comment

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

Can be refactored as

let { name, type, config } = body;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@Jobandeep2417
Copy link

@iskakaushik Did we consider using material-ui even if we want to use storybook, material-ui can be integrated with storybook (https://storybook.js.org/recipes/@mui/material). The out-of-the-box components provided by the storybook lib look pretty primitive (in styling, shimmering/loading behavior, etc.) . I think we should consider libraries like material-ui/Chara-ui etc from the starting stage of the UI, Please let me know your thoughts on this

ui/package.json Outdated
@@ -31,6 +31,7 @@
"@types/react": "18.2.21",
"@types/react-dom": "18.2.7",
"classnames": "^2.3.2",
"joi": "^17.10.2",
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's use zod instead, it feels like more idiomatic typescript.

<Button
disabled={!peerType}
onClick={() => {
router.push(`/peers/create/configuration?dbtype=${peerType}`);
Copy link
Contributor

Choose a reason for hiding this comment

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

CreatePeerStatus,
} from '@/grpc_generated/route';
import { GetFlowServiceClient } from '@/rpc/rpc';
import { constructPeer } from '../util';
Copy link
Contributor

Choose a reason for hiding this comment

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

lets move this method to this class, there isn't much happening in the utils still.

const body = await request.json();
const { name, type, config } = body;
const flowServiceAddress = process.env.PEERDB_FLOW_SERVER_ADDRESS!;
const flowServiceClient = GetFlowServiceClient(flowServiceAddress);
Copy link
Contributor

Choose a reason for hiding this comment

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

isn't there a helper for this already? Maybe we should have a method GetFlowServiceClientFromEnv, and update usage elsewhere too?

import { GetFlowServiceClient } from '@/rpc/rpc';
import { constructPeer } from '../util';

export async function POST(request: Request) {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we move this to peers/route.ts and service both validate and create based on a param in the json or something else?

};

// API call to create peer
export const handleCreate = async (
Copy link
Contributor

Choose a reason for hiding this comment

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

lets discuss the need for this

@Amogh-Bharadwaj Amogh-Bharadwaj merged commit 8a434aa into main Oct 3, 2023
19 checks passed
@serprex serprex deleted the ui-create-peer branch July 19, 2024 15:18
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.

3 participants