Journey view update.

This commit is contained in:
Mike Cao 2024-06-04 19:53:49 -07:00
parent 0333bec986
commit d0607303a1
6 changed files with 51 additions and 36 deletions

View File

@ -3,4 +3,5 @@
grid-template-rows: max-content 1fr; grid-template-rows: max-content 1fr;
grid-template-columns: max-content 1fr; grid-template-columns: max-content 1fr;
margin-bottom: 60px; margin-bottom: 60px;
height: 100%;
} }

View File

@ -1,5 +1,5 @@
.body { .body {
padding-inline-start: 20px; padding-inline-start: 20px;
grid-row: 2/3; grid-row: 2 / 3;
grid-column: 2 / 3; grid-column: 2 / 3;
} }

View File

@ -1,6 +1,6 @@
import styles from './ReportBody.module.css';
import { useContext } from 'react'; import { useContext } from 'react';
import { ReportContext } from './Report'; import { ReportContext } from './Report';
import styles from './ReportBody.module.css';
export function ReportBody({ children }) { export function ReportBody({ children }) {
const { report } = useContext(ReportContext); const { report } = useContext(ReportContext);

View File

@ -1,5 +1,6 @@
.container { .container {
height: 900px; width: 100%;
height: 100%;
position: relative; position: relative;
} }
@ -12,13 +13,13 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: nowrap; flex-wrap: nowrap;
gap: 60px;
overflow: auto; overflow: auto;
gap: 100px;
} }
.header { .header {
display: flex; display: flex;
margin-bottom: 20px; min-height: 70px;
} }
.num { .num {
@ -37,7 +38,11 @@
} }
.column { .column {
min-width: 300px; display: flex;
flex-direction: column;
}
.nodes {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
@ -48,14 +53,18 @@
padding: 10px 20px; padding: 10px 20px;
background: var(--base75); background: var(--base75);
border-radius: 5px; border-radius: 5px;
display: flex;
align-items: center;
min-width: 300px;
min-height: 60px;
} }
.item:hover:not(.highlight) { .item:hover:not(.selected) {
color: var(--base900); color: var(--base900);
background: var(--base100); background: var(--base100);
} }
.highlight { .selected {
color: var(--base75); color: var(--base75);
background: var(--base900); background: var(--base900);
font-weight: 400; font-weight: 400;

View File

@ -1,15 +1,17 @@
import { useContext, useMemo, useState } from 'react'; import { useContext, useMemo, useState } from 'react';
import { ReportContext } from '../[reportId]/Report'; import { ReportContext } from '../[reportId]/Report';
import { firstBy } from 'thenby'; import { firstBy } from 'thenby';
import styles from './JourneyView.module.css';
import classNames from 'classnames'; import classNames from 'classnames';
import { useEscapeKey } from 'components/hooks'; import { useEscapeKey } from 'components/hooks';
import styles from './JourneyView.module.css';
export default function JourneyView() { export default function JourneyView() {
const [selected, setSelected] = useState(null); const [selectedNode, setSelectedNode] = useState(null);
const { report } = useContext(ReportContext); const { report } = useContext(ReportContext);
const { data, parameters } = report || {}; const { data, parameters } = report || {};
useEscapeKey(() => setSelected(null));
useEscapeKey(() => setSelectedNode(null));
const columns = useMemo(() => { const columns = useMemo(() => {
if (!data) { if (!data) {
return []; return [];
@ -26,6 +28,9 @@ export default function JourneyView() {
item, item,
total: +count, total: +count,
index, index,
selected: !!selectedNode?.paths.find(arr => {
return arr.find(a => a.items[index] === item);
}),
paths: [ paths: [
data.filter((d, i) => { data.filter((d, i) => {
return d.items[index] === item && i !== index; return d.items[index] === item && i !== index;
@ -42,13 +47,13 @@ export default function JourneyView() {
.map(key => col[key]) .map(key => col[key])
.sort(firstBy('total', -1)); .sort(firstBy('total', -1));
}); });
}, [data]); }, [data, selectedNode]);
const handleClick = (item: string, index: number, paths: any[]) => { const handleClick = (item: string, index: number, paths: any[]) => {
if (item !== selected?.item || index !== selected?.index) { if (item !== selectedNode?.item || index !== selectedNode?.index) {
setSelected({ item, index, paths }); setSelectedNode({ item, index, paths });
} else { } else {
setSelected(null); setSelectedNode(null);
} }
}; };
@ -59,10 +64,10 @@ export default function JourneyView() {
return ( return (
<div className={styles.container}> <div className={styles.container}>
<div className={styles.view}> <div className={styles.view}>
{columns.map((column, index) => { {columns.map((nodes, index) => {
const current = index === selected?.index; const current = index === selectedNode?.index;
const behind = index <= selected?.index - 1; const behind = index <= selectedNode?.index - 1;
const ahead = index > selected?.index; const ahead = index > selectedNode?.index;
return ( return (
<div <div
@ -76,23 +81,22 @@ export default function JourneyView() {
<div className={styles.header}> <div className={styles.header}>
<div className={styles.num}>{index + 1}</div> <div className={styles.num}>{index + 1}</div>
</div> </div>
{column.map(({ item, total, paths }) => { <div className={styles.nodes}>
const highlight = selected?.paths.find(arr => { {nodes.map(({ item, total, selected, paths }, i) => {
return arr.find(a => a.items[index] === item); return (
}); <div
id={`node_${index}_${i}`}
return ( key={item}
<div className={classNames(styles.item, {
key={item} [styles.selected]: selected,
className={classNames(styles.item, { })}
[styles.highlight]: highlight, onClick={() => handleClick(item, index, paths)}
})} >
onClick={() => handleClick(item, index, paths)} {item} ({total})
> </div>
{item} ({total}) );
</div> })}
); </div>
})}
</div> </div>
); );
})} })}

View File

@ -4,6 +4,7 @@
flex-direction: column; flex-direction: column;
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%;
max-width: 1320px; max-width: 1320px;
margin: 0 auto; margin: 0 auto;
padding: 0 20px; padding: 0 20px;