First iteration of connect dialog component

This commit is contained in:
Carlos Alcaide committed 2021-06-09 10:30:53 -07:00
1 parent 9049bb2087
commit 2dfda037fe
7 files changed
+298 -38

No files matched your search

+2
View File
@@ -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>&nbsp;</row.cell>
</body.row>
<body.row as |row|>
<row.cell>ttl</row.cell>
<row.cell>&nbsp;</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>&nbsp;</row.cell>
</body.row>
<body.row as |row|>
<row.cell>ttl</row.cell>
<row.cell>&nbsp;</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
+66
View File
@@ -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%;
}
}
+1 -33
View File
@@ -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');
});
});