First iteration of connect dialog component
This commit is contained in:
1 parent
9049bb2087
commit
2dfda037fe
7 files changed
+298
-38
No files matched your search
@@ -6,6 +6,8 @@ import { attr } from '@ember-data/model';
|
||||
export default class SessionModel extends GeneratedSessionModel {
|
||||
// =attributes
|
||||
|
||||
@attr('boolean', { readOnly: true }) acknowledged;
|
||||
@attr('boolean', { readOnly: true }) started_desktop_client;
|
||||
@attr('string', { readOnly: true }) proxy_address;
|
||||
@attr('number', { readOnly: true }) proxy_port;
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
<Rose::Dialog
|
||||
class='connection-dialog'
|
||||
@heading={{@heading}}
|
||||
@dismiss={{@dismiss}}
|
||||
@dismissButtonText={{@dismissButtonText}}
|
||||
@style={{@style}}
|
||||
@icon={{@icon}}
|
||||
@modal={{true}}
|
||||
as |dialog|
|
||||
>
|
||||
<dialog.body>
|
||||
|
||||
{{!-- <Copyable
|
||||
@text={{concat @session.proxy_address ':' @session.proxy_port}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
{{t
|
||||
'states.connection.success.description'
|
||||
port=session.proxy_port
|
||||
address=session.proxy_address
|
||||
protocol='tcp'
|
||||
}}
|
||||
</Copyable>
|
||||
|
||||
<div class='connection-dialog-successfully'>Succesfully connected</div>
|
||||
|
||||
<h3>Proxy URL</h3>
|
||||
<div class="proxy-url">
|
||||
<p>www.verylongurl.com/section1/subsection2/how-to-tell-the-world-this-is-a-very-long-url-example</p>
|
||||
<Rose::Icon @name="copy-action" @size={{size}} />
|
||||
</div>
|
||||
|
||||
<Rose::Separator />
|
||||
<h3>Credentials</h3>
|
||||
<div class="credentials-card">
|
||||
<div class="credentials-card-header">
|
||||
<div><Rose::Icon @name="key" /> Credentials</div>
|
||||
<div>
|
||||
<Rose::Button
|
||||
@disabled={{false}}
|
||||
@style={{style}}
|
||||
@iconRight={{iconRight}}
|
||||
{{on "click" onClick}}
|
||||
>
|
||||
Credential library details
|
||||
</Rose::Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Rose::Separator />
|
||||
|
||||
<div class="credentials-card-body">
|
||||
<Rose::Table @style="condensed" as |table|>
|
||||
<table.header as |header|>
|
||||
<header.row as |row|>
|
||||
<row.headerCell @shrink={{true}}>Key</row.headerCell>
|
||||
<row.headerCell colspan="2">Value</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
<table.body as |body|>
|
||||
<body.row as |row|>
|
||||
<row.cell>Foo</row.cell>
|
||||
<row.cell> </row.cell>
|
||||
</body.row>
|
||||
<body.row as |row|>
|
||||
<row.cell>ttl</row.cell>
|
||||
<row.cell> </row.cell>
|
||||
</body.row>
|
||||
</table.body>
|
||||
</Rose::Table>
|
||||
</div>
|
||||
|
||||
<div class="credentials-card-footer">
|
||||
<p><LinkTo @route='index'>View raw API output</LinkTo></p>
|
||||
<Rose::Separator />
|
||||
<div>Code</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="credentials-card">
|
||||
<div class="credentials-card-header">
|
||||
<div><Rose::Icon @name="key" /> Credentials</div>
|
||||
<div>
|
||||
<Rose::Button
|
||||
@disabled={{false}}
|
||||
@style={{style}}
|
||||
@iconRight={{iconRight}}
|
||||
{{on "click" onClick}}
|
||||
>
|
||||
Credential library details
|
||||
</Rose::Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Rose::Separator />
|
||||
|
||||
<div class="credentials-card-body">
|
||||
<Rose::Table @style="condensed" as |table|>
|
||||
<table.header as |header|>
|
||||
<header.row as |row|>
|
||||
<row.headerCell @shrink={{true}}>Key</row.headerCell>
|
||||
<row.headerCell colspan="2">Value</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
<table.body as |body|>
|
||||
<body.row as |row|>
|
||||
<row.cell>Foo</row.cell>
|
||||
<row.cell> </row.cell>
|
||||
</body.row>
|
||||
<body.row as |row|>
|
||||
<row.cell>ttl</row.cell>
|
||||
<row.cell> </row.cell>
|
||||
</body.row>
|
||||
</table.body>
|
||||
</Rose::Table>
|
||||
</div>
|
||||
|
||||
<div class="credentials-card-footer">
|
||||
<p><LinkTo @route='index'>View raw API output</LinkTo></p>
|
||||
<Rose::Separator />
|
||||
<div>Code</div>
|
||||
</div>
|
||||
</div> --}}
|
||||
</dialog.body>
|
||||
<dialog.footer>
|
||||
<div>
|
||||
<Rose::Button
|
||||
@style='secondary'
|
||||
{{on 'click' (route-action 'acknowledge' session)}}
|
||||
>
|
||||
{{t 'actions.ok'}}
|
||||
</Rose::Button>
|
||||
</div>
|
||||
<div>
|
||||
<Rose::LinkButton
|
||||
@route='index'
|
||||
@style='inline-link-action'
|
||||
@iconRight='chevron-right'
|
||||
>
|
||||
View on Session page
|
||||
</Rose::LinkButton>
|
||||
</div>
|
||||
</dialog.footer>
|
||||
</Rose::Dialog>
|
||||
@@ -81,6 +81,11 @@ export default class ScopesScopeProjectsTargetsRoute extends Route {
|
||||
|
||||
// =actions
|
||||
|
||||
@action
|
||||
acknowledge(session) {
|
||||
session.acknowledged = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish a session to current target.
|
||||
* @param {TargetModel} model
|
||||
@@ -119,17 +124,13 @@ export default class ScopesScopeProjectsTargetsRoute extends Route {
|
||||
id: session_id,
|
||||
type: 'session',
|
||||
attributes: {
|
||||
started_desktop_client: true,
|
||||
proxy_address: address,
|
||||
proxy_port: port
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 150);
|
||||
|
||||
// Show the user a modal with basic connection info.
|
||||
// We don't await because this modal is purely informational.
|
||||
this.confirm.confirm(connectionDetails, { isConnectSuccess: true });
|
||||
|
||||
} catch(e) {
|
||||
this.confirm.confirm(e.message, { isConnectError: true })
|
||||
// Retry
|
||||
|
||||
@@ -325,3 +325,69 @@
|
||||
margin: sizing.rems(l) 0 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
// Dialog Detail
|
||||
// These styles are a Work In Progress. Expect changes (lots of them)
|
||||
.connection-dialog {
|
||||
.connection-dialog-successfully {
|
||||
// background: green;
|
||||
}
|
||||
|
||||
.proxy-url {
|
||||
display: flex;
|
||||
|
||||
p {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.credentials-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child { margin-bottom: 0; }
|
||||
|
||||
.credentials-card-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
width: 50%;
|
||||
|
||||
&:last-child {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
// border-bottom: 1px solid grey;
|
||||
}
|
||||
|
||||
.credentials-card-body {
|
||||
// background: yellow;
|
||||
}
|
||||
|
||||
.credentials-card-footer {
|
||||
// background: pink;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rose-dialog-footer {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
||||
div:nth-child(1) {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
div:nth-child(2) {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
@@ -103,39 +103,7 @@
|
||||
</EmberNotify>
|
||||
|
||||
<PendingConfirmations as |confirmation accept deny|>
|
||||
{{#if confirmation.options.isConnectSuccess}}
|
||||
<Rose::Dialog
|
||||
@heading={{t 'states.success'}}
|
||||
@dismissButtonText={{t 'actions.ok'}}
|
||||
@icon='check-circle-fill'
|
||||
@style='success'
|
||||
@modal={{true}}
|
||||
@dismiss={{deny}}
|
||||
as |dialog|
|
||||
>
|
||||
<dialog.body>
|
||||
|
||||
<Copyable
|
||||
@text={{concat confirmation.text.address ':' confirmation.text.port}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
{{t
|
||||
'states.connection.success.description'
|
||||
port=confirmation.text.port
|
||||
address=confirmation.text.address
|
||||
protocol=confirmation.text.protocol
|
||||
}}
|
||||
</Copyable>
|
||||
|
||||
</dialog.body>
|
||||
<dialog.footer>
|
||||
<Rose::Button @style='primary' {{on 'click' accept}}>
|
||||
{{t 'actions.ok'}}
|
||||
</Rose::Button>
|
||||
</dialog.footer>
|
||||
</Rose::Dialog>
|
||||
{{else if confirmation.options.isConnectError}}
|
||||
{{#if confirmation.options.isConnectError}}
|
||||
<Rose::Dialog
|
||||
@heading={{t 'states.error'}}
|
||||
@dismissButtonText={{t 'actions.ok'}}
|
||||
|
||||
@@ -1,3 +1,55 @@
|
||||
{{page-title (t 'resources.target.title_plural')}}
|
||||
|
||||
{{#each @model as |target|}}
|
||||
{{#each target.sessions as |session|}}
|
||||
{{#if session.started_desktop_client}}
|
||||
{{#unless session.acknowledged}}
|
||||
<Rose::Dialog
|
||||
@heading={{t 'states.success'}}
|
||||
@dismissButtonText={{t 'actions.ok'}}
|
||||
@icon='check-circle-fill'
|
||||
@style='success'
|
||||
@modal={{true}}
|
||||
@dismiss={{route-action 'acknowledge' session}}
|
||||
as |dialog|
|
||||
>
|
||||
<dialog.body>
|
||||
|
||||
<Copyable
|
||||
@text={{concat session.proxy_address ':' session.proxy_port}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
{{t
|
||||
'states.connection.success.description'
|
||||
port=session.proxy_port
|
||||
address=session.proxy_address
|
||||
protocol='tcp'
|
||||
}}
|
||||
</Copyable>
|
||||
|
||||
</dialog.body>
|
||||
<dialog.footer>
|
||||
<Rose::Button
|
||||
@style='primary'
|
||||
{{on 'click' (route-action 'acknowledge' session)}}
|
||||
>
|
||||
{{t 'actions.ok'}}
|
||||
</Rose::Button>
|
||||
</dialog.footer>
|
||||
</Rose::Dialog>
|
||||
{{!-- <DialogDetail
|
||||
@heading={{t 'states.success'}}
|
||||
@dismiss={{route-action 'acknowledge' session}}
|
||||
@dismissButtonText={{t 'actions.ok'}}
|
||||
@icon='check-circle-fill'
|
||||
@style='success'
|
||||
@session={{session}}
|
||||
>
|
||||
</DialogDetail> --}}
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
{{/each}}
|
||||
|
||||
{{outlet}}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
|
||||
module('Integration | Component | dialog-detail', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
// Set any properties with this.set('myProperty', 'value');
|
||||
// Handle any actions with this.set('myAction', function(val) { ... });
|
||||
|
||||
await render(hbs`<DialogDetail />`);
|
||||
|
||||
assert.equal(this.element.textContent.trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
await render(hbs`
|
||||
<DialogDetail>
|
||||
template block text
|
||||
</DialogDetail>
|
||||
`);
|
||||
|
||||
assert.equal(this.element.textContent.trim(), 'template block text');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user