feat: Introduce error component
This commit is contained in:
8 files changed
+162
-3
No files matched your search
@@ -0,0 +1,4 @@
|
||||
<Rose::Message @title={{t this.title}} @subtitle={{t this.subtitle}} @icon={{this.icon}} as |message|>
|
||||
<message.description>{{t this.description}}</message.description>
|
||||
<message.link @route={{this.helpRoute}}>{{t "actions.help"}}</message.link>
|
||||
</Rose::Message>
|
||||
@@ -0,0 +1,104 @@
|
||||
import Message from 'rose/components/rose/message';
|
||||
|
||||
/*
|
||||
* 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 status_messages = {
|
||||
'401' : {
|
||||
icon: 'disabled',
|
||||
title: 'errors.titles.unauthenticated-error',
|
||||
subtitle: 'errors.subtitles.unauthenticated-error',
|
||||
description: 'errors.descriptions.unauthenticated-error',
|
||||
},
|
||||
'403' : {
|
||||
icon: 'disabled',
|
||||
title: 'errors.titles.forbidden-error',
|
||||
subtitle: 'errors.subtitles.forbidden-error',
|
||||
description: 'errors.descriptions.forbidden-error',
|
||||
},
|
||||
'404' : {
|
||||
icon: 'help-circle-outline',
|
||||
title: 'errors.titles.notfound-error',
|
||||
subtitle: 'errors.subtitles.notfound-error',
|
||||
description: 'errors.descriptions.notfound-error',
|
||||
},
|
||||
'500' : {
|
||||
icon: 'alert-circle-outline',
|
||||
title: 'errors.titles.server-error',
|
||||
subtitle: 'errors.subtitles.server-error',
|
||||
description: 'errors.descriptions.server-error',
|
||||
},
|
||||
'unknown' : {
|
||||
icon: 'alert-circle-outline',
|
||||
title: 'errors.titles.unknown-error',
|
||||
subtitle: 'errors.subtitles.unknown-error',
|
||||
description: 'errors.descriptions.unknown-error',
|
||||
}
|
||||
};
|
||||
|
||||
export default class ErrorMessageComponent extends Message {
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Returns an icon name based on error status.
|
||||
* @return {string}
|
||||
*/
|
||||
get icon() {
|
||||
return this.statusMessage.icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a message title based on error status.
|
||||
* @return {string}
|
||||
*/
|
||||
get title() {
|
||||
return this.statusMessage.title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a message subtitle of error status prefixed with 'Error'.
|
||||
* @return {string}
|
||||
*/
|
||||
get subtitle() {
|
||||
return this.statusMessage.subtitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an error description based on error status.
|
||||
* @return {string}
|
||||
*/
|
||||
get description() {
|
||||
return this.statusMessage.description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an route string for help text in message.
|
||||
* @return {string}
|
||||
*/
|
||||
get helpRoute() {
|
||||
return 'index'
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object with message details based on error status.
|
||||
* Return message for `unkown` error when error status isn't part of
|
||||
* predefined message set.
|
||||
* @return {object}
|
||||
*/
|
||||
get statusMessage() {
|
||||
let status = this.status;
|
||||
if(!status_messages[status]) { status = 'unknown'; }
|
||||
return status_messages[status];
|
||||
}
|
||||
}
|
||||
@@ -50,8 +50,6 @@ export default class ApplicationRoute extends Route.extend(
|
||||
if (!Ember.testing) later(location, location.reload, 150);
|
||||
}
|
||||
|
||||
// =actions
|
||||
|
||||
/**
|
||||
* Delegates invalidation to the session service.
|
||||
*/
|
||||
|
||||
@@ -33,4 +33,5 @@ export default class ScopesScopeRoute extends Route {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<Rose::Layout::Centered>
|
||||
{{#each @model.errors as |error|}}
|
||||
{{title error.status}}
|
||||
<Error::Message @status={{error.status}}/>
|
||||
{{/each}}
|
||||
</Rose::Layout::Centered>
|
||||
@@ -1,6 +1,6 @@
|
||||
import config from '../config/environment';
|
||||
import { authHandler, deauthHandler } from './route-handlers/auth';
|
||||
//import { Response } from 'miragejs';
|
||||
import { Response } from 'miragejs';
|
||||
|
||||
export default function() {
|
||||
|
||||
@@ -288,4 +288,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.',
|
||||
// }]
|
||||
// }));
|
||||
}
|
||||
@@ -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 | error/message', 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`<Error::Message />`);
|
||||
|
||||
assert.equal(this.element.textContent.trim(), '');
|
||||
|
||||
// Template block usage:
|
||||
await render(hbs`
|
||||
<Error::Message>
|
||||
template block text
|
||||
</Error::Message>
|
||||
`);
|
||||
|
||||
assert.equal(this.element.textContent.trim(), 'template block text');
|
||||
});
|
||||
});
|
||||
@@ -162,6 +162,12 @@ errors:
|
||||
server-error: Server error
|
||||
unknown-error: Something went wrong
|
||||
authentication-failed: Authentication Failed
|
||||
subtitles:
|
||||
unauthenticated-error: Error 401
|
||||
forbidden-error: Error 403
|
||||
notfound-error: Error 404
|
||||
server-error: Error 500
|
||||
unknown-error: Error
|
||||
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.
|
||||
|
||||
Reference in new issue
Block a user