feat: update codex live automation and plan flows

This commit is contained in:
2026-04-24 08:06:36 +09:00
parent 916107dbe5
commit f2d6310efa
47 changed files with 2767 additions and 507 deletions

View File

@@ -87,6 +87,7 @@ function parseRoute(pathname: string): {
first === 'charts' ||
first === 'schedule' ||
first === 'history' ||
first === 'automation-type' ||
first === 'server-command')
) {
return {
@@ -146,6 +147,22 @@ function isRestrictedTopMenu(topMenu: TopMenuKey, hasAccess: boolean) {
return !hasAccess && topMenu !== 'docs';
}
function getIsMobileViewport() {
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
return false;
}
return window.matchMedia('(max-width: 768px)').matches;
}
function resolveSidebarCollapsedForViewport(isMobileViewport: boolean, topMenu: TopMenuKey) {
if (!isMobileViewport) {
return false;
}
return topMenu !== 'docs';
}
function resolveSidebarOpenKeys(
topMenu: TopMenuKey,
hasAccess: boolean,
@@ -189,9 +206,11 @@ export function MainLayout() {
const { openSearch, setOptions: setSearchOptions } = useSearchLayer();
const layoutData = useMainLayoutData();
const routeState = useMemo(() => parseRoute(location.pathname), [location.pathname]);
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
const [isMobileViewport, setIsMobileViewport] = useState(() => getIsMobileViewport());
const [sidebarCollapsed, setSidebarCollapsed] = useState(() =>
resolveSidebarCollapsedForViewport(getIsMobileViewport(), routeState.topMenu),
);
const [contentExpanded, setContentExpanded] = useState(false);
const [isMobileViewport, setIsMobileViewport] = useState(false);
const [sidebarOpenKeys, setSidebarOpenKeys] = useState<string[]>(
resolveSidebarOpenKeys(routeState.topMenu, hasAccess, routeState.planMenu, routeState.chatMenu),
);
@@ -221,12 +240,7 @@ export function MainLayout() {
}, []);
useEffect(() => {
if (!isMobileViewport) {
setSidebarCollapsed(false);
return;
}
setSidebarCollapsed(routeState.topMenu !== 'docs');
setSidebarCollapsed(resolveSidebarCollapsedForViewport(isMobileViewport, routeState.topMenu));
}, [isMobileViewport, routeState.topMenu]);
useEffect(() => {
@@ -370,7 +384,6 @@ export function MainLayout() {
const planMenuItems = useMemo(() => buildPlanMenuItems(hasAccess), [hasAccess]);
const chatMenuItems = useMemo(() => buildChatMenuItems(hasAccess, chatUnreadCount), [chatUnreadCount, hasAccess]);
const playMenuItems = useMemo(() => buildPlayMenuItems(savedLayouts), [savedLayouts]);
const showInlineMobileDocsSidebar = isMobileViewport && routeState.topMenu === 'docs';
const initialSelectedPlanId = Number(searchParams.get('planId'));
const initialSelectedWorkId = searchParams.get('workId');
@@ -414,7 +427,7 @@ export function MainLayout() {
}}
onChangeTopMenu={(menu) => {
navigate(resolveTopMenuPath(menu, currentDocsFolder));
setSidebarCollapsed(false);
setSidebarCollapsed(resolveSidebarCollapsedForViewport(isMobileViewport, menu));
}}
onOpenPlanQuickFilter={(filter) => {
const targetPlanMenu = resolvePlanQuickFilterMenu(filter);
@@ -428,13 +441,12 @@ export function MainLayout() {
)}
<Layout>
{contentExpanded || (isMobileViewport && sidebarCollapsed && !showInlineMobileDocsSidebar) ? null : (
{contentExpanded || (isMobileViewport && sidebarCollapsed) ? null : (
<MainSidebar
activeTopMenu={routeState.topMenu}
hasAccess={hasAccess}
sidebarCollapsed={sidebarCollapsed}
isMobileViewport={isMobileViewport}
mobileInline={showInlineMobileDocsSidebar}
openKeys={sidebarOpenKeys}
apiMenuItems={apiMenuItems}
docsMenuItems={docsMenuItems}
@@ -455,7 +467,7 @@ export function MainLayout() {
}}
onSelectDocsMenu={(key) => {
navigate(buildDocsPath(key));
if (isMobileViewport && !showInlineMobileDocsSidebar) {
if (isMobileViewport) {
setSidebarCollapsed(true);
}
}}
@@ -486,7 +498,7 @@ export function MainLayout() {
/>
)}
{isMobileViewport && !sidebarCollapsed && !showInlineMobileDocsSidebar ? null : (
{isMobileViewport && !sidebarCollapsed ? null : (
<MainContent contentExpanded={contentExpanded} onToggleContentExpanded={() => setContentExpanded((previous) => !previous)}>
<Outlet />
</MainContent>