mirror of
https://github.com/kremalicious/umami.git
synced 2025-02-14 21:10:34 +01:00
Journey view update.
This commit is contained in:
parent
0333bec986
commit
d0607303a1
@ -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%;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user