From 9726f98ce29170a1518bebe039df390f7627d6a2 Mon Sep 17 00:00:00 2001 From: cade Date: Tue, 17 Sep 2024 14:50:06 -0600 Subject: [PATCH] simplify insight settings --- .../insights/[insightId]/loading.tsx | 2 +- .../share/[subjectId]/insights/loading.tsx | 2 +- .../insights/[insightId]/edit/loading.tsx | 2 +- .../insights/[insightId]/edit/page.tsx | 2 +- .../insights/[insightId]/loading.tsx | 2 +- .../[subjectId]/insights/create/loading.tsx | 2 +- .../[subjectId]/insights/create/page.tsx | 2 +- .../subjects/[subjectId]/insights/loading.tsx | 2 +- app/_components/checkbox.tsx | 4 +- app/_components/insight-form.tsx | 516 +++++++++--------- app/_components/insight-page.tsx | 10 +- app/_components/insight-plot.tsx | 284 +++++----- app/_components/insight.tsx | 9 +- app/_components/insights-page.tsx | 2 +- app/_constants/enum-bar-reducer.ts | 9 - ...{enum-bar-interval.ts => enum-interval.ts} | 4 +- app/_types/insight-config-json.ts | 12 +- 17 files changed, 391 insertions(+), 475 deletions(-) delete mode 100644 app/_constants/enum-bar-reducer.ts rename app/_constants/{enum-bar-interval.ts => enum-interval.ts} (70%) diff --git a/app/(pages)/@modal/(layout)/share/[subjectId]/insights/[insightId]/loading.tsx b/app/(pages)/@modal/(layout)/share/[subjectId]/insights/[insightId]/loading.tsx index 79f8c3eb..61ad3e10 100644 --- a/app/(pages)/@modal/(layout)/share/[subjectId]/insights/[insightId]/loading.tsx +++ b/app/(pages)/@modal/(layout)/share/[subjectId]/insights/[insightId]/loading.tsx @@ -1,5 +1,5 @@ import PageModalLoading from '@/_components/page-modal-loading'; -const Loading = () => ; +const Loading = () => ; export default Loading; diff --git a/app/(pages)/@modal/(layout)/share/[subjectId]/insights/loading.tsx b/app/(pages)/@modal/(layout)/share/[subjectId]/insights/loading.tsx index 79f8c3eb..61ad3e10 100644 --- a/app/(pages)/@modal/(layout)/share/[subjectId]/insights/loading.tsx +++ b/app/(pages)/@modal/(layout)/share/[subjectId]/insights/loading.tsx @@ -1,5 +1,5 @@ import PageModalLoading from '@/_components/page-modal-loading'; -const Loading = () => ; +const Loading = () => ; export default Loading; diff --git a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/edit/loading.tsx b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/edit/loading.tsx index 79f8c3eb..036fff73 100644 --- a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/edit/loading.tsx +++ b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/edit/loading.tsx @@ -1,5 +1,5 @@ import PageModalLoading from '@/_components/page-modal-loading'; -const Loading = () => ; +const Loading = () => ; export default Loading; diff --git a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/edit/page.tsx b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/edit/page.tsx index 72cf0402..1cf8d2ee 100644 --- a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/edit/page.tsx +++ b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/edit/page.tsx @@ -21,7 +21,7 @@ const Page = async ({ params: { insightId, subjectId } }: PageProps) => { if (!events || !insight) return null; return ( - + diff --git a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/loading.tsx b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/loading.tsx index 202f27c9..813d4bb3 100644 --- a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/loading.tsx +++ b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/[insightId]/loading.tsx @@ -1,5 +1,5 @@ import PageModalLoading from '@/_components/page-modal-loading'; -const Loading = () => ; +const Loading = () => ; export default Loading; diff --git a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/create/loading.tsx b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/create/loading.tsx index 79f8c3eb..036fff73 100644 --- a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/create/loading.tsx +++ b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/create/loading.tsx @@ -1,5 +1,5 @@ import PageModalLoading from '@/_components/page-modal-loading'; -const Loading = () => ; +const Loading = () => ; export default Loading; diff --git a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/create/page.tsx b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/create/page.tsx index fcc19112..bbe4b2d1 100644 --- a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/create/page.tsx +++ b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/create/page.tsx @@ -19,7 +19,7 @@ const Page = async ({ params: { subjectId } }: PageProps) => { if (!events) return false; return ( - + diff --git a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/loading.tsx b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/loading.tsx index 79f8c3eb..61ad3e10 100644 --- a/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/loading.tsx +++ b/app/(pages)/@modal/(layout)/subjects/[subjectId]/insights/loading.tsx @@ -1,5 +1,5 @@ import PageModalLoading from '@/_components/page-modal-loading'; -const Loading = () => ; +const Loading = () => ; export default Loading; diff --git a/app/_components/checkbox.tsx b/app/_components/checkbox.tsx index 6d99a455..24cd38f0 100644 --- a/app/_components/checkbox.tsx +++ b/app/_components/checkbox.tsx @@ -16,7 +16,7 @@ const Checkbox = forwardRef( )} > ( > {label && } - + ), ); diff --git a/app/_components/insight-form.tsx b/app/_components/insight-form.tsx index 2ef21c0a..71a8b92a 100644 --- a/app/_components/insight-form.tsx +++ b/app/_components/insight-form.tsx @@ -11,10 +11,10 @@ import PageModalBackButton from '@/_components/page-modal-back-button'; import * as Popover from '@/_components/popover'; import Select, { IOption } from '@/_components/select'; import UnsavedChangesBanner from '@/_components/unsaved-changes-banner'; -import BarInterval from '@/_constants/enum-bar-interval'; -import BarReducer from '@/_constants/enum-bar-reducer'; import ChartType from '@/_constants/enum-chart-type'; +import Interval from '@/_constants/enum-interval'; import LineCurveFunction from '@/_constants/enum-line-curve-function'; +import Reducer from '@/_constants/enum-reducer'; import TimeSinceMilliseconds from '@/_constants/enum-time-since-milliseconds'; import useCachedForm from '@/_hooks/use-cached-form'; import upsertInsight from '@/_mutations/upsert-insight'; @@ -26,8 +26,8 @@ import getInputDetailsFromEvents from '@/_utilities/get-input-details-from-event import getInsightOptionsFromEvents from '@/_utilities/get-insight-options-from-events'; import { ArrowsPointingInIcon } from '@heroicons/react/24/outline'; import AdjustmentsHorizontalIcon from '@heroicons/react/24/outline/AdjustmentsHorizontalIcon'; -import EllipsisVerticalIcon from '@heroicons/react/24/outline/EllipsisVerticalIcon'; import FunnelIcon from '@heroicons/react/24/outline/FunnelIcon'; +import PlusIcon from '@heroicons/react/24/outline/PlusIcon'; import { useRouter } from 'next/navigation'; import { useTransition } from 'react'; import { Controller } from 'react-hook-form'; @@ -40,28 +40,29 @@ const INCLUDE_EVENTS_SINCE_OPTIONS = [ { id: TimeSinceMilliseconds.Year, label: '1 year ago' }, ]; +const INTERVAL_OPTIONS = [ + { id: Interval.Day, label: 'Day' }, + { id: Interval.Week, label: 'Week' }, + { id: Interval.Month, label: 'Month' }, + { id: Interval.Quarter, label: 'Quarter-year' }, + { id: Interval.Half, label: 'Half-year' }, + { id: Interval.Year, label: 'Year' }, +]; + const LINE_CURVE_FUNCTION_OPTIONS = [ { id: LineCurveFunction.Linear, label: 'Linear' }, + { id: LineCurveFunction.CatmullRom, label: 'Catmull-rom' }, { id: LineCurveFunction.Basis, label: 'Basis' }, { id: LineCurveFunction.Bundle, label: 'Bundle' }, - { id: LineCurveFunction.CatmullRom, label: 'Catmull-rom' }, { id: LineCurveFunction.Step, label: 'Step' }, ]; -const BAR_INTERVAL_OPTIONS = [ - { id: BarInterval.Day, label: 'Day' }, - { id: BarInterval.Week, label: 'Week' }, - { id: BarInterval.Month, label: 'Month' }, - { id: BarInterval.Quarter, label: '3 months' }, - { id: BarInterval.Half, label: '6 months' }, - { id: BarInterval.Year, label: 'Year' }, -]; - -const BAR_REDUCER_OPTIONS = [ - { id: BarReducer.Mean, isDisabled: false, label: 'Average' }, - { id: BarReducer.Sum, isDisabled: false, label: 'Sum' }, - { id: BarReducer.Min, isDisabled: false, label: 'Min' }, - { id: BarReducer.Max, isDisabled: false, label: 'Max' }, +const REDUCER_OPTIONS = [ + { id: Reducer.Count, label: 'Count' }, + { id: Reducer.Mean, label: 'Average' }, + { id: Reducer.Sum, label: 'Sum' }, + { id: Reducer.Min, label: 'Min' }, + { id: Reducer.Max, label: 'Max' }, ]; interface InsightFormProps { @@ -86,23 +87,19 @@ const InsightForm = ({ events, insight, subjectId }: InsightFormProps) => { annotationIncludeEventsFrom: config?.annotationIncludeEventsFrom ?? null, annotationInput: config?.annotationInput ?? null, annotationInputOptions: config?.annotationInputOptions ?? [], - annotationLabel: config?.annotationLabel ?? '', - barInterval: config?.barInterval ?? BarInterval.Day, - barReducer: config?.barReducer ?? BarReducer.Mean, includeEventsFrom: config?.includeEventsFrom ?? null, includeEventsSince: config?.includeEventsSince ?? null, input: config?.input, inputOptions: config?.inputOptions ?? [], + interval: config?.interval ?? null, lineCurveFunction: config?.lineCurveFunction ?? LineCurveFunction.Linear, marginBottom: config?.marginBottom ?? '60', - marginLeft: config?.marginLeft ?? '80', + marginLeft: config?.marginLeft ?? '100', marginRight: config?.marginRight ?? '60', marginTop: config?.marginTop ?? '60', name: insight?.name ?? '', order: insight?.order, - showBars: config?.showBars ?? false, - showDots: config?.showDots ?? true, - showLine: config?.showLine ?? false, + reducer: config?.reducer ?? Reducer.Mean, showLinearRegression: config?.showLinearRegression ?? false, showLinearRegressionConfidence: config?.showLinearRegressionConfidence ?? false, @@ -112,9 +109,7 @@ const InsightForm = ({ events, insight, subjectId }: InsightFormProps) => { const annotationInputId = form.watch('annotationInput'); const inputId = form.watch('input'); - const showBars = form.watch('showBars'); - const showLine = form.watch('showLine'); - + const interval = form.watch('interval'); const { isInputNominal } = getInputDetailsFromEvents({ events, inputId }); const inputOptions = getInsightOptionsFromEvents({ events, inputId }); @@ -142,19 +137,47 @@ const InsightForm = ({ events, insight, subjectId }: InsightFormProps) => { }), )} > -
- +
+ +
+
( - field.onChange((value as IOption)?.id) + name="includeEventsFrom" + render={({ field }) => { + let value; + + if (field.value) { + for (const group of inputOptions.eventTypeOrProtocolOptions) { + value = group.options.find((o) => o.id === field.value); + if (value) break; } - options={LINE_CURVE_FUNCTION_OPTIONS as IOption[]} - value={LINE_CURVE_FUNCTION_OPTIONS.find( - (o) => o.id === field.value, - )} - /> - )} + } + + return ( + - field.onChange((value as IOption)?.id) + field.onChange((value as IOption)?.id ?? null) } - options={BAR_INTERVAL_OPTIONS as IOption[]} - value={BAR_INTERVAL_OPTIONS.find( - (o) => o.id === field.value, + options={INCLUDE_EVENTS_SINCE_OPTIONS} + placeholder="The beginning of time…" + value={INCLUDE_EVENTS_SINCE_OPTIONS.find( + (o) => field.value === o.id, )} /> )} /> - {!isInputNominal && ( + {inputOptions.inputOptionsOptions[inputId] && ( - - Reducer + + Input options ( + field.onChange((value as IOption)?.id) + } + options={INTERVAL_OPTIONS} + placeholder="Select an interval…" + value={INTERVAL_OPTIONS.find( + (o) => o.id === field.value, + )} + /> + )} /> @@ -377,7 +359,7 @@ const InsightForm = ({ events, insight, subjectId }: InsightFormProps) => { className="rounded-l-none p-2.5" colorScheme="transparent" icon={} - label="Linear regression settings" + label="Interval settings" variant="primary" /> @@ -387,17 +369,78 @@ const InsightForm = ({ events, insight, subjectId }: InsightFormProps) => { side="top" > - - Confidence band + + Reducer - ( + + field.onChange((value as IOption)?.id) + } + options={LINE_CURVE_FUNCTION_OPTIONS as IOption[]} + value={LINE_CURVE_FUNCTION_OPTIONS.find( + (o) => o.id === field.value, + )} + /> + )} + /> + + )} + + + + + } + label="Add marks" + variant="primary" + /> + + Annotate @@ -417,7 +460,6 @@ const InsightForm = ({ events, insight, subjectId }: InsightFormProps) => { field.onChange(inputId ?? null); form.setValue('annotationIncludeEventsFrom', null); form.setValue('annotationInputOptions', []); - form.setValue('annotationLabel', ''); }} options={annotationInputOptions.inputOptions} placeholder="Select an input…" @@ -432,8 +474,8 @@ const InsightForm = ({ events, insight, subjectId }: InsightFormProps) => { } - label="Annotation settings" + icon={} + label="Annotation filters" variant="primary" /> @@ -442,15 +484,6 @@ const InsightForm = ({ events, insight, subjectId }: InsightFormProps) => { className="mr-0 w-96 space-y-6 p-8 pt-7" side="top" > - - - Custom label - - - Events from @@ -527,105 +560,42 @@ const InsightForm = ({ events, insight, subjectId }: InsightFormProps) => {
- - - - - } - label="Filters" - variant="primary" - /> - - - - - Events from - - { - let value; - - if (field.value) { - for (const group of inputOptions.eventTypeOrProtocolOptions) { - value = group.options.find((o) => o.id === field.value); - if (value) break; - } - } - - return ( - - field.onChange((value as IOption)?.id ?? null) - } - options={INCLUDE_EVENTS_SINCE_OPTIONS} - placeholder="The beginning of time…" - value={INCLUDE_EVENTS_SINCE_OPTIONS.find( - (o) => field.value === o.id, - )} - /> - )} - /> - - {inputOptions.inputOptionsOptions[inputId] && ( + {!isInputNominal && ( - - Input options + + Linear regression - ( -