Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

graph view and central data store #1108

Merged
merged 86 commits into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
ac271aa
graph view experiment 1: get data
oliver-sanders Aug 5, 2022
176cf14
graph view experiment 2: construct a global tree
oliver-sanders Aug 19, 2022
d3b2ca2
graph: implement the graph view
oliver-sanders Aug 22, 2022
18b1c18
store: refactor the store to eliminate cicrular references
oliver-sanders Sep 15, 2022
9edf7fe
graph node: contstrain task node to 100x100 box
oliver-sanders Sep 27, 2022
fbcd0e3
graph: auto-refresh
oliver-sanders Sep 27, 2022
5d5e0d7
graph node: make tasks clickable
oliver-sanders Sep 27, 2022
8377270
graph: fix reactivity issues
oliver-sanders Sep 27, 2022
5c4fafd
graph: add transpose option
oliver-sanders Sep 28, 2022
d8fdcfa
graph: add centre graph control
oliver-sanders Sep 28, 2022
c940d82
task: re-implement task icon
oliver-sanders Sep 29, 2022
817cf92
tests: add component tests for task modifiers
oliver-sanders Sep 29, 2022
b664721
workflow service: run global callback by default
oliver-sanders Sep 29, 2022
92f648c
task: switch to new task component
oliver-sanders Oct 3, 2022
6ee0155
store: add family support to the tree
oliver-sanders Oct 4, 2022
282dc1d
workflow service: fix query merging
oliver-sanders Oct 5, 2022
7d15851
tree: fix filtering & job-details nodes
oliver-sanders Oct 6, 2022
769470d
tree: only show workflow nodes when needed
oliver-sanders Oct 12, 2022
e8bb6ab
tree: handle cycle point "root" nodes correctly
oliver-sanders Oct 12, 2022
712c862
table: upgrade to run off of the central store
oliver-sanders Oct 12, 2022
4eb2e4f
update view icon for graph view
oliver-sanders Oct 12, 2022
36f399b
graph: add standalone graph view to the router
oliver-sanders Oct 12, 2022
372eea5
store: avoid duplicated nested workflow nodes
oliver-sanders Oct 13, 2022
801ac43
gscan: convert to run off of the central data store
oliver-sanders Oct 13, 2022
3711326
dashboard: convert to run off of the central data store
oliver-sanders Oct 13, 2022
8b0a955
sort cycles and jobs in reverse order
oliver-sanders Oct 26, 2022
6f85bda
task: ensure the task icons are clickable when waiting
oliver-sanders Oct 26, 2022
f3b1d29
gscan: fix sorting & filtering
oliver-sanders Oct 26, 2022
efa99c7
toolbar: fix data source
oliver-sanders Oct 13, 2022
b7be28f
aotf: fix node data
oliver-sanders Oct 27, 2022
07a0acc
tree: fix auto expansion
oliver-sanders Oct 27, 2022
6645669
store: housekeep the store for workflow subscriptions
oliver-sanders Oct 27, 2022
5a054de
task: delete unused styles and re-calibrate progress
oliver-sanders Oct 28, 2022
7c23fe2
graph: prevent Nanageddon
oliver-sanders Oct 28, 2022
ad9a6dc
graph: prevent SVG path error messages
oliver-sanders Oct 28, 2022
b730433
graph: test graph-utils
oliver-sanders Oct 28, 2022
e5ff894
tree: re-instate task progress animations
oliver-sanders Oct 28, 2022
c61be9c
task: fix progress icon in webkit/safari
oliver-sanders Oct 28, 2022
cf8a682
graph node: implement progress icon & test
oliver-sanders Oct 31, 2022
2d46207
graph node: only show the first N jobs
oliver-sanders Oct 31, 2022
51e41d4
graph: protect against undefined bboxes
oliver-sanders Oct 31, 2022
3c88f3d
graphql: only stripNull for updated Deltas
oliver-sanders Oct 31, 2022
fb3bf1d
tree: fix missing tasks on root family
oliver-sanders Oct 31, 2022
69b8bb5
graphql: remove unnecessary sorting
oliver-sanders Oct 31, 2022
b5ba5da
table: convert to run on central data store
oliver-sanders Oct 31, 2022
e1a9e06
graph: solve floating ghost node problem
oliver-sanders Nov 1, 2022
e114e95
graph: add toolbar and manual refresh
oliver-sanders Nov 1, 2022
4eafc93
tree: fix occasional traceback
oliver-sanders Nov 1, 2022
7391886
store: remove old stores, callbacks and fix tests
oliver-sanders Nov 1, 2022
fddd54c
tree: re-implement the cyclePointsOrderDesc configuration
oliver-sanders Nov 2, 2022
6724223
tests: fix offline data
oliver-sanders Nov 3, 2022
346beb6
tree: fix custom outputs and support messages
oliver-sanders Nov 3, 2022
391ad39
tests/e2e: fix tests after data store change
oliver-sanders Nov 4, 2022
88b05ef
tests/unit: fix alert test
oliver-sanders Nov 4, 2022
791efb1
table: fix table view post-filter change
oliver-sanders Nov 4, 2022
a7a655c
graph: fix edges on Firefox
oliver-sanders Nov 7, 2022
932fd77
tree: fix cycle point status
oliver-sanders Nov 7, 2022
00a83d6
aotf: fix node description
oliver-sanders Nov 7, 2022
16ec361
graphql: remove unused fields from queries
oliver-sanders Nov 7, 2022
94e2a55
tree: sort families before tasks
oliver-sanders Nov 7, 2022
c784f41
tree: fix erroneous filter issue
oliver-sanders Nov 7, 2022
8a73323
views: simplify access of job startedTime
oliver-sanders Nov 7, 2022
ebe38c8
tidy: remove console logs, commented code, etc
oliver-sanders Nov 7, 2022
b574a11
mutation: remove task icon from mutation form
oliver-sanders Nov 8, 2022
0e493af
task: make the queued modifier more prominent & add expired state
oliver-sanders Nov 8, 2022
1cf7973
store: tidy
oliver-sanders Nov 8, 2022
2cc7e53
misc: tidy
oliver-sanders Nov 8, 2022
3ad9edc
store: centralise tree walking functions
oliver-sanders Nov 8, 2022
08cbec6
graph: Apply suggestions from code review
oliver-sanders Nov 14, 2022
b43050e
guide: fix task icons
oliver-sanders Nov 14, 2022
c2a134f
graph node: re-jig item sizes
oliver-sanders Nov 14, 2022
3927ea0
store: fix subscription merging issue
oliver-sanders Nov 15, 2022
3e029be
store: fix edge removal
oliver-sanders Nov 15, 2022
196a45e
graph: prevent NaNageddon
oliver-sanders Nov 15, 2022
017873d
graph: fix scrollbars
oliver-sanders Nov 15, 2022
f95e3d5
store: fix merging of updates
oliver-sanders Nov 16, 2022
e26d672
graph: improve stability with large graphs
oliver-sanders Nov 16, 2022
ccc69dc
graph: package wasm file
oliver-sanders Nov 17, 2022
ac3bf77
graph: add offline data and first e2e test
oliver-sanders Nov 17, 2022
ac2e835
graph: allow display of edgeless graphs
oliver-sanders Nov 18, 2022
62ab67a
TreeItem: small fix
oliver-sanders Nov 21, 2022
51d67cf
changelog: graph view
oliver-sanders Nov 21, 2022
599e2cd
actions: upload cypress screenshots as artefacts
oliver-sanders Nov 23, 2022
1a0f1b8
graph: fix e2e test on Firefox
oliver-sanders Nov 23, 2022
fbe64e6
Update src/components/cylc/GraphNode.vue
oliver-sanders Nov 23, 2022
3d28f92
Apply suggestions from code review
oliver-sanders Nov 24, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ jobs:
env:
CYPRESS_baseUrl: http://localhost:8080/

