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

New Insights query UI, Option B #4233

Merged
merged 16 commits into from
May 7, 2021
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 6 additions & 83 deletions frontend/src/lib/components/PropertyFilters/PropertyFilters.js
Original file line number Diff line number Diff line change
@@ -1,94 +1,16 @@
import React, { useState } from 'react'
import { PropertyFilter } from './PropertyFilter'
import { Button } from 'antd'
import { useValues, useActions } from 'kea'
import React from 'react'
import { useValues } from 'kea'
import { propertyFilterLogic } from './propertyFilterLogic'
import { Popover, Row } from 'antd'
import { CloseButton } from 'lib/components/CloseButton'
import PropertyFilterButton from './PropertyFilterButton'
import '../../../scenes/actions/Actions.scss'

const FilterRow = React.memo(function FilterRow({
item,
index,
filters,
logic,
pageKey,
showConditionBadge,
totalCount,
popoverPlacement,
}) {
const { remove } = useActions(logic)
let [open, setOpen] = useState(false)
const { key } = item

let handleVisibleChange = (visible) => {
if (!visible && Object.keys(item).length >= 0 && !item[Object.keys(item)[0]]) {
remove(index)
}
setOpen(visible)
}

return (
<Row
align="middle"
className="mt-05 mb-05"
data-attr={'property-filter-' + index}
style={{
maxWidth: '90vw',
}}
>
<Popover
trigger="click"
onVisibleChange={handleVisibleChange}
destroyTooltipOnHide={true}
defaultVisible={false}
visible={open}
placement={popoverPlacement || 'bottomLeft'}
content={
<PropertyFilter
key={index}
index={index}
onComplete={() => setOpen(false)}
logic={logic}
selectProps={{
delayBeforeAutoOpen: 150,
}}
/>
}
>
{key ? (
<PropertyFilterButton onClick={() => setOpen(!open)} item={item} />
) : (
<Button type="default" shape="round" data-attr={'new-prop-filter-' + pageKey}>
Add filter
</Button>
)}
</Popover>
{!!Object.keys(filters[index]).length && (
<CloseButton
className="ml-1"
onClick={() => {
remove(index)
}}
style={{ cursor: 'pointer', float: 'none', marginLeft: 5 }}
/>
)}
{key && showConditionBadge && index + 1 < totalCount && (
<span style={{ marginLeft: 16, right: 16, position: 'absolute' }} className="stateful-badge and">
AND
</span>
)}
</Row>
)
})
import { FilterRow } from './components/FilterRow'
import 'scenes/actions/Actions.scss'

