feat(documents): admin-configurable Expired tab visibility
New documents_show_expired_tab system setting (default true). Public read via GET /api/v1/documents/feature-flags (gated on documents.view so reps can read it without holding manage_settings). When off, the Expired tab is hidden from the documents hub — useful when expired EOIs are noise that distracts reps from active deals. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
20
src/app/api/v1/documents/feature-flags/route.ts
Normal file
20
src/app/api/v1/documents/feature-flags/route.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { NextResponse } from 'next/server';
|
||||||
|
|
||||||
|
import { withAuth, withPermission } from '@/lib/api/helpers';
|
||||||
|
import { errorResponse } from '@/lib/errors';
|
||||||
|
import { getSetting } from '@/lib/services/settings.service';
|
||||||
|
|
||||||
|
export const GET = withAuth(
|
||||||
|
withPermission('documents', 'view', async (_req, ctx) => {
|
||||||
|
try {
|
||||||
|
const showExpired = await getSetting('documents_show_expired_tab', ctx.portId);
|
||||||
|
return NextResponse.json({
|
||||||
|
data: {
|
||||||
|
showExpiredTab: showExpired?.value !== false, // default true
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
@@ -210,6 +210,14 @@ const KNOWN_SETTINGS: Array<{
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
defaultValue: true,
|
defaultValue: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'documents_show_expired_tab',
|
||||||
|
label: 'Documents — show Expired tab',
|
||||||
|
description:
|
||||||
|
'When off, the Expired tab on the documents hub is hidden. Use this when expired EOIs are noise that distracts reps from active deals.',
|
||||||
|
type: 'boolean',
|
||||||
|
defaultValue: true,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export function SettingsManager() {
|
export function SettingsManager() {
|
||||||
|
|||||||
@@ -119,6 +119,13 @@ export function DocumentsHub({ portSlug, initialTab = 'all' }: DocumentsHubProps
|
|||||||
staleTime: 30_000,
|
staleTime: 30_000,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { data: flagsResp } = useQuery<{ data: { showExpiredTab: boolean } }>({
|
||||||
|
queryKey: ['documents', 'feature-flags'],
|
||||||
|
queryFn: () => apiFetch('/api/v1/documents/feature-flags'),
|
||||||
|
staleTime: 5 * 60 * 1000,
|
||||||
|
});
|
||||||
|
const showExpiredTab = flagsResp?.data.showExpiredTab ?? true;
|
||||||
|
|
||||||
useRealtimeInvalidation({
|
useRealtimeInvalidation({
|
||||||
'document:created': [['documents']],
|
'document:created': [['documents']],
|
||||||
'document:updated': [['documents']],
|
'document:updated': [['documents']],
|
||||||
@@ -275,7 +282,7 @@ export function DocumentsHub({ portSlug, initialTab = 'all' }: DocumentsHubProps
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TabsList>
|
<TabsList>
|
||||||
{documentsHubTabs.map((t) => (
|
{documentsHubTabs.filter((t) => t !== 'expired' || showExpiredTab).map((t) => (
|
||||||
<TabsTrigger key={t} value={t}>
|
<TabsTrigger key={t} value={t}>
|
||||||
{TAB_LABELS[t]}
|
{TAB_LABELS[t]}
|
||||||
{t !== 'all' && counts[t] > 0 ? (
|
{t !== 'all' && counts[t] > 0 ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user