Changed steps to dropdown.

This commit is contained in:
Mike Cao 2024-06-08 21:43:29 -07:00
parent edd679295c
commit 3234120bfb
3 changed files with 92 additions and 76 deletions

View file

@ -1,6 +1,15 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useMessages } from 'components/hooks'; import { useMessages } from 'components/hooks';
import { Form, FormButtons, FormInput, FormRow, SubmitButton, TextField } from 'react-basics'; import {
Dropdown,
Form,
FormButtons,
FormInput,
FormRow,
Item,
SubmitButton,
TextField,
} from 'react-basics';
import { ReportContext } from '../[reportId]/Report'; import { ReportContext } from '../[reportId]/Report';
import BaseParameters from '../[reportId]/BaseParameters'; import BaseParameters from '../[reportId]/BaseParameters';
@ -24,12 +33,12 @@ export function JourneyParameters() {
return ( return (
<Form values={parameters} onSubmit={handleSubmit} preventSubmit={true}> <Form values={parameters} onSubmit={handleSubmit} preventSubmit={true}>
<BaseParameters showDateSelect={true} allowWebsiteSelect={!id} /> <BaseParameters showDateSelect={true} allowWebsiteSelect={!id} />
<FormRow label={`${formatMessage(labels.steps)} (3 to 7)`}> <FormRow label={formatMessage(labels.steps)}>
<FormInput <FormInput
name="steps" name="steps"
rules={{ required: formatMessage(labels.required), pattern: /[0-9]+/, min: 3, max: 7 }} rules={{ required: formatMessage(labels.required), pattern: /[0-9]+/, min: 3, max: 7 }}
> >
<TextField autoComplete="off" /> <Dropdown items={[3, 4, 5, 6, 7]}>{item => <Item key={item}>{item}</Item>}</Dropdown>
</FormInput> </FormInput>
</FormRow> </FormRow>
<FormRow label={formatMessage(labels.startStep)}> <FormRow label={formatMessage(labels.startStep)}>

View file

@ -31,8 +31,8 @@ export default function JourneyView() {
const selectedNodes = selectedNode?.paths ?? []; const selectedNodes = selectedNode?.paths ?? [];
if (name) { if (name) {
const selected = !!selectedNodes.find(a => a.items[index] === name);
if (!column[name]) { if (!column[name]) {
const selected = !!selectedNodes.find(a => a.items[index] === name);
const paths = data.filter((d, i) => { const paths = data.filter((d, i) => {
return i !== index && d.items[index] === name; return i !== index && d.items[index] === name;
}); });
@ -43,23 +43,26 @@ export default function JourneyView() {
const { items, count } = path; const { items, count } = path;
const name = items[index - 1]; const name = items[index - 1];
if (!obj[name]) { if (!obj[name]) {
obj[name] = { name, count: +count }; obj[name] = { name, count };
} else { } else {
obj[name].count += +count; obj[name].count += count;
} }
return obj; return obj;
}, {}); }, {});
column[name] = { column[name] = {
name, name,
total: +count, count,
total: count,
columnIndex: index, columnIndex: index,
selected, selected,
selectedCount: count,
paths, paths,
from: objectToArray(from), from: objectToArray(from),
}; };
} else { } else {
column[name].total += +count; column[name].selectedCount += selected ? count : 0;
column[name].total += count;
} }
} }
}); });
@ -97,77 +100,81 @@ export default function JourneyView() {
<div className={styles.num}>{columnIndex + 1}</div> <div className={styles.num}>{columnIndex + 1}</div>
</div> </div>
<div className={styles.nodes}> <div className={styles.nodes}>
{column.nodes.map(({ name, total, selected, paths, from }, nodeIndex) => { {column.nodes.map(
const active = ({ name, total, selected, paths, from, selectedCount }, nodeIndex) => {
selected && activeNode?.paths.find(path => path.items[columnIndex] === name); const active =
selected && activeNode?.paths.find(path => path.items[columnIndex] === name);
const lines = from?.reduce((arr, { name }: any) => { const lines = from?.reduce((arr, { name }: any) => {
const fromIndex = columns[columnIndex - 1]?.nodes.findIndex(node => { const fromIndex = columns[columnIndex - 1]?.nodes.findIndex(node => {
return node.name === name && node.selected; return node.name === name && node.selected;
}); });
if (fromIndex > -1) { if (fromIndex > -1) {
arr.push([fromIndex, nodeIndex]); arr.push([fromIndex, nodeIndex]);
} }
return arr; return arr;
}, []); }, []);
return ( return (
<div <div
key={name} key={name}
className={classNames(styles.item, { className={classNames(styles.item, {
[styles.selected]: selected, [styles.selected]: selected,
[styles.active]: active, [styles.active]: active,
})}
onClick={() => handleClick(name, columnIndex, paths)}
onMouseEnter={() => selected && setActiveNode({ name, columnIndex, paths })}
onMouseLeave={() => selected && setActiveNode(null)}
>
<div className={styles.name}>{name}</div>
<div className={styles.count}>{total}</div>
{columnIndex < columns.length &&
lines.map(([fromIndex, nodeIndex], i) => {
const height =
(Math.abs(nodeIndex - fromIndex) + 1) * (NODE_HEIGHT + NODE_GAP) -
NODE_GAP;
const midHeight =
(Math.abs(nodeIndex - fromIndex) - 1) * (NODE_HEIGHT + NODE_GAP) +
NODE_GAP +
LINE_WIDTH;
const nodeName = columns[columnIndex - 1]?.nodes[fromIndex].name;
return (
<div
key={`${fromIndex}${nodeIndex}${i}`}
className={classNames(styles.line, {
[styles.active]:
active &&
activeNode?.paths.find(
path =>
path.items[columnIndex] === name &&
path.items[columnIndex - 1] === nodeName,
),
[styles.up]: fromIndex < nodeIndex,
[styles.down]: fromIndex > nodeIndex,
[styles.flat]: fromIndex === nodeIndex,
})}
style={{ height }}
>
<div className={classNames(styles.segment, styles.start)} />
<div
className={classNames(styles.segment, styles.mid)}
style={{
height: midHeight,
}}
/>
<div className={classNames(styles.segment, styles.end)} />
</div>
);
})} })}
</div> onClick={() => handleClick(name, columnIndex, paths)}
); onMouseEnter={() => selected && setActiveNode({ name, columnIndex, paths })}
})} onMouseLeave={() => selected && setActiveNode(null)}
>
<div className={styles.name}>{name}</div>
<div className={styles.count}>
{selected || active ? selectedCount : total}
</div>
{columnIndex < columns.length &&
lines.map(([fromIndex, nodeIndex], i) => {
const height =
(Math.abs(nodeIndex - fromIndex) + 1) * (NODE_HEIGHT + NODE_GAP) -
NODE_GAP;
const midHeight =
(Math.abs(nodeIndex - fromIndex) - 1) * (NODE_HEIGHT + NODE_GAP) +
NODE_GAP +
LINE_WIDTH;
const nodeName = columns[columnIndex - 1]?.nodes[fromIndex].name;
return (
<div
key={`${fromIndex}${nodeIndex}${i}`}
className={classNames(styles.line, {
[styles.active]:
active &&
activeNode?.paths.find(
path =>
path.items[columnIndex] === name &&
path.items[columnIndex - 1] === nodeName,
),
[styles.up]: fromIndex < nodeIndex,
[styles.down]: fromIndex > nodeIndex,
[styles.flat]: fromIndex === nodeIndex,
})}
style={{ height }}
>
<div className={classNames(styles.segment, styles.start)} />
<div
className={classNames(styles.segment, styles.mid)}
style={{
height: midHeight,
}}
/>
<div className={classNames(styles.segment, styles.end)} />
</div>
);
})}
</div>
);
},
)}
</div> </div>
</div> </div>
); );

View file

@ -10,7 +10,7 @@ interface JourneyResult {
e5: string; e5: string;
e6: string; e6: string;
e7: string; e7: string;
count: string; count: number;
} }
export async function getJourney( export async function getJourney(
@ -267,6 +267,6 @@ function combineSequentialDuplicates(array: any) {
function parseResult(data: any) { function parseResult(data: any) {
return data.map(({ e1, e2, e3, e4, e5, e6, e7, count }) => ({ return data.map(({ e1, e2, e3, e4, e5, e6, e7, count }) => ({
items: combineSequentialDuplicates([e1, e2, e3, e4, e5, e6, e7]), items: combineSequentialDuplicates([e1, e2, e3, e4, e5, e6, e7]),
count, count: +count,
})); }));
} }