diff --git a/frontend/src/views/AppLayout.vue b/frontend/src/views/AppLayout.vue index cbd5bedd..e37897a3 100644 --- a/frontend/src/views/AppLayout.vue +++ b/frontend/src/views/AppLayout.vue @@ -127,7 +127,7 @@ import { dashboardApi, notificationsApi } from '../api' import { fiscalWeek } from '@/utils/fiscalWeek' import { getFacilityName, getSiteLogo, getServicenowUrls, getEnvLabel } from '../utils/siteSettings' import { withBase } from '../utils/basePath' -import { isPluginEnabled } from '../composables/enabledPlugins' +import { isPluginEnabled, loadEnabledPlugins } from '../composables/enabledPlugins' const router = useRouter() const route = useRoute() @@ -147,15 +147,28 @@ const authStore = useAuthStore() // the plugin list, so it cannot carry the test on its own. const stagedRoutePaths = new Set(router.getRoutes().map(r => r.path)) const hasRoute = (path) => stagedRoutePaths.has(path) + +// Make kiosk visibility reactive - updates when plugin list loads +const pluginsLoaded = ref(false) + // Shopfloor Dashboard is a core view but runs entirely on the notifications // plugin (notificationsApi.getShopfloor + the calendar); without it the display // is empty, so gate the link on the notifications plugin being in this build. -const showShopfloor = hasRoute('/shopfloor') - && (hasRoute('/notifications') || hasRoute('/calendar')) -const showPartsKiosk = hasRoute('/parts-kiosk') && isPluginEnabled('printedparts') -const showUsbKiosk = hasRoute('/usb-kiosk') && isPluginEnabled('usb') -const showDisplays = showShopfloor || hasRoute('/tv') || showPartsKiosk - || showUsbKiosk +const showShopfloor = computed(() => + hasRoute('/shopfloor') && (hasRoute('/notifications') || hasRoute('/calendar')) +) + +const showPartsKiosk = computed(() => + pluginsLoaded.value && hasRoute('/parts-kiosk') && isPluginEnabled('printedparts') +) + +const showUsbKiosk = computed(() => + pluginsLoaded.value && hasRoute('/usb-kiosk') && isPluginEnabled('usb') +) + +const showDisplays = computed(() => + showShopfloor.value || hasRoute('/tv') || showPartsKiosk.value || showUsbKiosk.value +) const routeViewKey = computed(() => route.path.startsWith('/settings') ? '/settings' : route.path ) @@ -294,6 +307,10 @@ onMounted(async () => { // granted mid-session stays invisible until the person logs out and back in. if (authStore.isAuthenticated) authStore.fetchUser() + // Load enabled plugins list early so kiosk links render correctly + await loadEnabledPlugins() + pluginsLoaded.value = true + // Half-hourly: cheap, and it crosses midnight into the new week without a // reload on a screen nobody touches. fiscalWeekTimer = setInterval(() => { currentFiscalWeek.value = fiscalWeek() }, 30 * 60 * 1000)