From 247a0092d5a41fbdb9ce1bedf647e6f03c735faf Mon Sep 17 00:00:00 2001 From: Daiyi Yang Date: Fri, 29 Sep 2023 09:10:46 -0700 Subject: [PATCH] Add date range picker in the sidebar report config --- .../main-dashboard/MainDashboard.tsx | 75 ++++++++++--------- .../main-dashboard/SidebarReportConfig.tsx | 66 +++++++++++++++- .../src/components/uploader/DatePicker.tsx | 33 +++++++- .../BigqueryBasedReportConfig.tsx | 8 +- .../report-config/CSVBasedReportConfig.tsx | 30 ++++---- .../uploader/report-config/ReportConfig.tsx | 49 +++++++----- frontend/src/types/report-config.ts | 7 ++ 7 files changed, 189 insertions(+), 79 deletions(-) diff --git a/frontend/src/components/main-dashboard/MainDashboard.tsx b/frontend/src/components/main-dashboard/MainDashboard.tsx index b02a6a8..e63e50c 100644 --- a/frontend/src/components/main-dashboard/MainDashboard.tsx +++ b/frontend/src/components/main-dashboard/MainDashboard.tsx @@ -7,7 +7,6 @@ import { import { Bold, Card, - DateRangePickerValue, Divider, Flex, Grid, @@ -43,7 +42,12 @@ import { updateMetrics, } from "../../store/comparisonInsight"; import { DataSourceType, Schema } from "../../types/data-source"; -import { MetricColumn, TargetDirection } from "../../types/report-config"; +import { + DateRangeRelatedData, + MetricColumn, + TargetDirection, +} from "../../types/report-config"; +import { DateRangeData } from "../uploader/DatePicker"; import { MetricOverviewTable } from "./MetricOverviewTable"; import { SidebarReportConfig } from "./SidebarReportConfig"; import TopDimensionSlicesTable from "./TopDimensionSlicesTable"; @@ -58,8 +62,7 @@ enum ReportingType { interface RouterState { tableName?: string; fileId?: string; - baseDateRange: DateRangePickerValue; - comparisonDateRange: DateRangePickerValue; + dateRangeData: DateRangeRelatedData; metricColumn: MetricColumn; dateColumn: string; dateColumnType: string; @@ -85,8 +88,7 @@ export default function MainDashboard() { const { tableName, fileId, - baseDateRange, - comparisonDateRange, + dateRangeData, metricColumn, dateColumn, dateColumnType, @@ -131,8 +133,8 @@ export default function MainDashboard() { }>(apiPath, { tableName, fileId, - baseDateRange, - comparisonDateRange, + baseDateRange: dateRangeData.baseDateRangeData.range, + comparisonDateRange: dateRangeData.comparisonDateRangeData.range, dateColumn, dateColumnType, metricColumn, @@ -154,7 +156,7 @@ export default function MainDashboard() { dispatch(setError(e.error)); dispatch(setLoadingStatus(false)); }); - }, [baseDateRange, comparisonDateRange, fileId, dispatch]); + }, [dateRangeData, fileId, dispatch]); function renderSidebar() { let reportMenuElements: ReactElement[] = []; @@ -215,6 +217,8 @@ export default function MainDashboard() { schema={schema} filters={filters} key="report-config" + dateColumn={dateColumn} + dateRangeData={dateRangeData} allDimensions={schema.fields .map((h) => h.name) .filter( @@ -236,7 +240,12 @@ export default function MainDashboard() { ); })} dimensions={groupByColumns} - onSubmit={(newFilters: Filter[], newDimensions: string[]) => { + onSubmit={( + newFilters: Filter[], + newDimensions: string[], + newBaseDateRangeData: DateRangeData, + newComparisonDateRangeData: DateRangeData + ) => { navigate("/dashboard", { state: { schema, @@ -248,8 +257,11 @@ export default function MainDashboard() { dateColumn, dateColumnType, groupByColumns: newDimensions, - baseDateRange, - comparisonDateRange, + dateRangeData: { + baseDateRangeData: newBaseDateRangeData, + comparisonDateRangeData: newComparisonDateRangeData, + rowCountByDateColumn: dateRangeData.rowCountByDateColumn, + }, targetDirection, expectedValue, filters: newFilters, @@ -364,8 +376,7 @@ export default function MainDashboard() { dateColumn, dateColumnType, groupByColumns, - baseDateRange, - comparisonDateRange, + dateRangeData, targetDirection, expectedValue, filters: newFilters, @@ -562,26 +573,18 @@ export default function MainDashboard() { Top Segments Driving the Overall Change - {Object.keys(tableRowStatus).length > 0 ? ( - - ) : ( - - Unable to identify any significant driving segments. Either the - size of the data set is too small or the variations across all - segments are highly consistent. - - )} + )} {/* diff --git a/frontend/src/components/main-dashboard/SidebarReportConfig.tsx b/frontend/src/components/main-dashboard/SidebarReportConfig.tsx index 91b5377..3337f8f 100644 --- a/frontend/src/components/main-dashboard/SidebarReportConfig.tsx +++ b/frontend/src/components/main-dashboard/SidebarReportConfig.tsx @@ -2,10 +2,12 @@ import { Button, Flex, Text } from "@tremor/react"; import { useRef, useState } from "react"; import { Filter } from "../../common/types"; import { Schema } from "../../types/data-source"; +import { DateRangeRelatedData } from "../../types/report-config"; import { FiltersDropDown, FiltersDropDownHandler, } from "../common/FiltersDropdown"; +import DatePicker, { DateRangeData } from "../uploader/DatePicker"; import MultiSelector, { MultiSelectorHandles } from "../uploader/MultiSelector"; interface Props { @@ -13,7 +15,14 @@ interface Props { schema: Schema; dimensions: string[]; filters: Filter[]; - onSubmit: (newFilters: Filter[], newDimensions: string[]) => void; + dateColumn: string; + dateRangeData: DateRangeRelatedData; + onSubmit: ( + newFilters: Filter[], + newDimensions: string[], + newBaseDateRangeData: DateRangeData, + newComparisonDateRangeData: DateRangeData + ) => void; } export function SidebarReportConfig({ @@ -21,10 +30,16 @@ export function SidebarReportConfig({ schema, dimensions, filters, + dateColumn, + dateRangeData, onSubmit, }: Props) { const [localFilters, setLocalFilters] = useState(filters); const [localDimensions, setLocalDimensions] = useState(dimensions); + const [localBaseDateRangeData, setLocalBaseDateRangeData] = + useState(dateRangeData.baseDateRangeData); + const [localComparisonDateRangeData, setLocalComparisonDateRangeData] = + useState(dateRangeData.comparisonDateRangeData); const dimensionSelectorRef = useRef(null); const filtersDropDownRef = useRef(null); @@ -48,7 +63,24 @@ export function SidebarReportConfig({ ) ); - return hasChangeInDimensions || hasChangeInFilters; + const hasChangeInBaseDateRange = + dateRangeData.baseDateRangeData.range.from !== + localBaseDateRangeData.range.from || + dateRangeData.baseDateRangeData.range.to !== + localBaseDateRangeData.range.to; + + const hasChangeInComparisonDateRange = + dateRangeData.comparisonDateRangeData.range.from !== + localComparisonDateRangeData.range.from || + dateRangeData.comparisonDateRangeData.range.to !== + localComparisonDateRangeData.range.to; + + return ( + hasChangeInDimensions || + hasChangeInFilters || + hasChangeInBaseDateRange || + hasChangeInComparisonDateRange + ); } return ( <> @@ -59,6 +91,23 @@ export function SidebarReportConfig({ className="gap-y-2 p-2" >

Report Config

+ + setLocalComparisonDateRangeData(dateRangeData) + } + baseDateRangeData={localBaseDateRangeData} + setBaseDateRangeData={(dateRangeData) => + setLocalBaseDateRangeData(dateRangeData) + } + isOnSideBar={true} + /> Dimensions @@ -93,6 +149,10 @@ export function SidebarReportConfig({ onClick={() => { setLocalDimensions(dimensions); setLocalFilters(filters); + setLocalBaseDateRangeData(dateRangeData.baseDateRangeData); + setLocalComparisonDateRangeData( + dateRangeData.comparisonDateRangeData + ); dimensionSelectorRef.current?.reset(dimensions); filtersDropDownRef.current?.reset(filters); diff --git a/frontend/src/components/uploader/DatePicker.tsx b/frontend/src/components/uploader/DatePicker.tsx index 7829c0d..df49530 100644 --- a/frontend/src/components/uploader/DatePicker.tsx +++ b/frontend/src/components/uploader/DatePicker.tsx @@ -32,6 +32,7 @@ type DatePickerProps = { }; defaultBaseDateRange?: DateRangePickerValue; defaultComparisonDateRange?: DateRangePickerValue; + isOnSideBar?: boolean; }; type BaseDateMode = "previous" | "custom"; @@ -40,7 +41,6 @@ const oneDayMs = 24 * 60 * 60 * 1000; function DatePicker({ title, - comparisonDateRangeData, setComparisonDateRangeData, baseDateRangeData, @@ -48,6 +48,7 @@ function DatePicker({ countByDate, defaultBaseDateRange, defaultComparisonDateRange, + isOnSideBar, }: DatePickerProps) { useEffect(() => { if (defaultBaseDateRange) { @@ -202,6 +203,36 @@ function DatePicker({ ); } + if (isOnSideBar) { + return ( + <> + + Date Range + + + + Comparison Date Range + + + + ); + } + return ( diff --git a/frontend/src/components/uploader/report-config/BigqueryBasedReportConfig.tsx b/frontend/src/components/uploader/report-config/BigqueryBasedReportConfig.tsx index 4c07da0..b2444a5 100644 --- a/frontend/src/components/uploader/report-config/BigqueryBasedReportConfig.tsx +++ b/frontend/src/components/uploader/report-config/BigqueryBasedReportConfig.tsx @@ -1,7 +1,7 @@ import { useNavigate } from "react-router-dom"; import { BigquerySchema } from "../../../types/data-source"; import { - DateRangeConfig, + DateRangeRelatedData, MetricColumn, TargetDirection, } from "../../../types/report-config"; @@ -23,8 +23,7 @@ export default function BigqueryBasedReportConfig({ schema }: Props) { dateColumnType: string, metricColumn: MetricColumn, groupByColumns: string[], - baseDateRange: DateRangeConfig, - comparisonDateRange: DateRangeConfig, + dateRangeData: DateRangeRelatedData, targetDirection: TargetDirection, expectedValue: number ) => { @@ -38,8 +37,7 @@ export default function BigqueryBasedReportConfig({ schema }: Props) { dateColumn, dateColumnType, groupByColumns, - baseDateRange, - comparisonDateRange, + dateRangeData, targetDirection, expectedValue, filters: [], diff --git a/frontend/src/components/uploader/report-config/CSVBasedReportConfig.tsx b/frontend/src/components/uploader/report-config/CSVBasedReportConfig.tsx index 70c0ada..c366b6a 100644 --- a/frontend/src/components/uploader/report-config/CSVBasedReportConfig.tsx +++ b/frontend/src/components/uploader/report-config/CSVBasedReportConfig.tsx @@ -3,7 +3,7 @@ import { useNavigate } from "react-router-dom"; import { createNewDateWithBrowserTimeZone } from "../../../common/utils"; import { CSVSchema, DateField } from "../../../types/data-source"; import { - DateRangeConfig, + DateRangeRelatedData, MetricColumn, PrefillConfig, RowCountByDateAndColumn, @@ -50,7 +50,7 @@ const doorDashPrefills: PrefillConfig = { filter: { column: "order_status", value: "canceled", - } + }, }, denominator: { aggregationMethod: "nunique", @@ -58,7 +58,7 @@ const doorDashPrefills: PrefillConfig = { }, }, }, - dateColumn: 'order_date', + dateColumn: "order_date", groupByColumns: [ "order_canceled_by", "age_group", @@ -73,7 +73,7 @@ const doorDashPrefills: PrefillConfig = { "channel", "hour_of_the_day", "promo_code", - "payment_method" + "payment_method", ], baseDateRange: { from: createNewDateWithBrowserTimeZone("2023-08-14"), @@ -83,14 +83,14 @@ const doorDashPrefills: PrefillConfig = { from: createNewDateWithBrowserTimeZone("2023-08-21"), to: createNewDateWithBrowserTimeZone("2023-08-27"), }, -} +}; const insurancePrefills: PrefillConfig = { metricColumn: { aggregationOption: "sum", singularMetric: { columnName: "total_claim_amount", - } + }, }, groupByColumns: [ "age_group", @@ -107,9 +107,9 @@ const insurancePrefills: PrefillConfig = { "incident_city", "property_damage", "police_report_available", - "authorities_contacted" + "authorities_contacted", ], - dateColumn: 'incident_date', + dateColumn: "incident_date", baseDateRange: { from: createNewDateWithBrowserTimeZone("2023-07-04"), to: createNewDateWithBrowserTimeZone("2023-07-31"), @@ -118,7 +118,7 @@ const insurancePrefills: PrefillConfig = { from: createNewDateWithBrowserTimeZone("2023-08-01"), to: createNewDateWithBrowserTimeZone("2023-08-28"), }, -} +}; interface Props { schema: CSVSchema; @@ -137,7 +137,9 @@ export default function CSVBasedReportConfig({ const [rowCountByColumn, setRowCountByColumn] = useState<{ [key: string]: number; }>({}); - const [prefillConfig, setPrefillConfig] = useState(undefined); + const [prefillConfig, setPrefillConfig] = useState( + undefined + ); const prefill = (sample: "doordash" | "insurance") => { if (sample === "doordash") { @@ -145,7 +147,7 @@ export default function CSVBasedReportConfig({ } else if (sample === "insurance") { setPrefillConfig(insurancePrefills); } - } + }; useEffect(() => { if (prefillWithSampleData) { @@ -184,8 +186,7 @@ export default function CSVBasedReportConfig({ dateColumnType: string, metricColumn: MetricColumn, groupByColumns: string[], - baseDateRange: DateRangeConfig, - comparisonDateRange: DateRangeConfig, + dateRangeData: DateRangeRelatedData, targetDirection: TargetDirection, expectedValue: number ) => { @@ -199,8 +200,7 @@ export default function CSVBasedReportConfig({ dateColumnType, groupByColumns, metricColumn, - baseDateRange, - comparisonDateRange, + dateRangeData, targetDirection, expectedValue, filters: [], diff --git a/frontend/src/components/uploader/report-config/ReportConfig.tsx b/frontend/src/components/uploader/report-config/ReportConfig.tsx index f274f0f..a35abcd 100644 --- a/frontend/src/components/uploader/report-config/ReportConfig.tsx +++ b/frontend/src/components/uploader/report-config/ReportConfig.tsx @@ -15,7 +15,7 @@ import { getServerData } from "../../../common/server-data/server-data-loader"; import { useTracking } from "../../../common/tracking"; import { DataSourceType, Schema } from "../../../types/data-source"; import { - DateRangeConfig, + DateRangeRelatedData, MetricColumn, PrefillConfig, RowCountByColumn, @@ -40,8 +40,7 @@ type Props = { dateColumnType: string, metricColumn: MetricColumn, groupByColumns: string[], - baseDateRange: DateRangeConfig, - comparisonDateRange: DateRangeConfig, + dateRangeData: DateRangeRelatedData, targetDirection: TargetDirection, expectedValue: number ) => Promise; @@ -226,22 +225,31 @@ function ReportConfig({ return ( Report Config - { - debugMode && ( - + + Doordash + - - + + )} @@ -353,8 +361,11 @@ function ReportConfig({ dateColumnType, metricColumn, groupByColumns, - baseDateRangeData.range, - comparisonDateRangeData.range, + { + baseDateRangeData, + comparisonDateRangeData, + rowCountByDateColumn, + }, targetDirection, expectedValue ?? 0 ); diff --git a/frontend/src/types/report-config.ts b/frontend/src/types/report-config.ts index e9a2763..41a6cc8 100644 --- a/frontend/src/types/report-config.ts +++ b/frontend/src/types/report-config.ts @@ -1,4 +1,5 @@ import { DateRangePickerValue } from "@tremor/react"; +import { DateRangeData } from "../components/uploader/DatePicker"; import { FieldType } from "./data-source"; export type ColumnType = "metric" | "supporting_metric" | "dimension" | "date"; @@ -55,3 +56,9 @@ export interface PrefillConfig { baseDateRange: DateRangePickerValue; comparisonDateRange: DateRangePickerValue; } + +export interface DateRangeRelatedData { + baseDateRangeData: DateRangeData; + comparisonDateRangeData: DateRangeData; + rowCountByDateColumn?: RowCountByDateAndColumn; +}