blob: 0d9fff5f3f050296491fb710f0b6133c41add156 [file] [log] [blame]
import { h } from 'vue';
import StatusIcon from '../Global/StatusIcon';
import i18n from '@/i18n';
const BVToastMixin = {
components: {
StatusIcon,
},
methods: {
$_BVToastMixin_createTitle(title, status) {
const statusIcon = h(StatusIcon, { status });
return h('strong', { class: 'toast-icon' }, [statusIcon, title]);
},
$_BVToastMixin_createBody(messageBody) {
if (Array.isArray(messageBody)) {
return messageBody.map((message) => h('p', { class: 'mb-0' }, message));
} else {
return [h('p', { class: 'mb-0' }, messageBody)];
}
},
$_BVToastMixin_createTimestamp() {
const timestamp = this.$filters.formatTime(new Date());
return h('p', { class: 'mt-3 mb-0' }, timestamp);
},
$_BVToastMixin_createRefreshAction() {
return h(
'BLink',
{
class: 'd-inline-block mt-3',
onClick: () => {
require('@/eventBus').default.$emit('refresh-application');
},
},
i18n.global.t('global.action.refresh'),
);
},
$_BVToastMixin_initToast(body, title, variant) {
// Use global toast plugin (works with Options API)
// Extract text content from VNodes for display
// Extract title text from VNode
const titleText =
typeof title === 'string'
? title
: title?.children?.[1] || title?.children || '';
// Extract body text from VNode array
// Each VNode (paragraph) should be on its own line
const bodyLines = Array.isArray(body)
? body.map((node) => {
if (typeof node === 'string') return node;
// Extract text from VNode children
const text = node?.children || node?.props?.children || '';
// Ensure timestamps and other paragraphs are on separate lines
return text;
})
: [typeof body === 'string' ? body : body?.children || ''];
// Join with newlines to ensure timestamps appear on their own line
const bodyText = bodyLines.filter(Boolean).join('\n');
// Show toast via global plugin
if (this.$toast) {
this.$toast.show({
body: bodyText,
props: {
title: titleText,
variant,
isStatus: true,
solid: false, // Use light backgrounds with dark text (not solid colors)
// Success toasts auto-dismiss after 10s, others stay until closed
interval: variant === 'success' ? 10000 : 0,
// Note: Progress bar hidden via CSS in _toasts.scss (JS props to hide progress bar don't work as documented in Bootstrap Vue Next 0.40.8)
},
});
} else {
// Fallback: log to console
/* eslint-disable no-console */
console[variant === 'danger' ? 'error' : 'log'](
`[toast:${variant}]`,
bodyText,
);
/* eslint-enable no-console */
}
},
successToast(
message,
{
title: t = i18n.global.t('global.status.success'),
timestamp,
refreshAction,
} = {},
) {
const body = this.$_BVToastMixin_createBody(message);
const title = this.$_BVToastMixin_createTitle(t, 'success');
if (refreshAction) body.push(this.$_BVToastMixin_createRefreshAction());
if (timestamp) {
body.push(' '); // Extra newline for spacing above timestamp
body.push(this.$_BVToastMixin_createTimestamp());
}
this.$_BVToastMixin_initToast(body, title, 'success');
},
errorToast(
message,
{
title: t = i18n.global.t('global.status.error'),
timestamp,
refreshAction,
} = {},
) {
const body = this.$_BVToastMixin_createBody(message);
const title = this.$_BVToastMixin_createTitle(t, 'danger');
if (refreshAction) body.push(this.$_BVToastMixin_createRefreshAction());
if (timestamp) {
body.push(' '); // Extra newline for spacing above timestamp
body.push(this.$_BVToastMixin_createTimestamp());
}
this.$_BVToastMixin_initToast(body, title, 'danger');
},
warningToast(
message,
{
title: t = i18n.global.t('global.status.warning'),
timestamp,
refreshAction,
} = {},
) {
const body = this.$_BVToastMixin_createBody(message);
const title = this.$_BVToastMixin_createTitle(t, 'warning');
if (refreshAction) body.push(this.$_BVToastMixin_createRefreshAction());
if (timestamp) {
body.push(' '); // Extra newline for spacing above timestamp
body.push(this.$_BVToastMixin_createTimestamp());
}
this.$_BVToastMixin_initToast(body, title, 'warning');
},
infoToast(
message,
{
title: t = i18n.global.t('global.status.informational'),
timestamp,
refreshAction,
} = {},
) {
const body = this.$_BVToastMixin_createBody(message);
const title = this.$_BVToastMixin_createTitle(t, 'info');
if (refreshAction) body.push(this.$_BVToastMixin_createRefreshAction());
if (timestamp) {
body.push(' '); // Extra newline for spacing above timestamp
body.push(this.$_BVToastMixin_createTimestamp());
}
this.$_BVToastMixin_initToast(body, title, 'info');
},
},
};
export default BVToastMixin;