-
Notifications
You must be signed in to change notification settings - Fork 27
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
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 176cf14
graph view experiment 2: construct a global tree
oliver-sanders d3b2ca2
graph: implement the graph view
oliver-sanders 18b1c18
store: refactor the store to eliminate cicrular references
oliver-sanders 9edf7fe
graph node: contstrain task node to 100x100 box
oliver-sanders fbcd0e3
graph: auto-refresh
oliver-sanders 5d5e0d7
graph node: make tasks clickable
oliver-sanders 8377270
graph: fix reactivity issues
oliver-sanders 5c4fafd
graph: add transpose option
oliver-sanders d8fdcfa
graph: add centre graph control
oliver-sanders c940d82
task: re-implement task icon
oliver-sanders 817cf92
tests: add component tests for task modifiers
oliver-sanders b664721
workflow service: run global callback by default
oliver-sanders 92f648c
task: switch to new task component
oliver-sanders 6ee0155
store: add family support to the tree
oliver-sanders 282dc1d
workflow service: fix query merging
oliver-sanders 7d15851
tree: fix filtering & job-details nodes
oliver-sanders 769470d
tree: only show workflow nodes when needed
oliver-sanders e8bb6ab
tree: handle cycle point "root" nodes correctly
oliver-sanders 712c862
table: upgrade to run off of the central store
oliver-sanders 4eb2e4f
update view icon for graph view
oliver-sanders 36f399b
graph: add standalone graph view to the router
oliver-sanders 372eea5
store: avoid duplicated nested workflow nodes
oliver-sanders 801ac43
gscan: convert to run off of the central data store
oliver-sanders 3711326
dashboard: convert to run off of the central data store
oliver-sanders 8b0a955
sort cycles and jobs in reverse order
oliver-sanders 6f85bda
task: ensure the task icons are clickable when waiting
oliver-sanders f3b1d29
gscan: fix sorting & filtering
oliver-sanders efa99c7
toolbar: fix data source
oliver-sanders b7be28f
aotf: fix node data
oliver-sanders 07a0acc
tree: fix auto expansion
oliver-sanders 6645669
store: housekeep the store for workflow subscriptions
oliver-sanders 5a054de
task: delete unused styles and re-calibrate progress
oliver-sanders 7c23fe2
graph: prevent Nanageddon
oliver-sanders ad9a6dc
graph: prevent SVG path error messages
oliver-sanders b730433
graph: test graph-utils
oliver-sanders e5ff894
tree: re-instate task progress animations
oliver-sanders c61be9c
task: fix progress icon in webkit/safari
oliver-sanders cf8a682
graph node: implement progress icon & test
oliver-sanders 2d46207
graph node: only show the first N jobs
oliver-sanders 51e41d4
graph: protect against undefined bboxes
oliver-sanders 3c88f3d
graphql: only stripNull for updated Deltas
oliver-sanders fb3bf1d
tree: fix missing tasks on root family
oliver-sanders 69b8bb5
graphql: remove unnecessary sorting
oliver-sanders b5ba5da
table: convert to run on central data store
oliver-sanders e1a9e06
graph: solve floating ghost node problem
oliver-sanders e114e95
graph: add toolbar and manual refresh
oliver-sanders 4eafc93
tree: fix occasional traceback
oliver-sanders 7391886
store: remove old stores, callbacks and fix tests
oliver-sanders fddd54c
tree: re-implement the cyclePointsOrderDesc configuration
oliver-sanders 6724223
tests: fix offline data
oliver-sanders 346beb6
tree: fix custom outputs and support messages
oliver-sanders 391ad39
tests/e2e: fix tests after data store change
oliver-sanders 88b05ef
tests/unit: fix alert test
oliver-sanders 791efb1
table: fix table view post-filter change
oliver-sanders a7a655c
graph: fix edges on Firefox
oliver-sanders 932fd77
tree: fix cycle point status
oliver-sanders 00a83d6
aotf: fix node description
oliver-sanders 16ec361
graphql: remove unused fields from queries
oliver-sanders 94e2a55
tree: sort families before tasks
oliver-sanders c784f41
tree: fix erroneous filter issue
oliver-sanders 8a73323
views: simplify access of job startedTime
oliver-sanders ebe38c8
tidy: remove console logs, commented code, etc
oliver-sanders b574a11
mutation: remove task icon from mutation form
oliver-sanders 0e493af
task: make the queued modifier more prominent & add expired state
oliver-sanders 1cf7973
store: tidy
oliver-sanders 2cc7e53
misc: tidy
oliver-sanders 3ad9edc
store: centralise tree walking functions
oliver-sanders 08cbec6
graph: Apply suggestions from code review
oliver-sanders b43050e
guide: fix task icons
oliver-sanders c2a134f
graph node: re-jig item sizes
oliver-sanders 3927ea0
store: fix subscription merging issue
oliver-sanders 3e029be
store: fix edge removal
oliver-sanders 196a45e
graph: prevent NaNageddon
oliver-sanders 017873d
graph: fix scrollbars
oliver-sanders f95e3d5
store: fix merging of updates
oliver-sanders e26d672
graph: improve stability with large graphs
oliver-sanders ccc69dc
graph: package wasm file
oliver-sanders ac3bf77
graph: add offline data and first e2e test
oliver-sanders ac2e835
graph: allow display of edgeless graphs
oliver-sanders 62ab67a
TreeItem: small fix
oliver-sanders 51d67cf
changelog: graph view
oliver-sanders 599e2cd
actions: upload cypress screenshots as artefacts
oliver-sanders 1a0f1b8
graph: fix e2e test on Firefox
oliver-sanders fbe64e6
Update src/components/cylc/GraphNode.vue
oliver-sanders 3d28f92
Apply suggestions from code review
oliver-sanders File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
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) | ||
}) | ||
} | ||
}) | ||
}) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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.