diff --git a/core/frontend/bun.lockb b/core/frontend/bun.lockb index 6e157fedb1..62705370eb 100755 Binary files a/core/frontend/bun.lockb and b/core/frontend/bun.lockb differ diff --git a/core/frontend/package.json b/core/frontend/package.json index c6d91bf071..c74dd58817 100644 --- a/core/frontend/package.json +++ b/core/frontend/package.json @@ -16,6 +16,7 @@ "dependencies": { "@google/model-viewer": "^3.0.0", "@mdi/font": "^7.1.96", + "@sentry/vue": "^8.25.0", "@types/file-saver": "^2.0.5", "@types/lodash": "^4.14.175", "@types/marked": "^4.0.7", diff --git a/core/frontend/src/main.ts b/core/frontend/src/main.ts index 9255fa005f..fd913b9e44 100644 --- a/core/frontend/src/main.ts +++ b/core/frontend/src/main.ts @@ -1,3 +1,4 @@ +/// import './cosmos' import '@/style/css/vuetify-global.css' import '@/style/css/animations.css' @@ -9,6 +10,7 @@ import JsonViewer from 'vue-json-viewer' import VueTooltipDirective from 'vue-tooltip-directive' import VueDraggable from 'vuedraggable' import Vuetify from 'vuetify/lib' +import * as Sentry from "@sentry/vue"; import App from './App.vue' import DefaultTooltip from './components/common/DefaultTooltip.vue' @@ -33,6 +35,28 @@ Vue.component('VTour', VTour) Vue.component('VStep', VStep) Vue.prototype.$tours = {} +const project = 'BlueOS' +// Avoid logging local development +const version = import.meta.env.VITE_APP_GIT_DESCRIBE +const release = `${project}@${version}` +console.info(`Running: ${release}`) +if (version) { + Sentry.init({ + Vue, + release: release, + dsn: "https://d87285a04a74f71aac13445f60506708@o4507696465707008.ingest.us.sentry.io/4507765318615040", + integrations: [ + Sentry.browserTracingIntegration({ router }), + Sentry.replayIntegration(), + ], + tracesSampleRate: 1.0, + tracePropagationTargets: [], + replaysSessionSampleRate: 0.1, + replaysOnErrorSampleRate: 1.0, + transport: Sentry.makeBrowserOfflineTransport(Sentry.makeFetchTransport), + }) +} + new Vue({ router, store, diff --git a/core/frontend/vite.config.js b/core/frontend/vite.config.js index 3070a41d4a..47f6ab73e5 100644 --- a/core/frontend/vite.config.js +++ b/core/frontend/vite.config.js @@ -1,7 +1,7 @@ import vue from '@vitejs/plugin-vue2' import { VuetifyResolver } from 'unplugin-vue-components/resolvers' import Components from 'unplugin-vue-components/vite' -import { defineConfig } from 'vite' +import { defineConfig, loadEnv } from 'vite' import { VitePWA } from 'vite-plugin-pwa' const { name } = require('./package.json') @@ -16,160 +16,164 @@ const assert = require('assert'); // TODO: check if it works with https once we have something that does assert.ok(SERVER_ADDRESS.startsWith('http://'), 'SERVER_ADDRESS must start with http://'); -export default defineConfig({ - plugins: [ - vue(), - VitePWA({ - registerType: 'autoUpdate', - devOptions: { - enabled: true, +export default defineConfig(({ command, mode }) => { + const env = loadEnv(mode, process.cwd(), '') + return { + plugins: [ + vue(), + VitePWA({ + registerType: 'autoUpdate', + devOptions: { + enabled: true, + }, + includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'masked-icon.svg'], + }), + Components({ + // generate `components.d.ts` global declarations + // https://github.com/antfu/unplugin-vue-components#typescript + dts: true, + // auto import for directives + directives: false, + // resolvers for custom components + resolvers: [ + // Vuetify + VuetifyResolver(), + ], + // https://github.com/antfu/unplugin-vue-components#types-for-global-registered-components + types: [ + { + from: 'vue-router', + names: ['RouterLink', 'RouterView'], + }, + ], + // Vue version of project. + version: 2.7, + }), + ], + assetsInclude: ['**/*.gif', '**/*.glb', '**/*.png', '**/*.svg', '**/assets/ArduPilot-Parameter-Repository**.json'], + resolve: { + extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], + alias: { + '@': path.resolve(__dirname, './src'), }, - includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'masked-icon.svg'], - }), - Components({ - // generate `components.d.ts` global declarations - // https://github.com/antfu/unplugin-vue-components#typescript - dts: true, - // auto import for directives - directives: false, - // resolvers for custom components - resolvers: [ - // Vuetify - VuetifyResolver(), - ], - // https://github.com/antfu/unplugin-vue-components#types-for-global-registered-components - types: [ - { - from: 'vue-router', - names: ['RouterLink', 'RouterView'], - }, - ], - // Vue version of project. - version: 2.7, - }), - ], - assetsInclude: ['**/*.gif', '**/*.glb', '**/*.png', '**/*.svg', '**/assets/ArduPilot-Parameter-Repository**.json'], - resolve: { - extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], - alias: { - '@': path.resolve(__dirname, './src'), }, - }, - build: { - rollupOptions: { - input: { - main: path.resolve(__dirname, 'index.html'), + build: { + rollupOptions: { + input: { + main: path.resolve(__dirname, 'index.html'), + }, }, }, - }, - define: { - 'process.env': {}, - }, - server: { - port: 8080, - proxy: { - '^/status': { - target: SERVER_ADDRESS, - }, - '^/ardupilot-manager': { - target: SERVER_ADDRESS, - }, - '^/bag': { - target: SERVER_ADDRESS, - }, - '^/beacon': { - target: SERVER_ADDRESS, - }, - '^/bridget': { - target: SERVER_ADDRESS, - }, - '^/cable-guy': { - target: SERVER_ADDRESS, - }, - '^/commander': { - target: SERVER_ADDRESS, - }, - '^/docker': { - target: SERVER_ADDRESS, - }, - '^/file-browser': { - target: SERVER_ADDRESS, - }, - '^/helper': { - target: SERVER_ADDRESS, - }, - '^/upload': { - target: SERVER_ADDRESS, - }, - '^/kraken': { - target: SERVER_ADDRESS, - onProxyRes: (proxyRes, request, response) => { - proxyRes.on('data', (data) => { - response.write(data) - }) - proxyRes.on('end', () => { - response.end() - }) + define: { + 'process.env': {}, + __APP_ENV__: env.APP_ENV, + }, + server: { + port: 8080, + proxy: { + '^/status': { + target: SERVER_ADDRESS, }, - }, - '^/nmea-injector': { - target: SERVER_ADDRESS, - }, - '^/logviewer': { - target: SERVER_ADDRESS, - }, - '^/mavlink': { - target: SERVER_ADDRESS, - changeOrigin: true, - ws: true, - }, - '^/mavlink2rest': { - target: SERVER_ADDRESS, - changeOrigin: true, - ws: true, - }, - '^/mavlink-camera-manager': { - target: SERVER_ADDRESS, - }, - '^/network-test': { - target: SERVER_ADDRESS, - changeOrigin: true, - ws: true, - }, - '^/ping': { - target: SERVER_ADDRESS, - }, - '^/system-information': { - target: SERVER_ADDRESS, - changeOrigin: true, - ws: true, - }, - '^/terminal': { - target: SERVER_ADDRESS, - changeOrigin: true, - ws: true, - }, - '^/userdata': { - target: SERVER_ADDRESS, - changeOrigin: true, - }, - '^/vehicles': { - target: SERVER_ADDRESS, - }, - '^/version-chooser': { - target: SERVER_ADDRESS, - onProxyRes: (proxyRes, request, response) => { - proxyRes.on('data', (data) => { - response.write(data) - }) - proxyRes.on('end', () => { - response.end() - }) + '^/ardupilot-manager': { + target: SERVER_ADDRESS, + }, + '^/bag': { + target: SERVER_ADDRESS, + }, + '^/beacon': { + target: SERVER_ADDRESS, + }, + '^/bridget': { + target: SERVER_ADDRESS, + }, + '^/cable-guy': { + target: SERVER_ADDRESS, + }, + '^/commander': { + target: SERVER_ADDRESS, + }, + '^/docker': { + target: SERVER_ADDRESS, + }, + '^/file-browser': { + target: SERVER_ADDRESS, + }, + '^/helper': { + target: SERVER_ADDRESS, + }, + '^/upload': { + target: SERVER_ADDRESS, + }, + '^/kraken': { + target: SERVER_ADDRESS, + onProxyRes: (proxyRes, request, response) => { + proxyRes.on('data', (data) => { + response.write(data) + }) + proxyRes.on('end', () => { + response.end() + }) + }, + }, + '^/nmea-injector': { + target: SERVER_ADDRESS, + }, + '^/logviewer': { + target: SERVER_ADDRESS, + }, + '^/mavlink': { + target: SERVER_ADDRESS, + changeOrigin: true, + ws: true, + }, + '^/mavlink2rest': { + target: SERVER_ADDRESS, + changeOrigin: true, + ws: true, + }, + '^/mavlink-camera-manager': { + target: SERVER_ADDRESS, + }, + '^/network-test': { + target: SERVER_ADDRESS, + changeOrigin: true, + ws: true, + }, + '^/ping': { + target: SERVER_ADDRESS, + }, + '^/system-information': { + target: SERVER_ADDRESS, + changeOrigin: true, + ws: true, + }, + '^/terminal': { + target: SERVER_ADDRESS, + changeOrigin: true, + ws: true, + }, + '^/userdata': { + target: SERVER_ADDRESS, + changeOrigin: true, + }, + '^/vehicles': { + target: SERVER_ADDRESS, + }, + '^/version-chooser': { + target: SERVER_ADDRESS, + onProxyRes: (proxyRes, request, response) => { + proxyRes.on('data', (data) => { + response.write(data) + }) + proxyRes.on('end', () => { + response.end() + }) + }, + }, + '^/wifi-manager': { + target: SERVER_ADDRESS, }, - }, - '^/wifi-manager': { - target: SERVER_ADDRESS, }, }, - }, + } })