Skip to content

Commit 6c1d314

Browse files
feat(overmind-devtools): components tab
1 parent 2fbdae7 commit 6c1d314

File tree

18 files changed

+280
-14
lines changed

18 files changed

+280
-14
lines changed

package-lock.json

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/demos/todomvc/src/app/actions.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ export default (action: Action) => ({
1111
addTodo: action<React.FormEvent>()
1212
.do(helpers.preventEventDefault)
1313
.mutation(mutations.addTodo)
14-
.mutation(mutations.clearNewTodoTitle),
14+
.mutation(mutations.clearNewTodoTitle)
15+
.filter((_, { state }) => state.todos.length > 2)
16+
.map(() => Promise.resolve())
17+
.mutation((_, state) => (state.todos[2].title = 'mihihihi')),
1518
toggleCompleted: action<Todo>().mutation(mutations.toggleCompleted),
1619
})

packages/demos/todomvc/src/app/mutations.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { State, Todo } from './state'
22

3+
let nextTodoId = 0
4+
35
export const setNewTodoTitle = (value: string, state: State) =>
46
(state.newTodoTitle = value)
57

68
export const addTodo = (_, state: State) =>
79
state.todos.unshift({
10+
id: String(nextTodoId++),
811
title: state.newTodoTitle,
912
completed: false,
1013
})

packages/demos/todomvc/src/app/state.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export type Todo = {
2+
id: string
23
title: string
34
completed: boolean
45
}

packages/demos/todomvc/src/components/Todos/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import Todo from '../Todo'
55

66
const Todos: React.SFC<Connect> = ({ appState }) => (
77
<List>
8-
{appState.todos.map((todo) => <Todo key={todo.title} todo={todo} />)}
8+
{appState.todos.map(
9+
(todo, index) =>
10+
console.log('todo ID', todo.id) || <Todo key={todo.id} todo={todo} />
11+
)}
912
</List>
1013
)
1114

packages/node_modules/action-chain/src/ActionBase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export function actionBaseFactory<
107107

108108
function produceResult(currentValue) {
109109
if (currentValue instanceof StopExecution) {
110-
return currentValue.value
110+
return currentValue
111111
}
112112

113113
const context = actionChain.getContext(executionContextWithPath)

packages/node_modules/overmind-devtools/src/client/app/mutations.ts

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ export const addNewApp = (_, state: State) =>
2424
port: state.newPortValue,
2525
messages: [],
2626
state: {},
27+
components: {},
28+
flushes: [
29+
{
30+
mutations: [],
31+
components: [],
32+
},
33+
],
2734
})
2835

2936
export const resetNewPortValue = (_, state: State) => (state.newPortValue = '')
@@ -60,14 +67,58 @@ export const performMutationsByMessageType = (
6067
) => {
6168
message.message.forEach((clientMessage) => {
6269
switch (clientMessage.type) {
63-
case 'init':
70+
case 'init': {
6471
state.apps[message.port].state = clientMessage.data.state
6572
break
66-
case 'flush':
73+
}
74+
case 'flush': {
75+
state.apps[message.port].flushes.push({
76+
mutations: clientMessage.data.mutations,
77+
components: [],
78+
})
6779
clientMessage.data.mutations.forEach(
6880
runMutation(state.apps[message.port].state)
6981
)
7082
break
83+
}
84+
case 'component:add': {
85+
const id = `${clientMessage.data.componentId}_${
86+
clientMessage.data.componentInstanceId
87+
}`
88+
89+
state.apps[message.port].components[id] = {
90+
id,
91+
isMounted: true,
92+
updateCount: 0,
93+
...clientMessage.data,
94+
}
95+
state.apps[message.port].flushes[
96+
state.apps[message.port].flushes.length - 1
97+
].components.push(id)
98+
break
99+
}
100+
case 'component:update': {
101+
const id = `${clientMessage.data.componentId}_${
102+
clientMessage.data.componentInstanceId
103+
}`
104+
105+
state.apps[message.port].components[id].paths = clientMessage.data.paths
106+
state.apps[message.port].components[id].updateCount++
107+
state.apps[message.port].flushes[
108+
state.apps[message.port].flushes.length - 1
109+
].components.push(id)
110+
break
111+
}
112+
case 'component:remove':
113+
const id = `${clientMessage.data.componentId}_${
114+
clientMessage.data.componentInstanceId
115+
}`
116+
117+
state.apps[message.port].components[id].isMounted = false
118+
state.apps[message.port].flushes[
119+
state.apps[message.port].flushes.length - 1
120+
].components.push(id)
121+
break
71122
}
72123
})
73124
}

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,33 @@
1+
export type Mutation = {
2+
args: any[]
3+
method: string
4+
path: string
5+
}
6+
7+
export type Flush = {
8+
mutations: Mutation[]
9+
components: string[]
10+
}
11+
12+
export type Component = {
13+
id: string
14+
name: string
15+
isMounted: boolean
16+
paths: string[]
17+
updateCount: number
18+
}
19+
20+
export type Components = {
21+
[id: string]: Component
22+
}
23+
124
export type App = {
225
name: string
326
port: string
427
messages: AppMessage[]
528
state: object
29+
components: Components
30+
flushes: Flush[]
631
}
732

