feat(ui) - customm metrics ui review and changes
This commit is contained in:
parent
2fa444a26c
commit
3a08033f16
18 changed files with 150 additions and 71 deletions
|
|
@ -47,7 +47,7 @@ const Section = ({ index, title, description, content }) => (
|
|||
const integrationsRoute = client(CLIENT_TABS.INTEGRATIONS);
|
||||
|
||||
const AlertForm = props => {
|
||||
const { instance, slackChannels, webhooks, loading, onDelete, deleting, triggerOptions } = props;
|
||||
const { instance, slackChannels, webhooks, loading, onDelete, deleting, triggerOptions, metricId } = props;
|
||||
const write = ({ target: { value, name } }) => props.edit({ [ name ]: value })
|
||||
const writeOption = (e, { name, value }) => props.edit({ [ name ]: value });
|
||||
const onChangeOption = (e, { checked, name }) => props.edit({ [ name ]: checked })
|
||||
|
|
@ -70,8 +70,7 @@ const AlertForm = props => {
|
|||
const unit = metric ? metric.unit : '';
|
||||
const isThreshold = instance.detectionMethod === 'threshold';
|
||||
|
||||
console.log('triggerOptions', triggerOptions)
|
||||
|
||||
console.log('AlertForm', instance.query);
|
||||
|
||||
return (
|
||||
<Form className={ cn("p-6", stl.wrapper)} style={{ width: '580px' }} onSubmit={() => props.onSubmit(instance)} id="alert-form">
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ function AlertFormModal(props) {
|
|||
size="medium"
|
||||
content={ showModal &&
|
||||
<AlertForm
|
||||
metricId={ props.metricId }
|
||||
metricId={ metricId }
|
||||
edit={props.edit}
|
||||
slackChannels={slackChannels}
|
||||
webhooks={hooks}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import cn from 'classnames';
|
|||
import withPageTitle from 'HOCs/withPageTitle';
|
||||
import withPermissions from 'HOCs/withPermissions'
|
||||
import { setPeriod, setPlatform, fetchMetadataOptions } from 'Duck/dashboard';
|
||||
import { NoContent } from 'UI';
|
||||
import { NoContent, Icon } from 'UI';
|
||||
import { WIDGET_KEYS } from 'Types/dashboard';
|
||||
import CustomMetrics from 'Shared/CustomMetrics';
|
||||
import SessionListModal from 'Shared/CustomMetrics/SessionListModal';
|
||||
|
|
@ -58,6 +58,13 @@ const menuList = [
|
|||
icon: "info-square",
|
||||
label: getStatusLabel(OVERVIEW),
|
||||
active: status === OVERVIEW,
|
||||
},
|
||||
{
|
||||
key: OVERVIEW,
|
||||
section: 'metrics',
|
||||
icon: "sliders",
|
||||
label: getStatusLabel(CUSTOM_METRICS),
|
||||
active: status === CUSTOM_METRICS,
|
||||
},
|
||||
{
|
||||
key: ERRORS_N_CRASHES,
|
||||
|
|
@ -87,6 +94,8 @@ function getStatusLabel(status) {
|
|||
switch(status) {
|
||||
case OVERVIEW:
|
||||
return "Overview";
|
||||
case CUSTOM_METRICS:
|
||||
return "Custom Metrics";
|
||||
case PERFORMANCE:
|
||||
return "Performance";
|
||||
case ERRORS_N_CRASHES:
|
||||
|
|
@ -189,7 +198,7 @@ export default class Dashboard extends React.PureComponent {
|
|||
<div>
|
||||
<div className={ cn(styles.header, "flex items-center w-full") }>
|
||||
<MetricsFilters />
|
||||
<CustomMetrics />
|
||||
|
||||
{ activeWidget && <SessionListModal activeWidget={activeWidget} /> }
|
||||
</div>
|
||||
<div className="">
|
||||
|
|
@ -206,8 +215,21 @@ export default class Dashboard extends React.PureComponent {
|
|||
</div>
|
||||
</WidgetSection>
|
||||
|
||||
<WidgetSection title="Custom Metrics" type="customMetrics" className="mb-4">
|
||||
<div className={ cn("gap-4", { 'grid grid-cols-2' : !comparing })} ref={this.list[CUSTOM_METRICS]}>
|
||||
<WidgetSection
|
||||
title="Custom Metrics"
|
||||
type="customMetrics"
|
||||
className="mb-4"
|
||||
description={
|
||||
<div className="flex items-center">
|
||||
<div className="mr-4 text-sm flex items-center font-normal">
|
||||
<Icon name="info" size="12" className="mr-2" />
|
||||
Custom Metrics are not supported for comparison.
|
||||
</div>
|
||||
<CustomMetrics />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className={cn("gap-4 grid grid-cols-2")} ref={this.list[CUSTOM_METRICS]}>
|
||||
<CustomMetricsWidgets onClickEdit={(e) => null}/>
|
||||
</div>
|
||||
</WidgetSection>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Loader, NoContent, Icon } from 'UI';
|
||||
import { Loader, NoContent, Icon, Popup } from 'UI';
|
||||
import { Styles } from '../../common';
|
||||
import { ResponsiveContainer, AreaChart, XAxis, YAxis, CartesianGrid, Area, Tooltip } from 'recharts';
|
||||
import { LineChart, Line, Legend } from 'recharts';
|
||||
|
|
@ -89,25 +89,14 @@ function CustomMetricWidget(props: Props) {
|
|||
props.setActiveWidget({ widget: metric, startTimestamp, endTimestamp, timestamp: event.activePayload[0].payload.timestamp, index })
|
||||
}
|
||||
|
||||
// const onAlertClick = () => {
|
||||
// props.setShowAlerts(true)
|
||||
// props.setAlertMetricId(metric.metricId)
|
||||
// }
|
||||
|
||||
return (
|
||||
<div className={stl.wrapper}>
|
||||
<div className="flex items-center mb-10 p-2">
|
||||
<div className="font-medium">{metric.name + ' ' + metric.metricId}</div>
|
||||
<div className="ml-auto flex items-center">
|
||||
<div className="cursor-pointer mr-6" onClick={deleteHandler}>
|
||||
<Icon name="trash" size="14" />
|
||||
</div>
|
||||
<div className="cursor-pointer mr-6" onClick={() => props.edit(metric)}>
|
||||
<Icon name="pencil" size="14" />
|
||||
</div>
|
||||
<div className="cursor-pointer" onClick={props.onAlertClick}>
|
||||
<Icon name="bell-plus" size="14" />
|
||||
</div>
|
||||
<WidgetIcon className="cursor-pointer mr-6" icon="bell-plus" tooltip="Set Alert" onClick={props.onAlertClick} />
|
||||
<WidgetIcon className="cursor-pointer mr-6" icon="pencil" tooltip="Edit Metric" onClick={() => props.edit(metric)} />
|
||||
<WidgetIcon className="cursor-pointer" icon="close" tooltip="Hide Metric" onClick={deleteHandler} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -170,4 +159,19 @@ function CustomMetricWidget(props: Props) {
|
|||
|
||||
export default connect(state => ({
|
||||
period: state.getIn(['dashboard', 'period']),
|
||||
}), { remove, setShowAlerts, setAlertMetricId, edit, setActiveWidget })(CustomMetricWidget);
|
||||
}), { remove, setShowAlerts, setAlertMetricId, edit, setActiveWidget })(CustomMetricWidget);
|
||||
|
||||
|
||||
const WidgetIcon = ({ className = '', tooltip = '', icon, onClick }) => (
|
||||
<Popup
|
||||
size="small"
|
||||
trigger={
|
||||
<div className={className} onClick={onClick}>
|
||||
<Icon name={icon} size="14" />
|
||||
</div>
|
||||
}
|
||||
content={tooltip}
|
||||
position="top center"
|
||||
inverted
|
||||
/>
|
||||
)
|
||||
|
|
@ -125,7 +125,7 @@ function CustomMetricWidget(props: Props) {
|
|||
allowDecimals={false}
|
||||
label={{
|
||||
...Styles.axisLabelLeft,
|
||||
value: "Number of Errors"
|
||||
value: "Number of Sessions"
|
||||
}}
|
||||
/>
|
||||
<Legend />
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@ import { connect } from 'react-redux';
|
|||
import { fetchList } from 'Duck/customMetrics';
|
||||
import CustomMetricWidget from './CustomMetricWidget';
|
||||
import AlertFormModal from 'App/components/Alerts/AlertFormModal';
|
||||
import { init as initAlert } from 'Duck/alerts';
|
||||
|
||||
interface Props {
|
||||
fetchList: Function;
|
||||
list: any;
|
||||
onClickEdit: (e) => void;
|
||||
initAlert: Function;
|
||||
}
|
||||
function CustomMetricsWidgets(props: Props) {
|
||||
const { list } = props;
|
||||
|
|
@ -25,7 +27,10 @@ function CustomMetricsWidgets(props: Props) {
|
|||
<CustomMetricWidget
|
||||
metric={item}
|
||||
onClickEdit={props.onClickEdit}
|
||||
onAlertClick={(e) => setActiveMetricId(item.metricId)}
|
||||
onAlertClick={(e) => {
|
||||
setActiveMetricId(item.metricId)
|
||||
props.initAlert({ left: item.series.first().seriesId })
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
|
|
@ -40,4 +45,4 @@ function CustomMetricsWidgets(props: Props) {
|
|||
|
||||
export default connect(state => ({
|
||||
list: state.getIn(['customMetrics', 'list']),
|
||||
}), { fetchList })(CustomMetricsWidgets);
|
||||
}), { fetchList, initAlert })(CustomMetricsWidgets);
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { connect } from 'react-redux';
|
||||
import cn from 'classnames';
|
||||
import withToggle from 'HOCs/withToggle';
|
||||
import { IconButton, SlideModal, NoContent } from 'UI';
|
||||
import { IconButton, SlideModal, NoContent, Popup } from 'UI';
|
||||
import { updateAppearance } from 'Duck/user';
|
||||
import { WIDGET_LIST } from 'Types/dashboard';
|
||||
import stl from './addWidgets.css';
|
||||
|
|
@ -76,13 +76,21 @@ export default class AddWidgets extends React.PureComponent {
|
|||
}
|
||||
onClose={ this.props.switchOpen }
|
||||
/>
|
||||
<IconButton
|
||||
circle
|
||||
size="small"
|
||||
icon="plus"
|
||||
outline
|
||||
onClick={ this.props.switchOpen }
|
||||
disabled={ disabled || avaliableWidgets.length === 0 } //TODO disabled after Custom fields filtering
|
||||
<Popup
|
||||
trigger={
|
||||
<IconButton
|
||||
circle
|
||||
size="small"
|
||||
icon="plus"
|
||||
outline
|
||||
onClick={ this.props.switchOpen }
|
||||
disabled={ disabled || avaliableWidgets.length === 0 } //TODO disabled after Custom fields filtering
|
||||
/>
|
||||
}
|
||||
content={ `Add a metric to this section.` }
|
||||
size="tiny"
|
||||
inverted
|
||||
position="top center"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@ import React from 'react';
|
|||
import { Form, SegmentSelection, Button, IconButton } from 'UI';
|
||||
import FilterSeries from '../FilterSeries';
|
||||
import { connect } from 'react-redux';
|
||||
import { edit as editMetric, save, addSeries } from 'Duck/customMetrics';
|
||||
import { edit as editMetric, save, addSeries, remove } from 'Duck/customMetrics';
|
||||
import CustomMetricWidgetPreview from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricWidgetPreview';
|
||||
import { confirm } from 'UI/Confirmation';
|
||||
import { toast } from 'react-toastify';
|
||||
import cn from 'classnames';
|
||||
|
||||
interface Props {
|
||||
metric: any;
|
||||
|
|
@ -12,6 +15,7 @@ interface Props {
|
|||
loading: boolean;
|
||||
addSeries: (series?) => void;
|
||||
onClose: () => void;
|
||||
remove: (id) => Promise<void>;
|
||||
}
|
||||
|
||||
function CustomMetricForm(props: Props) {
|
||||
|
|
@ -52,7 +56,23 @@ function CustomMetricForm(props: Props) {
|
|||
};
|
||||
|
||||
const save = () => {
|
||||
props.save(metric).then(props.onClose);
|
||||
props.save(metric).then(() => {
|
||||
toast.success(metric.exists() ? 'Updated succesfully.' : 'Created succesfully.');
|
||||
props.onClose()
|
||||
});
|
||||
}
|
||||
|
||||
const deleteHandler = async () => {
|
||||
if (await confirm({
|
||||
header: 'Custom Metric',
|
||||
confirmButton: 'Delete',
|
||||
confirmation: `Are you sure you want to delete ${metric.name}`
|
||||
})) {
|
||||
props.remove(metric.metricId).then(() => {
|
||||
toast.success('Deleted succesfully.');
|
||||
props.onClose();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
@ -78,7 +98,7 @@ function CustomMetricForm(props: Props) {
|
|||
<div className="form-group">
|
||||
<label className="font-medium">Metric Type</label>
|
||||
<div className="flex items-center">
|
||||
<span className="bg-white p-1 px-2 border rounded">Timeseries</span>
|
||||
<span className="bg-white p-1 px-2 border rounded" style={{ height: '30px'}}>Timeseries</span>
|
||||
<span className="mx-2 color-gray-medium">of</span>
|
||||
<div>
|
||||
<SegmentSelection
|
||||
|
|
@ -89,7 +109,7 @@ function CustomMetricForm(props: Props) {
|
|||
onSelect={ changeConditionTab }
|
||||
value={{ value: metric.type }}
|
||||
list={ [
|
||||
{ name: 'Session Count', value: 'session_count' },
|
||||
{ name: 'Series 1', value: 'session_count' },
|
||||
{ name: 'Session Percentage', value: 'session_percentage' },
|
||||
]}
|
||||
/>
|
||||
|
|
@ -98,7 +118,7 @@ function CustomMetricForm(props: Props) {
|
|||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="font-medium">Series</label>
|
||||
<label className="font-medium">Chart Series</label>
|
||||
{metric.series && metric.series.size > 0 && metric.series.map((series: any, index: number) => (
|
||||
<div className="mb-2">
|
||||
<FilterSeries
|
||||
|
|
@ -111,19 +131,26 @@ function CustomMetricForm(props: Props) {
|
|||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<IconButton type="button" onClick={addSeries} primaryText label="SERIES" icon="plus" />
|
||||
<div className={cn("flex justify-end -my-4", {'disabled' : metric.series.size > 2})}>
|
||||
<IconButton hover type="button" onClick={addSeries} primaryText label="SERIES" icon="plus" />
|
||||
</div>
|
||||
|
||||
<div className="my-4" />
|
||||
<div className="my-8" />
|
||||
|
||||
<CustomMetricWidgetPreview metric={metric} />
|
||||
</div>
|
||||
|
||||
<div className="fixed border-t w-full bottom-0 px-5 py-2 bg-white">
|
||||
<Button loading={loading} primary disabled={!metric.validate()}>
|
||||
{ `${metric.exists() ? 'Update' : 'Create'}` }
|
||||
</Button>
|
||||
<div className="flex items-center fixed border-t w-full bottom-0 px-5 py-2 bg-white">
|
||||
<div className="mr-auto">
|
||||
<Button loading={loading} primary disabled={!metric.validate()}>
|
||||
{ `${metric.exists() ? 'Update' : 'Create'}` }
|
||||
</Button>
|
||||
|
||||
<Button type="button" className="ml-3" outline hover plain onClick={props.onClose}>Cancel</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button type="button" className="ml-3" outline hover plain onClick={deleteHandler}>Delete</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
|
|
@ -132,4 +159,4 @@ function CustomMetricForm(props: Props) {
|
|||
export default connect(state => ({
|
||||
metric: state.getIn(['customMetrics', 'instance']),
|
||||
loading: state.getIn(['customMetrics', 'saveRequest', 'loading']),
|
||||
}), { editMetric, save, addSeries })(CustomMetricForm);
|
||||
}), { editMetric, save, addSeries, remove })(CustomMetricForm);
|
||||
|
|
@ -15,12 +15,12 @@ function CustomMetrics(props: Props) {
|
|||
|
||||
return (
|
||||
<div className="self-start">
|
||||
<IconButton outline icon="plus" label="CREATE METRIC" onClick={() => props.init()} />
|
||||
<IconButton plain outline icon="plus" label="CREATE METRIC" onClick={() => props.init()} />
|
||||
|
||||
<SlideModal
|
||||
title={
|
||||
<div className="flex items-center">
|
||||
<span className="mr-3">{ 'Custom Metric' }</span>
|
||||
<span className="mr-3">{ metric && metric.exists() ? 'Update Custom Metric' : 'Create Custom Metric' }</span>
|
||||
</div>
|
||||
}
|
||||
isDisplayed={ !!metric }
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ function FilterSeries(props: Props) {
|
|||
onChangeEventsOrder={onChangeEventsOrder}
|
||||
/>
|
||||
): (
|
||||
<div className="color-gray-medium">Add user event or filter to build the series.</div>
|
||||
<div className="color-gray-medium">Add user event or filter to define the series by clicking Add Step.</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="px-5 border-t h-12 flex items-center">
|
||||
|
|
|
|||
|
|
@ -28,16 +28,22 @@ function SeriesName(props: Props) {
|
|||
|
||||
// const { name } = props;
|
||||
return (
|
||||
<div className="font-medium flex items-center">
|
||||
<input
|
||||
ref={ ref }
|
||||
name="name"
|
||||
className="fluid border-0 -mx-2 px-2"
|
||||
value={name} readOnly={!editing}
|
||||
onChange={write}
|
||||
onBlur={onBlur}
|
||||
onFocus={() => setEditing(true)}
|
||||
/>
|
||||
<div className="flex items-center">
|
||||
{ editing ? (
|
||||
<input
|
||||
ref={ ref }
|
||||
name="name"
|
||||
className="fluid border-0 -mx-2 px-2"
|
||||
value={name}
|
||||
// readOnly={!editing}
|
||||
onChange={write}
|
||||
onBlur={onBlur}
|
||||
onFocus={() => setEditing(true)}
|
||||
/>
|
||||
) : (
|
||||
<div className="text-base">{name}</div>
|
||||
)}
|
||||
|
||||
<div className="ml-3 cursor-pointer" onClick={() => setEditing(true)}><Icon name="pencil" size="14" /></div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ function SessionListModal(props: Props) {
|
|||
<SlideModal
|
||||
title={ activeWidget && (
|
||||
<div className="flex items-center">
|
||||
<div className="mr-auto">{ 'Custom Metric: ' + activeWidget.widget.name } </div>
|
||||
<div className="mr-auto">{ activeWidget.widget.name } </div>
|
||||
</div>
|
||||
)}
|
||||
isDisplayed={ !!activeWidget }
|
||||
|
|
@ -64,7 +64,7 @@ function SessionListModal(props: Props) {
|
|||
<TimezoneDropdown />
|
||||
</div>
|
||||
<div className="flex items-center ml-6">
|
||||
<span className="mr-2 color-gray-medium">Sort By</span>
|
||||
<span className="mr-2 color-gray-medium">Series</span>
|
||||
<Dropdown
|
||||
className={stl.dropdown}
|
||||
direction="left"
|
||||
|
|
@ -82,7 +82,8 @@ function SessionListModal(props: Props) {
|
|||
</div>
|
||||
<NoContent
|
||||
show={ !loading && (filteredSessions.length === 0 || filteredSessions.size === 0 )}
|
||||
title="No recordings found."
|
||||
title="No recordings found!"
|
||||
icon="exclamation-circle"
|
||||
>
|
||||
{ filteredSessions.map(session => <SessionItem key={ session.sessionId } session={ session } />) }
|
||||
</NoContent>
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ function SaveSearchModal(props: Props) {
|
|||
</Button>
|
||||
<Button className={ stl.cancelButton } marginRight onClick={ closeHandler }>{ 'Cancel' }</Button>
|
||||
</div>
|
||||
{ savedSearch && <Button className={ stl.cancelButton } marginRight onClick={ onDelete }>
|
||||
{ savedSearch && <Button noPadding className={ stl.cancelButton } marginRight onClick={ onDelete }>
|
||||
<Icon name="trash" size="18" />
|
||||
</Button> }
|
||||
</Modal.Actions>
|
||||
|
|
|
|||
|
|
@ -89,7 +89,10 @@
|
|||
}
|
||||
|
||||
&.plain {
|
||||
background-color: transparent;
|
||||
background-color: transparent !important;
|
||||
color: $teal !important;
|
||||
box-shadow: none !important;
|
||||
padding: 0 10px !important;
|
||||
&:hover {
|
||||
background-color: $active-blue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ const defaultInstance = CustomMetric({
|
|||
name: 'New',
|
||||
series: List([
|
||||
{
|
||||
name: 'Session Count',
|
||||
name: 'Series 1',
|
||||
filter: new Filter({ filters: [], eventsOrder: 'and' }),
|
||||
},
|
||||
])
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="bi bi-x" viewBox="0 0 16 16">
|
||||
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="bi bi-x-lg" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M13.854 2.146a.5.5 0 0 1 0 .708l-11 11a.5.5 0 0 1-.708-.708l11-11a.5.5 0 0 1 .708 0Z"/>
|
||||
<path fill-rule="evenodd" d="M2.146 2.146a.5.5 0 0 0 0 .708l11 11a.5.5 0 0 0 .708-.708l-11-11a.5.5 0 0 0-.708 0Z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 290 B After Width: | Height: | Size: 323 B |
3
frontend/app/svg/icons/sliders.svg
Normal file
3
frontend/app/svg/icons/sliders.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="bi bi-sliders" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M11.5 2a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM9.05 3a2.5 2.5 0 0 1 4.9 0H16v1h-2.05a2.5 2.5 0 0 1-4.9 0H0V3h9.05zM4.5 7a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM2.05 8a2.5 2.5 0 0 1 4.9 0H16v1H6.95a2.5 2.5 0 0 1-4.9 0H0V8h2.05zm9.45 4a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zm-2.45 1a2.5 2.5 0 0 1 4.9 0H16v1h-2.05a2.5 2.5 0 0 1-4.9 0H0v-1h9.05z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 460 B |
|
|
@ -6,7 +6,7 @@ import { capitalize } from 'App/utils';
|
|||
const countryOptions = Object.keys(countries).map(i => ({ text: countries[i], value: i }));
|
||||
|
||||
const ISSUE_OPTIONS = [
|
||||
{ text: 'Click Range', value: 'click_rage' },
|
||||
{ text: 'Click Rage', value: 'click_rage' },
|
||||
{ text: 'Dead Click', value: 'dead_click' },
|
||||
{ text: 'Excessive Scrolling', value: 'excessive_scrolling' },
|
||||
{ text: 'Bad Request', value: 'bad_request' },
|
||||
|
|
@ -40,7 +40,7 @@ export const filtersMap = {
|
|||
[FilterKey.PLATFORM]: { key: FilterKey.PLATFORM, type: FilterType.MULTIPLE_DROPDOWN, category: FilterCategory.GEAR, label: 'Platform', operator: 'is', operatorOptions: filterOptions.baseOperators, icon: 'filters/platform', options: platformOptions },
|
||||
[FilterKey.REVID]: { key: FilterKey.REVID, type: FilterType.MULTIPLE, category: FilterCategory.GEAR, label: 'RevId', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/rev-id' },
|
||||
[FilterKey.REFERRER]: { key: FilterKey.REFERRER, type: FilterType.MULTIPLE, category: FilterCategory.RECORDING_ATTRIBUTES, label: 'Referrer', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/referrer' },
|
||||
[FilterKey.DURATION]: { key: FilterKey.DURATION, type: FilterType.DURATION, category: FilterCategory.RECORDING_ATTRIBUTES, label: 'Duration', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/duration' },
|
||||
[FilterKey.DURATION]: { key: FilterKey.DURATION, type: FilterType.DURATION, category: FilterCategory.RECORDING_ATTRIBUTES, label: 'Duration', operator: 'is', operatorOptions: filterOptions.baseOperators, icon: 'filters/duration' },
|
||||
[FilterKey.USER_COUNTRY]: { key: FilterKey.USER_COUNTRY, type: FilterType.MULTIPLE_DROPDOWN, category: FilterCategory.RECORDING_ATTRIBUTES, label: 'User Country', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/country', options: countryOptions },
|
||||
// [FilterKey.CONSOLE]: { key: FilterKey.CONSOLE, type: FilterType.MULTIPLE, category: FilterCategory.JAVASCRIPT, label: 'Console', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/console' },
|
||||
[FilterKey.USERID]: { key: FilterKey.USERID, type: FilterType.MULTIPLE, category: FilterCategory.USER, label: 'User Id', operator: 'is', operatorOptions: filterOptions.stringOperators, icon: 'filters/userid' },
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue