Skip to content

Commit

Permalink
Insights table - New UI (#4700)
Browse files Browse the repository at this point in the history
Co-authored-by: Alex Kim <alexgkim205@gmail.com>
  • Loading branch information
paolodamico and alexkim205 authored Jun 15, 2021
1 parent 040458f commit 264f968
Show file tree
Hide file tree
Showing 11 changed files with 317 additions and 24 deletions.
7 changes: 4 additions & 3 deletions frontend/src/lib/components/DateDisplay/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import './DateDisplay.scss'
interface DateDisplayProps {
date: string
interval: IntervalType
hideWeekRange?: boolean
}

const DISPLAY_DATE_FORMAT: Record<IntervalType, string> = {
Expand All @@ -29,21 +30,21 @@ const dateHighlight = (parsedDate: dayjs.Dayjs, interval: IntervalType): string
case 'month':
return parsedDate.format('YYYY')
default:
return ''
return parsedDate.format('dd')
}
}

/* Returns a single line standardized component to display the date depending on context.
For example, a single date in a graph will be shown as: `Th` Apr 22.
*/
export function DateDisplay({ date, interval }: DateDisplayProps): JSX.Element {
export function DateDisplay({ date, interval, hideWeekRange }: DateDisplayProps): JSX.Element {
const parsedDate = dayjs(date)

return (
<>
<span className="dated-highlight">{dateHighlight(parsedDate, interval)}</span>
{parsedDate.format(DISPLAY_DATE_FORMAT[interval])}
{interval === 'week' && (
{interval === 'week' && !hideWeekRange && (
<>
{/* TODO: @EDsCODE will help validate; this should probably come from the backend */}
{' - '}
Expand Down
10 changes: 7 additions & 3 deletions frontend/src/lib/components/InsightLabel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ interface InsightsLabelProps {
action?: ActionFilter
value?: string
breakdownValue?: string
hideBreakdown?: boolean // Whether to hide the breakdown detail in the label
hideIcon?: boolean // Whether to hide the icon that showcases the color of the series
seriesStatus?: string // Used by lifecycle chart to display the series name
fallbackName?: string // Name to display for the series if it can be determined from `action`
hasMultipleSeries?: boolean // Whether the graph has multiple discrete series (not breakdown values)
Expand Down Expand Up @@ -47,6 +49,8 @@ export function InsightLabel({
action,
value,
breakdownValue,
hideBreakdown,
hideIcon,
seriesStatus,
fallbackName,
hasMultipleSeries,
Expand All @@ -58,7 +62,7 @@ export function InsightLabel({
return (
<Row className="insights-label" wrap={false}>
<Col style={{ display: 'flex', alignItems: 'center' }} flex="auto">
{!(hasMultipleSeries && !breakdownValue) && (
{!(hasMultipleSeries && !breakdownValue) && !hideIcon && (
<div
className="color-icon"
style={{
Expand All @@ -75,13 +79,13 @@ export function InsightLabel({
/>
)}
<div className="protect-width">
{showEventName && <PropertyKeyInfo disableIcon value={eventName} />}
{showEventName && <PropertyKeyInfo disableIcon disablePopover value={eventName} />}

{hasMultipleSeries && ((action?.math && action.math !== 'total') || showCountedByTag) && (
<MathTag math={action?.math} mathProperty={action?.math_property} />
)}

{breakdownValue && (
{breakdownValue && !hideBreakdown && (
<>
{hasMultipleSeries && <span style={{ padding: '0 2px' }}>-</span>}
{breakdownValue === 'total' ? <i>Total</i> : breakdownValue}
Expand Down
19 changes: 19 additions & 0 deletions frontend/src/lib/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
endWithPunctation,
dateFilterToText,
hexToRGBA,
average,
median,
} from './utils'

describe('capitalizeFirstLetter()', () => {
Expand Down Expand Up @@ -168,3 +170,20 @@ describe('hexToRGBA()', () => {
expect(hexToRGBA('#5375ff', 1)).toEqual('rgba(83,117,255,1)')
})
})

describe('average()', () => {
it('calculates average correctly', () => {
expect(average([9, 4, 1, 3, 5, 7])).toEqual(4.8)
expect(average([72, 35, 68, 66, 70, 9, 81])).toEqual(57.3) // Tests rounding too
expect(average([86.4, 46.321, 45.304, 34.1, 147])).toEqual(71.8) // Tests rounding too
})
})

describe('median()', () => {
it('returns middle number if array length is odd', () => {
expect(median([9, 4, 1, 3, 5, 7, 3, 6, 14])).toEqual(5)
})
it('returns avg of middle numbers if array length is even', () => {
expect(median([9, 4, 0, 5, 7, 3, 6, 14])).toEqual(5.5)
})
})
22 changes: 22 additions & 0 deletions frontend/src/lib/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -908,3 +908,25 @@ export function lightenDarkenColor(hex: string, pct: number): string {
export function toString(input?: any | null): string {
return input?.toString() || ''
}

export function average(input: number[]): number {
/**
* Returns the average of an array
* @param input e.g. [100,50, 75]
*/
return Math.round((input.reduce((acc, val) => acc + val, 0) / input.length) * 10) / 10
}

export function median(input: number[]): number {
/**
* Returns the median of an array
* @param input e.g. [3,7,10]
*/
const sorted = [...input].sort((a, b) => a - b)
const half = Math.floor(sorted.length / 2)

if (sorted.length % 2) {
return sorted[half]
}
return average([sorted[half - 1], sorted[half]])
}
8 changes: 6 additions & 2 deletions frontend/src/lib/utils/eventUsageLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export const eventUsageLogic = kea<
reportSavedInsightToDashboard: true,
reportInsightsTabReset: true,
reportInsightsControlsCollapseToggle: (collapsed: boolean) => ({ collapsed }),
reportInsightsTableCalcToggled: (mode: string) => ({ mode }),
},
listeners: {
reportAnnotationViewed: async ({ annotations }, breakpoint) => {
Expand Down Expand Up @@ -430,8 +431,11 @@ export const eventUsageLogic = kea<
reportInsightsTabReset: async () => {
posthog.capture('insights tab reset')
},
reportInsightsControlsCollapseToggle: async ({ collapsed }) => {
posthog.capture('insight controls collapse toggled', { collapsed })
reportInsightsControlsCollapseToggle: async (payload) => {
posthog.capture('insight controls collapse toggled', payload)
},
reportInsightsTableCalcToggled: async (payload) => {
posthog.capture('insights table calc toggled', payload)
},
},
})
18 changes: 12 additions & 6 deletions frontend/src/scenes/insights/Insights.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'

import { Tabs, Row, Col, Card, Button, Tooltip } from 'antd'
import { ACTIONS_LINE_GRAPH_LINEAR, ACTIONS_LINE_GRAPH_CUMULATIVE, FUNNEL_VIZ, FEATURE_FLAGS } from 'lib/constants'
import { FUNNEL_VIZ, FEATURE_FLAGS, ACTIONS_TABLE, ACTIONS_BAR_CHART_VALUE } from 'lib/constants'
import { annotationsLogic } from '~/lib/components/Annotations'
import { router } from 'kea-router'

Expand Down Expand Up @@ -363,20 +363,26 @@ export function Insights(): JSX.Element {
!showTimeoutMessage &&
activeView === ViewType.FUNNELS &&
allFilters.display === FUNNEL_VIZ && (
<Card style={{ marginTop: 16 }}>
<Card style={{ marginTop: 8 }}>
<FunnelPeople />
</Card>
)}
{(!allFilters.display ||
allFilters.display === ACTIONS_LINE_GRAPH_LINEAR ||
allFilters.display === ACTIONS_LINE_GRAPH_CUMULATIVE) &&
(allFilters.display !== ACTIONS_TABLE &&
allFilters.display !== ACTIONS_BAR_CHART_VALUE)) &&
(activeView === ViewType.TRENDS || activeView === ViewType.SESSIONS) && (
<Card style={{ marginTop: 16 }}>
/* InsightsTable is loaded for all trend views (except below), plus the sessions view.
Exclusions:
1. Table view. Because table is already loaded anyways in `Trends.tsx` as the main component.
2. Bar value chart. Because this view displays data in completely different dimensions.
*/
<Card style={{ marginTop: 8 }}>
<BindLogic
logic={trendsLogic}
props={{ dashboardItemId: null, view: activeView }}
>
<InsightsTable />
<h3 className="l3">Details table</h3>
<InsightsTable showTotalCount={activeView !== ViewType.SESSIONS} />
</BindLogic>
</Card>
)}
Expand Down
Loading

0 comments on commit 264f968

Please sign in to comment.