From 9aae5b721b8dbb51f8469521e03ed32d926956b8 Mon Sep 17 00:00:00 2001 From: Wilfred Asomani Date: Tue, 16 Jan 2024 10:54:44 +0000 Subject: [PATCH] web/satellite/v2: support v2 app on root path This change updates the v2 app to support being served on the root path of the console server. This includes conditionally setting the root of the vue router as v2 or not and making sure internal links work correctly regardless of how the app is being served. Issue: #6681 Change-Id: Iaa5e147adcd79aa06d4f9857200de90f46131f19 --- web/satellite/index-vuetify.html | 24 ++++++++++++ .../src/store/modules/configStore.ts | 3 ++ web/satellite/src/utils/httpClient.ts | 3 +- .../src/layouts/default/AppBar.vue | 6 +-- web/satellite/vuetify-poc/src/main.ts | 7 +++- .../vuetify-poc/src/plugins/index.ts | 24 +++++++----- web/satellite/vuetify-poc/src/router/index.ts | 37 ++++++++++--------- web/satellite/vuetify-poc/src/views/Login.vue | 2 +- .../vuetify-poc/src/views/PasswordReset.vue | 2 +- .../vuetify-poc/src/views/Signup.vue | 2 +- 10 files changed, 75 insertions(+), 35 deletions(-) diff --git a/web/satellite/index-vuetify.html b/web/satellite/index-vuetify.html index 6b93be87e198..4e399fc450ed 100644 --- a/web/satellite/index-vuetify.html +++ b/web/satellite/index-vuetify.html @@ -6,8 +6,32 @@ Storj + + +
diff --git a/web/satellite/src/store/modules/configStore.ts b/web/satellite/src/store/modules/configStore.ts index 17e812e996f3..841c2ad7b00b 100644 --- a/web/satellite/src/store/modules/configStore.ts +++ b/web/satellite/src/store/modules/configStore.ts @@ -22,6 +22,8 @@ export const useConfigStore = defineStore('config', () => { return state.config.pricingPackagesEnabled ? RouteConfig.PricingPlanStep : RouteConfig.OverviewStep; }); + const optionalV2Path = computed((): string => !state.config.prefixVuetifyUI ? '' : '/' + import.meta.env.VITE_VUETIFY_PREFIX); + async function getConfig(): Promise { const result = await configApi.get(); @@ -33,6 +35,7 @@ export const useConfigStore = defineStore('config', () => { return { state, firstOnboardingStep, + optionalV2Path, getConfig, }; }); diff --git a/web/satellite/src/utils/httpClient.ts b/web/satellite/src/utils/httpClient.ts index 491e046ebf66..1dcadb82546e 100644 --- a/web/satellite/src/utils/httpClient.ts +++ b/web/satellite/src/utils/httpClient.ts @@ -2,6 +2,7 @@ // See LICENSE for copying information. import { ErrorUnauthorized } from '@/api/errors/ErrorUnauthorized'; +import { useConfigStore } from '@/store/modules/configStore'; /** * HttpClient is a custom wrapper around fetch api. @@ -103,7 +104,7 @@ export class HttpClient { setTimeout(() => { const origin = window.location.origin; if (document.querySelector('.v-overlay-container')) { - window.location.href = origin + '/' + import.meta.env.VITE_VUETIFY_PREFIX + '/login'; + window.location.href = origin + useConfigStore().optionalV2Path + '/login'; return; } window.location.href = origin + '/login'; diff --git a/web/satellite/vuetify-poc/src/layouts/default/AppBar.vue b/web/satellite/vuetify-poc/src/layouts/default/AppBar.vue index 5e125da05bb1..9aba659d5a24 100644 --- a/web/satellite/vuetify-poc/src/layouts/default/AppBar.vue +++ b/web/satellite/vuetify-poc/src/layouts/default/AppBar.vue @@ -311,10 +311,10 @@ async function onLogout(): Promise { notify.error(error.message); } - analyticsStore.pageVisit(RouteConfig.Login.path); await router.push(RouteConfig.Login.path); - // TODO this reload will be unnecessary once vuetify poc has its own login and/or becomes the primary app - location.reload(); + if (configStore.state.config.prefixVuetifyUI) { + location.reload(); + } } diff --git a/web/satellite/vuetify-poc/src/main.ts b/web/satellite/vuetify-poc/src/main.ts index 8c582f56fb61..28e6132a6221 100644 --- a/web/satellite/vuetify-poc/src/main.ts +++ b/web/satellite/vuetify-poc/src/main.ts @@ -18,9 +18,12 @@ import { registerPlugins } from '@poc/plugins'; const app = createApp(App); -registerPlugins(app); +registerPlugins(app).then(() => { + const loader = document.getElementById('pre-app-loader'); + loader?.remove(); -app.mount('#app'); + app.mount('#app'); +}); // By default, Papa Parse uses a blob URL for loading its worker. // This isn't supported by our content security policy, so we override the URL. diff --git a/web/satellite/vuetify-poc/src/plugins/index.ts b/web/satellite/vuetify-poc/src/plugins/index.ts index 178af7d31b93..bb6d168b8ca0 100644 --- a/web/satellite/vuetify-poc/src/plugins/index.ts +++ b/web/satellite/vuetify-poc/src/plugins/index.ts @@ -12,11 +12,13 @@ import { App, watch } from 'vue'; import { createPinia, setActivePinia } from 'pinia'; import THEME_URLS from 'virtual:vuetify-theme-css'; -import { router, startTitleWatcher } from '../router'; +import { setupRouter } from '../router'; import vuetify from './vuetify'; -import NotificatorPlugin from '@/utils/plugins/notificator'; +import NotificatorPlugin, { Notificator } from '@/utils/plugins/notificator'; +import { useConfigStore } from '@/store/modules/configStore'; +import { FrontendConfig } from '@/types/config.gen'; const pinia = createPinia(); setActivePinia(pinia); @@ -59,12 +61,16 @@ function setupTheme() { }); } -export function registerPlugins(app: App) { +export async function registerPlugins(app: App) { setupTheme(); - app - .use(vuetify) - .use(router) - .use(pinia) - .use(NotificatorPlugin); - startTitleWatcher(); + app.use(vuetify).use(pinia).use(NotificatorPlugin); + + let config = new FrontendConfig(); + try { + config = await useConfigStore().getConfig(); + } catch (e) { + new Notificator().notifyError(e); + } + const router = setupRouter(config); + app.use(router); } diff --git a/web/satellite/vuetify-poc/src/router/index.ts b/web/satellite/vuetify-poc/src/router/index.ts index 263b113b4547..e68a51a0fee8 100644 --- a/web/satellite/vuetify-poc/src/router/index.ts +++ b/web/satellite/vuetify-poc/src/router/index.ts @@ -2,11 +2,12 @@ // See LICENSE for copying information. import { watch } from 'vue'; -import { RouteRecordRaw, createRouter, createWebHistory } from 'vue-router'; +import { RouteRecordRaw, createRouter, createWebHistory, Router } from 'vue-router'; import { useProjectsStore } from '@/store/modules/projectsStore'; import { useConfigStore } from '@/store/modules/configStore'; import { useAppStore } from '@poc/store/appStore'; +import { FrontendConfig } from '@/types/config.gen'; export enum RouteName { Billing = 'Billing', @@ -141,25 +142,27 @@ const routes: RouteRecordRaw[] = [ }, ]; -export const router = createRouter({ - history: createWebHistory(import.meta.env.VITE_VUETIFY_PREFIX), - routes, -}); +export function setupRouter(config: FrontendConfig): Router { + const basePath = !config.prefixVuetifyUI ? '' : import.meta.env.VITE_VUETIFY_PREFIX; + const history = createWebHistory(basePath); + const router = createRouter({ + history, + routes, + }); -router.beforeEach((to, from, next) => { - const appStore = useAppStore(); - appStore.setIsNavigating(true); + router.beforeEach((to, from, next) => { + const appStore = useAppStore(); + appStore.setIsNavigating(true); - if (to.name === RouteName.Projects && from.name === RouteName.Login) { - appStore.toggleHasJustLoggedIn(true); - } + if (to.name === RouteName.Projects && from.name === RouteName.Login) { + appStore.toggleHasJustLoggedIn(true); + } - next(); -}); + next(); + }); -router.afterEach(() => useAppStore().setIsNavigating(false)); + router.afterEach(() => useAppStore().setIsNavigating(false)); -export function startTitleWatcher(): void { const projectsStore = useProjectsStore(); const configStore = useConfigStore(); @@ -176,6 +179,6 @@ export function startTitleWatcher(): void { document.title = parts.join(' | '); }, ); -} -export default router; + return router; +} \ No newline at end of file diff --git a/web/satellite/vuetify-poc/src/views/Login.vue b/web/satellite/vuetify-poc/src/views/Login.vue index 92e38e7633d7..3ad0ddb7e66a 100644 --- a/web/satellite/vuetify-poc/src/views/Login.vue +++ b/web/satellite/vuetify-poc/src/views/Login.vue @@ -224,7 +224,7 @@ const satellite = computed({ const sats = configStore.state.config.partneredSatellites ?? []; const satellite = sats.find(sat => sat.name === value.satellite); if (satellite) { - window.location.href = satellite.address + '/v2/login'; + window.location.href = satellite.address + configStore.optionalV2Path + '/login'; } }, }); diff --git a/web/satellite/vuetify-poc/src/views/PasswordReset.vue b/web/satellite/vuetify-poc/src/views/PasswordReset.vue index 4a09bacf47c5..42ea5cdf49ae 100644 --- a/web/satellite/vuetify-poc/src/views/PasswordReset.vue +++ b/web/satellite/vuetify-poc/src/views/PasswordReset.vue @@ -123,7 +123,7 @@ const satellite = computed({ const sats = configStore.state.config.partneredSatellites ?? []; const satellite = sats.find(sat => sat.name === value.satellite); if (satellite) { - window.location.href = satellite.address + '/v2/password-reset'; + window.location.href = satellite.address + configStore.optionalV2Path + '/password-reset'; } }, }); diff --git a/web/satellite/vuetify-poc/src/views/Signup.vue b/web/satellite/vuetify-poc/src/views/Signup.vue index 48808ef00a1c..e1ccb6445174 100644 --- a/web/satellite/vuetify-poc/src/views/Signup.vue +++ b/web/satellite/vuetify-poc/src/views/Signup.vue @@ -354,7 +354,7 @@ const satellite = computed({ const sats = configStore.state.config.partneredSatellites ?? []; const satellite = sats.find(sat => sat.name === value.satellite); if (satellite) { - window.location.href = satellite.address + '/v2/login'; + window.location.href = satellite.address + configStore.optionalV2Path + '/signup'; } }, });