diff --git a/ui/core/app/components/error/message.hbs b/ui/core/app/components/error/message.hbs new file mode 100644 index 000000000..90c471554 --- /dev/null +++ b/ui/core/app/components/error/message.hbs @@ -0,0 +1,6 @@ + + {{t (concat "errors." this.messageCode ".description")}} + {{#if this.helpRoute}} + {{t "actions.help"}} + {{/if}} + \ No newline at end of file diff --git a/ui/core/app/components/error/message.js b/ui/core/app/components/error/message.js new file mode 100644 index 000000000..21b362c5f --- /dev/null +++ b/ui/core/app/components/error/message.js @@ -0,0 +1,61 @@ +import Message from 'rose/components/rose/message'; +import { computed } from '@ember/object'; + +/* + * Helpful error booleans are attached based on the error status code: + * + * - 401 - `error.isUnauthenticated`: the session isn't authenticated + * - 403 - `error.isForbidden`: the session is authenticated but does not have + * permission to perform the requested action + * - 404 - `error.isNotFound`: the requested resource could not be found + * - 500 - `error.isServer`: an internal server error occurred + * + * For an unknown error state, i.e error state not matching to the above defined list: + * - unknown - `error.isUnknown`: an error occurred, but we don't know which or + * we don't distinguish it yet + */ + +const statuses = ['401', '403', '404', '500']; + +export default class ErrorMessageComponent extends Message { + // =methods + + /** + * Returns an icon for error status. + * @return {string} + */ + @computed('status') + get icon() { + switch (this.status) { + case '401': + case '403': + return 'disabled'; + case '404': + return 'help-circle-outline'; + default: + return 'alert-circle-outline'; + } + } + + // TODO: Enable when help documentation can be linked in. + /** + * Returns an route string for help text in message. + * @return {string} + */ + // get helpRoute() { + // return 'index' + // } + + /** + * Returns 'unknown' status code when provided error status + * isn't part of predefined statuses. + * @return {string} + */ + @computed('status') + get messageCode() { + let messageCode = this.status; + if(!statuses.includes(messageCode)) messageCode = 'unknown'; + return messageCode; + } + +} diff --git a/ui/core/app/templates/scopes/scope/error.hbs b/ui/core/app/templates/scopes/scope/error.hbs new file mode 100644 index 000000000..8d56c81ce --- /dev/null +++ b/ui/core/app/templates/scopes/scope/error.hbs @@ -0,0 +1,6 @@ +{{title (t "errors.titles.error") }} + + {{#each @model.errors as |error|}} + + {{/each}} + \ No newline at end of file diff --git a/ui/core/mirage/config.js b/ui/core/mirage/config.js index e7044298f..399d7f03e 100644 --- a/ui/core/mirage/config.js +++ b/ui/core/mirage/config.js @@ -1,6 +1,7 @@ import config from '../config/environment'; import { authHandler, deauthHandler } from './route-handlers/auth'; -//import { Response } from 'miragejs'; +// Uncomment to use in simulating error responses +// import { Response } from 'miragejs'; export default function() { @@ -292,4 +293,18 @@ export default function() { } return target.update(updatedAttrs); }); + + /* Uncomment the following line and the Response import above + * Then change the response code to simulate error responses. + * this.get('/scopes', () => new Response(505)); + * + * Update error payload to simulate specific error responses. + */ + // this.get('/host-catalogs', () => new Response(404)); + // this.get('/scopes/:id', () => new Response(505, {}, { + // errors: [{ + // status: 505, + // message: 'HTTP version not supported.', + // }] + // })); } diff --git a/ui/core/tests/integration/components/error/message-test.js b/ui/core/tests/integration/components/error/message-test.js new file mode 100644 index 000000000..2671c9b7e --- /dev/null +++ b/ui/core/tests/integration/components/error/message-test.js @@ -0,0 +1,37 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, find } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | error/message', function (hooks) { + setupRenderingTest(hooks); + + test('it renders predefined message for known error status', async function (assert) { + await render(hbs``); + assert.equal( + find('.rose-message-title').textContent.trim(), + 'You are not signed in' + ); + assert.equal( + find('.rose-message-subtitle').textContent.trim(), + 'Error 401' + ); + assert.equal( + find('.rose-message-description').textContent.trim(), + 'You are not authenticated. Please authenticate and try again later.' + ); + }); + + test('it renders default error for unknown error status', async function (assert) { + await render(hbs``); + assert.equal( + find('.rose-message-title').textContent.trim(), + 'Something went wrong' + ); + assert.equal(find('.rose-message-subtitle').textContent.trim(), 'Error 599'); + assert.equal( + find('.rose-message-description').textContent.trim(), + 'Please contact your administrator or try again later.' + ); + }); +}); diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index e458c2b50..fdfb779f9 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -158,19 +158,24 @@ form: current_password: Current Password new_password: New Password errors: + 401: + title: You are not signed in + description: You are not authenticated. Please authenticate and try again later. + 403: + title: You are not authorized + description: You must be granted permissions to view this data. Ask your administrator if you think you should have access. + 404: + title: Resource not found + description: We could not find the requested resource. You can ask your administrator or try again later. + 500: + title: Server error + 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. titles: - unauthenticated-error: You are not signed in - forbidden-error: You are not authorized - notfound-error: Resource not found - server-error: Server error - unknown-error: Something went wrong authentication-failed: Authentication Failed - descriptions: - unauthenticated-error: You are not authenticated. Please authenticate and try again later. - forbidden-error: You must be granted permissions to view this data. Ask your administrator if you think you should have access. - notfound-error: We could not find the requested resource. You can ask your administrator or try again later. - server-error: We ran into a problem and could not continue. You can ask your administrator or try again later. - unknown-error: Please contact your administrator or try again later. + error: Error notify: create-success: Created succesfully. save-success: Saved succesfully.