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
feat: Gsheet adding sheets component #15598
Conversation
Codecov Report
@@ 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
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
}: FieldPropTypes) => { | ||
const [uploadOption, setUploadOption] = useState<number>( | ||
CredentialInfoOptions.jsonUpload.valueOf(), | ||
); | ||
const [fileToUpload, setFileToUpload] = useState<string | null | undefined>( | ||
null, | ||
); | ||
console.log('in credentials', isPublic); |
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.
remove
@@ -360,7 +361,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({ | |||
t('database'), | |||
addDangerToast, | |||
); | |||
|
|||
console.log(isPublic); |
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.
remove
Can you add more details in the PR description? |
superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm.tsx
Show resolved
Hide resolved
superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx
Outdated
Show resolved
Hide resolved
<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> |
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.
If you set the values to booleans you don't need to convert them from string:
<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> |
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.
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?
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.
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';
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.
good idea, I will make that change right now.
superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm.tsx
Outdated
Show resolved
Hide resolved
return ( | ||
<CredentialInfoForm> | ||
{!isEditMode && ( | ||
{!isEditMode && db?.engine === 'bigquery' && ( |
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.
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?
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.
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?
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.
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?
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.
Right, we could call it anything we want.
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.
👍 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) ? ( |
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.
same thing here. We want to avoid a bunch of if/thens by engine.
<Button | ||
className="input-upload-btn" | ||
onClick={() => | ||
document?.getElementById('selectedFile')?.click() |
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 we use a ref to get the element instead of the dom directly?
id="selectedFile" | ||
className="input-upload" | ||
type="file" | ||
onChange={async event => { |
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 we put this onChange in a separate function? It's a little long to be inline.
checked: false, | ||
}, | ||
}); | ||
(document.getElementById( |
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 we use a ref instead?
<FormLabel required>{t('Type of Google Sheets Allowed')}</FormLabel> | ||
<Select | ||
style={{ width: '100%' }} | ||
onChange={(value: string) => setPublicSheets(value)} |
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.
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.
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.
When I do this onChange = {setPublicSheets(value)
} I get this reference error.
ReferenceError: value is not defined
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.
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}</>; |
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.
is this placeholder code?
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.
yeah this was where i ran out of time
…atabaseConnectionForm.tsx Co-authored-by: Beto Dealmeida <roberto@dealmeida.net>
…ndex.tsx Co-authored-by: Beto Dealmeida <roberto@dealmeida.net>
6c001ac
to
84222b2
Compare
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.
left feedback re: conditionals with engine name.
in favor of this PR |
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