From baa6c916dca10edae79bb8338ebb6afabcf2423a Mon Sep 17 00:00:00 2001 From: Shekar Siri Date: Mon, 16 May 2022 16:26:16 +0200 Subject: [PATCH] feat(ui) - funnels - fitler dropdowns to select --- .../components/WidgetForm/WidgetForm.tsx | 65 ++++++++++++++----- .../app/components/shared/Select/Select.tsx | 9 ++- frontend/app/constants/filterOptions.js | 47 +++++++------- frontend/app/mstore/metricStore.ts | 52 +++++++-------- frontend/app/mstore/types/widget.ts | 2 +- 5 files changed, 109 insertions(+), 66 deletions(-) diff --git a/frontend/app/components/Dashboard/components/WidgetForm/WidgetForm.tsx b/frontend/app/components/Dashboard/components/WidgetForm/WidgetForm.tsx index 4659a4494..85dcab6ea 100644 --- a/frontend/app/components/Dashboard/components/WidgetForm/WidgetForm.tsx +++ b/frontend/app/components/Dashboard/components/WidgetForm/WidgetForm.tsx @@ -7,6 +7,7 @@ import { useObserver } from 'mobx-react-lite'; import { Button, Icon } from 'UI' import FilterSeries from '../FilterSeries'; import { confirm } from 'UI/Confirmation'; +import Select from 'Shared/Select' import { withSiteId, dashboardMetricDetails, metricDetails } from 'App/routes' import DashboardSelectionModal from '../DashboardSelectionModal/DashboardSelectionModal'; @@ -22,18 +23,20 @@ function WidgetForm(props: Props) { const { metricStore, dashboardStore } = useStore(); const dashboards = dashboardStore.dashboards; const isSaving = useObserver(() => metricStore.isSaving); - const metric: any = useObserver(() => metricStore.instance); + const metric: any = useObserver(() => metricStore.instance) const timeseriesOptions = metricOf.filter(i => i.type === 'timeseries'); const tableOptions = metricOf.filter(i => i.type === 'table'); const isTable = metric.metricType === 'table'; const isFunnel = metric.metricType === 'funnel'; - const _issueOptions = [{ text: 'All', value: 'all' }].concat(issueOptions); + const isErrors = metric.metricType === 'errors'; + const isSessions = metric.metricType === 'sessions'; + const _issueOptions = [{ label: 'All', value: 'all' }].concat(issueOptions); const canAddToDashboard = metric.exists() && dashboards.length > 0; const canAddSeries = metric.series.length < 3; - const write = ({ target: { value, name } }) => metricStore.merge({ [ name ]: value }); - const writeOption = (e, { value, name }) => { + // const write = ({ target: { value, name } }) => metricStore.merge({ [ name ]: value }); + const writeOption = ({ value: { value }, name }) => { const obj = { [ name ]: value }; if (name === 'metricValue') { @@ -86,66 +89,98 @@ function WidgetForm(props: Props) { const onObserveChanges = () => { // metricStore.fetchMetricChartData(metric); } - + return useObserver(() => (
- i.value === metric.metricType) || metricTypes[0]} + onChange={ writeOption } + /> + {/* + /> */} {metric.metricType === 'timeseries' && ( <> of - + {/* + /> */} )} {metric.metricType === 'table' && ( <> of - + {/* + /> */} )} {metric.metricOf === FilterKey.ISSUE && ( <> issue type - + {/* + /> */} )} {metric.metricType === 'table' && ( <> showing - + {/* + /> */} )}
diff --git a/frontend/app/components/shared/Select/Select.tsx b/frontend/app/components/shared/Select/Select.tsx index f7e834561..dc495ff8e 100644 --- a/frontend/app/components/shared/Select/Select.tsx +++ b/frontend/app/components/shared/Select/Select.tsx @@ -10,9 +10,11 @@ interface Props { plain?: boolean; components?: any; styles?: any; + onChange: (value: any) => void; + name?: string; [x:string]: any; } -export default function({ styles= {}, alignRight = false, plain = false, options, isSearchable = false, components = {}, defaultValue = '', ...rest }: Props) { +export default function({ name = '', onChange, styles= {}, alignRight = false, plain = false, options, isSearchable = false, components = {}, defaultValue = '', ...rest }: Props) { const defaultSelected = defaultValue ? options.find(x => x.value === defaultValue) : null; const customStyles = { @@ -54,6 +56,10 @@ export default function({ styles= {}, alignRight = false, plain = false, options border: 'solid thin #ddd', cursor: 'pointer', transition: 'all 0.5s', + ['&:hover']: { + backgroundColor: colors['gray-lightest'], + transition: 'all 0.2s ease-in-out' + } } if (plain) { obj['border'] = '1px solid transparent' @@ -100,6 +106,7 @@ export default function({ styles= {}, alignRight = false, plain = false, options DropdownIndicator, ...components, }} + onChange={(value) => onChange({ name, value: value })} styles={{ ...customStyles, ...styles }} theme={(theme) => ({ ...theme, diff --git a/frontend/app/constants/filterOptions.js b/frontend/app/constants/filterOptions.js index b3bcfc43c..be5100ee6 100644 --- a/frontend/app/constants/filterOptions.js +++ b/frontend/app/constants/filterOptions.js @@ -60,10 +60,11 @@ export const customOperators = [ ] export const metricTypes = [ - { text: 'Timeseries', value: 'timeseries' }, - { text: 'Table', value: 'table' }, - { text: 'Funnel', value: 'funnel' }, - { text: 'Error', value: 'error' }, + { label: 'Timeseries', value: 'timeseries' }, + { label: 'Table', value: 'table' }, + { label: 'Funnel', value: 'funnel' }, + { label: 'Errors', value: 'errors' }, + { label: 'Sessions', value: 'sessions' }, ]; export const tableColumnName = { @@ -76,13 +77,13 @@ export const tableColumnName = { } export const metricOf = [ - { text: 'Session Count', value: 'sessionCount', type: 'timeseries' }, - { text: 'Users', value: FilterKey.USERID, type: 'table' }, - { text: 'Issues', value: FilterKey.ISSUE, type: 'table' }, - { text: 'Browsers', value: FilterKey.USER_BROWSER, type: 'table' }, - { text: 'Devices', value: FilterKey.USER_DEVICE, type: 'table' }, - { text: 'Countries', value: FilterKey.USER_COUNTRY, type: 'table' }, - { text: 'URLs', value: FilterKey.LOCATION, type: 'table' }, + { label: 'Session Count', value: 'sessionCount', type: 'timeseries' }, + { label: 'Users', value: FilterKey.USERID, type: 'table' }, + { label: 'Issues', value: FilterKey.ISSUE, type: 'table' }, + { label: 'Browsers', value: FilterKey.USER_BROWSER, type: 'table' }, + { label: 'Devices', value: FilterKey.USER_DEVICE, type: 'table' }, + { label: 'Countries', value: FilterKey.USER_COUNTRY, type: 'table' }, + { label: 'URLs', value: FilterKey.LOCATION, type: 'table' }, ] export const methodOptions = [ @@ -98,18 +99,18 @@ export const methodOptions = [ ] export const issueOptions = [ - { text: 'Click Rage', value: IssueType.CLICK_RAGE }, - { text: 'Dead Click', value: IssueType.DEAD_CLICK }, - { text: 'Excessive Scrolling', value: IssueType.EXCESSIVE_SCROLLING }, - { text: 'Bad Request', value: IssueType.BAD_REQUEST }, - { text: 'Missing Resource', value: IssueType.MISSING_RESOURCE }, - { text: 'Memory', value: IssueType.MEMORY }, - { text: 'CPU', value: IssueType.CPU }, - { text: 'Slow Resource', value: IssueType.SLOW_RESOURCE }, - { text: 'Slow Page Load', value: IssueType.SLOW_PAGE_LOAD }, - { text: 'Crash', value: IssueType.CRASH }, - { text: 'Custom', value: IssueType.CUSTOM }, - { text: 'Error', value: IssueType.JS_EXCEPTION }, + { label: 'Click Rage', value: IssueType.CLICK_RAGE }, + { label: 'Dead Click', value: IssueType.DEAD_CLICK }, + { label: 'Excessive Scrolling', value: IssueType.EXCESSIVE_SCROLLING }, + { label: 'Bad Request', value: IssueType.BAD_REQUEST }, + { label: 'Missing Resource', value: IssueType.MISSING_RESOURCE }, + { label: 'Memory', value: IssueType.MEMORY }, + { label: 'CPU', value: IssueType.CPU }, + { label: 'Slow Resource', value: IssueType.SLOW_RESOURCE }, + { label: 'Slow Page Load', value: IssueType.SLOW_PAGE_LOAD }, + { label: 'Crash', value: IssueType.CRASH }, + { label: 'Custom', value: IssueType.CUSTOM }, + { label: 'Error', value: IssueType.JS_EXCEPTION }, ] export default { diff --git a/frontend/app/mstore/metricStore.ts b/frontend/app/mstore/metricStore.ts index eb9147620..2f847fe94 100644 --- a/frontend/app/mstore/metricStore.ts +++ b/frontend/app/mstore/metricStore.ts @@ -90,7 +90,7 @@ export default class MetricStore implements IMetricStore { // State Actions init(metric?: IWidget|null) { - const _metric = new Widget().fromJson(sampleJson) + const _metric = new Widget().fromJson(sampleJsonErrors) this.instance.update(metric || _metric) // this.instance.update(metric || new Widget()) @@ -191,7 +191,7 @@ export default class MetricStore implements IMetricStore { } } -const sampleJson = { +const sampleJsonFunnel = { // metricId: 1, name: "Funnel Sample", metricType: 'funnel', @@ -199,31 +199,31 @@ const sampleJson = { { name: 'Series 1', filter: { + eventsOrder: 'then', filters: [ - { - type: 'LOCATION', - operator: 'is', - value: ['/sessions', '/errors', '/users'], - percent: 100, - completed: 60, - dropped: 40, - }, - { - type: 'LOCATION', - operator: 'is', - value: ['/sessions'], - percent: 80, - completed: 40, - dropped: 60, - }, - { - type: 'CLICK', - operator: 'on', - value: ['DASHBOARDS'], - percent: 80, - completed: 10, - dropped: 90, - } + { type: 'LOCATION', operator: 'is', value: ['/sessions', '/errors', '/users'], percent: 100, completed: 60, dropped: 40, }, + { type: 'LOCATION', operator: 'is', value: ['/sessions'], percent: 80, completed: 40, dropped: 60, }, + { type: 'CLICK', operator: 'on', value: ['DASHBOARDS'], percent: 80, completed: 10, dropped: 90, } + ] + } + } + ], +} + +const sampleJsonErrors = { + // metricId: 1, + name: "Errors Sample", + metricType: 'errors', + metricFormat: 'sessionCount', + series: [ + { + name: 'Series 1', + filter: { + eventsOrder: 'then', + filters: [ + { type: 'LOCATION', operator: 'is', value: ['/sessions', '/errors', '/users'], percent: 100, completed: 60, dropped: 40, }, + { type: 'LOCATION', operator: 'is', value: ['/sessions'], percent: 80, completed: 40, dropped: 60, }, + { type: 'CLICK', operator: 'on', value: ['DASHBOARDS'], percent: 80, completed: 10, dropped: 90, } ] } } diff --git a/frontend/app/mstore/types/widget.ts b/frontend/app/mstore/types/widget.ts index a2fac1d80..8933602ac 100644 --- a/frontend/app/mstore/types/widget.ts +++ b/frontend/app/mstore/types/widget.ts @@ -138,7 +138,7 @@ export default class Widget implements IWidget { this.viewType = json.viewType this.name = json.name this.series = json.series ? json.series.map((series: any) => new FilterSeries().fromJson(series)) : [], - this.dashboards = json.dashboards + this.dashboards = json.dashboards || [] this.owner = json.ownerEmail this.lastModified = json.editedAt || json.createdAt ? DateTime.fromMillis(json.editedAt || json.createdAt) : null this.config = json.config