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

feat: Gsheet adding sheets component #15598

Closed

Conversation

AAfghahi
Copy link
Member

@AAfghahi AAfghahi commented Jul 8, 2021

SUMMARY

This creates the basic structure for the gsheets component for the database modal.

It also adds the Table_Catalog feature, which still needs to be fleshed out.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Screen.Recording.2021-07-09.at.10.59.20.AM.mov

TESTING INSTRUCTIONS

ADDITIONAL INFORMATION

  • Has associated issue:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

@AAfghahi AAfghahi marked this pull request as ready for review July 9, 2021 22:09
@AAfghahi AAfghahi changed the base branch from master to pexdax/improved-sheets July 9, 2021 22:09
@codecov
Copy link

codecov bot commented Jul 9, 2021

Codecov Report

Merging #15598 (0fede91) into pexdax/improved-sheets (accb48e) will decrease coverage by 0.01%.
The diff coverage is 20.00%.

❗ Current head 0fede91 differs from pull request most recent head 84222b2. Consider uploading reports for the commit 84222b2 to get more accurate results
Impacted file tree graph

@@                    Coverage Diff                     @@
##           pexdax/improved-sheets   #15598      +/-   ##
==========================================================
- Coverage                   76.96%   76.95%   -0.02%     
==========================================================
  Files                         976      976              
  Lines                       51347    51360      +13     
  Branches                     6907     6914       +7     
==========================================================
+ Hits                        39518    39522       +4     
- Misses                      11610    11619       +9     
  Partials                      219      219              
Flag Coverage Δ
javascript 71.40% <20.00%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
.../database/DatabaseModal/DatabaseConnectionForm.tsx 59.78% <16.66%> (-3.32%) ⬇️
...c/views/CRUD/data/database/DatabaseModal/index.tsx 47.74% <40.00%> (-0.12%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update accb48e...84222b2. Read the comment docs.

}: FieldPropTypes) => {
const [uploadOption, setUploadOption] = useState<number>(
CredentialInfoOptions.jsonUpload.valueOf(),
);
const [fileToUpload, setFileToUpload] = useState<string | null | undefined>(
null,
);
console.log('in credentials', isPublic);
Copy link
Member

Choose a reason for hiding this comment

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

remove

@@ -360,7 +361,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
t('database'),
addDangerToast,
);

console.log(isPublic);
Copy link
Member

Choose a reason for hiding this comment

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

remove

@eschutho
Copy link
Member

eschutho commented Jul 9, 2021

Can you add more details in the PR description?

Comment on lines 346 to 351
<Select.Option value="true" key={1}>
Publicly shared sheets only
</Select.Option>
<Select.Option value="false" key={2}>
Public and privately shared sheets
</Select.Option>
Copy link
Member

Choose a reason for hiding this comment

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

If you set the values to booleans you don't need to convert them from string:

Suggested change
<Select.Option value="true" key={1}>
Publicly shared sheets only
</Select.Option>
<Select.Option value="false" key={2}>
Public and privately shared sheets
</Select.Option>
<Select.Option value={true} key={1}>
Publicly shared sheets only
</Select.Option>
<Select.Option value={false} key={2}>
Public and privately shared sheets
</Select.Option>

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I tried this but the antd component only allows string or number:
https://3x.ant.design/components/select/

That's why I did the string conversion. Can we change that locally?

Copy link
Member

Choose a reason for hiding this comment

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

Ah, good point. I would convert it as soon as possible then, passing around a string that should really be a boolean is prone to bugs:

<Select
          style={{ width: '100%' }}
          onChange={(value: string) => setPublic(stringToBoolean(value))}

Where:

const stringToBoolean = (value: string): boolean => value === 'true';

Copy link
Member Author

Choose a reason for hiding this comment

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

good idea, I will make that change right now.

