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: Sqllab to Explore UX improvements #11755

Merged
merged 156 commits into from Dec 9, 2020
Merged

feat: Sqllab to Explore UX improvements #11755

merged 156 commits into from Dec 9, 2020

Conversation

hughhhh
Copy link
Member

@hughhhh hughhhh commented Nov 19, 2020

SUMMARY

Allow users the option to name their dataset or overwrite a previously created dataset they own. This a new flow to allow users to update datasets they currently own vs. only being able to create new ones.

Creating a new dataset

https://www.loom.com/share/52e624667090477f91db69addc42fccb

Overwriting a dataset

https://www.loom.com/share/4e77b441c4894dc69ccfb655804cc6ae

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

TEST PLAN

ADDITIONAL INFORMATION

  • Has associated issue:
  • Changes UI
  • Requires DB Migration.
  • Confirm DB Migration upgrade and downgrade tested.
  • Introduces new feature or API
  • Removes existing feature or API

}

componentDidMount() {
// only do this the first time the component is rendered/mounted
this.reRunQueryIfSessionTimeoutErrorOnMount();

// Todo: figure out how to get user information to properly query datasets they own
Copy link
Member

Choose a reason for hiding this comment

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

I think if you query the API on /api/v1/dataset/ it should return only datasets owned by the user (cc: @dpgaspar).

}),
);

this.setState({ userDatasetsOwned });
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 data loaded into redux when the app loads?

Copy link
Member Author

@hughhhh hughhhh Dec 8, 2020

Choose a reason for hiding this comment

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

The database_ids is actually living in the bootstap-data, but is behind a featureFlag. @mistercrunch has a PR to fix

https://github.com/apache/incubator-superset/pull/11934/files


if (
Object.keys(datasetToOverwrite).length === 0 &&
datasetToOverwrite.constructor === Object
Copy link
Member

Choose a reason for hiding this comment

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

will Object.keys(datasetToOverwrite).length === 0 ever be true and datasetToOverwrite.constructor === Object be false? Seems like if the former is true, then the constructor will always be an Object?

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 catch i actually figured out how to prevent this via onChangeAutocomplete. Users have to choose a value from the dropdown before progressing to the overwrite page. So we don't need this condition.

@@ -357,6 +658,7 @@ export default class ResultSet extends React.PureComponent<
if (query.progress > 0) {
progressBar = (
<ProgressBar
// @ts-ignore
Copy link
Member

Choose a reason for hiding this comment

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

are you running into issues where a value is missing on these types/interfaces?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yea wasn't able to figure out what the issue is

} = this.state;
const disableSaveAndExploreBtn =
(saveDatasetRadioBtnState === 1 && newSaveDatasetName.length === 0) ||
(saveDatasetRadioBtnState === 2 &&
Copy link
Member

Choose a reason for hiding this comment

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

do you want to use the enum DatasetRadioState here?

@pull-request-size pull-request-size bot added size/L and removed size/XL labels Dec 8, 2020
@graceguo-supercat
Copy link

graceguo-supercat commented Dec 8, 2020

Hi @hughhhh Thanks for making this PR. I have a question: Is there any permission check when one user overwriting an existed dataset? If not, i feel it is a very dangerous feature. It looks like anyone can overwrite my chart without my acknowledge, even they are not owner.

this.setState({ datasetToOverwrite: {} });
};

handleOverwriteDataset = async () => {

Choose a reason for hiding this comment

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

async/await usually used as a pair, to avoid nested callback hells. Could you please replace .then block with await?

@hughhhh
Copy link
Member Author

hughhhh commented Dec 8, 2020

Hi @hughhhh Thanks for making this PR. I have a question: Is there any permission check when one user overwriting an existed dataset? If not, i feel it is a very dangerous feature. It looks like anyone can overwrite my chart without my acknowledge, even they are not owner.

On the dataset.update we check for the ownership on every request.
https://github.com/apache/incubator-superset/blob/master/superset/datasets/commands/update.py#L88

I'm also only exposing datasets the user owns via getByUser
https://github.com/apache/incubator-superset/pull/11755/files#diff-4563e37b508d681c4d3470358bb89edf6a7f0577849e9f0c9dea92ee37fdd544R176

@graceguo-supercat

@graceguo-supercat
Copy link

It's good that users only see dataset list from they owned, and can only overwrite dataset that he owned.
But there is a can_access_all_datasources permission: Users with can_access_all_datasources can add anyone as owner of a dataset. For these users, they can still overwrite others dataset (after they add them as dataset owners).
Can you confirm this is expected behavior? There is no extra protection in can_access_all_datasources users?
Thanks @hughhhh!

>
Ok
Save &amp; Explore
Copy link
Member

Choose a reason for hiding this comment

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

i18n needed

'MM/DD/YYYY HH:mm:ss',
)}`,
userDatasetsOwned: [],
saveDatasetRadioBtnState: DatasetRadioState.SAVE_NEW,
Copy link
Member

Choose a reason for hiding this comment

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

This is getting too specific. I would just call it "shouldSaveAsNewDataset" or something aline. Imagine what if a future design changes the radio button to a dropdown select?

shouldOverwriteDataSet: false,
datasetToOverwrite: {},
saveModalAutocompleteValue: '',
userDatasetOptions: [],
Copy link
Member

@ktmud ktmud Dec 8, 2020

Choose a reason for hiding this comment

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

I feel you may be passing too many states between components unnecessarily. Can these be combined into one construct as the modal's local states and only be passed up to the parent component when users hit "Save"?

shouldOverwriteDataSet: false,
datasetToOverwrite: {},
newSaveDatasetName: `${this.props.query.tab} ${moment().format(
'MM/DD/YYYY HH:mm:ss',
Copy link
Member

Choose a reason for hiding this comment

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

This is US English only. No need to resolve in this PR, but we should really start thinking about an i18n strategy for things like date formatting.

cc @villebro @rusackas

Copy link
Member

@junlincc junlincc Dec 8, 2020

Choose a reason for hiding this comment

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

+1 i18n strategy

Copy link
Member

Choose a reason for hiding this comment

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

"YYYY-MM-DD HH:mm:ss" It's a more common way for i18n.

Copy link
Member

Choose a reason for hiding this comment

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

+1 on using YYYY-MM-DD HH:mm:ss by default before we add proper internalization/localization support.

newSaveDatasetName: `${this.props.query.tab} ${moment().format(
'MM/DD/YYYY HH:mm:ss',
)}`,
});
Copy link
Member

Choose a reason for hiding this comment

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

There's seem to be some repetitive code between Override and Save as New. Is there a chance for abstraction?

@hughhhh
Copy link
Member Author

hughhhh commented Dec 8, 2020

It's good that users only see dataset list from they owned, and can only overwrite dataset that he owned.
But there is a can_access_all_datasources permission: Users with can_access_all_datasources can add anyone as owner of a dataset. For these users, they can still overwrite others dataset (after they add them as dataset owners).
Can you confirm this is expected behavior? There is no extra protection in can_access_all_datasources users?
Thanks @hughhhh!

@graceguo-supercat So the only way for the users to overwrite a dataset is if they are in the owner list via check_ownership function. So if a user has access to all datasource they must first add themselves as an owner then they'll be able to overwrite.

@hughhhh hughhhh merged commit cc44a2c into master Dec 9, 2020
@amitmiran137 amitmiran137 deleted the hugh/SO-1117-modal branch March 29, 2021 18:11
@mistercrunch mistercrunch added 🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels 🚢 1.0.0 labels Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels size/L 🚢 1.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants