-
Notifications
You must be signed in to change notification settings - Fork 14.5k
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: Improve sorting for new chart dataset select #16414
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,7 @@ export type AddSliceContainerProps = {}; | |
export type AddSliceContainerState = { | ||
datasource?: { label: string; value: string }; | ||
visType: string | null; | ||
search: string; | ||
}; | ||
|
||
const ESTIMATED_NAV_HEIGHT = 56; | ||
|
@@ -186,6 +187,7 @@ export default class AddSliceContainer extends React.PureComponent< | |
super(props); | ||
this.state = { | ||
visType: null, | ||
search: '', | ||
}; | ||
|
||
this.changeDatasource = this.changeDatasource.bind(this); | ||
|
@@ -194,6 +196,8 @@ export default class AddSliceContainer extends React.PureComponent< | |
this.newLabel = this.newLabel.bind(this); | ||
this.loadDatasources = this.loadDatasources.bind(this); | ||
this.handleFilterOption = this.handleFilterOption.bind(this); | ||
this.handleFilterSort = this.handleFilterSort.bind(this); | ||
this.handleSearch = this.handleSearch.bind(this); | ||
} | ||
|
||
exploreUrl() { | ||
|
@@ -241,6 +245,10 @@ export default class AddSliceContainer extends React.PureComponent< | |
); | ||
} | ||
|
||
handleSearch(search: string) { | ||
this.setState({ search }); | ||
} | ||
|
||
loadDatasources(search: string, page: number, pageSize: number) { | ||
const query = rison.encode({ | ||
columns: ['id', 'table_name', 'description', 'datasource_type'], | ||
|
@@ -256,15 +264,12 @@ export default class AddSliceContainer extends React.PureComponent< | |
const list: { | ||
label: string; | ||
value: string; | ||
}[] = response.json.result | ||
.map((item: Dataset) => ({ | ||
value: `${item.id}__${item.datasource_type}`, | ||
label: this.newLabel(item), | ||
labelText: item.table_name, | ||
})) | ||
.sort((a: { labelText: string }, b: { labelText: string }) => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fun fact, this didn't do anything since the selector re-sorts the options again :P Adding a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @etr2460 Screen.Recording.2021-08-24.at.7.29.40.AM.movThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @etr2460 The ideal solution would be to disable the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm, interesting, i didn't even see results rendering when clicking into the modal without typing anything. although maybe that's because in our env we have too many datasets so it didn't render fast enough. i'll see what i can do to fix the sorting for all use cases here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @etr2460 for the scenario where the paginated query with no search (100 results by default) is heavy, we created a prop called |
||
a.labelText.localeCompare(b.labelText), | ||
); | ||
}[] = response.json.result.map((item: Dataset) => ({ | ||
value: `${item.id}__${item.datasource_type}`, | ||
label: this.newLabel(item), | ||
labelText: item.table_name, | ||
})); | ||
|
||
return { | ||
data: list, | ||
totalCount: response.json.count, | ||
|
@@ -281,6 +286,23 @@ export default class AddSliceContainer extends React.PureComponent< | |
return labelText.toLowerCase().includes(searchValue); | ||
} | ||
|
||
handleFilterSort( | ||
a: { label: string; value: number; labelText: string }, | ||
b: { label: string; value: number; labelText: string }, | ||
) { | ||
const optionA = a.labelText.toLowerCase(); | ||
const optionB = b.labelText.toLowerCase(); | ||
const search = this.state.search.toLowerCase(); | ||
|
||
if (optionA === search) { | ||
return -1; | ||
} | ||
if (optionB === search) { | ||
return 1; | ||
} | ||
return optionA.localeCompare(optionB); | ||
} | ||
|
||
render() { | ||
const isButtonDisabled = this.isBtnDisabled(); | ||
return ( | ||
|
@@ -297,11 +319,13 @@ export default class AddSliceContainer extends React.PureComponent< | |
ariaLabel={t('Dataset')} | ||
name="select-datasource" | ||
filterOption={this.handleFilterOption} | ||
filterSort={this.handleFilterSort} | ||
onChange={this.changeDatasource} | ||
options={this.loadDatasources} | ||
placeholder={t('Choose a dataset')} | ||
showSearch | ||
value={this.state.datasource} | ||
onSearch={this.handleSearch} | ||
/> | ||
<span> | ||
{t( | ||
|
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.
I think we should just replace both
filterOption
andfilterSort
withmatch-sorter
. It has worked well for the Explore page Dataset side panel.This basically means controlling the filtering outside of AntD Select---which should give more consistent filtering behavior across the board.
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.
woah, i haven't seen
match-sorter
yet. i think that'll work? although antd select has made it tricky to take control over filtering and sorting. i'll play with itThere 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.
@ktmud Do you think we should try and add this to the default Select component in superset? just apply it across the board?
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.
Yes, that'd be ideal. The Select component can provide a
matchSorterKey
prop to override the default match-sorting keys.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.
@ktmud @etr2460
filterSort
is useful when all the values are present in the select. It's less useful when we are using the async version of our select, which is the majority of the cases. In the async version, the sorting should be done on the server-side before the pagination to ensure the correct results are returned. Client-side sorting on paginated requests can produce wrong results. We can usematch-sorter
for the static version but so far we haven't found any case where the default sorting wasn't sufficient. I think the best way to fix this is to make the endpoint respect the sorting parameters and implement the exact match behavior on the server-side.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.
Yes, bumping exact matches is probably good enough for now.
It'd definitely be nice to have paginated backend searches. Hopefully we'll come up with a solution that's generalized enough even for omni-searches in the future.
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.
I'd love to make this an optional search backend! 🍻
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.
I think we all agree here. Thanks @villebro ! do you think i should close this pr then?
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.
@etr2460 I have a POC in mind but it would introduce a fairly significant change on FAB, so I want to discuss it first with Daniel before starting the work, and he's currently on PTO. I don't expect my POC to be ready for another few weeks (will require review and a new release), so if this is needed in the interim then we can merge this IMO unless @michael-s-molina has some objections.
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.
@villebro I don't have any objections as a temporary solution. We can come back later and remove the client-side sorting. We'll probably need to do that anyway with other selects.
Before merging, we need to also sort the values when the user opens the select as stated here #16414 (comment)