diff --git a/addons/core/tests/integration/components/error/message-test.js b/addons/core/tests/integration/components/error/message-test.js
index f7e92a534..47651bd89 100644
--- a/addons/core/tests/integration/components/error/message-test.js
+++ b/addons/core/tests/integration/components/error/message-test.js
@@ -60,7 +60,7 @@ module('Integration | Component | error/message', function (hooks) {
);
assert.equal(
find('.rose-message-description').textContent.trim(),
- 'Please contact your administrator or try again later.'
+ 'We\'re not sure what happened. Please contact your administrator or try again later.'
);
});
});
diff --git a/addons/core/translations/actions/en-us.yaml b/addons/core/translations/actions/en-us.yaml
index 89165233a..1c4c2483a 100644
--- a/addons/core/translations/actions/en-us.yaml
+++ b/addons/core/translations/actions/en-us.yaml
@@ -3,6 +3,7 @@ cancel: Cancel
delete: Delete
remove: Remove
discard: Discard
+disconnect: Disconnect
dismiss: Dismiss
save: Save
submit: Submit
diff --git a/addons/core/translations/errors/en-us.yaml b/addons/core/translations/errors/en-us.yaml
index c814611d0..0f05b94a7 100644
--- a/addons/core/translations/errors/en-us.yaml
+++ b/addons/core/translations/errors/en-us.yaml
@@ -12,7 +12,7 @@
description: We ran into a problem and could not continue. You can ask your administrator or try again later.
unknown:
title: Something went wrong
- description: Please contact your administrator or try again later.
+ description: We're not sure what happened. Please contact your administrator or try again later.
generic:
title: Error
authentication-failed:
diff --git a/ui/desktop/app/routes/application.js b/ui/desktop/app/routes/application.js
index 45c73b24a..f32dbf9bc 100644
--- a/ui/desktop/app/routes/application.js
+++ b/ui/desktop/app/routes/application.js
@@ -71,6 +71,16 @@ export default class ApplicationRoute extends Route.extend(
this.session.invalidate();
}
+ /**
+ * Disconnects from origin and invalidates session, thereby resetting
+ * the client and reloading to the onboarding origin screen.
+ */
+ @action
+ disconnect() {
+ this.origin.resetOrigin();
+ this.invalidateSession();
+ }
+
/**
* Hooks into ember-loading to kick off loading indicator in the
* application template.
diff --git a/ui/desktop/app/services/origin.js b/ui/desktop/app/services/origin.js
index ba280a1ae..e72a738f0 100644
--- a/ui/desktop/app/services/origin.js
+++ b/ui/desktop/app/services/origin.js
@@ -1,6 +1,7 @@
import Service from '@ember/service';
import { assert } from '@ember/debug';
import { inject as service } from '@ember/service';
+import { notifyError } from 'core/decorators/notify';
export default class OriginService extends Service {
@@ -72,4 +73,13 @@ export default class OriginService extends Service {
}
}
+ /**
+ * Resets the origin.
+ */
+ @notifyError(({ message }) => message, { catch: true })
+ async resetOrigin() {
+ this.rendererOrigin = null;
+ await this.ipc.invoke('resetOrigin');
+ }
+
}
diff --git a/ui/desktop/app/templates/error.hbs b/ui/desktop/app/templates/error.hbs
index c93470673..f5fcb9fbf 100644
--- a/ui/desktop/app/templates/error.hbs
+++ b/ui/desktop/app/templates/error.hbs
@@ -1,7 +1,15 @@
{{page-title (t "errors.generic.title") }}
+
+
+
+
+ {{t "actions.disconnect"}}
+
+
+
diff --git a/ui/desktop/app/templates/scopes/scope/projects/error.hbs b/ui/desktop/app/templates/scopes/scope/projects/error.hbs
new file mode 100644
index 000000000..57529c9f8
--- /dev/null
+++ b/ui/desktop/app/templates/scopes/scope/projects/error.hbs
@@ -0,0 +1,23 @@
+{{page-title (t "errors.generic.title") }}
+
+{{! Most error types will land here }}
+{{#if @model.errors}}
+
+ {{#each @model.errors as |error|}}
+
+ {{/each}}
+
+{{/if}}
+
+{{! But a disconnected state doesn't get normalized errors }}
+{{#unless @model.errors}}
+
+
+
+
+
+
+ {{t "actions.disconnect"}}
+
+
+{{/unless}}
diff --git a/ui/desktop/electron-app/src/handlers.js b/ui/desktop/electron-app/src/handlers.js
index f4b9a62b4..948e82c51 100644
--- a/ui/desktop/electron-app/src/handlers.js
+++ b/ui/desktop/electron-app/src/handlers.js
@@ -17,6 +17,13 @@ handle('setOrigin', async (requestOrigin) => {
origin.origin = requestOrigin;
});
+/**
+ * Resets the origin.
+ */
+handle('resetOrigin', async (requestOrigin) => {
+ origin.resetOrigin();
+});
+
/**
* Check for boundary cli existence
*/
diff --git a/ui/desktop/electron-app/src/origin.js b/ui/desktop/electron-app/src/origin.js
index f4461e8f0..7d85e4466 100644
--- a/ui/desktop/electron-app/src/origin.js
+++ b/ui/desktop/electron-app/src/origin.js
@@ -24,7 +24,7 @@ class RuntimeSettings {
}
/**
- *
+ * Validates the origin is reachable and has a scopes endpoint.
*/
async validateOrigin(origin) {
// If the origin is the Electron origin, it is automatically valid.
@@ -40,6 +40,13 @@ class RuntimeSettings {
}
}
+ /**
+ * Sets the origin to null.
+ */
+ async resetOrigin() {
+ this.origin = null;
+ }
+
// Quick and dirty event handler pattern to enable the application to respond
// when the origin is changed.
#originWatchers = [];