feat: separate codex live and automation context

This commit is contained in:
2026-04-24 08:53:15 +09:00
parent f2d6310efa
commit 91230304e0
9 changed files with 142 additions and 60 deletions

View File

@@ -3,12 +3,14 @@ import {
BellOutlined,
ClockCircleOutlined,
CopyOutlined,
DownOutlined,
FileMarkdownOutlined,
LoadingOutlined,
MenuFoldOutlined,
MenuUnfoldOutlined,
ProfileOutlined,
ReloadOutlined,
RightOutlined,
SettingOutlined,
} from '@ant-design/icons';
import {
@@ -883,6 +885,7 @@ export function MainHeader({
const navigate = useNavigate();
const location = useLocation();
const [settingsOpen, setSettingsOpen] = useState(false);
const [automationGroupExpanded, setAutomationGroupExpanded] = useState(false);
const [settingsModalOpen, setSettingsModalOpen] = useState(false);
const [activeSettingsModal, setActiveSettingsModal] = useState<SettingsModalKey>('appSettings');
const [activeAppSettingsCategory, setActiveAppSettingsCategory] = useState<AppSettingsCategoryKey>('automation');
@@ -958,6 +961,8 @@ export function MainHeader({
const workServerPendingUpdateCount =
workServerStatus && (workServerStatus.updateAvailable || workServerStatus.buildRequired) ? 1 : 0;
const totalPendingUpdateCount = testServerPendingUpdateCount + prodServerPendingUpdateCount + workServerPendingUpdateCount;
const totalAutomationShortcutCount =
planShortcutCounts.working + planShortcutCounts.releasePendingMain + planShortcutCounts.automationFailed;
const settingsStatusClassName =
totalPendingUpdateCount >= 2
? 'app-header__status-dot--inactive'
@@ -2621,68 +2626,20 @@ export function MainHeader({
const settingsMenu = (
<div className="app-header__settings-menu">
{hasAccess ? (
<>
<div className="app-header__settings-group">
<button
type="button"
className="app-header__settings-item"
aria-expanded={automationGroupExpanded}
onClick={() => {
setSettingsOpen(false);
onOpenPlanQuickFilter('working');
}}
>
<span className="app-header__settings-icon">
<ProfileOutlined />
<span
className={`app-header__status-dot ${
planShortcutCounts.working > 0
? 'app-header__status-dot--active'
: 'app-header__status-dot--inactive'
}`}
aria-hidden="true"
/>
</span>
<span className="app-header__settings-label">
<Text type="secondary"> {planShortcutCounts.working}</Text>
</span>
</button>
<button
type="button"
className="app-header__settings-item"
onClick={() => {
setSettingsOpen(false);
onOpenPlanQuickFilter('release-pending-main');
}}
>
<span className="app-header__settings-icon">
<ProfileOutlined />
<span
className={`app-header__status-dot ${
planShortcutCounts.releasePendingMain > 0
? 'app-header__status-dot--warning'
: 'app-header__status-dot--inactive'
}`}
aria-hidden="true"
/>
</span>
<span className="app-header__settings-label">
release
<Text type="secondary"> {planShortcutCounts.releasePendingMain}</Text>
</span>
</button>
<button
type="button"
className="app-header__settings-item"
onClick={() => {
setSettingsOpen(false);
onOpenPlanQuickFilter('automation-failed');
setAutomationGroupExpanded((current) => !current);
}}
>
<span className="app-header__settings-icon">
<ReloadOutlined />
<span
className={`app-header__status-dot ${
planShortcutCounts.automationFailed > 0
totalAutomationShortcutCount > 0
? 'app-header__status-dot--warning'
: 'app-header__status-dot--inactive'
}`}
@@ -2690,11 +2647,93 @@ export function MainHeader({
/>
</span>
<span className="app-header__settings-label">
<Text type="secondary"> {planShortcutCounts.automationFailed}</Text>
<Text type="secondary"> {totalAutomationShortcutCount}</Text>
</span>
<span className="app-header__settings-group-arrow" aria-hidden="true">
{automationGroupExpanded ? <DownOutlined /> : <RightOutlined />}
</span>
</button>
</>
{automationGroupExpanded ? (
<div className="app-header__settings-group-children">
<button
type="button"
className="app-header__settings-item app-header__settings-item--nested"
onClick={() => {
setSettingsOpen(false);
setAutomationGroupExpanded(false);
onOpenPlanQuickFilter('working');
}}
>
<span className="app-header__settings-icon">
<ProfileOutlined />
<span
className={`app-header__status-dot ${
planShortcutCounts.working > 0
? 'app-header__status-dot--active'
: 'app-header__status-dot--inactive'
}`}
aria-hidden="true"
/>
</span>
<span className="app-header__settings-label">
<Text type="secondary"> {planShortcutCounts.working}</Text>
</span>
</button>
<button
type="button"
className="app-header__settings-item app-header__settings-item--nested"
onClick={() => {
setSettingsOpen(false);
setAutomationGroupExpanded(false);
onOpenPlanQuickFilter('release-pending-main');
}}
>
<span className="app-header__settings-icon">
<ProfileOutlined />
<span
className={`app-header__status-dot ${
planShortcutCounts.releasePendingMain > 0
? 'app-header__status-dot--warning'
: 'app-header__status-dot--inactive'
}`}
aria-hidden="true"
/>
</span>
<span className="app-header__settings-label">
release
<Text type="secondary"> {planShortcutCounts.releasePendingMain}</Text>
</span>
</button>
<button
type="button"
className="app-header__settings-item app-header__settings-item--nested"
onClick={() => {
setSettingsOpen(false);
setAutomationGroupExpanded(false);
onOpenPlanQuickFilter('automation-failed');
}}
>
<span className="app-header__settings-icon">
<ReloadOutlined />
<span
className={`app-header__status-dot ${
planShortcutCounts.automationFailed > 0
? 'app-header__status-dot--warning'
: 'app-header__status-dot--inactive'
}`}
aria-hidden="true"
/>
</span>
<span className="app-header__settings-label">
<Text type="secondary"> {planShortcutCounts.automationFailed}</Text>
</span>
</button>
</div>
) : null}
</div>
) : null}
<button
type="button"

View File

@@ -174,10 +174,23 @@
gap: 8px;
}
.app-header__settings-group {
display: flex;
flex-direction: column;
gap: 6px;
}
.app-header__settings-item:hover {
background: #f3f7ff;
}
.app-header__settings-item--nested {
margin-left: 12px;
min-width: 0;
padding-left: 14px;
background: #f8fbff;
}
.app-header__settings-icon {
position: relative;
display: inline-flex;
@@ -241,10 +254,23 @@
}
.app-header__settings-label {
display: inline-flex;
align-items: center;
gap: 4px;
flex: 1;
font-size: 14px;
font-weight: 600;
}
.app-header__settings-group-arrow {
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
color: #64748b;
font-size: 12px;
}
.app-header__update-progress {
display: flex;
flex-direction: column;