export function PropertyFilters({
endpoint = null,
propertyFilters = null,
onChange = null,
pageKey,
showConditionBadge = false,
disablePopover = false,
popoverPlacement = null,
style = {},
}) {
Expand All @@ -109,6 +31,7 @@ export function PropertyFilters({
filters={filters}
pageKey={pageKey}
showConditionBadge={showConditionBadge}
disablePopover={disablePopover}
popoverPlacement={popoverPlacement}
/>
)
Expand Down
105 changes: 105 additions & 0 deletions frontend/src/lib/components/PropertyFilters/components/FilterRow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import React, { useState } from 'react'
import { PropertyFilter } from './PropertyFilter'
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'

export const FilterRow = React.memo(function FilterRow({
item,
index,
filters,
logic,
pageKey,
showConditionBadge,
totalCount,
disablePopover = false, // use bare PropertyFilter without popover
popoverPlacement,
}) {
const { remove } = useActions(logic)
let [open, setOpen] = useState(false)
const { key } = item

let handleVisibleChange = (visible) => {
if (!visible && Object.keys(item).length >= 0 && !item[Object.keys(item)[0]]) {
remove(index)
}
setOpen(visible)
}

const propertyFilterCommonProps = {
key: index,
index,
onComplete: () => setOpen(false),
logic,
selectProps: {
delayBeforeAutoOpen: 150,
},
}

return (
<Row
align="middle"
className="mt-05 mb-05"
data-attr={'property-filter-' + index}
style={{
maxWidth: '90vw',
}}
>
{disablePopover ? (
<>
<PropertyFilter {...propertyFilterCommonProps} variant="unified" />
{!!Object.keys(filters[index]).length && (
<Button
type="link"
onClick={() => remove(index)}
style={{
padding: 0,
paddingLeft: 5,
}}
>
<DeleteOutlined />
</Button>
)}
</>
) : (
<>
<Popover
trigger="click"
onVisibleChange={handleVisibleChange}
destroyTooltipOnHide={true}
defaultVisible={false}
visible={open}
placement={popoverPlacement || 'bottomLeft'}
content={<PropertyFilter {...propertyFilterCommonProps} variant="tabs" />}
>
{key ? (
<PropertyFilterButton onClick={() => setOpen(!open)} item={item} />
) : (
<Button type="default" shape="round" data-attr={'new-prop-filter-' + pageKey}>
Add filter
</Button>
)}
</Popover>
{!!Object.keys(filters[index]).length && (
<CloseButton
className="ml-1"
onClick={() => {
remove(index)
}}
style={{ cursor: 'pointer', float: 'none', marginLeft: 5 }}
/>
)}
</>
)}
{key && showConditionBadge && index + 1 < totalCount && (
<span style={{ marginLeft: 16, right: 16, position: 'absolute' }} className="stateful-badge and">
AND
</span>
)}
</Row>
)
})
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import React, { useState } from 'react'
import { PropertyOperator } from '~/types'
import { Col, Select } from 'antd'
import { Col, Select, SelectProps } from 'antd'
import { isOperatorFlag, isOperatorMulti, operatorMap } from 'lib/utils'
import { PropertyValue } from 'lib/components/PropertyFilters/PropertyValue'
import { PropertyValue } from './PropertyValue'
import { ColProps } from 'antd/lib/col'

export type OperatorValueFilterType = string | number | Array<string | number> | null

interface OperatorValueSelectProps {
type: string
propkey: string
operator: PropertyOperator | undefined
value: string | number | Array<string | number> | null
columnOptions?: ColProps
onChange: (operator: PropertyOperator, value: string | number | Array<string | number> | null) => void
columnOptions?: ColProps | [ColProps, ColProps]
onChange: (operator: PropertyOperator, value: OperatorValueFilterType) => void
operatorSelectProps?: Omit<SelectProps<any>, 'onChange'>
}

interface OperatorSelectProps {
interface OperatorSelectProps extends SelectProps<any> {
operator: PropertyOperator
operators: Array<PropertyOperator>
onChange: (operator: PropertyOperator) => void
Expand All @@ -27,12 +30,13 @@ export function OperatorValueSelect({
value,
columnOptions,
onChange,
operatorSelectProps,
}: OperatorValueSelectProps): JSX.Element {
const [currentOperator, setCurrentOperator] = useState(operator)

return (
<>
<Col {...columnOptions}>
<Col {...(Array.isArray(columnOptions) ? columnOptions[0] : columnOptions)}>
<OperatorSelect
operator={currentOperator || 'exact'}
operators={Object.keys(operatorMap) as Array<PropertyOperator>}
Expand All @@ -52,10 +56,11 @@ export function OperatorValueSelect({
onChange(newOperator, value)
}
}}
{...operatorSelectProps}
/>
</Col>
{!isOperatorFlag(currentOperator || 'exact') && (
<Col {...columnOptions}>
<Col {...(Array.isArray(columnOptions) ? columnOptions[1] : columnOptions)}>
<PropertyValue
type={type}
key={propkey}
Expand All @@ -77,7 +82,7 @@ type CustomOptionsType = {
label: string
}

export function OperatorSelect({ operator, operators, onChange }: OperatorSelectProps): JSX.Element {
export function OperatorSelect({ operator, operators, onChange, ...props }: OperatorSelectProps): JSX.Element {
return (
<Select
style={{ width: '100%' }}
Expand All @@ -92,6 +97,7 @@ export function OperatorSelect({ operator, operators, onChange }: OperatorSelect
const newOperator = op as typeof op & CustomOptionsType
onChange(newOperator.value)
}}
{...props}
>
{operators.map((op) => (
<Select.Option key={op} value={op || 'exact'}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react'
import { SelectGradientOverflowProps } from 'lib/components/SelectGradientOverflow'
import { propertyFilterLogic } from '../propertyFilterLogic'
import { TabbedPropertyFilter } from './TabbedPropertyFilter'
import { UnifiedPropertyFilter } from './UnifiedPropertyFilter'

export interface PropertyFilterInternalProps {
index: number
onComplete: CallableFunction
logic: typeof propertyFilterLogic
selectProps: Partial<SelectGradientOverflowProps>
}

export interface PropertyFilterProps extends PropertyFilterInternalProps {
variant: 'tabs' | 'unified'
}

export function PropertyFilter({ variant = 'tabs', ...props }: PropertyFilterProps): JSX.Element {
switch (variant) {
case 'unified':
return <UnifiedPropertyFilter {...props} />
case 'tabs':
return <TabbedPropertyFilter {...props} />
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { formatPropertyLabel } from 'lib/utils'
import React from 'react'
import { cohortsModel } from '~/models'
import { PropertyFilter } from '~/types'
import { keyMapping } from '../PropertyKeyInfo'
import { keyMapping } from 'lib/components/PropertyKeyInfo'

export interface Props {
item: PropertyFilter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ interface Props {
placeholder: string
autoOpenIfEmpty?: boolean
delayBeforeAutoOpen?: number
dropdownMatchSelectWidth?: boolean | number
}

interface PropertyOptionGroup {
export interface PropertyOptionGroup {
type: 'event' | 'person' | 'element'
label: string
options: Array<{ value: string }>
Expand Down Expand Up @@ -55,6 +56,7 @@ export function PropertySelect({
placeholder,
autoOpenIfEmpty,
delayBeforeAutoOpen,
dropdownMatchSelectWidth = true,
}: Props): JSX.Element {
const [search, setSearch] = useState(false as string | false)
return (
Expand All @@ -78,6 +80,7 @@ export function PropertySelect({
onChange(type, val.replace(/^(event_|person_|element_)/gi, ''))
}}
style={{ width: '100%' }}
dropdownMatchSelectWidth={dropdownMatchSelectWidth}
>
{optionGroups.map(
(group) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react'
import { AutoComplete, Select } from 'antd'
import { useThrottledCallback } from 'use-debounce'
import api from '../../api'
import api from 'lib/api'
import { isMobile, isOperatorFlag, isOperatorMulti, isOperatorRegex, isValidRegex } from 'lib/utils'
import { SelectGradientOverflow } from 'lib/components/SelectGradientOverflow'

Expand Down
Loading