833
export type Apps = {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import styled from '../../styled-components'
2+
3+
export const Wrapper = styled.div`
4+
display: flex;
5+
flex-direction: column;
6+
padding: ${({ theme }) => theme.padding.normal};
7+
`
8+
9+
export const Panels = styled.div`
10+
display: flex;
11+
justify-content: space-around;
12+
`
13+
14+
export const Panel = styled.div`
15+
padding: ${({ theme }) => theme.padding.smaller};
16+
`
Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,70 @@
11
import * as React from 'react'
22
import { connect, Connect } from '../../app'
3+
import Text from '../common/Text'
4+
import Table, { Row, Cell } from '../common/Table'
5+
import Pill from '../common/Pill'
6+
import { Wrapper, Panels, Panel } from './elements'
37

4-
const Components: React.SFC<Connect> = () => <h1>Components</h1>
8+
const Components: React.SFC<Connect> = ({ appState }) => {
9+
const components = appState.apps[appState.currentPort].components
10+
const keys = Object.keys(components)
11+
const mountedKeys = keys.filter((key) => components[key].isMounted)
12+
const updatesCount = keys.reduce(
13+
(aggr, key) => aggr + components[key].updateCount,
14+
0
15+
)
16+
const statePathsCount = keys.reduce(
17+
(aggr, key) => aggr + components[key].paths.length,
18+
0
19+
)
20+
return (
21+
<Wrapper>
22+
<Panels>
23+
<Panel>
24+
<Text variant="label" dense>
25+
connected
26+
</Text>
27+
<Text variant="header" dense>
28+
{mountedKeys.length}
29+
</Text>
30+
</Panel>
31+
<Panel>
32+
<Text variant="label" dense>
33+
updates
34+
</Text>
35+
<Text variant="header" dense>
36+
{updatesCount}
37+
</Text>
38+
</Panel>
39+
<Panel>
40+
<Text variant="label" dense>
41+
values watched
42+
</Text>
43+
<Text variant="header" dense>
44+
{statePathsCount}
45+
</Text>
46+
</Panel>
47+
</Panels>
48+
<Table headers={['name', 'updates', 'values']}>
49+
{mountedKeys.map((key) => {
50+
const component = components[key]
51+
return (
52+
<Row key={component.id}>
53+
<Cell>{component.name}</Cell>
54+
<Cell>
55+
<Text variant="title" dense>
56+
{component.updateCount}
57+
</Text>
58+
</Cell>
59+
<Cell>
60+
{component.paths.map((path) => <Pill key={path}>{path}</Pill>)}
61+
</Cell>
62+
</Row>
63+
)
64+
})}
65+
</Table>
66+
</Wrapper>
67+
)
68+
}
569

670
export default connect(Components)

0 commit comments

Comments
 (0)