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

🪟 🎉 Add column selection UI to new stream table #21058

Merged
merged 24 commits into from
Jan 25, 2023

Conversation

josephkmh
Copy link
Contributor

@josephkmh josephkmh commented Jan 5, 2023

What

Closes #20584

Adds column selection UI to the new stream table design.

field.selection.in.new.table.mov

How

  • Adds a column to the new StreamFieldsTable for a "Sync" checkbox for each top-level field
  • Updates the stream config when the checkbox is toggled
  • Adds a checkbox in the header to select/deselect all fields
  • Does some conditional checks based on syncMode and destinationSyncMode - primary keys and cursors in these modes should not be deselected
  • Adds unit tests for various scenarios of selecting/deselecting fields

@octavia-squidington-iv octavia-squidington-iv added area/platform issues related to the platform area/frontend Related to the Airbyte webapp labels Jan 5, 2023
@octavia-squidington-iv octavia-squidington-iv removed the area/platform issues related to the platform label Jan 11, 2023
Comment on lines +142 to +151
const onToggleFieldSelected = useCallback(
(fieldPath: string[], isSelected: boolean) => {
if (!config) {
return;
}
const updatedConfig = updateFieldSelected({ config, fields, fieldPath, isSelected, numberOfFieldsInStream });
updateStreamWithConfig(updatedConfig);
},
[config, fields, numberOfFieldsInStream, updateStreamWithConfig]
);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This has been extracted to streamConfigHelpers to make unit testing easier (see streamConfigHelpers.test.ts)

Comment on lines 21 to 38
const FIELD_ONE: SyncSchemaField = {
path: ["field_one"],
cleanedName: "field_one",
key: "field_one",
type: "string",
};
const FIELD_TWO: SyncSchemaField = {
path: ["field_two"],
cleanedName: "field_two",
key: "field_two",
type: "string",
};
const FIELD_THREE: SyncSchemaField = {
cleanedName: "field_three",
type: "todo",
key: "field_three",
path: ["field_three"],
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I redefined FIELD_ONE, FIELD_TWO and FIELD_THREE in this file, which is one of the reasons for the large diff.

@josephkmh josephkmh changed the title [DRAFT] 🪟 🎉 Add column selection UI to new stream table 🪟 🎉 Add column selection UI to new stream table Jan 12, 2023
@josephkmh josephkmh marked this pull request as ready for review January 12, 2023 22:40
Comment on lines +57 to +61
const fields = useMemo(() => {
const traversedFields = traverseSchemaToField(stream?.jsonSchema, stream?.name);
return traversedFields.sort(naturalComparatorBy((field) => field.cleanedName));
}, [stream?.jsonSchema, stream?.name]);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This has just been moved up in the file, not changed!

Copy link
Contributor

@edmundito edmundito left a comment

Choose a reason for hiding this comment

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

Code looks good but there were a few issues I noticed during testing.

Can you follow up with Nico about the "Sync" column? I'm not sure if that is outdated design so I'm not sure what exactly is the intent there (previous designs had a switch instead of checkbox)
image

The field count needs to appear in the main table. Is this intended to be done separately?
image

I tried just unselecting my primary key and saving and got an error. But the error is a little vague. It works for one stream, but what about multiple streams? One option is to invalidate the selected primary key immediately so that the user has to update the key right away (Probably can be addressed separately.)

image

After you delete a connection and go back to it (we call this readonly mode), you can still check and uncheck the checkboxes:
image

When I check and uncheck the boxes, the save changes button is enabled instead of going back to being disabled:
image

Let me know which ones you want to address in this PR and which will be addressed separately.

Comment on lines 53 to 60
<CheckBox
checkboxSize="sm"
checked={isFieldSelected}
onChange={() => handleFieldToggle(field.path, !isFieldSelected)}
/>
)}
{isDisabled && (
<Tooltip control={<CheckBox checkboxSize="sm" disabled checked={isFieldSelected} readOnly />}>
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I'm always in favor of rendering the same component instead of splitting the logic into two render calls. Meaning that an alternative would be to create the CheckBox in a variable with all the possible fields, then if disabled, wrap it in a tooltip.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I understand, and I think I generally agree when there's a lot of JSX, but I'm not sure if it would be any clearer in this instance. This component's render function basically does one thing only: checks the boolean isDisabled and returns one or the other bit of JSX. If I split that into another variable, wouldn't that same logic be repeated in the variable? What would the benefit be?

selectedFields: [],
fieldSelectionEnabled: false,
});
});
});
});