- uses: actions/upload-artifact@v2
if: failure()
with:
name: cypress-screenshots
path: tests/e2e/screenshots

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
Expand Down
11 changes: 11 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,22 @@ ones in. -->

### Enhancements

[#1108](https://github.com/cylc/cylc-ui/pull/1108) -
Graph view: A new view which displays tasks and dependencies as a graph (like
the Cylc 7 graph view).

[#1108](https://github.com/cylc/cylc-ui/pull/1108) -
Tree view: Task messages are now shown along with outputs.

[#1124](https://github.com/cylc/cylc-ui/pull/1075) - Table view: More options
for number of tasks per page.

### Fixes

[#1108](https://github.com/cylc/cylc-ui/pull/1108) -
Tree view: Task outputs are now correctly associated with the jobs that created
them.

[#1075](https://github.com/cylc/cylc-ui/pull/1075) - Reverse default sort order
of the table view so it matches the tree view.

Expand Down
214 changes: 214 additions & 0 deletions cypress/component/cylc-graph-node.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/**
* Copyright (C) NIWA & British Crown (Met Office) & Contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { TaskStateUserOrder, JobStates } from '@/model/TaskState.model'
import GraphNode from '@/components/cylc/GraphNode'
import { Tokens } from '@/utils/uid'
import {
MEAN_ELAPSED_TIME,
getStartTime
} from './utils/task'

function makeTaskNode (id, state, jobStates) {
const tokens = new Tokens(id)
const jobs = []
let itt = 1
let job
for (const jobState of jobStates) {
const jobTokens = tokens.clone({ job: `0${itt}` })
job = {
id: jobTokens.id,
name: jobTokens.job,
node: {
state: jobState
}
}
if (jobState === 'running') { // TODO constant
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment is at best cryptic, at worst suggests somthing else you want to do.

job.node.startedTime = getStartTime(50)
}
jobs.push(job)
itt++
}

const task = {
id: tokens.id,
name: tokens.task,
tokens,
node: {
cyclePoint: tokens.cycle,
isHeld: false,
state,
task: {
meanElapsedTime: MEAN_ELAPSED_TIME
}
}
}

return [task, jobs]
}

const GraphNodeSVG = {
template: `
<svg id="app" class="job_theme--default" width="100%" height="100%">
<GraphNode :task="task" :jobs="jobs" :maxJobs="maxJobs" />
</svg>
`,
props: {
task: {
required: true
},
jobs: {
required: true
},
maxJobs: {
default: 6,
required: false
}
},
components: { GraphNode }
}

describe('graph node component', () => {
it('Renders with multiple jobs', () => {
const [task, jobs] = makeTaskNode(
'~a/b//20000101T0000Z/task_name',
'running',
['running', 'failed', 'failed', 'failed']
)
cy.mount(
GraphNodeSVG,
{
propsData: { task, jobs }
}
)
// there should be 4 jobs
cy.get('.c-graph-node:last .jobs')
.children()
.should('have.length', 4)
// there shouldn't be a job overflow indicator
cy.get('.c-graph-node:last .job-overflow').should('not.exist')

cy.get('.c-graph-node').last().parent().screenshot(
`graph-node-multiple-jobs`,
{ overwrite: true, disableTimersAndAnimations: false }
)
})

it('Hides excessive numbers of jobs', () => {
const [task, jobs] = makeTaskNode(
'~a/b//20000101T0000Z/task_name',
'running',
['running', 'failed', 'failed', 'failed', 'failed', 'failed']
)
cy.mount(
GraphNodeSVG,
{
propsData: { task, jobs, maxJobs: 4 }
}
)
// there should be <maxJobs> jobs
cy.get('.c-graph-node:last .jobs')
.children()
.should('have.length', 4)
// there should be a job overflow indicator with the number of overflow jobs
cy.get('.c-graph-node:last .job-overflow')
.should('exist')
.get('text')
.contains('+2')

cy.get('.c-graph-node').last().parent().screenshot(
`graph-node-overflow-jobs`,
{ overwrite: true, disableTimersAndAnimations: false }
)
})

it('Renders for each task state', () => {
let task
let jobs
let jobStates
for (const state of TaskStateUserOrder) {
jobStates = []
for (const jobState of JobStates) {
if (state.name === jobState.name) {
jobStates = [state.name]
break
}
}
[task, jobs] = makeTaskNode(
`~a/b//20000101T0000Z/${state.name}`,
state.name,
jobStates
)
console.log(jobs)
cy.mount(GraphNodeSVG, { propsData: { task, jobs } })
cy.get('.c-graph-node').last().parent().screenshot(
`graph-node-${state.name}`,
{ overwrite: true, disableTimersAndAnimations: false }
)
}
})

it('Renders for each task modifier', () => {
let task
let jobs
for (const modifier of ['isHeld', 'isQueued', 'isRunahead']) {
[task, jobs] = makeTaskNode(
`~a/b//20000101T0000Z/${modifier}`,
'waiting',
[]
)
task.node[modifier] = true
cy.mount(GraphNodeSVG, { propsData: { task, jobs } })
cy.get('.c-graph-node').last().parent().screenshot(
`graph-node-${modifier}`,
{ overwrite: true, disableTimersAndAnimations: false }
)
}
})

it('Animates task progress', () => {
let task
let jobs
for (const percent of [0, 25, 50, 75, 100]) {
[task, jobs] = makeTaskNode(
`~a/b//${percent}/running`,
'running',
['running']
)
jobs[0].node.startedTime = getStartTime(percent)
cy.mount(GraphNodeSVG, { propsData: { task, jobs } })
cy.get('.c-graph-node').last().parent().screenshot(
`graph-node-running-${percent}`,
{ overwrite: true, disableTimersAndAnimations: false }
)
// check the progress animation
.get('.c8-task:last .status > .progress')
// the animation duration should be equal to the expected job duration
.should('have.css', 'animation-duration', `${MEAN_ELAPSED_TIME}s`)
// the offset should be set to the "percent" of the expected job duration
.should('have.css', 'animation-delay')
.and('match', /([\d\.]+)s/) // NOTE the delay should be negative
.then((number) => {
// convert the duration string into a number that we can test
cy.wrap(Number(number.match(/([\d\.]+)s/)[1]))
// ensure this number is ±5 from the expected value
// (give it a little bit of margin to allow for timing error)
.should('closeTo', MEAN_ELAPSED_TIME * (percent / 100), 5)
})
}
})
})
Loading