Skip to content

Commit f342f2b

Browse files
feat(overmind-devtools): improve path and flush indication
1 parent b70ae62 commit f342f2b

File tree

17 files changed

+285
-154
lines changed

17 files changed

+285
-154
lines changed

packages/node_modules/overmind-devtools/src/components/Action/index.tsx

Lines changed: 104 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,116 @@
1-
import { createElement, FunctionComponent } from 'react'
1+
import { createElement, FunctionComponent, Fragment } from 'react'
22
import { useOvermind } from '../../overmind'
33
import * as styles from './styles'
44
import ActionOperator from '../ActionOperator'
5-
import Flush from '../ActionFlush'
6-
import { getActionId, getOperatorId } from '../../overmind/utils'
5+
import { getOperatorId, nameToColor } from '../../overmind/utils'
6+
import { Operator } from '../../overmind/types'
77

8+
type OperatorsByPath = {
9+
path: string
10+
operators: Operator[]
11+
children: OperatorsByPath[]
12+
value: any
13+
}
14+
15+
// TODO: Remove flush by action id?
816
const Action: FunctionComponent = () => {
917
const { state } = useOvermind()
10-
const flushReference =
11-
state.currentApp.flushByActionId[getActionId(state.currentAction)]
12-
const flush =
13-
flushReference && state.currentApp.flushes[flushReference.flushId]
18+
19+
const operators = Object.keys(state.currentAction.operators)
20+
.sort()
21+
.map((operatorId) => state.currentAction.operators[operatorId])
22+
const operatorsByPath = operators.reduce(
23+
(aggr, operator): OperatorsByPath[] => {
24+
let currentValue = state.currentAction.value
25+
const traversePath = operator.path.slice()
26+
traversePath.unshift('')
27+
traversePath.reduce((children, key, index) => {
28+
let child = children.reduce(
29+
(hit, child) => (child.path === key ? child : hit),
30+
null
31+
)
32+
33+
if (index === traversePath.length - 1) {
34+
if (child && !child.children.length) {
35+
child.operators.push(operator)
36+
} else {
37+
child = {
38+
path: key,
39+
operators: [operator],
40+
children: [],
41+
value: child
42+
? child.operators[child.operators.length - 1].result
43+
: currentValue,
44+
}
45+
children.push(child)
46+
}
47+
} else {
48+
currentValue = child.value
49+
}
50+
51+
return child.children
52+
}, aggr)
53+
54+
return aggr
55+
},
56+
[]
57+
)
58+
function renderOperators(operators: OperatorsByPath[]) {
59+
return operators.map((operatorsByPath, index) => {
60+
return (
61+
<div
62+
key={operatorsByPath.path + index}
63+
className={styles.operatorChildren}
64+
>
65+
{operatorsByPath.path ? (
66+
<div
67+
className={styles.path}
68+
style={{
69+
backgroundColor: nameToColor(operatorsByPath.path),
70+
}}
71+
>
72+
{operatorsByPath.path}
73+
</div>
74+
) : null}
75+
<div className={styles.pathOperators}>
76+
{operatorsByPath.operators.map((operator, index) => {
77+
const flushReference =
78+
state.currentApp.flushByOperatorId[getOperatorId(operator)]
79+
const flush =
80+
flushReference &&
81+
state.currentApp.flushes[flushReference.flushId]
82+
83+
return (
84+
<Fragment key={getOperatorId(operator)}>
85+
<ActionOperator
86+
operator={operator}
87+
flush={flush}
88+
value={
89+
index === 0
90+
? operatorsByPath.value
91+
: operatorsByPath.operators[index - 1].result
92+
}
93+
/>
94+
</Fragment>
95+
)
96+
})}
97+
{operatorsByPath.children.length
98+
? renderOperators(operatorsByPath.children)
99+
: null}
100+
</div>
101+
</div>
102+
)
103+
})
104+
}
105+
106+
console.log(operatorsByPath)
14107

15108
return (
16109
<div className={styles.wrapper}>
17-
{Object.keys(state.currentAction.operators)
18-
.sort()
19-
.map((operatorId, index, keys) => {
20-
const operator = state.currentAction.operators[operatorId]
21-
const prevOperator = state.currentAction.operators[index - 1]
22-
const value =
23-
index === 0 ? state.currentAction.value : prevOperator.result
24-
const flushReference =
25-
state.currentApp.flushByOperatorId[getOperatorId(operator)]
26-
const flush =
27-
flushReference && state.currentApp.flushes[flushReference.flushId]
28-
29-
return (
30-
<div key={operator.actionId + '_' + operator.operatorId}>
31-
<ActionOperator
32-
prevOperator={prevOperator}
33-
operator={operator}
34-
value={value}
35-
operatorIndex={index}
36-
/>
37-
{index === keys.length - 1 &&
38-
state.currentAction.isIntercepted ? (
39-
<div className={styles.breakStyle}>break</div>
40-
) : null}
41-
{flush ? <Flush flush={flush} /> : null}
42-
</div>
43-
)
44-
})}
45-
{!state.currentAction.isRunning && flush ? <Flush flush={flush} /> : null}
110+
{renderOperators(operatorsByPath)}
111+
{state.currentAction.isIntercepted ? (
112+
<div className={styles.breakStyle}>break</div>
113+
) : null}
46114
</div>
47115
)
48116
}

