1import { createApp, h } from "vue";
2import {
3 Badge,
4 Button,
5 Dialog,
6 ErrorMessage,
7 FormControl,
8 frappeRequest,
9 FrappeUI,
10 setConfig,
11 TextInput,
12 toast,
13 Tooltip,
14} from "frappe-ui";
15import { createPinia } from "pinia";
16import App from "./App.vue";
17import { spritePlugin } from "frappe-ui/experimental";
18import { createDialog } from "./components/dialogs";
19import "./index.css";
20import { router } from "./router";
21import { telemetryPlugin } from "@framework/ui";
22import { translationPlugin } from "./translation";
23import CircleAlert from "~icons/lucide/circle-alert";
24import { initSocket } from "./socket";
25
26const globalComponents = {
27 Badge,
28 Button,
29 Dialog,
30 ErrorMessage,
31 FormControl,
32 Tooltip,
33 TextInput,
34};
35
36// Attached to the fetcher, not set as the global `serverMessagesHandler`: the
37// global one also governs `call()`, which beta.63 started routing a response's
38// `_server_messages` through. Resources keep toasting, `call()` stays silent.
39setConfig("resourceFetcher", (options) =>
40 frappeRequest({ ...options, onServerMessages: showServerMessages })
41);
42
43function showServerMessages(msgs) {
44 msgs.forEach((msg) => {
45 msg = JSON.parse(msg);
46 // `alert` is frappe's own flag for throwaway desk chatter ("Document
47 // renamed from X to Y"), which our own toasts already cover. No opendesk
48 // msgprint sets it.
49 if (!msg || msg.alert) return;
50 if (msg.message == "Feedback email has been sent to the customer.") {
51 toast.success(msg.message);
52 return;
53 }
54 toast(msg.message, {
55 icon: () => h(CircleAlert, { class: "text-ink-blue-5" }),
56 });
57 });
58}
59setConfig("fallbackErrorHandler", (error) => {
60 const msg = error.exc_type
61 ? (error.messages || error.message || []).join(", ")
62 : error.message;
63 toast.error(msg);
64});
65
66const pinia = createPinia();
67const app = createApp(App);
68
69app.use(FrappeUI);
70app.use(spritePlugin);
71app.use(pinia);
72app.use(router);
73app.use(translationPlugin);
74app.use(telemetryPlugin, { app_name: "opendesk" });
75
76for (const c in globalComponents) {
77 app.component(c, globalComponents[c]);
78}
79
80app.config.globalProperties.$dialog = createDialog;
81
82let socket;
83if (import.meta.env.DEV) {
84 frappeRequest({
85 url: "/api/method/opendesk.www.opendesk.index.get_context_for_dev",
86 }).then((values) => {
87 for (let key in values) {
88 window[key] = values[key];
89 }
90 if (window.dir) document.documentElement.dir = window.dir;
91 if (window.lang) document.documentElement.lang = window.lang;
92 socket = initSocket();
93 app.config.globalProperties.$socket = socket;
94 app.mount("#app");
95 });
96} else {
97 socket = initSocket();
98 app.config.globalProperties.$socket = socket;
99 app.mount("#app");
100}
101