Merge branch 'main' into refactor-recursive-desktop

This commit is contained in:
Randall Morey authored and GitHub committed 2021-02-11 10:45:07 -05:00
commit 0e0083b6c7
11 files changed
+123 -92

No files matched your search

@@ -17,3 +17,5 @@ generic:
title: Error
authentication-failed:
title: Authentication Failed
origin-verification-failed:
description: Unable to connect to the specified origin. Please check the URL and try again.
@@ -0,0 +1,36 @@
import Controller from '@ember/controller';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import { A } from '@ember/array';
export default class ScopesScopeProjectsTargetsTargetSessionsController extends Controller {
// =services
@service session;
/**
* Sort and filter to active sessions of current user
* @param {[SessionModel]} model
* @param {object} session
* @type {[SessionModel]}
*/
@computed('model.@each.{created_time,active}', 'session.data.authenticated.user_id')
get selfActiveSessions() {
const sessions = this.model;
const userId = this.session.data.authenticated.user_id;
const filteredSessions =
sessions.filter(session =>
session.isCancelable &&
session.user_id === userId
);
// Sort sessions
const sortedSessions = A(filteredSessions).sortBy('created_time').reverse();
// Move active sessions to top
return [
...sortedSessions.filter(session => session.isActive),
...sortedSessions.filter(session => !session.isActive)
]
}
}
@@ -1,36 +1,17 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { A } from '@ember/array';
export default class ScopesScopeProjectsTargetsTargetRoute extends Route {
// =services
@service session;
// =methods
/**
* Load a target and it's active sessions
* Load a target
* @param {object} params
* @param {string} params.target_id
* @return {{TargetModel, [SessionModel]}}
* @return {TargetModel}
*/
async model({ target_id }) {
const userId = this.session.data.authenticated.user_id;
const target = await this.store.findRecord('target', target_id, { reload: true });
const sessions = await this.store.query('session', { scope_id: target.scopeID });
// Filter to current user, current target, and active state
const filteredSessions = sessions.filter(
session => session.user_id === userId &&
session.target_id === target.id &&
session.isCancelable
)
// Sort sessions by time created
const sortedSessions =
A(filteredSessions).sortBy('session.created_time').reverse();
return { target, sessions: sortedSessions };
model({ target_id }) {
return this.store.findRecord('target', target_id, { reload: true });
}
/**
@@ -18,7 +18,7 @@ export default class ScopesScopeProjectsTargetsTargetHostsRoute extends Route {
* @return {Promise{[HostModel]}}
*/
async model() {
const { target } = this.modelFor('scopes.scope.projects.targets.target');
const target = this.modelFor('scopes.scope.projects.targets.target');
// Load all host-sets
const hostSets = await all(
target.host_sets.map(({ host_set_id }) =>
@@ -3,6 +3,16 @@ import { action } from '@ember/object';
import { notifySuccess, notifyError } from 'core/decorators/notify';
export default class ScopesScopeProjectsTargetsTargetSessionsRoute extends Route {
// =methods
/**
* @return {[SessionModel]}
*/
model() {
return this.modelFor('scopes.scope.projects.targets.target').sessions;
}
// =actions
/**
@@ -1,65 +1,58 @@
{{page-title (t "actions.authenticate")}}
{{!--
<Rose::Form::Input
@type="text"
@name=""
@value={{this.origin.rendererOrigin}}
@label={{t "form.origin.label"}}
@disabled={{true}}
/>
<Rose::Button @style="ghost">Change</Rose::Button> --}}
<BrandedCard
@title={{t 'actions.authenticate'}}
@description={{t 'auth.descriptions.authenticating-with-org' name=@model.scope.displayName}}
>
<main>
<BrandedCard
@title={{t 'actions.authenticate'}}
@description={{t 'auth.descriptions.authenticating-with-org' name=@model.scope.displayName}}
>
<Rose::Dropdown
@text={{t "actions.choose-different-org"}}
@icon="user-organization"
as |dropdown|>
<dropdown.link @route="scopes.scope.authenticate" @model="global">
{{t "titles.global"}}
</dropdown.link>
{{#each this.sortedScopes as |scope|}}
<dropdown.link @route="scopes.scope.authenticate" @model={{scope.id}}>
{{scope.displayName}}
<Rose::Dropdown
@text={{t "actions.choose-different-org"}}
@icon="user-organization"
as |dropdown|>
<dropdown.link @route="scopes.scope.authenticate" @model="global">
{{t "titles.global"}}
</dropdown.link>
{{/each}}
</Rose::Dropdown>
{{#each this.sortedScopes as |scope|}}
<dropdown.link @route="scopes.scope.authenticate" @model={{scope.id}}>
{{scope.displayName}}
</dropdown.link>
{{/each}}
</Rose::Dropdown>
<Rose::Nav::Tabs as |nav|>
{{#each @model.authMethods as |authMethod|}}
<nav.link @route="scopes.scope.authenticate.method" @model={{authMethod.id}}>
{{t (concat "resources.auth-method.types." authMethod.type)}}
</nav.link>
{{/each}}
</Rose::Nav::Tabs>
<Rose::Nav::Tabs as |nav|>
{{#each @model.authMethods as |authMethod|}}
<nav.link @route="scopes.scope.authenticate.method" @model={{authMethod.id}}>
{{t (concat "resources.auth-method.types." authMethod.type)}}
</nav.link>
{{/each}}
</Rose::Nav::Tabs>
{{#if @model.authMethods}}
{{outlet}}
{{#if @model.authMethods}}
{{outlet}}
<p class="change-origin">
{{t "origin.connected-to"}}:
<code>{{this.origin}}</code>
<br>
<LinkTo @route="origin">
{{t "actions.change-origin"}}
</LinkTo>
</p>
<p class="change-origin">
{{t "origin.connected-to"}}:
<code>{{this.origin}}</code>
<br>
<LinkTo @route="origin">
{{t "actions.change-origin"}}
</LinkTo>
</p>
{{/if}}
{{#unless @model.authMethods}}
<Rose::Layout::Centered>
<Rose::Message
@title={{t "resources.auth-method.messages.none.title"}}
@icon="alert-circle-outline"
as |message|>
<message.description>
{{t "resources.auth-method.messages.none.description"}}
</message.description>
</Rose::Message>
</Rose::Layout::Centered>
{{/unless}}
{{/if}}
{{#unless @model.authMethods}}
<Rose::Layout::Centered>
<Rose::Message
@title={{t "resources.auth-method.messages.none.title"}}
@icon="alert-circle-outline"
as |message|>
<message.description>
{{t "resources.auth-method.messages.none.description"}}
</message.description>
</Rose::Message>
</Rose::Layout::Centered>
{{/unless}}
</BrandedCard>
</BrandedCard>
</main>
@@ -1,3 +1,3 @@
<Rose::Button @style="primary" {{on "click" (route-action "connect" @model.target)}}>
<Rose::Button @style="primary" {{on "click" (route-action "connect" @model)}}>
{{t "resources.session.actions.connect"}}
</Rose::Button>
@@ -1,18 +1,18 @@
<h2>
{{@model.target.displayName}}
{{#if @model.target.isActive}}
{{@model.displayName}}
{{#if @model.isActive}}
<Rose::Badge @style="success">
{{t "states.active"}}
</Rose::Badge>
{{/if}}
</h2>
<p>{{@model.target.description}}</p>
<p>{{@model.description}}</p>
<p>
<Copyable
@text={{@model.target.id}}
@text={{@model.id}}
@buttonText={{t "actions.copy-to-clipboard"}}
@acknowledgeText={{t "states.copied"}}
>
<code>{{@model.target.id}}</code>
<code>{{@model.id}}</code>
</Copyable>
</p>
@@ -1,10 +1,6 @@
<Rose::Table as |table|>
<table.body as |body|>
{{!--
TODO: sort these via the controller so that active and pending appear first
similar to the way the sessions routes are sorted.
--}}
{{#each @model.target.sessions as |session|}}
{{#each this.selfActiveSessions as |session|}}
<body.row as |row|>
<row.cell class="nowrap">
<Rose::Icon
@@ -34,7 +34,8 @@ module.exports = {
{
name: "@electron-forge/maker-dmg",
config: {
name: "Boundary Desktop"
name: "boundary-desktop",
title: "Boundary Desktop"
}
}
]
@@ -0,0 +1,12 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Controller | scopes/scope/projects/targets/target/sessions', function(hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function(assert) {
let controller = this.owner.lookup('controller:scopes/scope/projects/targets/target/sessions');
assert.ok(controller);
});
});