import { createApp } from 'vue'; import { setConfig, frappeRequest, pageMetaPlugin, resourcesPlugin, } from 'jingrow-ui'; import App from './App.vue'; import router from './router'; import { initSocket } from './socket'; import { subscribeToJobUpdates } from './utils/agentJob'; import { fetchPlans } from './data/plans.js'; import * as Sentry from '@sentry/vue'; import { session } from './data/session.js'; import { unreadNotificationsCount } from './data/notifications.js'; import registerGlobalComponents from './components/global/register'; import './vendor/posthog.js'; const request = (options) => { const _options = options || {}; _options.headers = options.headers || {}; const currentTeam = localStorage.getItem('current_team') || window.default_team; if (currentTeam) { _options.headers['X-Press-Team'] = currentTeam; } return frappeRequest(_options); }; setConfig('resourceFetcher', request); setConfig('defaultListUrl', 'press.api.client.get_list'); setConfig('defaultDocGetUrl', 'press.api.client.get'); setConfig('defaultDocInsertUrl', 'press.api.client.insert'); setConfig('defaultRunDocMethodUrl', 'press.api.client.run_pg_method'); setConfig('defaultDocUpdateUrl', 'press.api.client.set_value'); setConfig('defaultDocDeleteUrl', 'press.api.client.delete'); let app; let socket; getInitialData().then(() => { app = createApp(App); app.use(router); app.use(resourcesPlugin); app.use(pageMetaPlugin); registerGlobalComponents(app); socket = initSocket(); app.config.globalProperties.$socket = socket; window.$socket = socket; subscribeToJobUpdates(socket); if (session.isLoggedIn) { fetchPlans(); session.roles.fetch(); unreadNotificationsCount.fetch(); } if (window.press_dashboard_sentry_dsn.includes('https://')) { Sentry.init({ app, dsn: window.press_dashboard_sentry_dsn, integrations: [ Sentry.browserTracingIntegration({ router }), Sentry.replayIntegration({ maskAllText: false, blockAllMedia: false, }), Sentry.thirdPartyErrorFilterIntegration({ // Specify the application keys that you specified in the Sentry bundler plugin filterKeys: ['press-dashboard'], // Defines how to handle errors that contain third party stack frames. // Possible values are: // - 'drop-error-if-contains-third-party-frames' // - 'drop-error-if-exclusively-contains-third-party-frames' // - 'apply-tag-if-contains-third-party-frames' // - 'apply-tag-if-exclusively-contains-third-party-frames' behaviour: 'apply-tag-if-contains-third-party-frames', }), ], tracesSampleRate: 1.0, replaysSessionSampleRate: 0.1, replaysOnErrorSampleRate: 1.0, beforeSend(event, hint) { const ignoreErrors = [ // /api\/method\/press.api.client/, // /dynamically imported module/, // /NetworkError when attempting to fetch resource/, // /Failed to fetch/, // /Load failed/, // /jingrow is not defined/, // /Cannot read properties of undefined \(reading 'exc_type'\)/, // /Failed to execute 'transaction' on 'IDBDatabase': The database connection is closing/, // /Importing a module script failed./, // /o is undefined/, // /undefined is not an object \(evaluating 'o.exc_type'\)/, // /e is not defined/, // /Cannot set property ethereum of # which has only a getter/, // /Can't find variable: ResizeObserver/, // /Method not found/, // /Menu caption text is required/, // /Internal error opening backing store for indexedDB.open/, ]; const ignoreErrorTypes = [ // 'BuildValidationError', // 'ValidationError', // 'PermissionError', // 'SecurityException', // 'AAAARecordExists', // 'AuthenticationError', // 'RateLimitExceededError', // 'InsufficientSpaceOnServer', // 'ConflictingDNSRecord', // 'MultipleARecords', ]; const error = hint.originalException; if ( error?.name === 'DashboardError' || ignoreErrorTypes.includes(error?.exc_type) || (error?.message && ignoreErrors.some((re) => re.test(error.message))) ) { return null; } return event; }, logErrors: true, }); Sentry.setTag('team', localStorage.getItem('current_team')); } if ( window.press_frontend_posthog_project_id && window.press_frontend_posthog_host && window.posthog ) { window.posthog.init(window.press_frontend_posthog_project_id, { api_host: window.press_frontend_posthog_host, person_profiles: 'identified_only', autocapture: false, disable_session_recording: true, session_recording: { maskAllInputs: true, maskInputFn: (text, element) => { if (element?.dataset['record'] === 'true') { return text; } return '*'.repeat(text.trim().length); }, }, }); } else { // unset posthog if not configured window.posthog = undefined; } importGlobals().then(() => { app.mount('#app'); }); }); function getInitialData() { if (import.meta.env.DEV) { return frappeRequest({ url: '/api/method/press.www.dashboard.get_context_for_dev', }).then((values) => Object.assign(window, values)); } else { return Promise.resolve(); } } function importGlobals() { return import('./globals.ts').then((globals) => { app.use(globals.default); }); }