Skip to content

Commit

Permalink
experimental DAG ui
Browse files Browse the repository at this point in the history
  • Loading branch information
johanhenriksson committed Mar 1, 2021
1 parent ae874fa commit 8cf16ea
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 5 deletions.
5 changes: 5 additions & 0 deletions cloud/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cloud/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@types/react-router-dom": "^5.1.5",
"@types/react-syntax-highlighter": "^11.0.4",
"@types/redux-logger": "^3.0.7",
"dagre-d3-react": "^0.2.4",
"eslint-webpack-plugin": "^2.4.3",
"lodash": "^4.17.19",
"polished": "^3.6.3",
Expand Down
27 changes: 25 additions & 2 deletions cloud/src/components/task/TaskState.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,41 @@
import React from 'react'
import { ContentBlock, Code } from '../ui'
import TaskGraph from './task-ui/TaskGraph'

type Props = {
state?: object
state: State
}

type State = {
ui?: TaskComponent[]
[key: string]: any
}

type TaskComponent = {
component: string
path: string
}

function renderComponent(def: TaskComponent, state: State) {
switch(def.component) {
case 'ui.cowait.io/task-graph':
return <TaskGraph graph={state[def.path]} />
default:
throw new Error(`Unknown Task Component ${def.component}`)
}
}

export const TaskState: React.FC<Props> = ({ state }) => {
if (!state) {
return null
}
const components = state.ui || []

return <ContentBlock>
<h4>State</h4>
<Code language="json">{JSON.stringify(state, null, 4)}</Code>
{components.map(c => renderComponent(c, state))}
</ContentBlock>
// <Code language="json">{JSON.stringify(state, null, 4)}</Code>
}

export default TaskState
1 change: 1 addition & 0 deletions cloud/src/components/task/styled/Log.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const LogOutput = styled.pre<Props>`
font-family: ${p => p.theme.fonts.monospace};
color: ${p => p.theme.colors.text.secondary};
line-height: 1.25em;
max-width: 100vh;
`

export const LogContainer = styled.div<Props>`
Expand Down
105 changes: 105 additions & 0 deletions cloud/src/components/task/task-ui/TaskGraph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import _ from 'lodash'
import React from 'react'
import { useSelector } from 'react-redux'
import { RootState } from '../../../store'
import DagreGraph from 'dagre-d3-react'
import styled from 'styled-components'

const DagStyle = styled.div`
.nodes {
fill: darkgray;
cursor: pointer;
rx: 0.5em;
}
.nodes .work {
fill: #82b332;
}
.nodes .done {
fill: green;
}
.nodes .fail {
fill: red;
}
.nodes .stop {
fill: orange;
}
.nodes text {
fill: white;
}
path {
stroke: white;
fill: white;
stroke-width: 3px;
}
`

type Props = {
graph: TaskGraph
}

type TaskGraph = {
[id: string]: TaskNode,
}

type TaskNode = {
id: string
task: string
depends_on: string[]
task_id?: string
}

type d3Link = {
source: string
target: string
class?: string
label?: string
config?: object
}

export const TaskGraph: React.FC<Props> = ({ graph }) => {
const tasks = useSelector((state: RootState) => state.tasks.items)
let nodes = _.map(graph, node => {
if (node.task_id && tasks[node.task_id]) {
let task = tasks[node.task_id]
return {
id: node.id,
label: task.id,
class: task.status,
}
}
return {
id: node.id,
label: node.task,
class: 'pending',
}
})
let links: d3Link[] = []
_.each(graph, node => {
_.each(node.depends_on, edge => {
links.push({
source: edge,
target: node.id,
})
})
})
return <DagStyle>
<DagreGraph
nodes={nodes}
links={links}
config={{
rankdir: 'LR',
align: 'UL',
ranker: 'tight-tree'
}}
width='100%'
height='500'
animate={100}
shape='rect'
zoomable
onNodeClick={(e: any) => console.log(e)}
/>
</DagStyle>
}

export default TaskGraph
16 changes: 13 additions & 3 deletions cowait/tasks/graph/graph_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@


class GraphTask(Task):
def init(self) -> dict:
return {
'ui': [
{
'component': 'ui.cowait.io/task-graph',
'path': 'graph',
},
]
}

async def define(self, graph, **inputs):
# this is where you would define your graph nodes
# to create a dag, override this function in a subclass
Expand All @@ -22,12 +32,12 @@ async def send_state():
for node in graph.nodes:
task = node_tasks.get(node, None)
state[node.id] = {
'id': node.id,
'id': str(node.id),
'task': node.task if not issubclass(node.task, Task) else node.task.__module__,
'depends_on': [edge.id for edge in node.edges],
'depends_on': [str(edge.id) for edge in node.edges],
'task_id': None if not task else task.id,
}
await self.set_state(state)
await self.set_state({'graph': state})

await send_state()

Expand Down

0 comments on commit 8cf16ea

Please sign in to comment.