diff --git a/ui/app/adapters/job.js b/ui/app/adapters/job.js index c51690a05..1c6e69bd0 100644 --- a/ui/app/adapters/job.js +++ b/ui/app/adapters/job.js @@ -4,6 +4,8 @@ import ApplicationAdapter from './application'; const { RSVP } = Ember; export default ApplicationAdapter.extend({ + shouldReloadAll: () => true, + findRecord(store, { modelName }, id, snapshot) { // To make a findRecord response reflect the findMany response, the JobSummary // from /summary needs to be stitched into the response. diff --git a/ui/app/components/allocation-row.js b/ui/app/components/allocation-row.js index 415d5f3fe..044d368d2 100644 --- a/ui/app/components/allocation-row.js +++ b/ui/app/components/allocation-row.js @@ -18,4 +18,19 @@ export default Component.extend({ click(event) { lazyClick([this.get('onClick'), event]); }, + + didReceiveAttrs() { + // If the job for this allocation is incomplete, reload it to get + // detailed information. + const allocation = this.get('allocation'); + if ( + allocation && + allocation.get('job') && + !allocation.get('job.isPending') && + !allocation.get('taskGroup') + ) { + const job = allocation.get('job.content'); + job && job.reload(); + } + }, }); diff --git a/ui/app/controllers/jobs/job/loading.js b/ui/app/controllers/jobs/job/loading.js new file mode 100644 index 000000000..bb159e836 --- /dev/null +++ b/ui/app/controllers/jobs/job/loading.js @@ -0,0 +1,8 @@ +import Ember from 'ember'; + +const { Controller, computed, inject } = Ember; + +export default Controller.extend({ + jobController: inject.controller('jobs.job'), + breadcrumbs: computed.alias('jobController.breadcrumbs'), +}); diff --git a/ui/app/styles/components.scss b/ui/app/styles/components.scss index 59d521617..5a9b452fc 100644 --- a/ui/app/styles/components.scss +++ b/ui/app/styles/components.scss @@ -7,6 +7,7 @@ @import "./components/inline-definitions"; @import "./components/job-diff"; @import "./components/json-viewer"; +@import "./components/loading-spinner"; @import "./components/metrics"; @import "./components/node-status-light"; @import "./components/status-text"; diff --git a/ui/app/styles/components/loading-spinner.scss b/ui/app/styles/components/loading-spinner.scss new file mode 100644 index 000000000..0bf07e49e --- /dev/null +++ b/ui/app/styles/components/loading-spinner.scss @@ -0,0 +1,71 @@ +.loading-spinner { + width: 40px; + height: 40px; + margin: 100px auto; + + .loading-spinner-square { + width: 33%; + height: 33%; + background-color: $primary; + float: left; + animation: loading-spinner-squareGridScaleDelay 1.3s infinite ease-in-out; + } + + .loading-spinner-square1 { + animation-delay: 0.2s; + } + + .loading-spinner-square2 { + animation-delay: 0.3s; + } + + .loading-spinner-square3 { + animation-delay: 0.4s; + } + + .loading-spinner-square4 { + animation-delay: 0.1s; + } + + .loading-spinner-square5 { + animation-delay: 0.2s; + } + + .loading-spinner-square6 { + animation-delay: 0.3s; + } + + .loading-spinner-square7 { + animation-delay: 0s; + } + + .loading-spinner-square8 { + animation-delay: 0.1s; + } + + .loading-spinner-square9 { + animation-delay: 0.2s; + } +} + +@-webkit-keyframes loading-spinner-squareGridScaleDelay { + 0%, + 70%, + 100% { + transform: scale3D(1, 1, 1); + } + 35% { + transform: scale3D(0, 0, 1); + } +} + +@keyframes loading-spinner-squareGridScaleDelay { + 0%, + 70%, + 100% { + transform: scale3D(1, 1, 1); + } + 35% { + transform: scale3D(0, 0, 1); + } +} diff --git a/ui/app/templates/components/allocation-row.hbs b/ui/app/templates/components/allocation-row.hbs index 200cda7f3..ee68d60fa 100644 --- a/ui/app/templates/components/allocation-row.hbs +++ b/ui/app/templates/components/allocation-row.hbs @@ -11,8 +11,12 @@