/** * Copyright (c) HashiCorp, Inc. * SPDX-License-Identifier: BUSL-1.1 */ import Service, { inject as service } from '@ember/service'; import callableType from 'consul-ui/utils/callable-type'; const TYPE_SUCCESS = 'success'; const TYPE_ERROR = 'error'; const defaultStatus = function (type, obj) { return type; }; const notificationDefaults = function () { return { timeout: 6000, extendedTimeout: 300, destroyOnClick: true, }; }; export default class FeedbackService extends Service { @service('flashMessages') notify; @service('logger') logger; notification(action, modelName) { return { success: (item) => this.success(item, action, undefined, modelName), error: (e) => this.error(e, action, undefined, modelName), }; } success(item, action, status = defaultStatus, model) { const getAction = callableType(action); const getStatus = callableType(status); // returning exactly `false` for a feedback action means even though // its successful, please skip this notification and don't display it if (item !== false) { this.notify.clearMessages(); // TODO right now the majority of `item` is a Transition // but you can resolve an object this.notify.add({ ...notificationDefaults(), type: getStatus(TYPE_SUCCESS), // here.. action: getAction(), item: item, model: model, }); } } error(e, action, status = defaultStatus, model) { const getAction = callableType(action); const getStatus = callableType(status); this.notify.clearMessages(); this.logger.execute(e); if (e.name === 'TransitionAborted') { this.notify.add({ ...notificationDefaults(), type: getStatus(TYPE_SUCCESS), // and here action: getAction(), model: model, }); } else { this.notify.add({ ...notificationDefaults(), type: getStatus(TYPE_ERROR, e), action: getAction(), error: e, model: model, }); } } async execute(handle, action, status, routeName) { let result; try { result = await handle(); this.success(result, action, status, routeName); } catch (e) { this.error(e, action, status, routeName); } } }