feat(FN-2154): show dismissible setup warning on project page
- Render SetupWarningBanner from App only in project view when setup readiness reports warnings - Persist dismiss state per project via scoped storage and restore it when switching projects - Add optional dismiss action to SetupWarningBanner with close button UI and responsive styles - Remove inline banner from QuickEntryBox and add tests covering dismiss button behavior
This commit is contained in:
@@ -19,6 +19,7 @@ import { AppModals } from "./components/AppModals";
|
||||
import { DashboardLoader, type DashboardLoaderStage } from "./components/DashboardLoader";
|
||||
import { ExecutorStatusBar } from "./components/ExecutorStatusBar";
|
||||
import { SessionNotificationBanner } from "./components/SessionNotificationBanner";
|
||||
import { SetupWarningBanner } from "./components/SetupWarningBanner";
|
||||
import { OnboardingResumeCard } from "./components/OnboardingResumeCard";
|
||||
import { PostOnboardingRecommendations } from "./components/PostOnboardingRecommendations";
|
||||
import {
|
||||
@@ -42,6 +43,7 @@ import { useAppSettings } from "./hooks/useAppSettings";
|
||||
import { useDeepLink } from "./hooks/useDeepLink";
|
||||
import { useFavorites } from "./hooks/useFavorites";
|
||||
import { useAuthOnboarding } from "./hooks/useAuthOnboarding";
|
||||
import { useSetupReadiness } from "./hooks/useSetupReadiness";
|
||||
import { useViewState, type TaskView } from "./hooks/useViewState";
|
||||
import { useProjectActions } from "./hooks/useProjectActions";
|
||||
import { useTaskHandlers } from "./hooks/useTaskHandlers";
|
||||
@@ -50,6 +52,9 @@ import { useRemoteNodeEvents } from "./hooks/useRemoteNodeEvents";
|
||||
import { NodeProvider, useNodeContext } from "./context/NodeContext";
|
||||
import type { AiSessionSummary } from "./api";
|
||||
import { fetchAiSession, fetchUnreadCount, reportDashboardPerf } from "./api";
|
||||
import { getScopedItem, setScopedItem } from "./utils/projectStorage";
|
||||
|
||||
const SETUP_WARNING_DISMISSED_KEY = "kb-setup-warning-dismissed";
|
||||
|
||||
function AppInner() {
|
||||
const { toasts, addToast, removeToast } = useToast();
|
||||
@@ -59,7 +64,13 @@ function AppInner() {
|
||||
const { projects, loading: projectsLoading, error: projectsError, refresh: refreshProjects, register: registerProject, update: updateProjectHook, unregister: unregisterProjectHook } = useProjects();
|
||||
const { nodes } = useNodes();
|
||||
const { currentProject, setCurrentProject, clearCurrentProject, loading: currentProjectLoading } = useCurrentProject(projects);
|
||||
|
||||
const {
|
||||
hasAiProvider,
|
||||
hasGithub,
|
||||
loading: setupReadinessLoading,
|
||||
hasWarnings,
|
||||
} = useSetupReadiness(currentProject?.id);
|
||||
|
||||
// Node context for local/remote node switching
|
||||
const { currentNode, currentNodeId, isRemote, setCurrentNode, clearCurrentNode } = useNodeContext();
|
||||
|
||||
@@ -203,6 +214,20 @@ function AppInner() {
|
||||
const [missionTargetId, setMissionTargetId] = useState<string | undefined>(undefined);
|
||||
const [milestoneSliceResumeSessionId, setMilestoneSliceResumeSessionId] = useState<string | undefined>(undefined);
|
||||
const [quickChatOpen, setQuickChatOpen] = useState(false);
|
||||
const [setupWarningDismissed, setSetupWarningDismissed] = useState(
|
||||
() => getScopedItem(SETUP_WARNING_DISMISSED_KEY, currentProject?.id) === "true",
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setSetupWarningDismissed(
|
||||
getScopedItem(SETUP_WARNING_DISMISSED_KEY, currentProject?.id) === "true",
|
||||
);
|
||||
}, [currentProject?.id]);
|
||||
|
||||
const handleDismissSetupWarning = useCallback(() => {
|
||||
setScopedItem(SETUP_WARNING_DISMISSED_KEY, "true", currentProject?.id);
|
||||
setSetupWarningDismissed(true);
|
||||
}, [currentProject?.id]);
|
||||
|
||||
// Settings state
|
||||
const {
|
||||
@@ -665,6 +690,13 @@ function AppInner() {
|
||||
onOpenSettings={(section) => modalManager.openSettings(section as SectionId)}
|
||||
/>
|
||||
)}
|
||||
{viewMode === "project" && currentProject && !setupReadinessLoading && hasWarnings && !setupWarningDismissed && (
|
||||
<SetupWarningBanner
|
||||
hasAiProvider={hasAiProvider}
|
||||
hasGithub={hasGithub}
|
||||
onDismiss={handleDismissSetupWarning}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className={`project-content${viewMode === "project" && currentProject ? " project-content--with-footer" : ""}${isMobile ? " project-content--with-mobile-nav" : ""}`}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user