Add danger toast

This commit is contained in:
Stanislav Romanov 2022-09-21 14:11:29 +03:00
parent d2b110ab84
commit 0a3fa41208
11 changed files with 170 additions and 33 deletions

View file

@ -0,0 +1 @@
export { Check as default } from 'ember-mdi';

View file

@ -1,6 +1,6 @@
{{#in-element this.toaster.destinationElement insertBefore=null}}
<div
class='absolute max-w-sm border rounded bg-base-7 shadow-sm'
class='absolute border rounded shadow-sm'
role='alert'
style={{this.style}}
{{did-insert this.didInsert}}

View file

@ -0,0 +1,20 @@
import ToastThemeComponent from './theme';
import { ExclamationThick } from 'ember-mdi';
export default class ToastDangerComponent extends ToastThemeComponent {
get bg() {
return 'bg-danger-light';
}
get color() {
return null;
}
get borderColor() {
return 'border-danger';
}
get icon() {
return ExclamationThick;
}
}

View file

@ -1,19 +0,0 @@
<Toast>
<div class='inline-flex flex-shrink-0 justify-center items-center self-start'>
<Icons::Loading @spin={{true}} class='mr-4' />
</div>
<div>
{{@text}}
</div>
<button
type='button'
class='ml-auto self-start'
{{! data-dismiss-target='#toast-default' }}
aria-label='Close'
{{on 'click' @onClose}}
>
<Icons::Close />
</button>
</Toast>

View file

@ -1,3 +1,24 @@
import Component from '@glimmer/component';
import ToastThemeComponent from './theme';
import { Check } from 'ember-mdi';
export default class ToastSuccessComponent extends Component {}
export default class ToastSuccessComponent extends ToastThemeComponent {
get bg() {
return 'bg-success-light';
}
get color() {
return null;
}
get borderColor() {
return 'border-success';
}
get icon() {
return Check;
}
get autoClose() {
return true;
}
}

View file

@ -0,0 +1,35 @@
<Toast
@autoClose={{this.autoClose}}
@onClose={{@onClose}}
class='{{this.bg}} {{this.color}} {{this.borderColor}} {{this.width}}'
as |toast|
>
<div class='flex items-center'>
{{#if this.icon}}
<div
class='inline-flex flex-shrink-0 justify-center items-center self-start'
>
<this.icon class='mr-4 {{this.color}}' />
</div>
{{/if}}
<div class='mr-4'>
{{#if @header}}
<div class='font-semibold mb-2'>{{@header}}</div>
{{/if}}
{{#if @text}}
{{@text}}
{{/if}}
</div>
<button
type='button'
class='ml-auto self-start'
{{! data-dismiss-target='#toast-default' }}
aria-label='Close'
{{on 'click' toast.invokeOnClose}}
>
<Icons::Close />
</button>
</div>
</Toast>

View file

@ -0,0 +1,19 @@
import Component from '@glimmer/component';
export default class ToastThemeComponent extends Component {
get bg() {
return 'bg-base-7';
}
get color() {
return null;
}
get borderColor() {
return null;
}
get width() {
return 'w-80';
}
}

View file

@ -26,6 +26,11 @@ export default class AdminKeysKeyEditController extends Controller {
try {
const key = await this.model.save(value);
this.toaster.successToast({
header: 'Success',
text: 'The key has been successfuly updated',
});
if (this.router.isActive('admin.keys.key')) {
await this.router.refresh('admin.keys.key', key.uid);
}

View file

@ -3,6 +3,7 @@ import { tracked } from '@glimmer/tracking';
import { hbs } from 'ember-template-imports';
import { action } from '@ember/object';
import SuccessToast from '../components/toast/success';
import DangerToast from '../components/toast/danger';
import TaskToast from '../components/toast/task';
export default class ToasterService extends Service {
@ -18,12 +19,23 @@ export default class ToasterService extends Service {
}
@action
successToast({ text }) {
successToast({ text, header }) {
const onClose = () => {
this.container = this.container.filter((item) => item !== wrapper);
};
const wrapper = hbs`<SuccessToast @text={{text}} @onClose={{onClose}} />`;
const wrapper = hbs`<SuccessToast @header={{header}} @text={{text}} @onClose={{onClose}} />`;
this.container = this.container.concat([wrapper]);
}
@action
dangerToast({ text, header }) {
const onClose = () => {
this.container = this.container.filter((item) => item !== wrapper);
};
const wrapper = hbs`<DangerToast @header={{header}} @text={{text}} @onClose={{onClose}} />`;
this.container = this.container.concat([wrapper]);
}

View file

@ -2,6 +2,7 @@ import { instance } from '../instance-initializers/application';
export default function query(path, options = {}) {
const session = instance.lookup('service:session');
const toaster = instance.lookup('service:toaster');
const { url, key } = session.data.authenticated;
const defaultHeaders = { 'Content-Type': 'application/json' };
const headers = new Headers(Object.assign(defaultHeaders, options.headers));
@ -15,13 +16,29 @@ export default function query(path, options = {}) {
Object.assign(options, { headers })
);
return fetch(req).then((response) => {
if (response.status === 204) {
return;
} else if (response.ok) {
return response.json();
} else {
throw new Error('Network response was not OK');
}
});
return fetch(req)
.then((response) => {
if (response.status === 204) {
return;
} else if (response.ok) {
return response.json();
} else {
response.json().then((reason) => {
toaster.dangerToast({
header: reason.type,
text: reason.message,
});
throw new Error('Network response was not OK');
});
}
})
.catch((response) => {
response.json().then((reason) => {
toaster.dangerToast({
header: reason.type,
text: reason.message,
});
});
});
}

View file

@ -0,0 +1,26 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'meiliadmin/tests/helpers';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | toast/theme', 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`<Toast::Theme />`);
assert.dom(this.element).hasText('');
// Template block usage:
await render(hbs`
<Toast::Theme>
template block text
</Toast::Theme>
`);
assert.dom(this.element).hasText('template block text');
});
});