packages/node_modules/overmind-devtools/src/components/Action/styles.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import { css } from 'emotion'
22
import { colors } from '../../theme'
33

44
export const wrapper = css({
5-
marginLeft: '1rem',
6-
paddingTop: '0.5rem',
5+
padding: '1rem',
6+
height: '100%',
7+
overflowY: 'scroll',
8+
boxSizing: 'border-box',
79
})
810

911
export const pipe = css({
@@ -20,3 +22,34 @@ export const breakStyle = css({
2022
padding: '0 0.5rem',
2123
marginBottom: '1rem',
2224
})
25+
26+
export const operatorChildren = css({
27+
display: 'flex',
28+
paddingBottom: '1rem',
29+
'> div:last-child': {
30+
paddingBottom: 0,
31+
},
32+
})
33+
34+
export const path = css({
35+
writingMode: 'vertical-rl',
36+
display: 'flex',
37+
textOrientation: 'upright',
38+
fontSize: 10,
39+
lineHeight: '14px',
40+
padding: '0.25rem 0',
41+
backgroundColor: colors.white2,
42+
borderRadius: 3,
43+
color: colors.dark,
44+
marginRight: '0.5rem',
45+
fontWeight: 'bold',
46+
justifyContent: 'center',
47+
})
48+
49+
export const pathOperators = css({
50+
paddingBottom: '1rem',
51+
flex: 1,
52+
'> :last-child': {
53+
paddingBottom: 0,
54+
},
55+
})

packages/node_modules/overmind-devtools/src/components/ActionFlush/index.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { Flush as FlushType } from '../../overmind/types'
44
import * as actionStyles from '../Action/styles'
55
import * as styles from './styles'
66
import * as textStyles from '../../styles/text'
7-
import Path from '../ActionPath'
87
import { css } from 'emotion'
98
import { FaCode, FaLink } from 'react-icons/fa'
109

@@ -13,13 +12,19 @@ type Props = {
1312
}
1413

1514
const ActionFlush: FunctionComponent<Props> = ({ flush }) => {
16-
const { state, actions } = useOvermind()
15+
const { state } = useOvermind()
1716

1817
return (
19-
<div className={actionStyles.pipe}>
20-
<Path />
21-
<div className={styles.flush}>
22-
<div className={styles.flushHeader}>flush</div>
18+
<div className={styles.flush}>
19+
<div className={styles.flushHeader}>
20+
<span>
21+
{flush.components.length} <FaCode />
22+
</span>
23+
<span>
24+
{flush.derived.length} <FaLink />
25+
</span>
26+
</div>
27+
{flush.components.length || flush.derived.length ? (
2328
<div className={styles.flushBody}>
2429
{flush.components.map((componentId) => (
2530
<div key={componentId}>
@@ -42,7 +47,7 @@ const ActionFlush: FunctionComponent<Props> = ({ flush }) => {
4247
</div>
4348
))}
4449
</div>
45-
</div>
50+
) : null}
4651
</div>
4752
)
4853
}

packages/node_modules/overmind-devtools/src/components/ActionFlush/styles.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,49 @@ import { css } from 'emotion'
22
import { colors } from '../../theme'
33

44
export const flush = css({
5-
flex: 1,
6-
display: 'flex',
7-
flexDirection: 'column',
85
cursor: 'pointer',
6+
backgroundColor: colors.yellow,
7+
borderTopRightRadius: 3,
8+
borderBottomRightRadius: 3,
9+
position: 'relative',
10+
':hover div:nth-child(2)': {
11+
display: 'block',
12+
},
13+
':hover': {
14+
borderBottomRightRadius: 0,
15+
},
916
})
1017

1118
export const flushHeader = css({
1219
display: 'flex',
1320
alignItems: 'center',
14-
borderRadius: 3,
1521
color: colors.dark,
16-
backgroundColor: colors.yellow,
1722
padding: '0 0.5rem',
23+
fontSize: 12,
24+
fontWeight: 'bold',
25+
'> span': {
26+
display: 'flex',
27+
alignItems: 'center',
28+
},
29+
'> span svg': {
30+
marginLeft: 3,
31+
},
32+
'> span:last-child': {
33+
marginLeft: '0.5rem',
34+
},
1835
})
1936

2037
export const flushBody = css({
21-
margin: '0.5rem',
22-
display: 'flex',
38+
position: 'absolute',
39+
top: '100%',
40+
right: 0,
41+
padding: '0.5rem 1rem',
42+
backgroundColor: colors.dark,
43+
borderBottomRightRadius: 3,
44+
display: 'none',
2345
flexWrap: 'wrap',
24-
'> *': {
46+
boxShadow: '0px 10px 13px 0px rgba(0,0,0,0.1)',
47+
'> *:not(:last-child)': {
2548
marginRight: 15,
2649
},
2750
})

packages/node_modules/overmind-devtools/src/components/ActionOperator/index.tsx

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,29 @@ import {
44
EventType,
55
Effect,
66
Mutation,
7+
Flush,
78
} from '../../overmind/types'
89
import ValueInspector from '../ValueInspector'
9-
import Path from '../ActionPath'
1010
import * as styles from './styles'
1111
import * as actionStyles from '../Action/styles'
1212
import * as textStyles from '../../styles/text'
1313
import { css } from 'emotion'
1414
import { colors } from '../../theme'
15+
import ActionFlush from '../ActionFlush'
1516

1617
type Props = {
17-
prevOperator: OperatorType
1818
operator: OperatorType
1919
value: any
20-
operatorIndex: number
20+
flush: Flush
2121
}
2222

2323
const ActionOperator: FunctionComponent<Props> = ({
24-
prevOperator,
2524
operator,
2625
value,
26+
flush,
2727
}) => {
2828
return (
2929
<div className={actionStyles.pipe}>
30-
<Path
31-
visible={
32-
Boolean(prevOperator) &&
33-
Boolean(operator.path.length) &&
34-
prevOperator.path.join('.') !== operator.path.join('.')
35-
}
36-
>
37-
{operator.path.length ? (
38-
<span className={textStyles.hint}>
39-
<b>{operator.path.join('.')}</b>
40-
</span>
41-
) : null}
42-
</Path>
4330
<div className={styles.operator}>
4431
<div className={styles.operatorHeader}>
4532
<span
@@ -51,12 +38,13 @@ const ActionOperator: FunctionComponent<Props> = ({
5138
>
5239
{operator.type}
5340
</span>
54-
{operator.name}
55-
{value === undefined ? null : (
56-
<div className={styles.value}>
41+
<span className={styles.operatorName}>{operator.name}</span>
42+
<div className={styles.value}>
43+
{value === undefined ? null : (
5744
<ValueInspector value={value} small />
58-
</div>
59-
)}
45+
)}
46+
</div>
47+
{flush ? <ActionFlush flush={flush} /> : null}
6048
</div>
6149
<div
6250
className={styles.operatorBody}

packages/node_modules/overmind-devtools/src/components/ActionOperator/styles.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ export const operatorType = css({
2121
padding: '0 0.5rem',
2222
borderTopLeftRadius: 3,
2323
borderBottomLeftRadius: 3,
24-
marginRight: '0.5rem',
24+
fontSize: 14,
25+
})
26+
27+
export const operatorName = css({
28+
marginLeft: '0.5rem',
2529
})
2630

2731
export const notVisible = css({

0 commit comments

Comments
 (0)