feat: Basic sessions view
This commit is contained in:
11 files changed
+190
-2
No files matched your search
@@ -10,7 +10,10 @@ export default factory.extend({
|
||||
withAccountsAndUsers: trait({
|
||||
afterCreate(authMethod, server) {
|
||||
const { scope } = authMethod;
|
||||
server.createList('user', 5, { scope }).map(user => {
|
||||
const users = server.createList('user', 5, { scope });
|
||||
// Create authorized user: user123
|
||||
users.push(server.create('user', { scope, id: 'user123' }));
|
||||
users.map(user => {
|
||||
const { id } = server.create('account', { scope, authMethod });
|
||||
user.update({ accountIds: [id] });
|
||||
});
|
||||
|
||||
@@ -41,6 +41,29 @@ export default factory.extend({
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sessions generated with this trait will automatically form
|
||||
* associations to target, host set, and host (if available) within
|
||||
* the current scope and for specified user.
|
||||
*/
|
||||
withUserAssociations: trait({
|
||||
afterCreate(record, server) {
|
||||
const scopeId = record.scopeId;
|
||||
const user = record.user;
|
||||
record.update({ user });
|
||||
const target = server.schema.targets.where({ scopeId }).models[0];
|
||||
if (target) {
|
||||
record.update({ target });
|
||||
const hostSet = target.hostSets.models[0];
|
||||
if (hostSet) {
|
||||
record.update({ hostSet });
|
||||
const host = hostSet.hosts.models[0];
|
||||
if (host) record.update({ host });
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
@@ -29,6 +29,9 @@ export default function(server) {
|
||||
server.createList('host-catalog', 2, { scope }, 'withChildren');
|
||||
server.createList('target', 2, { scope }, 'withRandomHostSets');
|
||||
server.createList('session', 4, { scope }, 'withAssociations');
|
||||
// Create sessions for all users
|
||||
server.schema.users.where({ scopeId: scope.scope.id }).models.forEach(user =>
|
||||
server.createList('session', 4, { scope, user }, 'withUserAssociations')
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
@@ -14,6 +14,7 @@ Router.map(function () {
|
||||
});
|
||||
this.route('projects', function () {
|
||||
this.route('targets', function () {});
|
||||
this.route('sessions', function() {});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { all, hash } from 'rsvp';
|
||||
import { A } from '@ember/array';
|
||||
|
||||
export default class ScopesScopeProjectsSessionsRoute extends Route {
|
||||
|
||||
// =services
|
||||
|
||||
@service session;
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* If arriving here unauthenticated, redirect to index for further processing.
|
||||
*/
|
||||
beforeModel() {
|
||||
if (!this.session.isAuthenticated) this.transitionTo('index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all sessions under the current scope and encapsulates them into
|
||||
* an array of objects filtering to current user
|
||||
* @return {Promise{[{session: SessionModel, target: TargetModel}]}}
|
||||
*/
|
||||
async model() {
|
||||
const projects = this.modelFor('scopes.scope.projects');
|
||||
const userId = this.session.data.authenticated.user_id;
|
||||
let projectSessions = await all(
|
||||
projects.map(({ id: scope_id }) =>
|
||||
this.store.query('session', { scope_id })
|
||||
)
|
||||
);
|
||||
|
||||
// Filter sessions to current user
|
||||
let sessions = projectSessions.map(sessions => {
|
||||
return sessions.filter(session => {
|
||||
console.log(session.user_id, userId)
|
||||
return session.user_id === userId
|
||||
});
|
||||
}).flat();
|
||||
|
||||
const sessionAggregates = await all(
|
||||
sessions.map(session => hash({
|
||||
session,
|
||||
target: session.target_id
|
||||
? (
|
||||
this.store.peekRecord('target', session.target_id) ||
|
||||
this.store.findRecord('target', session.target_id)
|
||||
)
|
||||
: null,
|
||||
}))
|
||||
);
|
||||
|
||||
// Sort sessions by time created...
|
||||
let sortedSessionAggregates =
|
||||
A(sessionAggregates).sortBy('session.created_time').reverse();
|
||||
// Then move active sessions to the top...
|
||||
sortedSessionAggregates = [
|
||||
...sortedSessionAggregates.filter((aggregate) => aggregate.session.status === 'active'),
|
||||
...sortedSessionAggregates.filter((aggregate) => aggregate.session.status !== 'active'),
|
||||
];
|
||||
|
||||
return sortedSessionAggregates;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import Route from '@ember/routing/route';
|
||||
|
||||
export default class ScopesScopeProjectsSessionsIndexRoute extends Route {
|
||||
}
|
||||
@@ -7,6 +7,13 @@
|
||||
@size="medium" />
|
||||
{{t "resources.target.title_plural"}}
|
||||
</nav.link>
|
||||
|
||||
<nav.link @route="scopes.scope.projects.sessions">
|
||||
<Rose::Icon
|
||||
@name="app-icons/action-session"
|
||||
@size="medium" />
|
||||
{{t "resources.session.title_plural"}}
|
||||
</nav.link>
|
||||
</Rose::Nav::Sidebar>
|
||||
</sidebarLayout.sidebar>
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{{outlet}}
|
||||
@@ -0,0 +1,58 @@
|
||||
<Rose::Layout::Page as |page|>
|
||||
|
||||
<page.header>
|
||||
<h2>{{t "resources.session.title_plural"}}</h2>
|
||||
</page.header>
|
||||
|
||||
<page.body>
|
||||
|
||||
{{#if @model}}
|
||||
|
||||
<Rose::Table as |table|>
|
||||
<table.header as |header|>
|
||||
<header.row as |row|>
|
||||
<row.headerCell>{{t "form.id.label"}}</row.headerCell>
|
||||
<row.headerCell>{{t "resources.target.title"}}</row.headerCell>
|
||||
<row.headerCell>{{t "form.started.label"}}</row.headerCell>
|
||||
<row.headerCell>{{t "form.status.label"}}</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
<table.body as |body|>
|
||||
{{#each @model as |sessionAggregate|}}
|
||||
<body.row as |row|>
|
||||
<row.headerCell class="nowrap">
|
||||
<Rose::Icon
|
||||
class={{concat "session-status-" sessionAggregate.session.status}}
|
||||
@name="app-icons/action-session"
|
||||
@size="medium" />
|
||||
<code>{{sessionAggregate.session.id}}</code>
|
||||
</row.headerCell>
|
||||
<row.cell>{{sessionAggregate.target.displayName}}</row.cell>
|
||||
<row.cell>
|
||||
<time datetime={{format-date-iso sessionAggregate.session.created_time}}>
|
||||
{{format-date-iso-human sessionAggregate.session.created_time}}
|
||||
</time>
|
||||
</row.cell>
|
||||
<row.cell>
|
||||
<Rose::Badge>{{sessionAggregate.session.status}}</Rose::Badge>
|
||||
</row.cell>
|
||||
</body.row>
|
||||
{{/each}}
|
||||
</table.body>
|
||||
</Rose::Table>
|
||||
|
||||
{{else}}
|
||||
|
||||
<Rose::Layout::Centered>
|
||||
<Rose::Message @title={{t "resources.session.messages.none.title"}} as |message|>
|
||||
<message.description>
|
||||
{{t "resources.session.messages.none.description"}}
|
||||
</message.description>
|
||||
</Rose::Message>
|
||||
</Rose::Layout::Centered>
|
||||
|
||||
{{/if}}
|
||||
|
||||
</page.body>
|
||||
|
||||
</Rose::Layout::Page>
|
||||
@@ -0,0 +1,11 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Route | scopes/scope/projects/sessions', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.owner.lookup('route:scopes/scope/projects/sessions');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Route | scopes/scope/projects/sessions/index', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.owner.lookup('route:scopes/scope/projects/sessions/index');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user