diff --git a/ui/desktop/app/components/target/host-modal/index.hbs b/ui/desktop/app/components/target/host-modal/index.hbs index 9e1580d3b..fd92eabd1 100644 --- a/ui/desktop/app/components/target/host-modal/index.hbs +++ b/ui/desktop/app/components/target/host-modal/index.hbs @@ -4,7 +4,7 @@ }} {{#if @showModal}} - + {{t 'resources.session.actions.host'}} diff --git a/ui/desktop/app/controllers/scopes/scope/projects/targets/target.js b/ui/desktop/app/controllers/scopes/scope/projects/targets/target.js index 64cc886c4..4a74c7238 100644 --- a/ui/desktop/app/controllers/scopes/scope/projects/targets/target.js +++ b/ui/desktop/app/controllers/scopes/scope/projects/targets/target.js @@ -17,7 +17,7 @@ export default class ScopesScopeProjectsTargetsTargetController extends Controll // =methods @action - toggle() { - this.isConnecting = !this.isConnecting; + toggleModal(value) { + this.isConnecting = value; } } diff --git a/ui/desktop/app/routes/scopes/scope/projects/targets/target.js b/ui/desktop/app/routes/scopes/scope/projects/targets/target.js index efb1845f0..a55f4d457 100644 --- a/ui/desktop/app/routes/scopes/scope/projects/targets/target.js +++ b/ui/desktop/app/routes/scopes/scope/projects/targets/target.js @@ -17,6 +17,10 @@ export default class ScopesScopeProjectsTargetsTargetRoute extends Route { @service router; @service session; + // =attributes + + isConnectionError = false; + // =methods /** @@ -65,6 +69,42 @@ export default class ScopesScopeProjectsTargetsTargetRoute extends Route { } } + /** + * Sets the 'isConnecting' queryParam to false if connection failed. + * @returns {boolean} + */ + @action + didTransition() { + if (this.isConnectionError) { + /* eslint-disable-next-line ember/no-controller-access-in-routes */ + const controller = this.controllerFor( + 'scopes.scope.projects.targets.target' + ); + controller.set('isConnecting', false); + this.isConnectionError = false; + } + return true; + } + + /** + * Establish a session to current target. + * @param {TargetModel} target + * @param {HostModel} host + * hostConnect is only called when making a connection with a host and ensures that the host modal is automatically closed in the case of a connection error. + */ + @action + async hostConnect(target, host) { + await this.connect(target, host); + if (this.isConnectionError) { + /* eslint-disable-next-line ember/no-controller-access-in-routes */ + const controller = this.controllerFor( + 'scopes.scope.projects.targets.target' + ); + controller.set('isConnecting', false); + this.isConnectionError = false; + } + } + /** * Determine if we show host modal or quick connect based on target attributes. * @param {TargetModel} model @@ -75,7 +115,7 @@ export default class ScopesScopeProjectsTargetsTargetRoute extends Route { if (model.target.address || model.hosts.length === 1) { await this.connect(model.target); } else { - toggleModal(); + toggleModal(true); } } @@ -127,10 +167,11 @@ export default class ScopesScopeProjectsTargetsTargetRoute extends Route { session ); } catch (e) { + this.isConnectionError = true; this.confirm .confirm(e.message, { isConnectError: true }) // Retry - .then(() => this.connect(model)) + .then(() => this.connect(model, host)) .catch(() => null /* no op */); } } diff --git a/ui/desktop/app/templates/scopes/scope/projects/targets/target.hbs b/ui/desktop/app/templates/scopes/scope/projects/targets/target.hbs index 94bcd80bb..89d953afa 100644 --- a/ui/desktop/app/templates/scopes/scope/projects/targets/target.hbs +++ b/ui/desktop/app/templates/scopes/scope/projects/targets/target.hbs @@ -22,7 +22,7 @@ @icon='entry-point' @iconPosition='trailing' disabled={{not (can 'initiateConnection target' @model.target)}} - {{on 'click' (route-action 'preConnect' @model this.toggle)}} + {{on 'click' (route-action 'preConnect' @model this.toggleModal)}} /> {{/if}} @@ -32,8 +32,8 @@ {{#if (can 'initiateConnection target' @model.target)}} diff --git a/ui/desktop/tests/acceptance/projects/targets/index-test.js b/ui/desktop/tests/acceptance/projects/targets/index-test.js index f88555903..9cdce1bef 100644 --- a/ui/desktop/tests/acceptance/projects/targets/index-test.js +++ b/ui/desktop/tests/acceptance/projects/targets/index-test.js @@ -32,6 +32,8 @@ module('Acceptance | projects | targets', function (hooks) { const APP_STATE_TITLE = '.hds-application-state__title'; const TARGET_DETAILS_ROUTE_NAME = 'scopes.scope.projects.targets.target.index'; + const ROSE_DIALOG_MODAL = '.rose-dialog-error'; + const CHOOSE_HOST_MODAL = '[data-test-host-modal]'; const instances = { scopes: { @@ -240,4 +242,17 @@ module('Acceptance | projects | targets', function (hooks) { assert.strictEqual(currentRouteName(), TARGET_DETAILS_ROUTE_NAME); assert.dom(APP_STATE_TITLE).includesText('Cannot connect'); }); + + test('choose host modal does not render when there is a connect error', async function (assert) { + assert.expect(2); + const confirmService = this.owner.lookup('service:confirm'); + confirmService.enabled = true; + await visit(urls.projects); + + await click(`[href="${urls.targets}"]`); + await click(`[data-test-targets-connect-button="${instances.target.id}"]`); + + assert.dom(ROSE_DIALOG_MODAL).exists(); + assert.dom(CHOOSE_HOST_MODAL).doesNotExist(); + }); }); diff --git a/ui/desktop/tests/integration/components/target/host-modal-test.js b/ui/desktop/tests/integration/components/target/host-modal-test.js index 832aa03a3..93d61371c 100644 --- a/ui/desktop/tests/integration/components/target/host-modal-test.js +++ b/ui/desktop/tests/integration/components/target/host-modal-test.js @@ -18,13 +18,13 @@ module('Integration | Component | target/host-modal', function (hooks) { let hostA; let hostB; let connect; - let toggle; + let toggleModal; hooks.beforeEach(function () { connect = () => { this.set('called', true); }; - toggle = () => { + toggleModal = () => { this.set('called', true); }; store = this.owner.lookup('service:store'); @@ -47,13 +47,13 @@ module('Integration | Component | target/host-modal', function (hooks) { test('it renders', async function (assert) { assert.expect(1); this.set('connect', connect); - this.set('toggle', toggle); + this.set('toggleModal', toggleModal); this.set('hosts', [hostA, hostB]); this.set('target', target); await render(hbs``); @@ -67,14 +67,14 @@ module('Integration | Component | target/host-modal', function (hooks) { this.set('showModal', false); }; this.set('connect', connect); - this.set('toggle', toggleModal); + this.set('toggleModal', toggleModal); this.set('showModal', true); this.set('hosts', [hostA, hostB]); this.set('target', target); await render(hbs``); @@ -89,13 +89,13 @@ module('Integration | Component | target/host-modal', function (hooks) { test('it calls connect when Quick Connect button clicked', async function (assert) { assert.expect(1); this.set('connect', connect); - this.set('toggle', toggle); + this.set('toggleModal', toggleModal); this.set('hosts', [hostA, hostB]); this.set('target', target); await render(hbs``); @@ -108,13 +108,13 @@ module('Integration | Component | target/host-modal', function (hooks) { test('it calls connect when host item is clicked', async function (assert) { assert.expect(1); this.set('connect', connect); - this.set('toggle', toggle); + this.set('toggleModal', toggleModal); this.set('hosts', [hostA, hostB]); this.set('target', target); await render(hbs``);