xref: /openbmc/webui-vue/src/plugins/toast.js (revision d36ac8a8be8636ddd0e64ce005d507b21bcdeb00)
1import { useToast } from 'bootstrap-vue-next';
2
3// Global toast plugin for Options API components
4// Bootstrap Vue Next's useToast is a composable that needs setup() context
5// This plugin makes it accessible globally via app.config.globalProperties
6
7let toastController = null;
8
9export const ToastPlugin = {
10  install(app) {
11    // Initialize toast controller in the app context
12    // This will be called once during app setup
13    app.mixin({
14      beforeCreate() {
15        // Only initialize once at the root
16        if (!toastController && this === this.$root) {
17          try {
18            toastController = useToast();
19          } catch (e) {
20            console.warn('Failed to initialize toast controller:', e);
21          }
22        }
23      },
24    });
25
26    // Provide global toast methods
27    app.config.globalProperties.$toast = {
28      show(options) {
29        if (toastController?.create) {
30          toastController.create(options);
31        } else {
32          console.warn('Toast controller not available:', options);
33        }
34      },
35      info(body, options = {}) {
36        this.show({
37          ...options,
38          body,
39          props: {
40            variant: 'info',
41            isStatus: true,
42            ...options.props,
43          },
44        });
45      },
46      success(body, options = {}) {
47        this.show({
48          ...options,
49          body,
50          props: {
51            variant: 'success',
52            isStatus: true,
53            interval: 10000,
54            // Note: Progress bar hidden via CSS in _toasts.scss (JS props don't work as documented in Bootstrap Vue Next 0.40.8)
55            ...options.props,
56          },
57        });
58      },
59      warning(body, options = {}) {
60        this.show({
61          ...options,
62          body,
63          props: {
64            variant: 'warning',
65            isStatus: true,
66            ...options.props,
67          },
68        });
69      },
70      danger(body, options = {}) {
71        this.show({
72          ...options,
73          body,
74          props: {
75            variant: 'danger',
76            isStatus: true,
77            ...options.props,
78          },
79        });
80      },
81    };
82  },
83};
84