-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
329 additions
and
12 deletions.
There are no files selected for viewing
66 changes: 66 additions & 0 deletions
66
bitmovin-analytics-datasource/src/components/FilterInput.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import * as React from 'react'; | ||
import { QueryFilterOperator, SELECTABLE_QUERY_FILTER_OPERATORS, SelectableQueryFilter } from '../types/queryFilter'; | ||
import { QueryAttribute, SELECTABLE_QUERY_ATTRIBUTES } from '../types/queryAttributes'; | ||
import { QueryAdAttribute, SELECTABLE_QUERY_AD_ATTRIBUTES } from '../types/queryAdAttributes'; | ||
import { Field, HorizontalGroup, IconButton, Input, Select } from '@grafana/ui'; | ||
import { Space } from '@grafana/plugin-ui'; | ||
import { convertFilterValueToProperType } from '../utils/filterUtils'; | ||
import { useState } from 'react'; | ||
|
||
type Props = { | ||
readonly isAdAnalytics: boolean; | ||
readonly filter: SelectableQueryFilter; | ||
readonly onAttributeChange: (newValue: QueryAttribute | QueryAdAttribute) => void; | ||
readonly onOperatorChange: (newValue: QueryFilterOperator) => void; | ||
readonly onFilterValueChange: (newValue: boolean | number | string | Array<string>) => void; | ||
readonly onDelete: () => void; | ||
}; | ||
export const FilterInput = (props: Props) => { | ||
const [filterValueError, setFilterValueError] = useState(null); | ||
|
||
//TODOMY delay check here, only on enter? Small timeout or check button? | ||
const onFilterValueChange = (value: string, filter: SelectableQueryFilter) => { | ||
try { | ||
const convertedValue = convertFilterValueToProperType(value, filter, props.isAdAnalytics); | ||
setFilterValueError(null); | ||
props.onFilterValueChange(convertedValue); | ||
} catch (e) { | ||
setFilterValueError(e.message); | ||
} | ||
}; | ||
|
||
return ( | ||
<HorizontalGroup spacing="xs"> | ||
{ | ||
//TODOMY fix autospaching ui issue | ||
} | ||
|
||
<Field label="Dimension"> | ||
<Select | ||
value={props.filter.name} | ||
onChange={(value) => props.onAttributeChange(value.value as QueryAttribute | QueryAdAttribute)} | ||
options={props.isAdAnalytics ? SELECTABLE_QUERY_AD_ATTRIBUTES : SELECTABLE_QUERY_ATTRIBUTES} | ||
/> | ||
</Field> | ||
|
||
<Field label="Operator"> | ||
<Select | ||
value={props.filter.operator} | ||
onChange={(value) => props.onOperatorChange(value.value as QueryFilterOperator)} | ||
options={SELECTABLE_QUERY_FILTER_OPERATORS} | ||
/> | ||
</Field> | ||
<Field label="Value" invalid={filterValueError !== null} error={filterValueError}> | ||
<Input onChange={(value) => onFilterValueChange(value.currentTarget.value, props.filter)} /> | ||
</Field> | ||
<Space h={1} /> | ||
<IconButton | ||
name="trash-alt" | ||
size="xl" | ||
tooltip="Delete Order By" | ||
onClick={() => props.onDelete()} | ||
variant="destructive" | ||
/> | ||
</HorizontalGroup> | ||
); | ||
}; |
84 changes: 84 additions & 0 deletions
84
bitmovin-analytics-datasource/src/components/FilterRow.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import * as React from 'react'; | ||
import { useState } from 'react'; | ||
import { QueryAttribute } from '../types/queryAttributes'; | ||
import { QueryAdAttribute } from '../types/queryAdAttributes'; | ||
import { FieldSet, IconButton } from '@grafana/ui'; | ||
import { QueryFilter, QueryFilterOperator, SelectableQueryFilter } from '../types/queryFilter'; | ||
import { FilterInput } from './FilterInput'; | ||
|
||
type Props = { | ||
readonly isAdAnalytics: boolean; | ||
readonly onChange: (newFilters: QueryFilter[]) => void; | ||
}; | ||
export const FilterRow = (props: Props) => { | ||
const [filters, setFilters] = useState<SelectableQueryFilter[]>([]); | ||
|
||
const deleteFilter = (index: number) => { | ||
const newFilter = [...filters]; | ||
newFilter.splice(index, 1); | ||
|
||
setFilters(newFilter); | ||
props.onChange(newFilter as QueryFilter[]); | ||
}; | ||
|
||
const onAttributesChange = (index: number, newAttribute: QueryAttribute | QueryAdAttribute) => { | ||
const newFilters = [...filters]; | ||
const newValue = { | ||
name: newAttribute, | ||
operator: newFilters[index].operator, | ||
value: newFilters[index].value, | ||
} as QueryFilter; | ||
newFilters.splice(index, 1, newValue); | ||
setFilters(newFilters); | ||
props.onChange(newFilters as QueryFilter[]); | ||
}; | ||
|
||
const onOperatorChange = (index: number, newOperator: QueryFilterOperator) => { | ||
const newFilters = [...filters]; | ||
const newValue = { | ||
name: newFilters[index].name, | ||
operator: newOperator, | ||
value: newFilters[index].value, | ||
} as QueryFilter; | ||
newFilters.splice(index, 1, newValue); | ||
setFilters(newFilters); | ||
props.onChange(newFilters as QueryFilter[]); | ||
}; | ||
|
||
const onFilterValueChange = (index: number, newFilterValue: string | number) => { | ||
const newFilters = [...filters]; | ||
const newValue = { | ||
name: newFilters[index].name, | ||
operator: newFilters[index].operator, | ||
value: newFilterValue, | ||
} as QueryFilter; | ||
newFilters.splice(index, 1, newValue); | ||
setFilters(newFilters); | ||
props.onChange(newFilters as QueryFilter[]); | ||
}; | ||
|
||
const addFilterInput = () => { | ||
//TODOMY what to use as the default value | ||
setFilters((prevState) => [...prevState, { name: '', operator: '', value: '' }]); | ||
}; | ||
|
||
return ( | ||
<FieldSet> | ||
{filters.map((item, index) => ( | ||
<FilterInput | ||
isAdAnalytics={props.isAdAnalytics} | ||
filter={filters[index]} | ||
onAttributeChange={(newValue: QueryAttribute | QueryAdAttribute) => onAttributesChange(index, newValue)} | ||
onOperatorChange={(newValue: QueryFilterOperator) => onOperatorChange(index, newValue)} | ||
onFilterValueChange={(newValue: string | number) => onFilterValueChange(index, newValue)} | ||
onDelete={() => deleteFilter(index)} | ||
/> | ||
))} | ||
|
||
{ | ||
//TODOMY fix position of the IconButton | ||
} | ||
<IconButton name="plus-square" tooltip="Add Order By" size="xl" onClick={() => addFilterInput()} /> | ||
</FieldSet> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { QueryAdAttribute } from './queryAdAttributes'; | ||
import { SelectableValue } from '@grafana/data'; | ||
import { QueryAttribute } from './queryAttributes'; | ||
|
||
enum QUERY_FILTER_OPERATORS { | ||
GT = 'GT', | ||
GTE = 'GTE', | ||
LT = 'LT', | ||
LTE = 'LTE', | ||
EQ = 'EQ', | ||
NE = 'NE', | ||
CONTAINS = 'CONTAINS', | ||
NOTCONTAINS = 'NOTCONTAINS', | ||
IN = 'IN', | ||
} | ||
|
||
export type QueryFilterOperator = keyof typeof QUERY_FILTER_OPERATORS; | ||
|
||
export const SELECTABLE_QUERY_FILTER_OPERATORS: SelectableValue<QueryFilterOperator>[] = [ | ||
{ value: QUERY_FILTER_OPERATORS.GT, label: QUERY_FILTER_OPERATORS.GT }, | ||
{ value: QUERY_FILTER_OPERATORS.GTE, label: QUERY_FILTER_OPERATORS.GTE }, | ||
{ value: QUERY_FILTER_OPERATORS.LT, label: QUERY_FILTER_OPERATORS.LT }, | ||
{ value: QUERY_FILTER_OPERATORS.LTE, label: QUERY_FILTER_OPERATORS.LTE }, | ||
{ value: QUERY_FILTER_OPERATORS.EQ, label: QUERY_FILTER_OPERATORS.EQ }, | ||
{ value: QUERY_FILTER_OPERATORS.NE, label: QUERY_FILTER_OPERATORS.NE }, | ||
{ value: QUERY_FILTER_OPERATORS.CONTAINS, label: QUERY_FILTER_OPERATORS.CONTAINS }, | ||
{ value: QUERY_FILTER_OPERATORS.NOTCONTAINS, label: QUERY_FILTER_OPERATORS.NOTCONTAINS }, | ||
{ value: QUERY_FILTER_OPERATORS.IN, label: QUERY_FILTER_OPERATORS.IN }, | ||
]; | ||
|
||
export type QueryFilter = { | ||
name: QueryAdAttribute | QueryAttribute; | ||
operator: QueryFilterOperator; | ||
value: boolean | number | string | Array<string>; | ||
}; | ||
|
||
export type SelectableQueryFilter = { | ||
name: QueryAdAttribute | QueryAttribute | ''; | ||
operator: QueryFilterOperator | ''; | ||
value: boolean | number | string | Array<string>; | ||
}; | ||
|
||
//TODOMY add specific filter attributes |
Oops, something went wrong.