-
Notifications
You must be signed in to change notification settings - Fork 13.8k
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
Make time filter more usable #4981
Make time filter more usable #4981
Conversation
…TOOLS-324_ui_for_time_filter
Codecov Report
@@ Coverage Diff @@
## master #4981 +/- ##
===========================================
- Coverage 77.15% 61.24% -15.92%
===========================================
Files 44 373 +329
Lines 8892 23600 +14708
Branches 0 2735 +2735
===========================================
+ Hits 6861 14453 +7592
- Misses 2031 9132 +7101
- Partials 0 15 +15
Continue to review full report at Codecov.
|
@GabeLoins , mind taking a look into this as this falls under similar as your recent work? |
For UI consistency with the work on |
I'll take a look. Plus plus for using react-bootstrap Tabs for switching between Range and Start/End for visual consistency. We have also been thinking about ways to improve this section on our side. For future work, if you're interested, I think it'd be great to collapse all three components in the |
}; | ||
|
||
|
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.
accidental newline?
Another thought- for the metric and filter popovers I had the state in the popover only persist when the user clicked |
export default class DateFilterControl extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
const value = props.value || ''; | ||
const value = props.value || defaultProps.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.
isn't this redundant of how react already deals with defaultProps?
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 was unsure about this and was afraid of breaking things. I assume it's protecting cases where value
is explicitly set to null
?
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.
PropTypes (if the field is required) will prevent against null being passed in- I'd say drop the || defaultProps.value
.
If the field can't be required, I'd still say its not needed- controls across explore take in the value prop at face value and don't do this check. For it to create a problem someone would have to start setting value as null
in a higher level explore component which I think would be a bigger issue.
// for start:end(includes freeform) | ||
since: DEFAULT_SINCE, | ||
until: DEFAULT_UNTIL, | ||
isFreeform: {}, |
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 feel like this value should be a boolean if its prefixed with is
?
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.
What if we initialize it as:
isFreeform: { since: false, until: false }
I can also rename it to freeformFields
.
superset/assets/package.json
Outdated
@@ -88,6 +88,7 @@ | |||
"react-addons-shallow-compare": "^15.4.2", | |||
"react-alert": "^2.3.0", | |||
"react-bootstrap": "^0.31.5", | |||
"react-bootstrap-datetimepicker": "0.0.22", |
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.
just noticed this component is deprecated, should we switch to the non-deprecated package?
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.
Let me take a look at how much effort is needed to use that one... I remember testing it when I was looking for calendar components, and it didn't work for some cases but TBH I don't remember the details.
const INVALID_DATE_MESSAGE = 'Invalid date'; | ||
const SEPARATOR = ' : '; | ||
const FREEFORM_TOOLTIP = t( | ||
'Superset supports smart date parsing. Strings like `last sunday` or ' + |
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.
[honest question] is this functionality worth supporting? It seems like if I wasn't a power user I wouldn't know which keywords work and which don't. For example, would "2 weeks ago" work? What about "the quarter before last"
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.
Even if we decided we're better off without it, it'd be hard to deprecate (would break charts).
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, without feedback informing if the input is valid this doesn't seem very usable. We could do a backend call and show it in red if not supported?
this.state.dttm = value; | ||
this.state.type = 'fix'; | ||
if (value.indexOf(SEPARATOR) >= 0) { | ||
this.state.type = 'startend'; |
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.
Since put this string in a constant at the top of this file it seems like it'd be best if you referenced it from the constant as well? Otherwise why use a constant?
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 point, let me fix this.
const grainOptions = TIME_GRAIN_OPTIONS.map((grain, index) => ( | ||
<MenuItem | ||
onSelect={this.setCustomRange.bind(this, 'grain')} | ||
key={'grain-' + index} |
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.
generally using index
as a key is considered an antipattern (https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318)
also style nit: I don't think you need to add that grain-
prefix
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, #TIL. Will fix, though in this case it should be safe (no reordering or updates in the list).
key={'grain-' + index} | ||
eventKey={grain} | ||
active={grain === this.state.grain} | ||
>{grain} |
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.
nit: {grain} should be on its own line
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.
Will fix.
} | ||
setDatetime(dttm) { | ||
this.setState({ dttm: dttm.format().substring(0, 19) }); | ||
updateRefs() { |
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.
this seems like it adds quite a bit of indirection. Would it be possible just to pass value
as a prop to these components rather than setting their state via a ref? https://github.com/YouCanBookMe/react-datetime#api
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.
This is needed for freeform text. The calendar component uses moment
to parse the string, and if it fails the state is not set. This prevents us from initializing the component saved with freeform values.
</PopoverSection> | ||
<Tab eventKey={1} title="Range"> | ||
<FormGroup> | ||
{timeFrames} |
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.
maybe this should be its own third tab? It seems like the Range tab is a little busy with the radio buttons and also the dropdown menus
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.
@vylc, any thoughts here? Personally I like this design, since the common ranges and the dropdown serve the same purpose, and allow for a lot of control in a single place.
There's some great improvements here! My thoughts on other issues being discussed
|
For It could be nice if druid/sqlalchemy were consistent, but changing it now would make existing slices incorrect (as people have adjusted to this difference). When we move to using druid sql, this will be consistent. I'll try to look around more for specific suggestions. Maybe something like |
Yeah, I'm unsure about the naming. Maybe we could use "simple" and "custom", like the filters? @michellethomas, how are they different? Is one of them inclusive and the other exclusive? |
Yeah after looking into it, it may be difficult to message because it depends on whether you are using a date or not (and also which engine you are using). For us using dates (not datetime): sqla tries to be inclusive on both ends and will add a filter like Here's a discussion of the issue. I think it was just dropped because we couldn't find a regression, but there's still an inconsistency we should discuss (maybe out of scope for this PR) https://apache-superset.slack.com/archives/C7G8CG0LR/p1512418244000100 |
++ Tabs I think tabs work great to separate different concepts or types of tasks. As Max pointed out they should be visually consistent. The tabs in the gif look a bit like buttons to me. I agree with Chris that "Range" and "Start/End" are confusing since they are both types of ranges. I also view the use of "range" in this context as a type of smart default. A few thoughts:
For example: Defaults
Custom
An open question I have that effects the order of the tabs is what will people use most often? We should order accordingly. |
Looks great! |
@vylc, "relative" is not a good name for the first tab because the second one can also be relative, eg, you could have "last Sunday" as the start and "today" as the end time. |
looking good, thanks for iterating on/incorporating the feedback! |
LGTM |
* Initial work * WIP * WIP * Working * WIP * Still WIP * Frontend done * Working version * Migration working * Migration working * Fix freeform rerender * Remove jquery * Fix filter * Unit tests and lint * Fix py.test * Improve unit tests * Ensure freeform is computed at init * Fix lint * Trying to fix pyfreeze error * Remove freezegun * Address comments * Use tabs instead of pills * Regroup options * WIP * Change type when clicking calendar * Fix CSS * Fix JS lint
* Initial work * WIP * WIP * Working * WIP * Still WIP * Frontend done * Working version * Migration working * Migration working * Fix freeform rerender * Remove jquery * Fix filter * Unit tests and lint * Fix py.test * Improve unit tests * Ensure freeform is computed at init * Fix lint * Trying to fix pyfreeze error * Remove freezegun * Address comments * Use tabs instead of pills * Regroup options * WIP * Change type when clicking calendar * Fix CSS * Fix JS lint
This PR addresses #4292. The main change is that it combines the
since
anduntil
controls into a single one,time_range
:This has a few benefits:
Additionally, there are other improvements to the UX:
(@vylc, note that instead of using "Relative" and "Fixed/Freeform" like in your mocks, I used "Range" and "Start/End". This is because the latter can also be relative, since freeform can take strings like "last Sunday", eg. I'm open to better naming suggestions.)
Tests
since
anduntil
work.