feat(ui) - custom metrics

This commit is contained in:
Shekar Siri 2022-01-26 17:05:19 +05:30
parent 2008d3dc2f
commit d41299b6fe
14 changed files with 43 additions and 62 deletions

View file

@ -40,7 +40,7 @@ function FilterSeries(props: Props) {
});
props.updateSeries(seriesIndex, {
...series.toData(),
...series,
filter: {
...series.filter,
filters: newFilters,

View file

@ -4,8 +4,9 @@
border-radius: 3px;
display: flex;
align-items: center;
background-color: white;
& input {
height: 28px;
height: 24px;
font-size: 13px !important;
padding: 0 5px !important;
border-top-left-radius: 3px;
@ -14,7 +15,7 @@
}
& .right {
height: 28px;
height: 24px;
display: flex;
align-items: stretch;
padding: 0;

View file

@ -1,5 +1,5 @@
import React from 'react';
import FilterOperator from '../FilterOperator/FilterOperator';
import FilterOperator from '../FilterOperator';
import FilterSelection from '../FilterSelection';
import FilterValue from '../FilterValue';
import { Icon } from 'UI';
@ -12,51 +12,30 @@ interface Props {
isFilter?: boolean;
}
function FitlerItem(props: Props) {
const { isFilter = false, filterIndex, filter, onUpdate } = props;
const { isFilter = false, filterIndex, filter } = props;
const replaceFilter = (filter) => {
onUpdate(filter);
props.onUpdate({ ...filter, value: [""]});
};
// const onAddValue = () => {
// const newValues = filter.value.concat("")
// onUpdate({ ...filter, value: newValues })
// }
// const onRemoveValue = (valueIndex) => {
// const newValues = filter.value.filter((_, _index) => _index !== valueIndex)
// onUpdate({ ...filter, value: newValues })
// }
// const onSelect = (e, item, valueIndex) => {
// const newValues = filter.value.map((_, _index) => {
// if (_index === valueIndex) {
// return item.value;
// }
// return _;
// })
// onUpdate({ ...filter, value: newValues })
// }
const onOperatorChange = (e, { name, value }) => {
console.log('onOperatorChange', name, value)
onUpdate({ ...filter, operator: value })
props.onUpdate({ ...filter, operator: value })
}
return (
<div className="flex items-center mb-4">
<div className="flex items-start mr-auto">
{ !isFilter && <div className="mt-1 w-6 h-6 text-xs flex justify-center rounded-full bg-gray-light-shade mr-2">{filterIndex+1}</div> }
<div className="flex items-center hover:bg-active-blue -mx-5 px-5 py-2">
<div className="flex items-start w-full">
{ !isFilter && <div className="mt-1 flex-shrink-0 border w-6 h-6 text-xs flex justify-center rounded-full bg-gray-light-shade mr-2">{filterIndex+1}</div> }
<FilterSelection filter={filter} onFilterClick={replaceFilter} />
<FilterOperator filter={filter} onChange={onOperatorChange} className="mx-2 flex-shrink-0"/>
<FilterValue filter={filter} onUpdate={onUpdate} />
<FilterValue filter={filter} onUpdate={props.onUpdate} />
</div>
<div className="flex self-start mt-2">
<div className="flex self-start mt-2 ml-auto">
<div
className="cursor-pointer p-1"
onClick={props.onRemoveFilter}
>
<Icon name="trash" size="16" />
<Icon name="trash" size="14" />
</div>
</div>
</div>

View file

@ -62,7 +62,7 @@ function FilterList(props: Props) {
{hasFilters && (
<>
<div className='border-t -mx-5 mb-2' />
{hasEvents && <div className='border-t -mx-5 mb-2' />}
<div className="mb-2 text-sm color-gray-medium mr-auto">FILTERS</div>
{filters.map((filter, filterIndex) => !filter.isEvent ? (
<FilterItem

View file

@ -1,6 +1,6 @@
.operatorDropdown {
font-weight: 400;
height: 30px;
height: 26px;
min-width: 60px;
display: flex !important;
align-items: center;
@ -9,7 +9,7 @@
font-size: 13px;
/* background-color: rgba(255, 255, 255, 0.8) !important; */
background-color: $gray-lightest !important;
border: solid thin rgba(34, 36, 38, 0.15) !important;
border: solid thin #e9e9e9 !important;
border-radius: 4px !important;
color: $gray-darkest !important;
font-size: 14px !important;

View file

@ -15,7 +15,7 @@ function FilterOperator(props: Props) {
return (
<Dropdown
className={ cn(stl.operatorDropdown, className) }
className={ cn(stl.operatorDropdown, className, 'hover:bg-gray-light-shade') }
options={ filter.operatorOptions }
name="operator"
value={ filter.operator }

View file

@ -22,8 +22,8 @@ function FilterSelection(props: Props) {
>
{ children ? React.cloneElement(children, { onClick: () => setShowModal(true)}) : (
<div
className="rounded py-1 px-3 flex items-center cursor-pointer bg-gray-lightest text-ellipsis"
style={{ width: '140px', height: '30px', border: 'solid thin rgba(34, 36, 38, 0.15)'}}
className="rounded py-1 px-3 flex items-center cursor-pointer bg-gray-lightest text-ellipsis hover:bg-gray-light-shade"
style={{ width: '140px', height: '26px', border: 'solid thin #e9e9e9' }}
onClick={() => setShowModal(true)}
>
<span className="mr-auto truncate">{filter.label}</span>

View file

@ -52,6 +52,8 @@ function FilterValue(props: Props) {
}
const renderValueFiled = (value, valueIndex) => {
const showCloseButton = filter.value.length > 1;
const showOrButton = valueIndex === filter.value.length - 1;
switch(filter.type) {
case FilterType.DROPDOWN:
return (
@ -71,6 +73,10 @@ function FilterValue(props: Props) {
filter={filter}
options={filter.options}
onChange={(e, { name, value }) => onSelect(e, { value }, valueIndex)}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
/>
)
case FilterType.DURATION:
@ -97,8 +103,8 @@ function FilterValue(props: Props) {
return (
<FilterAutoComplete
value={value}
showCloseButton={filter.value.length > 1}
showOrButton={valueIndex === filter.value.length - 1}
showCloseButton={showCloseButton}
showOrButton={showOrButton}
onAddValue={onAddValue}
onRemoveValue={() => onRemoveValue(valueIndex)}
method={'GET'}
@ -113,7 +119,7 @@ function FilterValue(props: Props) {
}
return (
<div className="grid grid-cols-3 gap-3">
<div className="grid grid-cols-3 gap-3 w-full">
{ filter.type === FilterType.DURATION ? (
renderValueFiled(filter.value, 0)
) : (

View file

@ -1,7 +1,7 @@
.wrapper {
border: solid thin $gray-light !important;
border-radius: 3px;
background-color: $gray-lightest !important;
background-color: white !important;
display: flex;
align-items: center;
height: 30px;
@ -14,6 +14,7 @@
background-color: $gray-lightest;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
margin-left: auto;
& div {
/* background-color: red; */

View file

@ -31,6 +31,7 @@ function FilterValueDropdown(props: Props) {
value={ value }
onChange={ onChange }
placeholder="Select"
fluid
icon={ <Icon className="ml-5" name="chevron-down" size="12" /> }
/>
<div

View file

@ -27,7 +27,7 @@ function SaveSearchModal(props: Props) {
closeHandler();
});
}
console.log('filter', filter);
return (
<Modal size="tiny" open={ show }>
<Modal.Header className={ stl.modalHeader }>

View file

@ -32,7 +32,7 @@ function SessionSearch(props) {
});
props.edit({
...appliedFilter.filter,
...appliedFilter,
filters: newFilters,
});
}

View file

@ -1,15 +1,10 @@
import { List, Map } from 'immutable';
import { clean as cleanParams } from 'App/api_client';
import ErrorInfo, { RESOLVED, UNRESOLVED, IGNORED } from 'Types/errorInfo';
// import { clean as cleanParams } from 'App/api_client';
import CustomMetric, { FilterSeries } from 'Types/customMetric'
import { createFetch, fetchListType, fetchType, saveType, removeType, editType, createRemove, createEdit } from './funcTools/crud';
// import { createEdit, createInit } from './funcTools/crud';
import { createRequestReducer, ROOT_KEY } from './funcTools/request';
import { array, request, success, failure, createListUpdater, mergeReducers } from './funcTools/tools';
import Filter from 'Types/filter';
import NewFilter from 'Types/filter/newFilter';
import Event from 'Types/filter/event';
// import CustomFilter from 'Types/filter/customFilter';
const name = "custom_metric";
const idKey = "metricId";
@ -50,18 +45,15 @@ const initialState = Map({
function reducer(state = initialState, action = {}) {
switch (action.type) {
case EDIT:
console.log('EDIT', action);
return state.mergeIn([ 'instance' ], CustomMetric(action.instance));
case UPDATE_SERIES:
console.log('update series', action.series);
return state.setIn(['instance', 'series', action.index], FilterSeries(action.series));
return state.mergeIn([ 'instance' ], action.instance);
case UPDATE_SERIES:
return state.mergeIn(['instance', 'series', action.index], action.series);
case success(SAVE):
return state.set([ 'instance' ], CustomMetric(action.data));
return state.mergeIn([ 'instance' ], action.data);
case success(REMOVE):
console.log('action', action)
return state.update('list', list => list.filter(item => item.metricId !== action.id));
case success(FETCH):
return state.set("instance", ErrorInfo(action.data));
return state.set("instance", CustomMetric(action.data));
case success(FETCH_LIST):
const { data } = action;
return state.set("list", List(data.map(CustomMetric)));

View file

@ -12,7 +12,7 @@ import { fetchList as fetchErrorsList } from './errors';
const ERRORS_ROUTE = errorsRoute();
const name = "custom_metric";
const name = "search";
const idKey = "metricId";
const FETCH_LIST = fetchListType(name);
@ -84,6 +84,7 @@ const filterMap = ({value, type, key, operator, source, custom, isEvent }) => ({
});
const reduceThenFetchResource = actionCreator => (...args) => (dispatch, getState) => {
console.log('reduceThenFetchResource', args);
dispatch(actionCreator(...args));
const filter = getState().getIn([ 'search', 'instance']).toData();
filter.filters = filter.filters.map(filterMap);
@ -135,7 +136,7 @@ export function save(instance) {
export function fetchList() {
return {
types: array(FETCH_LIST),
call: client => client.get(`/${name}s`),
call: client => client.get(`/saved_search`),
};
}