: AppShell owns that landmark, one per page.
);
}
function useGitLabStatusFetch(workspaceId: string | undefined, enabled: boolean) {
const [result, setResult] = useState<{ workspaceId?: string; status: GitLabStatus | null }>({
workspaceId,
status: null,
});
const [loading, setLoading] = useState(true);
useEffect(() => {
if (!enabled || !workspaceId) {
setLoading(true);
return;
}
let cancelled = false;
setLoading(true);
fetchGitLabStatus({ cache: "no-store", workspaceId })
.then((s) => {
if (!cancelled) setResult({ workspaceId, status: s });
})
.catch(() => {
if (!cancelled) setResult({ workspaceId, status: null });
})
.finally(() => {
if (!cancelled) setLoading(false);
});
return () => {
cancelled = true;
};
}, [enabled, workspaceId]);
const current = enabled && result.workspaceId === workspaceId;
return { status: current ? result.status : null, loading: !current || loading };
}
function GitLabPageBody({
statusLoading,
connected,
reconnect,
workspaceId,
state,
mrPresets,
issuePresets,
onStartTask,
host,
}: {
statusLoading: boolean;
connected: boolean;
reconnect: boolean;
workspaceId?: string;
state: GitLabPageState;
mrPresets: GitLabTaskPreset[];
issuePresets: GitLabTaskPreset[];
onStartTask: (payload: GitLabLaunchPayload) => void;
host: string;
}) {
const { t } = useTranslation();
if (statusLoading) {
return (
{t("gitlab:checkingGitlabStatus")}
);
}
if (!connected) {
return (
);
}
return (
);
}
function GitLabPageOverlays({
state,
mobileSidebarOpen,
setMobileSidebarOpen,
workspaceId,
workflows,
steps,
repositories,
configuredHost,
launchPayload,
setLaunchPayload,
}: {
state: GitLabPageState;
mobileSidebarOpen: boolean;
setMobileSidebarOpen: (open: boolean) => void;
workspaceId?: string;
workflows: Workflow[];
steps: WorkflowStep[];
repositories: Repository[];
configuredHost: string;
launchPayload: GitLabLaunchPayload | null;
setLaunchPayload: (payload: GitLabLaunchPayload | null) => void;
}) {
const { t } = useTranslation();
const onMobileSidebarSelect = (selection: Parameters[0]) => {
state.onSelect(selection);
setMobileSidebarOpen(false);
};
const onMobileSaveCurrent = () => {
setMobileSidebarOpen(false);
state.onOpenSaveDialog();
};
return (
<>
{t("gitlab:filters")}
setLaunchPayload(null)}
/>
>
);
}
function useGitLabWorkspaceScope(serverWorkspaceId?: string) {
const activeWorkspaceId = useAppStore((state) => state.workspaces.activeId);
const workspaceId = activeWorkspaceId ?? serverWorkspaceId;
const switching = Boolean(serverWorkspaceId && workspaceId && serverWorkspaceId !== workspaceId);
const { status, loading } = useGitLabStatusFetch(workspaceId, !switching);
useEffect(() => {
if (switching) window.location.reload();
}, [switching]);
return {
workspaceId,
switching,
status,
statusLoading: switching || loading,
connected: Boolean(status?.authenticated),
reconnect: Boolean(status?.token_configured && !status.authenticated),
};
}
function useGitLabTaskPresets(workspaceId: string | undefined, switching: boolean) {
const { presets } = useGitLabActionPresets(switching ? null : workspaceId);
const mrPresets = useMemo(() => (presets?.mr ?? []).map(toGitLabTaskPreset), [presets?.mr]);
const issuePresets = useMemo(
() => (presets?.issue ?? []).map(toGitLabTaskPreset),
[presets?.issue],
);
return { mrPresets, issuePresets };
}
export function GitLabPageClient({
workspaceId,
workflows = [],
steps = [],
repositories = [],
}: GitLabPageClientProps = {}) {
const { t } = useTranslation();
const scope = useGitLabWorkspaceScope(workspaceId);
const { status, statusLoading, connected, reconnect } = scope;
const host = status?.host ?? "https://gitlab.com";
const state = useGitLabPageState(!statusLoading && connected, scope.workspaceId);
const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
const [launchPayload, setLaunchPayload] = useState(null);
const { mrPresets, issuePresets } = useGitLabTaskPresets(scope.workspaceId, scope.switching);
useEffect(() => resetKnownProjectsStore, []);
const onOpenMobileSidebar = useCallback(() => setMobileSidebarOpen(true), []);
return (
}
scroll="none"
actions={
!statusLoading &&
connected && (
)
}
>
);
}