describe(`${updateFieldSelected.name}`, () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I've been using this convention:

Function: #${myFunction.name}
Component: <${MyComponent.name} />

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure I quite follow here - are you suggesting that I put a # before the function name in the test title? Something like this?

describe(`#${updateFieldSelected.name}`, () => {

I can't find any other usage like this in the codebase, so I think I'm misunderstanding here.

@josephkmh
Copy link
Contributor Author

josephkmh commented Jan 16, 2023

Thanks for the review! I'll address the comments today/tomorrow.

The field count needs to appear in the main table. Is this intended to be done separately?

Yes, this is missing and I think I will actually leave it out for the moment to keep this PR as small as possible. It should be an easy follow-up PR: #21772

@josephkmh
Copy link
Contributor Author

josephkmh commented Jan 16, 2023

Can you follow up with Nico about the "Sync" column? I'm not sure if that is outdated design so I'm not sure what exactly is the intent there (previous designs had a switch instead of checkbox)

Confirmed with @Upmitt that checkboxes are correct, latest figma designs here

@josephkmh
Copy link
Contributor Author

I tried just unselecting my primary key and saving and got an error. But the error is a little vague. It works for one stream, but what about multiple streams? One option is to invalidate the selected primary key immediately so that the user has to update the key right away (Probably can be addressed separately.)

image

This is definitely unexpected, and deselection of the primary key or cursor field should be prevented on the client side already:
image

Could you let me know steps to reproduce this?

@josephkmh
Copy link
Contributor Author

josephkmh commented Jan 16, 2023

When I check and uncheck the boxes, the save changes button is enabled instead of going back to being disabled

Good catch, this one is because the backend does not return selectedFields in stream.config if fieldSelectionEnabled: false. I'm checking with @mfsiega-airbyte if we should reliably return this field from the backend. If not, we can fix this by removing selectedFields: [] when fieldSelectionEnabled: false

Edit: following up, looks like we will need to do this validation client-side. So we'll have to conditionally delete selectedFields from the config if fieldSelectionEnabled is set to false: d311cb9

@josephkmh
Copy link
Contributor Author

After you delete a connection and go back to it (we call this readonly mode), you can still check and uncheck the checkboxes:

Thanks for catching this! I did not have readonly mode on my radar. Here's a fix for that: 706163d

@josephkmh
Copy link
Contributor Author

I tried just unselecting my primary key and saving and got an error. But the error is a little vague. It works for one stream, but what about multiple streams? One option is to invalidate the selected primary key immediately so that the user has to update the key right away (Probably can be addressed separately.)

This has been fixed here: 427a3b6

Copy link
Contributor

@dizel852 dizel852 left a comment

Choose a reason for hiding this comment

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

Overall - LGTM 👍
But have a question: do we support stream selection functionality during connection creation?

Since I got an error when tried to create a connection with unselected field:
image

@josephkmh
Copy link
Contributor Author

@dizel852 thank you for pointing that out, it looks like a backend error that we're looking into 👍

@josephkmh
Copy link
Contributor Author

josephkmh commented Jan 21, 2023

@dizel852 this has been fixed in #21647 ! Thanks again for reporting that.

Copy link
Contributor

@edmundito edmundito left a comment

Choose a reason for hiding this comment

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

I did some testing and noticed something 👀

@edoang
Copy link

edoang commented Apr 17, 2023

@josephkmh i'm trying to test this feature on the latest version (0.44.0) but i don't find the way to select columns. I'm using postgres src and dest. am i missing something?

@josephkmh
Copy link
Contributor Author

josephkmh commented May 9, 2023

@edoang this is indeed only available in Airbyte cloud currently. It will be coming to OSS, but we don't have a timeline for that just yet!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/frontend Related to the Airbyte webapp
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add column selection UI to new stream table
5 participants