diff --git a/addons/api/addon/generated/models/session.js b/addons/api/addon/generated/models/session.js
index ee751a988..a33426e4c 100644
--- a/addons/api/addon/generated/models/session.js
+++ b/addons/api/addon/generated/models/session.js
@@ -12,6 +12,7 @@ export default class GeneratedSessionModel extends BaseModel {
@attr('string', {
description: 'The name of the current status of this session.',
+ readOnly: true,
})
status;
diff --git a/ui/core/app/routes/scopes/scope/projects/project/sessions.js b/ui/core/app/routes/scopes/scope/projects/project/sessions.js
index 48bbb5cc0..b41d76d7a 100644
--- a/ui/core/app/routes/scopes/scope/projects/project/sessions.js
+++ b/ui/core/app/routes/scopes/scope/projects/project/sessions.js
@@ -2,6 +2,9 @@ import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { all, hash } from 'rsvp';
+import { task, timeout } from 'ember-concurrency';
+
+const POLL_TIMEOUT_SECONDS = 2.5;
export default class ScopesScopeProjectsProjectSessionsRoute extends Route {
@@ -10,6 +13,25 @@ export default class ScopesScopeProjectsProjectSessionsRoute extends Route {
@service intl;
@service notify;
+ // =attributes
+
+ /**
+ * A simple Ember Concurrency-based polling task that refreshes the route
+ * every POLL_TIMEOUT_SECONDS seconds. This is necessary to display changes
+ * to session `status` that may occur.
+ *
+ * NOTE: tasks are sort of attributes and sort of methods, but they are not
+ * language-level constructs. Thus we annotate this task as if it
+ * is an attribute.
+ * @type {Task}
+ */
+ @task(function * () {
+ while(true) {
+ yield timeout(POLL_TIMEOUT_SECONDS * 1000);
+ yield this.refresh();
+ }
+ }).drop() poller;
+
// =methods
/**
@@ -29,6 +51,22 @@ export default class ScopesScopeProjectsProjectSessionsRoute extends Route {
);
}
+ /**
+ * When this route is activated (entered), begin polling for changes.
+ */
+ activate() {
+ this.poller.perform();
+ }
+
+ /**
+ * When this route is deactivated (exited), stop polling for changes.
+ */
+ deactivate() {
+ this.poller.cancelAll();
+ }
+
+ // =actions
+
/**
* Cancels the specified session and notifies user of success or error.
* @param {SessionModel}
diff --git a/ui/core/app/templates/scopes/scope/projects/project/sessions/index.hbs b/ui/core/app/templates/scopes/scope/projects/project/sessions/index.hbs
index 83e480e5e..6fe82d12b 100644
--- a/ui/core/app/templates/scopes/scope/projects/project/sessions/index.hbs
+++ b/ui/core/app/templates/scopes/scope/projects/project/sessions/index.hbs
@@ -19,6 +19,7 @@
{{t "resources.user"}}
{{t "resources.target"}}
{{t "form.label.started"}}
+ {{t "form.label.status"}}
{{t "titles.actions"}}
@@ -35,6 +36,9 @@
{{format-date-iso-human sessionAggregate.session.created_time}}
+
+ {{sessionAggregate.session.status}}
+
{{t "actions.cancel"}}
diff --git a/ui/core/mirage/config.js b/ui/core/mirage/config.js
index fa23ee0e4..6803aac3d 100644
--- a/ui/core/mirage/config.js
+++ b/ui/core/mirage/config.js
@@ -1,5 +1,6 @@
import config from '../config/environment';
import { authHandler, deauthHandler } from './route-handlers/auth';
+import { pickRandomStatusString } from './factories/session';
//import { Response } from 'miragejs';
export default function() {
@@ -295,10 +296,22 @@ export default function() {
// session
+ // To simulate changes to `session.status` that may occur in the backend,
+ // we quietly randomize the value of the field on GET.
this.get('/sessions', function ({ sessions }, { queryParams: { scope_id } }) {
- return sessions.where(session => session.scopeId === scope_id);
+ sessions.where(session => session.scopeId === scope_id)
+ .models
+ .forEach(session => session.update({
+ status: pickRandomStatusString()
+ }));
+ return sessions.where(session => session.scopeId === scope_id)
+ });
+ this.get('/sessions/:id', function ({ sessions }, { params: { id } }) {
+ const session = sessions.find(id);
+ return session.update({
+ status: pickRandomStatusString()
+ });
});
- this.get('/sessions/:id');
this.post('/sessions/:idMethod', function ({ sessions }, { params: { idMethod } }) {
const attrs = this.normalizedRequestAttrs();
const id = idMethod.split(':')[0];
@@ -308,7 +321,7 @@ export default function() {
version: attrs.version
};
if (method === 'cancel') {
- updatedAttrs.status = 'canceled';
+ updatedAttrs.status = 'canceling';
}
return session.update(updatedAttrs);
});
diff --git a/ui/core/mirage/factories/session.js b/ui/core/mirage/factories/session.js
index 9e5e31913..0100a4b75 100644
--- a/ui/core/mirage/factories/session.js
+++ b/ui/core/mirage/factories/session.js
@@ -1,9 +1,20 @@
import factory from '../generated/factories/target';
import { trait } from 'ember-cli-mirage';
+import { random } from 'faker';
+
+const statusStrings = [
+ 'pending',
+ 'active',
+ 'canceling',
+ 'terminated'
+];
+
+export const pickRandomStatusString = () => random.arrayElement(statusStrings);
export default factory.extend({
id: (i) => `session-id-${i}`,
+ status: pickRandomStatusString,
/**
* Sessions generated with this trait will automatically form
diff --git a/ui/core/package.json b/ui/core/package.json
index 258f13a98..212ce3416 100644
--- a/ui/core/package.json
+++ b/ui/core/package.json
@@ -54,6 +54,7 @@
"ember-cli-sri": "^2.1.1",
"ember-cli-template-lint": "^1.0.0-beta.3",
"ember-cli-uglify": "^3.0.0",
+ "ember-concurrency": "^1.3.0",
"ember-data": "~3.16.0",
"ember-data-model-fragments": "5.0.0-beta.0",
"ember-exam": "^5.0.1",
diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml
index 7fb4748de..a37c9bfe3 100644
--- a/ui/core/translations/en-us.yaml
+++ b/ui/core/translations/en-us.yaml
@@ -163,6 +163,7 @@ form:
current_password: Current Password
new_password: New Password
started: Started
+ status: Status
errors:
titles:
unauthenticated-error: You are not signed in
diff --git a/yarn.lock b/yarn.lock
index 5304e5ace..658b62c2e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8923,6 +8923,15 @@ ember-compatibility-helpers@^1.1.1, ember-compatibility-helpers@^1.1.2, ember-co
ember-cli-version-checker "^2.1.1"
semver "^5.4.1"
+ember-concurrency@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/ember-concurrency/-/ember-concurrency-1.3.0.tgz#66f90fb792687470bcee1172adc0ebf33f5e8b9c"
+ integrity sha512-DwGlfWFpYyAkTwsedlEtK4t1DznJSculAW6Vq5S1C0shVPc5b6tTpHB2FFYisannSYkm+wpm1f1Pd40qiNPtOQ==
+ dependencies:
+ ember-cli-babel "^7.7.3"
+ ember-compatibility-helpers "^1.2.0"
+ ember-maybe-import-regenerator "^0.1.6"
+
ember-cookies@^0.5.0, ember-cookies@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/ember-cookies/-/ember-cookies-0.5.2.tgz#06e33463f2f83254fefaf224cc944dec3fb9d3ba"