Skip to content

Commit

Permalink
New filtering experience UI enhancements (#4296)
Browse files Browse the repository at this point in the history
samwinslow authored May 12, 2021
1 parent ff0aa43 commit c7b71c4
Showing 11 changed files with 300 additions and 153 deletions.
117 changes: 79 additions & 38 deletions frontend/src/lib/components/ChartFilter/ChartFilter.js
Original file line number Diff line number Diff line change
@@ -12,6 +12,14 @@ import {
} from '~/lib/constants'
import { chartFilterLogic } from './chartFilterLogic'
import { ViewType } from 'scenes/insights/insightLogic'
import {
OrderedListOutlined,
LineChartOutlined,
AreaChartOutlined,
BarChartOutlined,
TableOutlined,
PieChartOutlined,
} from '@ant-design/icons'

export function ChartFilter(props) {
let { filters, onChange } = props
@@ -34,6 +42,75 @@ export function ChartFilter(props) {
? FUNNEL_VIZ
: ACTIONS_LINE_GRAPH_LINEAR

function Label({ icon, children = null }) {
return (
<>
{icon} {children}
</>
)
}

const options =
filters.insight === ViewType.FUNNELS
? [
{
value: FUNNEL_VIZ,
label: <Label icon={<OrderedListOutlined />}>Steps</Label>,
},
{
value: ACTIONS_LINE_GRAPH_LINEAR,
label: (
<Label icon={<LineChartOutlined />}>
Trends
<Tag color="orange" style={{ marginLeft: 8, fontSize: 10 }}>
BETA
</Tag>
</Label>
),
},
]
: [
{
label: 'Line Chart',
options: [
{
value: ACTIONS_LINE_GRAPH_LINEAR,
label: <Label icon={<LineChartOutlined />}>Linear</Label>,
disabled: linearDisabled,
},
{
value: ACTIONS_LINE_GRAPH_CUMULATIVE,
label: <Label icon={<AreaChartOutlined />}>Cumulative</Label>,
disabled: cumulativeDisabled,
},
],
},
{
label: 'Bar Chart',
options: [
{
value: ACTIONS_BAR_CHART,
label: <Label icon={<BarChartOutlined />}>Time</Label>,
disabled: barDisabled,
},
{
value: ACTIONS_BAR_CHART_VALUE,
label: <Label icon={<BarChartOutlined />}>Value</Label>,
disabled: barValueDisabled,
},
],
},
{
value: ACTIONS_TABLE,
label: <Label icon={<TableOutlined />}>Table</Label>,
disabled: tableDisabled,
},
{
value: ACTIONS_PIE_CHART,
label: <Label icon={<PieChartOutlined />}>Pie</Label>,
disabled: pieDisabled,
},
]
return (
<Select
key="2"
@@ -47,43 +124,7 @@ export function ChartFilter(props) {
dropdownMatchSelectWidth={false}
data-attr="chart-filter"
disabled={props.disabled}
>
{filters.insight === ViewType.FUNNELS ? (
<>
<Select.Option value={FUNNEL_VIZ}>Steps</Select.Option>
<Select.Option value={ACTIONS_LINE_GRAPH_LINEAR}>
Trends
<Tag color="orange" style={{ marginLeft: 8, fontSize: 10 }}>
BETA
</Tag>
</Select.Option>
</>
) : (
<>
<Select.OptGroup label={'Line Chart'}>
<Select.Option value={ACTIONS_LINE_GRAPH_LINEAR} disabled={linearDisabled}>
Linear
</Select.Option>
<Select.Option value={ACTIONS_LINE_GRAPH_CUMULATIVE} disabled={cumulativeDisabled}>
Cumulative
</Select.Option>
</Select.OptGroup>
<Select.OptGroup label={'Bar Chart'}>
<Select.Option value={ACTIONS_BAR_CHART} disabled={barDisabled}>
Time
</Select.Option>
<Select.Option value={ACTIONS_BAR_CHART_VALUE} disabled={barValueDisabled}>
Value
</Select.Option>
</Select.OptGroup>
<Select.Option value={ACTIONS_TABLE} disabled={tableDisabled}>
Table
</Select.Option>
<Select.Option value={ACTIONS_PIE_CHART} disabled={pieDisabled}>
Pie
</Select.Option>
</>
)}
</Select>
options={options}
/>
)
}
93 changes: 50 additions & 43 deletions frontend/src/lib/components/IntervalFilter/IntervalFilter.tsx
Original file line number Diff line number Diff line change
@@ -4,54 +4,70 @@ import { intervalFilterLogic } from './intervalFilterLogic'
import { useValues, useActions } from 'kea'
import { ViewType } from 'scenes/insights/insightLogic'
import { disableHourFor, disableMinuteFor } from 'lib/utils'
import { CalendarOutlined, ClockCircleOutlined } from '@ant-design/icons'

const intervalMapping = {
minute: 'Minute',
hour: 'Hourly',
day: 'Daily',
week: 'Weekly',
month: 'Monthly',
const intervals = {
minute: {
label: 'Minute',
newDateFrom: 'dStart',
icon: <ClockCircleOutlined />,
},
hour: {
label: 'Hourly',
newDateFrom: 'dStart',
icon: <ClockCircleOutlined />,
},
day: {
label: 'Daily',
newDateFrom: undefined,
icon: <ClockCircleOutlined />,
},
week: {
label: 'Weekly',
newDateFrom: '-30d',
icon: <CalendarOutlined />,
},
month: {
label: 'Monthly',
newDateFrom: '-90d',
icon: <CalendarOutlined />,
},
}

const defaultInterval = intervals.day

type IntervalKeyType = keyof typeof intervals

interface InvertalFilterProps {
view: ViewType
disabled?: boolean
}

export function IntervalFilter({ view, disabled }: InvertalFilterProps): JSX.Element {
const interval: 'minute' | 'hour' | 'day' | 'week' | 'month' = useValues(intervalFilterLogic).interval
const interval: IntervalKeyType = useValues(intervalFilterLogic).interval
const { setIntervalFilter, setDateFrom } = useActions(intervalFilterLogic)
const options = Object.entries(intervals).map(([key, { label, icon }]) => ({
key,
value: key,
label: (
<>
{icon} {label}
</>
),
disabled: (key === 'minute' || key === 'hour') && view === ViewType.SESSIONS,
}))
return (
<Select
bordered={false}
disabled={disabled}
defaultValue={intervalMapping[interval] || intervalMapping['day']}
value={intervalMapping[interval]}
defaultValue={interval || 'day'}
value={interval}
dropdownMatchSelectWidth={false}
onChange={(key) => {
let newDateFrom

switch (key) {
case 'minute':
newDateFrom = 'dStart'
break
case 'hour':
newDateFrom = 'dStart'
break
case 'week':
newDateFrom = '-30d'
break
case 'month':
newDateFrom = '-90d'
break
default:
newDateFrom = undefined
break
}

const minute_disabled = key === 'minute' && newDateFrom && disableMinuteFor[newDateFrom]
const hour_disabled = key === 'hour' && newDateFrom && disableHourFor[newDateFrom]
if (minute_disabled || hour_disabled) {
const { newDateFrom } = intervals[key as IntervalKeyType] || defaultInterval
const minuteDisabled = key === 'minute' && newDateFrom && disableMinuteFor[newDateFrom]
const hourDisabled = key === 'hour' && newDateFrom && disableHourFor[newDateFrom]
if (minuteDisabled || hourDisabled) {
return false
}

@@ -62,16 +78,7 @@ export function IntervalFilter({ view, disabled }: InvertalFilterProps): JSX.Ele
setIntervalFilter(key)
}}
data-attr="interval-filter"
>
{Object.entries(intervalMapping).map(([key, value]) => (
<Select.Option
key={key}
value={key}
disabled={(key === 'minute' || key === 'hour') && view === ViewType.SESSIONS}
>
{value}
</Select.Option>
))}
</Select>
options={options}
/>
)
}
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ export function PropertyFilters({
onChange = null,
pageKey,
showConditionBadge = false,
disablePopover = false,
disablePopover = false, // use bare PropertyFilter without popover
popoverPlacement = null,
style = {},
}) {
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@ import { Button } from 'antd'
import { useActions } from 'kea'
import { Popover, Row } from 'antd'
import { CloseButton } from 'lib/components/CloseButton'
import { DeleteOutlined } from '@ant-design/icons'
import PropertyFilterButton from './PropertyFilterButton'
import 'scenes/actions/Actions.scss'

@@ -47,22 +46,19 @@ export const FilterRow = React.memo(function FilterRow({
data-attr={'property-filter-' + index}
style={{
maxWidth: '90vw',
margin: '0.25rem 0',
padding: '0.25rem 0',
}}
wrap={false}
>
{disablePopover ? (
<>
<PropertyFilter {...propertyFilterCommonProps} variant="unified" />
{!!Object.keys(filters[index]).length && (
<Button
type="link"
<CloseButton
onClick={() => remove(index)}
style={{
padding: 0,
paddingLeft: 5,
}}
>
<DeleteOutlined />
</Button>
style={{ cursor: 'pointer', float: 'none', paddingLeft: 8 }}
/>
)}
</>
) : (
@@ -87,9 +83,7 @@ export const FilterRow = React.memo(function FilterRow({
{!!Object.keys(filters[index]).length && (
<CloseButton
className="ml-1"
onClick={() => {
remove(index)
}}
onClick={() => remove(index)}
style={{ cursor: 'pointer', float: 'none', marginLeft: 5 }}
/>
)}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.property-filter-row {
min-width: 0;

.filter-where {
height: 32px; // matches antd Select height
flex-shrink: 0;
display: flex;
align-items: center;

.arrow {
color: #c4c4c4;
font-size: 18px;
padding-left: 6px;
padding-right: 8px;
position: relative;
top: -4px;
}
}

.filter-dropdown-container {
min-width: 6em;

.ant-btn {
width: 100%;
}
}
}
Loading

0 comments on commit c7b71c4

Please sign in to comment.