chore: test deploy snapshot
This commit is contained in:
@@ -14,7 +14,7 @@ test('extractChatMessageParts normalizes absolute legacy dot-codex prompt previe
|
|||||||
assert.ok(prompt);
|
assert.ok(prompt);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
prompt.options[0]?.preview?.url,
|
prompt.options[0]?.preview?.url,
|
||||||
'/api/chat/resources/chat-room/resource/source/chat-room-reference.md',
|
'/api/chat/resources/.codex_chat/chat-room/resource/source/chat-room-reference.md',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ test('parseChatMessageParts normalizes absolute legacy link card urls to api cha
|
|||||||
{
|
{
|
||||||
type: 'link_card',
|
type: 'link_card',
|
||||||
title: 'legacy resource',
|
title: 'legacy resource',
|
||||||
url: '/api/chat/resources/chat-room/resource/uploads/spec.png',
|
url: '/api/chat/resources/.codex_chat/chat-room/resource/uploads/spec.png',
|
||||||
actionLabel: '열기',
|
actionLabel: '열기',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -90,6 +90,20 @@ const CHAT_PUBLIC_DOT_CODEX_MARKER = '/public/.codex_chat/';
|
|||||||
const RESOURCE_MANAGER_PREVIEW_MARKER = '/api/resource-manager/preview/';
|
const RESOURCE_MANAGER_PREVIEW_MARKER = '/api/resource-manager/preview/';
|
||||||
const RESOURCE_MANAGER_ROOT_MARKER = 'resource/';
|
const RESOURCE_MANAGER_ROOT_MARKER = 'resource/';
|
||||||
|
|
||||||
|
function buildCanonicalChatApiResourcePath(relativePath: string) {
|
||||||
|
const normalizedRelativePath = normalizeText(relativePath).replace(/^\/+/, '');
|
||||||
|
|
||||||
|
if (!normalizedRelativePath) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedRelativePath.startsWith('.codex_chat/')) {
|
||||||
|
return `${CHAT_API_RESOURCE_MARKER}${normalizedRelativePath}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${CHAT_API_RESOURCE_MARKER}.codex_chat/${normalizedRelativePath}`;
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeText(value: unknown) {
|
function normalizeText(value: unknown) {
|
||||||
return String(value ?? '').trim();
|
return String(value ?? '').trim();
|
||||||
}
|
}
|
||||||
@@ -239,11 +253,11 @@ function normalizeUrl(value: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pathname.startsWith(CHAT_PUBLIC_DOT_CODEX_MARKER)) {
|
if (pathname.startsWith(CHAT_PUBLIC_DOT_CODEX_MARKER)) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${pathname.slice(CHAT_PUBLIC_DOT_CODEX_MARKER.length)}`;
|
return buildCanonicalChatApiResourcePath(pathname.slice(CHAT_PUBLIC_DOT_CODEX_MARKER.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathname.startsWith(CHAT_DOT_CODEX_MARKER)) {
|
if (pathname.startsWith(CHAT_DOT_CODEX_MARKER)) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${pathname.slice(CHAT_DOT_CODEX_MARKER.length)}`;
|
return buildCanonicalChatApiResourcePath(pathname.slice(CHAT_DOT_CODEX_MARKER.length));
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Fall through to handle relative and embedded resource paths below.
|
// Fall through to handle relative and embedded resource paths below.
|
||||||
@@ -259,18 +273,18 @@ function normalizeUrl(value: string) {
|
|||||||
const apiPath = normalized.slice(apiMarkerIndex);
|
const apiPath = normalized.slice(apiMarkerIndex);
|
||||||
const dotCodexIndex = apiPath.indexOf(CHAT_DOT_CODEX_MARKER);
|
const dotCodexIndex = apiPath.indexOf(CHAT_DOT_CODEX_MARKER);
|
||||||
return dotCodexIndex >= 0
|
return dotCodexIndex >= 0
|
||||||
? `${CHAT_API_RESOURCE_MARKER}${apiPath.slice(dotCodexIndex + 1)}`
|
? buildCanonicalChatApiResourcePath(apiPath.slice(dotCodexIndex + 1))
|
||||||
: apiPath;
|
: apiPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
const publicDotCodexIndex = normalized.lastIndexOf(CHAT_PUBLIC_DOT_CODEX_MARKER);
|
const publicDotCodexIndex = normalized.lastIndexOf(CHAT_PUBLIC_DOT_CODEX_MARKER);
|
||||||
if (publicDotCodexIndex >= 0) {
|
if (publicDotCodexIndex >= 0) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${normalized.slice(publicDotCodexIndex + 8)}`;
|
return buildCanonicalChatApiResourcePath(normalized.slice(publicDotCodexIndex + 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
const dotCodexIndex = normalized.lastIndexOf(CHAT_DOT_CODEX_MARKER);
|
const dotCodexIndex = normalized.lastIndexOf(CHAT_DOT_CODEX_MARKER);
|
||||||
if (dotCodexIndex >= 0) {
|
if (dotCodexIndex >= 0) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${normalized.slice(dotCodexIndex + 1)}`;
|
return buildCanonicalChatApiResourcePath(normalized.slice(dotCodexIndex + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalized === 'resource' || normalized === '/resource' || normalized.startsWith('resource/') || normalized.includes('/resource/')) {
|
if (normalized === 'resource' || normalized === '/resource' || normalized.startsWith('resource/') || normalized.includes('/resource/')) {
|
||||||
|
|||||||
@@ -6,6 +6,20 @@ const CHAT_PUBLIC_DOT_CODEX_MARKER = '/public/.codex_chat/';
|
|||||||
const RESOURCE_MANAGER_PREVIEW_MARKER = '/api/resource-manager/preview/';
|
const RESOURCE_MANAGER_PREVIEW_MARKER = '/api/resource-manager/preview/';
|
||||||
const RESOURCE_MANAGER_ROOT_MARKER = 'resource/';
|
const RESOURCE_MANAGER_ROOT_MARKER = 'resource/';
|
||||||
|
|
||||||
|
function buildCanonicalChatApiResourcePath(relativePath: string) {
|
||||||
|
const normalizedRelativePath = String(relativePath ?? '').trim().replace(/^\/+/, '');
|
||||||
|
|
||||||
|
if (!normalizedRelativePath) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedRelativePath.startsWith('.codex_chat/')) {
|
||||||
|
return `${CHAT_API_RESOURCE_MARKER}${normalizedRelativePath}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${CHAT_API_RESOURCE_MARKER}.codex_chat/${normalizedRelativePath}`;
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeUrlFragmentValue(value: string) {
|
function normalizeUrlFragmentValue(value: string) {
|
||||||
const normalized = String(value ?? '').trim().replace(/^#+/, '');
|
const normalized = String(value ?? '').trim().replace(/^#+/, '');
|
||||||
|
|
||||||
@@ -154,20 +168,20 @@ function extractEmbeddedResourcePath(value: string) {
|
|||||||
const apiPath = normalized.slice(apiMarkerIndex);
|
const apiPath = normalized.slice(apiMarkerIndex);
|
||||||
const dotCodexIndex = apiPath.indexOf(CHAT_DOT_CODEX_MARKER);
|
const dotCodexIndex = apiPath.indexOf(CHAT_DOT_CODEX_MARKER);
|
||||||
return dotCodexIndex >= 0
|
return dotCodexIndex >= 0
|
||||||
? `${CHAT_API_RESOURCE_MARKER}${apiPath.slice(dotCodexIndex + 1)}`
|
? buildCanonicalChatApiResourcePath(apiPath.slice(dotCodexIndex + 1))
|
||||||
: apiPath;
|
: apiPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
const publicDotCodexIndex = normalized.lastIndexOf(CHAT_PUBLIC_DOT_CODEX_MARKER);
|
const publicDotCodexIndex = normalized.lastIndexOf(CHAT_PUBLIC_DOT_CODEX_MARKER);
|
||||||
|
|
||||||
if (publicDotCodexIndex >= 0) {
|
if (publicDotCodexIndex >= 0) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${normalized.slice(publicDotCodexIndex + 8)}`;
|
return buildCanonicalChatApiResourcePath(normalized.slice(publicDotCodexIndex + 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
const dotCodexIndex = normalized.lastIndexOf(CHAT_DOT_CODEX_MARKER);
|
const dotCodexIndex = normalized.lastIndexOf(CHAT_DOT_CODEX_MARKER);
|
||||||
|
|
||||||
if (dotCodexIndex >= 0) {
|
if (dotCodexIndex >= 0) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${normalized.slice(dotCodexIndex + 1)}`;
|
return buildCanonicalChatApiResourcePath(normalized.slice(dotCodexIndex + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalized === 'resource' || normalized === '/resource' || normalized.startsWith('resource/') || normalized.includes('/resource/')) {
|
if (normalized === 'resource' || normalized === '/resource' || normalized.startsWith('resource/') || normalized.includes('/resource/')) {
|
||||||
@@ -197,11 +211,11 @@ function extractKnownPreviewPath(value: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pathname.startsWith(CHAT_PUBLIC_DOT_CODEX_MARKER)) {
|
if (pathname.startsWith(CHAT_PUBLIC_DOT_CODEX_MARKER)) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${pathname.slice(CHAT_PUBLIC_DOT_CODEX_MARKER.length)}`;
|
return buildCanonicalChatApiResourcePath(pathname.slice(CHAT_PUBLIC_DOT_CODEX_MARKER.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathname.startsWith(CHAT_DOT_CODEX_MARKER)) {
|
if (pathname.startsWith(CHAT_DOT_CODEX_MARKER)) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${pathname.slice(CHAT_DOT_CODEX_MARKER.length)}`;
|
return buildCanonicalChatApiResourcePath(pathname.slice(CHAT_DOT_CODEX_MARKER.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
return normalized;
|
return normalized;
|
||||||
|
|||||||
@@ -19,6 +19,20 @@ const CHAT_DOT_CODEX_MARKER = '/.codex_chat/';
|
|||||||
const CHAT_PUBLIC_DOT_CODEX_MARKER = '/public/.codex_chat/';
|
const CHAT_PUBLIC_DOT_CODEX_MARKER = '/public/.codex_chat/';
|
||||||
const RESOURCE_MANAGER_PREVIEW_MARKER = '/api/resource-manager/preview/';
|
const RESOURCE_MANAGER_PREVIEW_MARKER = '/api/resource-manager/preview/';
|
||||||
const RESOURCE_MANAGER_ROOT_MARKER = 'resource/';
|
const RESOURCE_MANAGER_ROOT_MARKER = 'resource/';
|
||||||
|
|
||||||
|
function buildCanonicalChatApiResourcePath(relativePath: string) {
|
||||||
|
const normalizedRelativePath = normalizeText(relativePath).replace(/^\/+/, '');
|
||||||
|
|
||||||
|
if (!normalizedRelativePath) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedRelativePath.startsWith('.codex_chat/')) {
|
||||||
|
return `${CHAT_API_RESOURCE_MARKER}${normalizedRelativePath}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${CHAT_API_RESOURCE_MARKER}.codex_chat/${normalizedRelativePath}`;
|
||||||
|
}
|
||||||
type PromptPart = Extract<ChatMessagePart, { type: 'prompt' }>;
|
type PromptPart = Extract<ChatMessagePart, { type: 'prompt' }>;
|
||||||
type PromptOption = PromptPart['options'][number];
|
type PromptOption = PromptPart['options'][number];
|
||||||
type PromptPreview = NonNullable<PromptOption['preview']>;
|
type PromptPreview = NonNullable<PromptOption['preview']>;
|
||||||
@@ -174,11 +188,11 @@ function extractKnownPreviewPath(value: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pathname.startsWith(CHAT_PUBLIC_DOT_CODEX_MARKER)) {
|
if (pathname.startsWith(CHAT_PUBLIC_DOT_CODEX_MARKER)) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${pathname.slice(CHAT_PUBLIC_DOT_CODEX_MARKER.length)}`;
|
return buildCanonicalChatApiResourcePath(pathname.slice(CHAT_PUBLIC_DOT_CODEX_MARKER.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathname.startsWith(CHAT_DOT_CODEX_MARKER)) {
|
if (pathname.startsWith(CHAT_DOT_CODEX_MARKER)) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${pathname.slice(CHAT_DOT_CODEX_MARKER.length)}`;
|
return buildCanonicalChatApiResourcePath(pathname.slice(CHAT_DOT_CODEX_MARKER.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
return normalized;
|
return normalized;
|
||||||
@@ -210,18 +224,18 @@ function normalizeUrl(value: string) {
|
|||||||
const apiPath = normalized.slice(apiMarkerIndex);
|
const apiPath = normalized.slice(apiMarkerIndex);
|
||||||
const dotCodexIndex = apiPath.indexOf(CHAT_DOT_CODEX_MARKER);
|
const dotCodexIndex = apiPath.indexOf(CHAT_DOT_CODEX_MARKER);
|
||||||
return dotCodexIndex >= 0
|
return dotCodexIndex >= 0
|
||||||
? `${CHAT_API_RESOURCE_MARKER}${apiPath.slice(dotCodexIndex + 1)}`
|
? buildCanonicalChatApiResourcePath(apiPath.slice(dotCodexIndex + 1))
|
||||||
: apiPath;
|
: apiPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
const publicDotCodexIndex = normalized.lastIndexOf(CHAT_PUBLIC_DOT_CODEX_MARKER);
|
const publicDotCodexIndex = normalized.lastIndexOf(CHAT_PUBLIC_DOT_CODEX_MARKER);
|
||||||
if (publicDotCodexIndex >= 0) {
|
if (publicDotCodexIndex >= 0) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${normalized.slice(publicDotCodexIndex + 8)}`;
|
return buildCanonicalChatApiResourcePath(normalized.slice(publicDotCodexIndex + 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
const dotCodexIndex = normalized.lastIndexOf(CHAT_DOT_CODEX_MARKER);
|
const dotCodexIndex = normalized.lastIndexOf(CHAT_DOT_CODEX_MARKER);
|
||||||
if (dotCodexIndex >= 0) {
|
if (dotCodexIndex >= 0) {
|
||||||
return `${CHAT_API_RESOURCE_MARKER}${normalized.slice(dotCodexIndex + 1)}`;
|
return buildCanonicalChatApiResourcePath(normalized.slice(dotCodexIndex + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalized === 'resource' || normalized === '/resource' || normalized.startsWith('resource/') || normalized.includes('/resource/')) {
|
if (normalized === 'resource' || normalized === '/resource' || normalized.startsWith('resource/') || normalized.includes('/resource/')) {
|
||||||
|
|||||||
@@ -1658,6 +1658,7 @@
|
|||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
color: rgba(30, 41, 59, 0.92);
|
color: rgba(30, 41, 59, 0.92);
|
||||||
background: rgba(226, 232, 240, 0.72);
|
background: rgba(226, 232, 240, 0.72);
|
||||||
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-share-page__process-inspector-sections {
|
.chat-share-page__process-inspector-sections {
|
||||||
@@ -1673,8 +1674,9 @@
|
|||||||
|
|
||||||
.chat-share-page__process-inspector-section {
|
.chat-share-page__process-inspector-section {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 6px;
|
gap: 8px;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
align-content: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-share-page__process-inspector-section--checklist,
|
.chat-share-page__process-inspector-section--checklist,
|
||||||
@@ -1695,6 +1697,14 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-section-head-actions {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 6px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.chat-share-page__process-inspector-checklist,
|
.chat-share-page__process-inspector-checklist,
|
||||||
.chat-share-page__process-inspector-narratives,
|
.chat-share-page__process-inspector-narratives,
|
||||||
.chat-share-page__process-inspector-log {
|
.chat-share-page__process-inspector-log {
|
||||||
@@ -1797,6 +1807,7 @@
|
|||||||
@media (max-width: 960px) {
|
@media (max-width: 960px) {
|
||||||
.chat-share-page__process-inspector {
|
.chat-share-page__process-inspector {
|
||||||
width: min(100vw - 16px, 720px);
|
width: min(100vw - 16px, 720px);
|
||||||
|
max-height: min(100dvh - 16px, 760px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-share-page__process-inspector-sections {
|
.chat-share-page__process-inspector-sections {
|
||||||
@@ -1811,6 +1822,88 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.chat-share-page__process-inspector {
|
||||||
|
width: calc(100vw - 12px);
|
||||||
|
max-height: calc(100dvh - 12px);
|
||||||
|
border-radius: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-drag {
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-drag-copy {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-window-actions {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-summary {
|
||||||
|
gap: 10px;
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-sections {
|
||||||
|
gap: 14px;
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-summary-head,
|
||||||
|
.chat-share-page__process-inspector-section-head {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-section-head {
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-section-head .ant-typography {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-section-head-actions {
|
||||||
|
align-self: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-table-row,
|
||||||
|
.chat-share-page__process-inspector-narrative {
|
||||||
|
grid-template-columns: minmax(0, 1fr);
|
||||||
|
gap: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-check-item {
|
||||||
|
grid-template-columns: minmax(0, 1fr);
|
||||||
|
gap: 6px;
|
||||||
|
align-items: start;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-check-item .ant-tag,
|
||||||
|
.chat-share-page__process-inspector-summary-toggle.ant-btn {
|
||||||
|
justify-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-summary-toggle.ant-btn {
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-log {
|
||||||
|
max-height: min(38dvh, 320px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-share-page__process-inspector-log-line {
|
||||||
|
grid-template-columns: 28px minmax(0, 1fr);
|
||||||
|
gap: 8px;
|
||||||
|
padding: 9px 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.chat-share-page__process-inspector-minimized {
|
.chat-share-page__process-inspector-minimized {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ type ShareNotificationClientStatus = {
|
|||||||
tone: ShareNotificationStatusTone;
|
tone: ShareNotificationStatusTone;
|
||||||
};
|
};
|
||||||
type ShareProcessInspectorMode = 'default' | 'fullscreen' | 'minimized';
|
type ShareProcessInspectorMode = 'default' | 'fullscreen' | 'minimized';
|
||||||
type ShareProcessInspectorExpandedSection = 'summary' | 'narratives' | null;
|
type ShareProcessInspectorExpandedSection = 'summary' | 'checklist' | 'narratives' | 'log' | null;
|
||||||
type ShareProcessChecklistStep = {
|
type ShareProcessChecklistStep = {
|
||||||
key: string;
|
key: string;
|
||||||
label: string;
|
label: string;
|
||||||
@@ -5565,7 +5565,7 @@ export function ChatSharePage() {
|
|||||||
|
|
||||||
setActiveProcessInspectorRequestId(requestId);
|
setActiveProcessInspectorRequestId(requestId);
|
||||||
setProcessInspectorMode('default');
|
setProcessInspectorMode('default');
|
||||||
setProcessInspectorExpandedSection(null);
|
setProcessInspectorExpandedSection('checklist');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const closeProcessInspector = useCallback(() => {
|
const closeProcessInspector = useCallback(() => {
|
||||||
@@ -5577,9 +5577,16 @@ export function ChatSharePage() {
|
|||||||
setProcessInspectorExpandedSection((current) => (current === 'summary' ? null : 'summary'));
|
setProcessInspectorExpandedSection((current) => (current === 'summary' ? null : 'summary'));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleToggleProcessInspectorChecklist = useCallback(() => {
|
||||||
|
setProcessInspectorExpandedSection((current) => (current === 'checklist' ? null : 'checklist'));
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleToggleProcessInspectorNarratives = useCallback(() => {
|
const handleToggleProcessInspectorNarratives = useCallback(() => {
|
||||||
setProcessInspectorExpandedSection((current) => (current === 'narratives' ? null : 'narratives'));
|
setProcessInspectorExpandedSection((current) => (current === 'narratives' ? null : 'narratives'));
|
||||||
}, []);
|
}, []);
|
||||||
|
const handleToggleProcessInspectorLog = useCallback(() => {
|
||||||
|
setProcessInspectorExpandedSection((current) => (current === 'log' ? null : 'log'));
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleProgramMinimizedPointerDown = useCallback((event: ReactPointerEvent<HTMLDivElement>) => {
|
const handleProgramMinimizedPointerDown = useCallback((event: ReactPointerEvent<HTMLDivElement>) => {
|
||||||
if (event.pointerType === 'mouse' && event.button !== 0) {
|
if (event.pointerType === 'mouse' && event.button !== 0) {
|
||||||
@@ -7506,7 +7513,9 @@ export function ChatSharePage() {
|
|||||||
[activeProcessInspectorRequestId, requestById],
|
[activeProcessInspectorRequestId, requestById],
|
||||||
);
|
);
|
||||||
const isProcessInspectorSummaryCollapsed = processInspectorExpandedSection !== 'summary';
|
const isProcessInspectorSummaryCollapsed = processInspectorExpandedSection !== 'summary';
|
||||||
|
const isProcessInspectorChecklistCollapsed = processInspectorExpandedSection !== 'checklist';
|
||||||
const isProcessInspectorNarrativesCollapsed = processInspectorExpandedSection !== 'narratives';
|
const isProcessInspectorNarrativesCollapsed = processInspectorExpandedSection !== 'narratives';
|
||||||
|
const isProcessInspectorLogCollapsed = processInspectorExpandedSection !== 'log';
|
||||||
const activeProcessInspectorPayload = useMemo(() => {
|
const activeProcessInspectorPayload = useMemo(() => {
|
||||||
if (!activeProcessInspectorRequest) {
|
if (!activeProcessInspectorRequest) {
|
||||||
return null;
|
return null;
|
||||||
@@ -7720,7 +7729,17 @@ export function ChatSharePage() {
|
|||||||
<section className="chat-share-page__process-inspector-section chat-share-page__process-inspector-section--checklist">
|
<section className="chat-share-page__process-inspector-section chat-share-page__process-inspector-section--checklist">
|
||||||
<div className="chat-share-page__process-inspector-section-head">
|
<div className="chat-share-page__process-inspector-section-head">
|
||||||
<Text strong>계획 체크리스트</Text>
|
<Text strong>계획 체크리스트</Text>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
className="chat-share-page__process-inspector-summary-toggle"
|
||||||
|
icon={isProcessInspectorChecklistCollapsed ? <DownOutlined /> : <UpOutlined />}
|
||||||
|
onClick={handleToggleProcessInspectorChecklist}
|
||||||
|
>
|
||||||
|
{isProcessInspectorChecklistCollapsed ? '보기' : '접기'}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
{isProcessInspectorChecklistCollapsed ? null : (
|
||||||
<div className="chat-share-page__process-inspector-checklist" role="table" aria-label="계획 체크리스트">
|
<div className="chat-share-page__process-inspector-checklist" role="table" aria-label="계획 체크리스트">
|
||||||
{activeProcessInspectorPayload.checklist.map((step) => (
|
{activeProcessInspectorPayload.checklist.map((step) => (
|
||||||
<div key={step.key} className="chat-share-page__process-inspector-check-item" role="row">
|
<div key={step.key} className="chat-share-page__process-inspector-check-item" role="row">
|
||||||
@@ -7740,6 +7759,7 @@ export function ChatSharePage() {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</section>
|
</section>
|
||||||
<section className="chat-share-page__process-inspector-section chat-share-page__process-inspector-section--narratives">
|
<section className="chat-share-page__process-inspector-section chat-share-page__process-inspector-section--narratives">
|
||||||
<div className="chat-share-page__process-inspector-section-head">
|
<div className="chat-share-page__process-inspector-section-head">
|
||||||
@@ -7768,8 +7788,20 @@ export function ChatSharePage() {
|
|||||||
<section className="chat-share-page__process-inspector-section chat-share-page__process-inspector-section--log">
|
<section className="chat-share-page__process-inspector-section chat-share-page__process-inspector-section--log">
|
||||||
<div className="chat-share-page__process-inspector-section-head">
|
<div className="chat-share-page__process-inspector-section-head">
|
||||||
<Text strong>활동 로그</Text>
|
<Text strong>활동 로그</Text>
|
||||||
|
<div className="chat-share-page__process-inspector-section-head-actions">
|
||||||
<Text type="secondary">{activeProcessInspectorPayload.activityLines.length}줄</Text>
|
<Text type="secondary">{activeProcessInspectorPayload.activityLines.length}줄</Text>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
className="chat-share-page__process-inspector-summary-toggle"
|
||||||
|
icon={isProcessInspectorLogCollapsed ? <DownOutlined /> : <UpOutlined />}
|
||||||
|
onClick={handleToggleProcessInspectorLog}
|
||||||
|
>
|
||||||
|
{isProcessInspectorLogCollapsed ? '보기' : '접기'}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
{isProcessInspectorLogCollapsed ? null : (
|
||||||
<div className="chat-share-page__process-inspector-log" role="table" aria-label="활동 로그">
|
<div className="chat-share-page__process-inspector-log" role="table" aria-label="활동 로그">
|
||||||
{activeProcessInspectorPayload.activityLines.length > 0 ? (
|
{activeProcessInspectorPayload.activityLines.length > 0 ? (
|
||||||
activeProcessInspectorPayload.activityLines.map((line, index) => (
|
activeProcessInspectorPayload.activityLines.map((line, index) => (
|
||||||
@@ -7782,6 +7814,7 @@ export function ChatSharePage() {
|
|||||||
<Text type="secondary">활동 로그가 아직 기록되지 않았습니다.</Text>
|
<Text type="secondary">활동 로그가 아직 기록되지 않았습니다.</Text>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
SyncOutlined,
|
SyncOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { Alert, Button, Empty, Space, Tag, Typography, message } from 'antd';
|
import { Alert, Button, Empty, Space, Tag, Typography, message } from 'antd';
|
||||||
import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';
|
import { useEffect, useEffectEvent, useMemo, useRef, useState, type ReactNode } from 'react';
|
||||||
import { useTokenAccess } from '../../app/main/tokenAccess';
|
import { useTokenAccess } from '../../app/main/tokenAccess';
|
||||||
import { DataStatePanel } from '../../components/dataStatePanel';
|
import { DataStatePanel } from '../../components/dataStatePanel';
|
||||||
import { copyText } from '../../app/main/mainChatPanel';
|
import { copyText } from '../../app/main/mainChatPanel';
|
||||||
@@ -802,6 +802,13 @@ export function ServerCommandPage({ sharedAccess = null }: ServerCommandPageProp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const refreshServerCommandState = useEffectEvent((options?: { silent?: boolean }) => Promise.all([
|
||||||
|
loadItems(options),
|
||||||
|
loadReservation({ silent: true }),
|
||||||
|
loadWorkServerDeployment({ silent: true }),
|
||||||
|
loadTestDeployment({ silent: true }),
|
||||||
|
]));
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!hasAccess && !isSharedManageMode) {
|
if (!hasAccess && !isSharedManageMode) {
|
||||||
setItems([]);
|
setItems([]);
|
||||||
@@ -813,7 +820,7 @@ export function ServerCommandPage({ sharedAccess = null }: ServerCommandPageProp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Promise.all([loadItems(), loadReservation({ silent: true }), loadWorkServerDeployment({ silent: true }), loadTestDeployment({ silent: true })]);
|
void refreshServerCommandState();
|
||||||
}, [allowedKeysKey, hasAccess, isSharedManageMode, sharedAccess?.shareToken]);
|
}, [allowedKeysKey, hasAccess, isSharedManageMode, sharedAccess?.shareToken]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -834,12 +841,7 @@ export function ServerCommandPage({ sharedAccess = null }: ServerCommandPageProp
|
|||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
try {
|
try {
|
||||||
await Promise.all([
|
await refreshServerCommandState({ silent: true });
|
||||||
loadItems({ silent: true }),
|
|
||||||
loadReservation({ silent: true }),
|
|
||||||
loadWorkServerDeployment({ silent: true }),
|
|
||||||
loadTestDeployment({ silent: true }),
|
|
||||||
]);
|
|
||||||
} catch {
|
} catch {
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
// ignore polling errors and keep the latest visible state
|
// ignore polling errors and keep the latest visible state
|
||||||
@@ -858,6 +860,28 @@ export function ServerCommandPage({ sharedAccess = null }: ServerCommandPageProp
|
|||||||
};
|
};
|
||||||
}, [hasAccess, isSharedManageMode, runningActionKey, sharedAccess?.shareToken, testDeployment?.status, workServerDeployment?.status]);
|
}, [hasAccess, isSharedManageMode, runningActionKey, sharedAccess?.shareToken, testDeployment?.status, workServerDeployment?.status]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!hasAccess && !isSharedManageMode) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleWindowAttention = () => {
|
||||||
|
if (document.visibilityState !== 'visible') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void refreshServerCommandState({ silent: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('focus', handleWindowAttention);
|
||||||
|
document.addEventListener('visibilitychange', handleWindowAttention);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('focus', handleWindowAttention);
|
||||||
|
document.removeEventListener('visibilitychange', handleWindowAttention);
|
||||||
|
};
|
||||||
|
}, [hasAccess, isSharedManageMode, refreshServerCommandState]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!workServerDeployment || workServerDeployment.status === 'idle' || workServerDeployment.status === 'running') {
|
if (!workServerDeployment || workServerDeployment.status === 'idle' || workServerDeployment.status === 'running') {
|
||||||
return;
|
return;
|
||||||
@@ -874,6 +898,7 @@ export function ServerCommandPage({ sharedAccess = null }: ServerCommandPageProp
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (workServerDeployment.status === 'completed') {
|
if (workServerDeployment.status === 'completed') {
|
||||||
|
void refreshServerCommandState({ silent: true });
|
||||||
void messageApi.success('WORK 서버 무중단 배포가 완료되었습니다.');
|
void messageApi.success('WORK 서버 무중단 배포가 완료되었습니다.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user