Skip to content

Commit

Permalink
Merge pull request #280 from kinow/add-subscriptions
Browse files Browse the repository at this point in the history
Add subscriptions
  • Loading branch information
oliver-sanders authored Dec 23, 2019
2 parents c17cc82 + e318e3a commit 6dc38f5
Show file tree
Hide file tree
Showing 25 changed files with 1,714 additions and 1,356 deletions.
5 changes: 4 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ workflows only.
[#283](https://github.com/cylc/cylc-ui/pull/283) - Load user information
on application startup.

[#283](https://github.com/cylc/cylc-ui/pull/285) - Update Vuetify to 2.1,
[#285](https://github.com/cylc/cylc-ui/pull/285) - Update Vuetify to 2.1,
along with other dependencies with updates available.

[#291](https://github.com/cylc/cylc-ui/pull/291) - Add families to Tree
Expand All @@ -38,6 +38,9 @@ dashboard workflows summary.
[#307](https://github.com/cylc/cylc-ui/pull/307) - Invoke mutations to
hold, release, and stop workflows.

[#280](https://github.com/cylc/cylc-ui/pull/280) - Add WebSockets client
for GraphQL subscriptions.

### Fixes

[#275](https://github.com/cylc/cylc-ui/pull/275) - Fix size of dashboard
Expand Down
2,656 changes: 1,478 additions & 1,178 deletions package-lock.json

Large diffs are not rendered by default.

14 changes: 10 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"apollo-boost": "^0.4.4",
"apollo-utilities": "^1.3.2",
"axios-fetch": "^1.1.0",
"cytoscape": "^3.9.0",
"cytoscape-cise": "^1.0.0",
Expand All @@ -37,7 +37,6 @@
"tippy.js": "^4.3.5",
"vee-validate": "^3.0.11",
"vue": "^2.6.10",
"vue-apollo": "^3.0.0-beta.30",
"vue-cytoscape": "^0.2.10",
"vue-i18n": "^8.14.1",
"vue-meta": "^2.3.1",
Expand All @@ -55,11 +54,17 @@
"@vue/cli-plugin-unit-mocha": "^3.12.0",
"@vue/cli-service": "^3.12.0",
"@vue/test-utils": "^1.0.0-beta.29",
"apollo-cache-inmemory": "^1.6.3",
"apollo-client": "^2.6.4",
"apollo-link": "^1.2.13",
"apollo-link-http": "^1.5.16",
"apollo-link-ws": "^1.0.19",
"axios": "^0.19.0",
"babel-eslint": "^10.0.3",
"chai": "^4.2.0",
"cross-env": "^6.0.3",
"eslint": "^6.5.1",
"cross-fetch": "^3.0.4",
"eslint-config-vuetify": "*",
"eslint-plugin-vue": "^5.2.3",
"istanbul-instrumenter-loader": "^3.0.1",
Expand All @@ -68,10 +73,11 @@
"nyc": "^14.1.1",
"sass": "^1.23.0",
"sass-loader": "^7.3.1",
"sinon": "^7.4.1",
"standard": "^14.0.2",
"sinon": "^7.5.0",
"standard": "^14.3.1",
"svgo": "^1.3.2",
"vue-cli-plugin-apollo": "^0.21.0",
"subscriptions-transport-ws": "^0.9.16",
"vue-cli-plugin-eslint-config-vuetify": "latest",
"vue-cli-plugin-vuetify": "latest",
"vue-cli-plugin-vuetify-essentials": "latest",
Expand Down
12 changes: 5 additions & 7 deletions src/components/cylc/Graph.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,10 @@ import VueCytoscape from '@/components/core/Cytoscape.vue'
import { mixin } from '@/mixins/index'
// eslint-disable-next-line no-unused-vars
import { debounce, each, has, isEmpty, isUndefined, memoize } from 'lodash'
// eslint-disable-next-line no-unused-vars
import { workflowService } from 'workflow-service'
const QUERIES = {
root: `
{
subscription {
workflows(ids: ["WORKFLOW_ID"]) {
id
status
Expand Down Expand Up @@ -625,7 +623,7 @@ export default {
if (tippy) {
tippy.hide()
}
workflowService.unregister(this)
this.$workflowService.unregister(this)
},
mounted () {
Expand All @@ -637,7 +635,7 @@ export default {
created (cy) {
console.debug('CREATED')
workflowService.register(
this.$workflowService.register(
this,
{
activeCallback: this.setActive
Expand All @@ -653,7 +651,7 @@ export default {
methods: {
subscribe (queryName) {
const id = workflowService.subscribe(
const id = this.$workflowService.subscribe(
this,
QUERIES[queryName].replace('WORKFLOW_ID', this.workflowName)
)
Expand All @@ -666,7 +664,7 @@ export default {
unsubscribe (queryName) {
if (queryName in this.subscriptions) {
workflowService.unsubscribe(
this.$workflowService.unsubscribe(
this.subscriptions[queryName].id
)
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/cylc/Toolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export default {
const vm = this
if (this.isHeld) {
// release
this.$apollo.mutate({
this.$apolloClient.mutate({
mutation: RELEASE_WORKFLOW,
variables: {
workflow: this.currentWorkflow.id
Expand All @@ -156,7 +156,7 @@ export default {
})
} else {
// hold
this.$apollo.mutate({
this.$apolloClient.mutate({
mutation: HOLD_WORKFLOW,
variables: {
workflow: this.currentWorkflow.id
Expand All @@ -168,7 +168,7 @@ export default {
},
onClickStop () {
const vm = this
this.$apollo.mutate({
this.$apolloClient.mutate({
mutation: STOP_WORKFLOW,
variables: {
workflow: this.currentWorkflow.id
Expand Down
11 changes: 5 additions & 6 deletions src/components/cylc/gscan/GScan.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,11 @@

<script>
import Job from '@/components/cylc/Job'
import { workflowService } from 'workflow-service'
import { getWorkflowSummary } from '@/components/cylc/gscan/index'
const QUERIES = {
root: `
{
subscription {
workflows {
id
name
Expand Down Expand Up @@ -137,7 +136,7 @@ export default {
},
created () {
this.viewID = `GScan(*): ${Math.random()}`
workflowService.register(
this.$workflowService.register(
this,
{
activeCallback: this.setActive
Expand All @@ -146,7 +145,7 @@ export default {
this.subscribe('root')
},
beforeDestroy () {
workflowService.unregister(this)
this.$workflowService.unregister(this)
},
methods: {
subscribe (queryName) {
Expand All @@ -156,7 +155,7 @@ export default {
*/
if (!(queryName in this.subscriptions)) {
this.subscriptions[queryName] =
workflowService.subscribe(
this.$workflowService.subscribe(
this,
QUERIES[queryName]
)
Expand All @@ -169,7 +168,7 @@ export default {
* @param {string} queryName - Must be in QUERIES.
*/
if (queryName in this.subscriptions) {
workflowService.unsubscribe(
this.$workflowService.unsubscribe(
this.subscriptions[queryName]
)
}
Expand Down
23 changes: 12 additions & 11 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,23 @@ import i18n from '@/i18n'
import router from '@/router'
import store from '@/store'

// GraphQL
import VueApollo from 'vue-apollo'

// GraphQL client
import SubscriptionWorkflowService from 'workflow-service'
import { createApolloClient } from '@/utils/graphql'

const apolloClient = createApolloClient(
`${window.location.pathname}/graphql`
)
const apolloProvider = new VueApollo({
defaultClient: apolloClient
})

// Sync store with router
sync(store, router)

// TODO: revisit this and evaluate other ways to build the GraphQL URL - not safe to rely on window.location (?)
const baseUrl = `${window.location.hostname}${window.location.port ? ':' + window.location.port : ''}${window.location.pathname}`
const httpUrl = `${window.location.protocol}//${baseUrl}graphql`
const wsUrl = `ws://${baseUrl}subscriptions`
Vue.prototype.$apolloClient = createApolloClient(httpUrl, wsUrl)

// WorkflowService singleton available application-wide
const workflowService = new SubscriptionWorkflowService(Vue.prototype.$apolloClient)
Vue.prototype.$workflowService = workflowService

Vue.config.productionTip = false

/* eslint-disable no-new */
Expand All @@ -38,6 +40,5 @@ new Vue({
router,
store,
vuetify,
apolloProvider,
render: h => h(App)
}).$mount('#app')
23 changes: 0 additions & 23 deletions src/model/User.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,4 @@ export default class User {
*/
this.server = server
}

/**
* Return the Hub URL for the currently logged in user. The Vue app when created
* uses a route guard to load the user information from JupyterHub REST API.
*
* This stored information contains the `server` parameter that includes the
* base URL. We use the base URL in this function to create the Hub URL. Otherwise
* we would end up with 404 errors for users that have a value set for the
* base URL (which is blank by default).
*
* @link https://github.com/cylc/cylc-ui/issues/258
* @returns {string}
*/
getHubUrl () {
const hubUrl = '/hub/home'
let baseUrl = ''
const server = this.server
const userTokenIdx = server.lastIndexOf('/user')
if (userTokenIdx > 0) {
baseUrl = server.substring(0, userTokenIdx)
}
return `${baseUrl}${hubUrl}`
}
}
4 changes: 0 additions & 4 deletions src/plugins/apollo.js

This file was deleted.

1 change: 0 additions & 1 deletion src/plugins/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import './axios'
import './layouts'
import './veevalidate'
import './apollo'
40 changes: 2 additions & 38 deletions src/services/gquery.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { parse } from 'graphql/language/parser'
import { print } from 'graphql/language/printer'

import { createApolloClient } from '@/utils/graphql'

import Alert from '@/model/Alert.model'
import store from '@/store/'

function gClone (query) {
/** Clone a GraphQL query.
* Why oh why isn't there a better way of doing this in JS!
Expand Down Expand Up @@ -76,11 +71,8 @@ class GQuery {
* GraphQL endpoint for a collection of views with potentially overlapping
* queries.
*/

constructor () {
this.apolloClient = createApolloClient(
`${window.location.pathname}/graphql`
)
constructor (apolloClient) {
this.apolloClient = apolloClient
this.query = null
this.subscriptions = []
this.views = []
Expand Down Expand Up @@ -162,34 +154,6 @@ class GQuery {
}

request () {
/**
* Perform a REST GraphQL request for all subscriptions.
*/
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.debug('graphql request:', this.query)
}
return this.apolloClient.query({
query: this.query,
fetchPolicy: 'no-cache'
}).then((response) => {
// commit results
store.dispatch(
'workflows/set',
response.data.workflows
)
// set all subscriptions to active
this.subscriptions
.filter(s => s.active === false)
.forEach(s => { s.active = true })
// run callback functions on the views
this.callbackActive()
}).catch((error) => {
store.dispatch(
'setAlert',
new Alert(error.message, null, 'error')
)
})
}

callbackActive () {
Expand Down
10 changes: 5 additions & 5 deletions src/services/mock/workflow.service.mock.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { checkpoint } from '@/services/mock/checkpoint.js'
import { GQuery } from '@/services/gquery'
import store from '@/store/'
import store from '@/store/index'

class MockWorkflowService extends GQuery {
/**
Expand All @@ -9,9 +9,9 @@ class MockWorkflowService extends GQuery {
*/

constructor () {
super()
super(/* enableWebSockets */ false)
// load mock data
store.dispatch('workflows/set', checkpoint.workflows)
store.dispatch('workflows/set', checkpoint.workflows).then(() => {})
}

subscribe (view, query) {
Expand All @@ -28,6 +28,6 @@ class MockWorkflowService extends GQuery {
}
}

const workflowService = new MockWorkflowService()
export { MockWorkflowService }

export { workflowService }
export default MockWorkflowService
Loading

0 comments on commit 6dc38f5

Please sign in to comment.