return (
<CredentialInfoForm>
{!isEditMode && (
{!isEditMode && db?.engine === 'bigquery' && (
Copy link
Member

Choose a reason for hiding this comment

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

By making these conditionals by engine, we're heading towards what we tried to avoid originally which was to make a large if/then block with a bunch of engines. Can we instead make this more dynamic and look for some property of the engine that is relevant to the code below, like uploadOption?

Copy link
Member

Choose a reason for hiding this comment

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

We currently return this for BQ:

{
  "available_drivers": [
    "bigquery"
  ],
  "default_driver": "bigquery",
  "engine": "bigquery",
  "name": "Google BigQuery",
  "parameters": {
    "properties": {
      "credentials_info": {
        "description": "Contents of BigQuery JSON credentials.",
        "type": "string",
        "x-encrypted-extra": true
      }
    },
    "required": [
      "credentials_info"
    ],
    "type": "object"
  },
  "preferred": false,
  "sqlalchemy_uri_placeholder": "bigquery://{project_id}"
}

Note how for credentials_info we have extra metadata informing that the value should be sent via encrypted_extra:

      "credentials_info": {
        "description": "Contents of BigQuery JSON credentials.",
        "type": "string",
        "x-encrypted-extra": true
      }

We can add more extra metadata in the BE to inform the FE that this should be an upload/past form, eg:

      "credentials_info": {
        "description": "Contents of BigQuery JSON credentials.",
        "type": "string",
        "x-encrypted-extra": true,
        "x-special-input-types": ["paste", "upload"]
      }

So that the FE knows to render the component without hardcoding the engine.

For GSheets this is a bit more complicated, because we want to have conditional rendering of the component. Not sure how to proceed there.

@eschutho, thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason why we have to use ‘credentials_info’ as the key for the field? For most fields, that key is the return value for the api, but since we’re renaming it, can’t we call it something like encrypted_credentials?

Copy link
Member

Choose a reason for hiding this comment

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

Right, we could call it anything we want.

Copy link
Member

Choose a reason for hiding this comment

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

👍 Then encrypted_credentials could be a paste/upload component.. no need for the api to define it.

@@ -104,9 +109,10 @@ const CredentialsInfo = ({
)}
{uploadOption === CredentialInfoOptions.copyPaste ||
isEditMode ||
editNewDb ? (
editNewDb ||
(db?.engine === 'gsheets' && !isPublic) ? (
Copy link
Member

Choose a reason for hiding this comment

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

same thing here. We want to avoid a bunch of if/thens by engine.

<Button
className="input-upload-btn"
onClick={() =>
document?.getElementById('selectedFile')?.click()
Copy link
Member

Choose a reason for hiding this comment

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

can we use a ref to get the element instead of the dom directly?

id="selectedFile"
className="input-upload"
type="file"
onChange={async event => {
Copy link
Member

Choose a reason for hiding this comment

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

can we put this onChange in a separate function? It's a little long to be inline.

checked: false,
},
});
(document.getElementById(
Copy link
Member

Choose a reason for hiding this comment

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

can we use a ref instead?

<FormLabel required>{t('Type of Google Sheets Allowed')}</FormLabel>
<Select
style={{ width: '100%' }}
onChange={(value: string) => setPublicSheets(value)}
Copy link
Member

Choose a reason for hiding this comment

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

if you're not manipulating the arguments at all, you should be able to just pass the function itself, rather than create a new arrow function.

Copy link
Member Author

Choose a reason for hiding this comment

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

When I do this onChange = {setPublicSheets(value)} I get this reference error.

ReferenceError: value is not defined

Copy link
Member

Choose a reason for hiding this comment

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

When you write:

// this is a function
(value: string) => setPublicSheets(value)

You're defining an anonymous function that takes a string called value and calls setPublicSheets on it. You're passing that function to onChange:

onChange={(value: string) => setPublicSheets(value)}

If you wanted to name that function, you could do this:

const func = (value: string) => setPublicSheets(value);

Then you could write:

onChange={func}

But why do you need to create that anonymous function and pass to onChange? You already have a function that takes a string called value and returns the result of passing it to setPublicSheets... it's setPublicSheets itself!

So all you need to do is:

onChange={setPublicSheets}

isEditMode,
db,
editNewDb,
}: FieldPropTypes) => <>hello! {db?.engine}</>;
Copy link
Member

Choose a reason for hiding this comment

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

is this placeholder code?

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah this was where i ran out of time

AAfghahi and others added 4 commits July 13, 2021 10:10
…atabaseConnectionForm.tsx

Co-authored-by: Beto Dealmeida <roberto@dealmeida.net>
…ndex.tsx

Co-authored-by: Beto Dealmeida <roberto@dealmeida.net>
Copy link
Member

@eschutho eschutho left a comment

Choose a reason for hiding this comment

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

left feedback re: conditionals with engine name.

@AAfghahi
Copy link
Member Author

#15801

in favor of this PR

@AAfghahi AAfghahi closed this Jul 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants