Skip to content

Commit d4c9fe9

Browse files
feat(overmind-devtools-client): initial implementation of charts
1 parent a93a445 commit d4c9fe9

File tree

7 files changed

+274
-6
lines changed

7 files changed

+274
-6
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import { css } from 'emotion'
2+
import { FunctionComponent, createElement } from 'react'
3+
import { nameToColor } from '../../overmind/utils'
4+
import { useOvermind } from '../../overmind'
5+
import * as textStyles from '../../styles/text'
6+
import * as styles from './styles'
7+
8+
const Chart: FunctionComponent = () => {
9+
const { state, actions } = useOvermind()
10+
11+
const chart = state.currentChart
12+
13+
return (
14+
<div className={styles.wrapper}>
15+
{Object.keys(chart.chart).map((key) => (
16+
<div key={key} className={styles.stateItem}>
17+
<div className={styles.stateNameCell}>
18+
<div
19+
className={styles.stateName}
20+
style={{
21+
backgroundColor:
22+
chart.state === key
23+
? nameToColor(chart.path.join('.'))
24+
: null,
25+
}}
26+
>
27+
<span className={textStyles.label}>{key}</span>
28+
</div>
29+
</div>
30+
<div className={styles.stateLineCell}>
31+
<div
32+
className={styles.selectedLine}
33+
style={{
34+
backgroundColor:
35+
chart.state === key
36+
? nameToColor(chart.path.join('.'))
37+
: null,
38+
}}
39+
/>
40+
</div>
41+
{chart.chart[key].entry ? (
42+
<div className={styles.stateNameCell}>
43+
<div className={styles.stateName}>
44+
<span className={textStyles.normal}>
45+
{chart.chart[key].entry}
46+
</span>
47+
</div>
48+
</div>
49+
) : (
50+
<div className={styles.stateLineCell}>
51+
<div
52+
className={styles.selectedLine}
53+
style={{
54+
backgroundColor:
55+
chart.state === key
56+
? nameToColor(chart.path.join('.'))
57+
: null,
58+
}}
59+
/>
60+
</div>
61+
)}
62+
<div className={styles.stateLineCell}>
63+
<div
64+
className={styles.selectedLine}
65+
style={{
66+
backgroundColor:
67+
chart.state === key
68+
? nameToColor(chart.path.join('.'))
69+
: null,
70+
}}
71+
/>
72+
</div>
73+
<div
74+
className={styles.onCell}
75+
style={{
76+
borderColor:
77+
chart.state === key ? nameToColor(chart.path.join('.')) : null,
78+
}}
79+
>
80+
{Object.keys(chart.chart[key].on).map((onKey) => (
81+
<div
82+
key={onKey}
83+
className={css(
84+
styles.onName,
85+
chart.actions[onKey] && styles.activeAction
86+
)}
87+
>
88+
<span className={textStyles.normal}>{onKey}</span>
89+
</div>
90+
))}
91+
</div>
92+
{chart.chart[key].exit ? (
93+
<div className={styles.stateLineCell}>
94+
<div
95+
className={styles.selectedLine}
96+
style={{
97+
backgroundColor:
98+
chart.state === key
99+
? nameToColor(chart.path.join('.'))
100+
: null,
101+
}}
102+
/>
103+
</div>
104+
) : (
105+
<div className={styles.stateLineCell} />
106+
)}
107+
{chart.chart[key].exit ? (
108+
<div className={styles.stateNameCell}>
109+
<div className={styles.stateName}>
110+
<span className={textStyles.normal}>
111+
{chart.chart[key].exit}
112+
</span>
113+
</div>
114+
</div>
115+
) : (
116+
<div className={styles.stateLineCell} />
117+
)}
118+
</div>
119+
))}
120+
</div>
121+
)
122+
}
123+
124+
export default Chart
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { css } from 'emotion'
2+
3+
import { colors } from '../../theme'
4+
5+
export const wrapper = css({
6+
position: 'relative',
7+
display: 'table',
8+
margin: '2rem',
9+
borderSpacing: '0 0.25rem',
10+
})
11+
12+
export const stateItem = css({
13+
display: 'table-row',
14+
})
15+
16+
export const stateNameCell = css({
17+
display: 'table-cell',
18+
padding: '0.5rem 0 ',
19+
})
20+
21+
export const stateLineCell = css({
22+
position: 'relative',
23+
display: 'table-cell',
24+
width: '1rem',
25+
})
26+
27+
export const stateName = css({
28+
borderRadius: 3,
29+
padding: '0.5rem',
30+
boxSizing: 'border-box',
31+
width: '100%',
32+
textAlign: 'center',
33+
backgroundColor: colors.foreground,
34+
})
35+
36+
export const selectedLine = css({
37+
position: 'absolute',
38+
height: 2,
39+
backgroundColor: colors.foreground,
40+
width: '100%',
41+
top: '2rem',
42+
})
43+
44+
export const entryCell = css({
45+
position: 'relative',
46+
display: 'table-cell',
47+
width: '1rem',
48+
})
49+
50+
export const onName = css({
51+
borderRadius: 3,
52+
padding: '0.5rem',
53+
margin: '0.25rem 0',
54+
boxSizing: 'border-box',
55+
width: '100%',
56+
textAlign: 'center',
57+
backgroundColor: colors.foreground,
58+
opacity: 0.5,
59+
})
60+
61+
export const activeAction = css({
62+
opacity: 1,
63+
})
64+
65+
export const onCell = css({
66+
display: 'table-cell',
67+
padding: '0.5rem ',
68+
border: '2px solid ' + colors.foreground,
69+
borderRadius: 3,
70+
})

packages/node_modules/overmind-devtools-client/src/components/Charts/index.tsx

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,56 @@
1+
import { css } from 'emotion'
12
import { FunctionComponent, createElement } from 'react'
3+
import { nameToColor } from '../../overmind/utils'
24
import SplitPane from 'react-split-pane'
35

46
import { useOvermind } from '../../overmind'
57
import * as textStyles from '../../styles/text'
68
import * as styles from './styles'
9+
import Chart from '../Chart'
710

811
const Charts: FunctionComponent = () => {
912
const { state, actions } = useOvermind()
13+
const chartKeys = Object.keys(state.currentApp.charts)
1014

1115
return (
1216
<div className={styles.wrapper}>
13-
{state.currentAction ? (
17+
{state.currentChart ? (
1418
<div className={styles.columns}>
1519
<SplitPane
1620
split="vertical"
1721
minSize={100}
18-
defaultSize={state.actionsSplitSize}
19-
onChange={(size) => actions.updateActionsSplitSize(size)}
22+
defaultSize={state.chartsSplitSize}
23+
onChange={(size) => actions.updateChartsSplitSize(size)}
2024
>
21-
<div>List</div>
22-
<div>Chart</div>
25+
<div className={styles.listWrapper}>
26+
{chartKeys.map((path) => {
27+
return (
28+
<div
29+
className={css(
30+
styles.chartItem,
31+
state.currentApp.currentChartId === path &&
32+
styles.selected
33+
)}
34+
key={path}
35+
onClick={() => actions.selectChart(path)}
36+
>
37+
<span
38+
className={styles.chartColor}
39+
style={{
40+
backgroundColor: nameToColor(path),
41+
}}
42+
/>
43+
<span className={textStyles.denseNormal}>{path}</span>
44+
</div>
45+
)
46+
})}
47+
</div>
48+
<Chart />
2349
</SplitPane>
2450
</div>
2551
) : (
2652
<div className={styles.centerWrapper}>
27-
<span className={textStyles.header}>no actions triggered...</span>
53+
<span className={textStyles.header}>no charts defined...</span>
2854
</div>
2955
)}
3056
</div>

packages/node_modules/overmind-devtools-client/src/components/Charts/styles.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ export const wrapper = css({
99
height: '100%',
1010
})
1111

12+
export const listWrapper = css({
13+
padding: '1rem',
14+
})
15+
1216
export const centerWrapper = css({
1317
display: 'flex',
1418
height: '100%',
@@ -27,3 +31,29 @@ export const columns = css({
2731
flex: 1,
2832
position: 'relative',
2933
})
34+
35+
export const chartItem = css({
36+
position: 'relative',
37+
display: 'flex',
38+
alignItems: 'center',
39+
padding: '0.1rem',
40+
borderRadius: 3,
41+
cursor: 'pointer',
42+
':hover': {
43+
backgroundColor: colors.foreground,
44+
},
45+
marginBottom: 2,
46+
})
47+
48+
export const selected = css({
49+
backgroundColor: colors.foreground,
50+
fontWeight: 'bold',
51+
})
52+
53+
export const chartColor = css({
54+
borderRadius: 2,
55+
flex: '0 0 10px',
56+
height: 10,
57+
marginLeft: 10,
58+
marginRight: 10,
59+
})

packages/node_modules/overmind-devtools-client/src/overmind/actions.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,20 @@ export const updateActionsSplitSize: Operator<number> = pipe(
226226
})
227227
)
228228

229+
export const updateChartsSplitSize: Operator<number> = pipe(
230+
debounce(200),
231+
mutate(async ({ state, effects }, size) => {
232+
state.chartsSplitSize = size
233+
234+
await effects.storage.set('devtool.chartsSplitSize', size)
235+
})
236+
)
237+
229238
export const clearActions: Action = ({ state }) => {
230239
state.currentApp.actionsList = []
231240
state.currentApp.currentActionId = null
232241
}
242+
243+
export const selectChart: Action<string> = ({ state }, id) => {
244+
state.currentApp.currentChartId = id
245+
}

packages/node_modules/overmind-devtools-client/src/overmind/state.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type State = {
4343
currentOperatorsByPath: Derive<State, OperatorsByPath[]>
4444
isShowingRuntime: boolean
4545
actionsSplitSize: number
46+
chartsSplitSize: number
4647
}
4748

4849
const state: State = {
@@ -52,6 +53,7 @@ const state: State = {
5253
showApps: false,
5354
currentAppName: null,
5455
actionsSplitSize: 200,
56+
chartsSplitSize: 200,
5557
port: 3031,
5658
apps: {},
5759
newPortValue: '',

packages/node_modules/overmind-devtools-client/src/overmind/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,4 +404,7 @@ export type Chart = {
404404
}
405405
}
406406
}
407+
actions: {
408+
[name: string]: boolean
409+
}
407410
}

0 commit comments

Comments
 (0)