- Add _normalize_timestamp_value to key column values in orchestrator.py and executor.py before SQL generation - Fix test mocks for .options(joinedload()) chain, explicit None attrs for mock job - Add global translation run progress indicator (TranslationRunGlobalIndicator + store) - Fix translate page import missing translationRunStore - All 208 translate tests pass
102 lines
4.5 KiB
Svelte
102 lines
4.5 KiB
Svelte
<!-- #region RootLayout [C:3] [TYPE Layout] [SEMANTICS sveltekit, layout, sidebar, navigation, shell] -->
|
|
<!-- @BRIEF Root layout component providing global UI structure: Sidebar, TopNavbar, Footer, TaskDrawer, Toasts. -->
|
|
<!-- @LAYER Layout -->
|
|
<!-- @RELATION DEPENDS_ON -> [Sidebar] -->
|
|
<!-- @RELATION DEPENDS_ON -> [TopNavbar] -->
|
|
<!-- @RELATION DEPENDS_ON -> [Footer] -->
|
|
<!-- @RELATION DEPENDS_ON -> [Toast] -->
|
|
<!-- @RELATION DEPENDS_ON -> [ProtectedRoute] -->
|
|
<!-- @RELATION DEPENDS_ON -> [TaskDrawer] -->
|
|
<!-- @RELATION DEPENDS_ON -> [Breadcrumbs] -->
|
|
<!-- @RELATION DEPENDS_ON -> [AssistantChatPanel] -->
|
|
<!-- @RELATION BINDS_TO -> [isProductionContextStore] -->
|
|
<!-- @RELATION BINDS_TO -> [selectedEnvironmentStore] -->
|
|
<!-- @RELATION BINDS_TO -> [sidebarStore] -->
|
|
<!-- @UX_STATE Loading -> Sidebar/TopNavbar rendered; page content loading. -->
|
|
<!-- @UX_STATE LoginRoute -> Only login page content rendered, no shell. -->
|
|
<!-- @UX_STATE Authenticated -> Full shell rendered with Sidebar, TopNavbar, Footer, global components. -->
|
|
<!-- @UX_FEEDBACK Production context warning bar visible when isProductionContext = true. -->
|
|
<!-- @UX_FEEDBACK Toast notifications rendered globally. -->
|
|
<!-- @INVARIANT All pages except /login wrapped in ProtectedRoute. -->
|
|
<!-- @INVARIANT Sidebar width adapts (ml-60 vs ml-16) based on sidebar expanded state. -->
|
|
<script>
|
|
import '../app.css';
|
|
import Navbar from '../components/Navbar.svelte';
|
|
import Footer from '../components/Footer.svelte';
|
|
import Toast from '../components/Toast.svelte';
|
|
import ProtectedRoute from '../components/auth/ProtectedRoute.svelte';
|
|
import Breadcrumbs from '$lib/components/layout/Breadcrumbs.svelte';
|
|
import Sidebar from '$lib/components/layout/Sidebar.svelte';
|
|
import TopNavbar from '$lib/components/layout/TopNavbar.svelte';
|
|
import TaskDrawer from '$lib/components/layout/TaskDrawer.svelte';
|
|
import AssistantChatPanel from '$lib/components/assistant/AssistantChatPanel.svelte';
|
|
import TranslationRunGlobalIndicator from '$lib/components/translate/TranslationRunGlobalIndicator.svelte';
|
|
import { t } from '$lib/i18n';
|
|
import {
|
|
isProductionContextStore,
|
|
selectedEnvironmentStore
|
|
} from '$lib/stores/environmentContext.js';
|
|
import { page } from '$app/state';
|
|
import { sidebarStore } from '$lib/stores/sidebar.js';
|
|
import { fromStore } from 'svelte/store';
|
|
|
|
let { children } = $props();
|
|
|
|
const sidebarState = fromStore(sidebarStore);
|
|
const productionContextState = fromStore(isProductionContextStore);
|
|
const selectedEnvironmentState = fromStore(selectedEnvironmentStore);
|
|
|
|
let isLoginPage = $derived(page.url.pathname === '/login');
|
|
let isExpanded = $derived(sidebarState.current?.isExpanded || true);
|
|
let isProductionContext = $derived(productionContextState.current);
|
|
let selectedEnvironment = $derived(selectedEnvironmentState.current);
|
|
</script>
|
|
|
|
<Toast />
|
|
|
|
<!-- Global persistent translation run progress indicator -->
|
|
<TranslationRunGlobalIndicator />
|
|
|
|
<main class="min-h-screen {isProductionContext ? 'bg-red-50/40' : 'bg-slate-50'}">
|
|
{#if isLoginPage}
|
|
<div class="p-4">
|
|
{@render children?.()}
|
|
</div>
|
|
{:else}
|
|
<ProtectedRoute>
|
|
<!-- Sidebar -->
|
|
<Sidebar />
|
|
|
|
<!-- Main content area with TopNavbar -->
|
|
<div class="flex flex-col min-h-screen {isExpanded ? 'md:ml-60' : 'md:ml-16'} transition-all duration-200">
|
|
<!-- Top Navigation Bar -->
|
|
<TopNavbar />
|
|
<!-- Breadcrumbs -->
|
|
<div class="mt-16 pt-3">
|
|
<Breadcrumbs />
|
|
</div>
|
|
|
|
{#if isProductionContext}
|
|
<div class="mx-4 mb-3 rounded-md border border-red-300 bg-red-100 px-4 py-2 text-sm font-semibold text-red-900 md:mx-6">
|
|
{$t.common?.prod_context_warning || "PROD context active"}:
|
|
{selectedEnvironment?.name || selectedEnvironment?.id || 'environment'}
|
|
</div>
|
|
{/if}
|
|
|
|
<!-- Page content -->
|
|
<div class="flex-grow px-4 pb-6 pt-2 md:px-6 {isProductionContext ? 'md:border-l-4 md:border-red-500' : ''}">
|
|
{@render children?.()}
|
|
</div>
|
|
|
|
<!-- Footer -->
|
|
<Footer />
|
|
</div>
|
|
|
|
<!-- Global Task Drawer -->
|
|
<TaskDrawer />
|
|
<AssistantChatPanel />
|
|
</ProtectedRoute>
|
|
{/if}
|
|
</main>
|
|
<!-- #endregion RootLayout -->
|