Backend - HealthResponse exposes inspectModeEnabled / chunksModeEnabled / askModeEnabled (additive; defaults true). main.py /api/health populates them from settings. - infra/settings.py: three new env-var-driven booleans (defaults true) parsed in from_env() like the existing reasoning_enabled flag. - tests/test_api_endpoints.py: extra assertion that /api/health surfaces the three new fields with their defaults. Frontend — flag store - features/feature-flags/store.ts: FeatureFlag union extended with inspectMode / chunksMode / askMode. New entries in featureRegistry are gated on context fields populated from health. Missing fields fall back to true so a frontend pointed at an older backend keeps every mode visible. - store gains a modeFlags() helper returning Record<DocMode, boolean> so the routing guard does not need to know the FeatureFlag union. Frontend — routing - shared/routing/resolveMode.ts: pure resolver. If the requested mode is enabled, return it; else first enabled in priority ask > chunks > inspect; else null. - app/router/index.ts: beforeEach guard scoped to ROUTES.DOC_WORKSPACE. Disabled mode → rewrite ?mode= to the first enabled one. All three off → redirect to /docs?reason=no-mode-enabled. Frontend — flash - pages/DocsLibraryPage.vue: shows a banner when ?reason=no-mode-enabled is set. #211 will move this into the proper library page banner. - i18n flags.allModesDisabled added in fr + en. Tests - shared/routing/resolveMode.test.ts (6 cases): every (requested, enabled) combination including all-disabled, priority order, missing requested. - features/feature-flags/store.test.ts: three new cases covering the new fields in /api/health, fall-back-to-true on missing fields, and modeFlags() shape. Refs #210
39 lines
1,023 B
Vue
39 lines
1,023 B
Vue
<template>
|
|
<div>
|
|
<div v-if="showFlashAllModesDisabled" class="flash flash--warning" role="alert">
|
|
{{ t('flags.allModesDisabled') }}
|
|
</div>
|
|
<ComingSoonShell
|
|
:title="t('comingSoon.title')"
|
|
:subtitle="t('comingSoon.subtitle.docsLibrary')"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
|
|
import { useI18n } from '../shared/i18n'
|
|
import ComingSoonShell from '../shared/ui/ComingSoonShell.vue'
|
|
|
|
const { t } = useI18n()
|
|
const route = useRoute()
|
|
|
|
// Surfaced when the router redirected here because every doc workspace
|
|
// mode is feature-flagged off (#210). #211 will replace this with a
|
|
// proper banner inside the library page.
|
|
const showFlashAllModesDisabled = computed(() => route.query.reason === 'no-mode-enabled')
|
|
</script>
|
|
|
|
<style scoped>
|
|
.flash {
|
|
margin: 1rem;
|
|
padding: 0.75rem 1rem;
|
|
border-radius: 6px;
|
|
font-size: 0.875rem;
|
|
color: #92400e;
|
|
background: #fef3c7;
|
|
border: 1px solid #fde68a;
|
|
}
|
|
</style>
|