chore: test deploy snapshot

This commit is contained in:
2026-05-28 14:34:49 +09:00
parent 82c46f4be4
commit bb275c0534
14 changed files with 531 additions and 193 deletions

View File

@@ -86,6 +86,10 @@ async function resetServiceWorkersAndReload() {
reloadAppWithCacheBuster();
}
export async function forceReloadApp() {
await resetServiceWorkersAndReload();
}
async function unregisterServiceWorkers() {
if (!isAppUpdateSupported()) {
return;

View File

@@ -196,6 +196,14 @@ function extractKnownPreviewPath(value: string) {
return normalizePreviewPathHash(pathname);
}
if (pathname.startsWith(CHAT_PUBLIC_DOT_CODEX_MARKER)) {
return `${CHAT_API_RESOURCE_MARKER}${pathname.slice(CHAT_PUBLIC_DOT_CODEX_MARKER.length)}`;
}
if (pathname.startsWith(CHAT_DOT_CODEX_MARKER)) {
return `${CHAT_API_RESOURCE_MARKER}${pathname.slice(CHAT_DOT_CODEX_MARKER.length)}`;
}
return normalized;
} catch {
return normalizePreviewPathHash(extractEmbeddedResourcePath(normalized));

View File

@@ -173,6 +173,14 @@ function extractKnownPreviewPath(value: string) {
return normalizePreviewPathHash(pathname);
}
if (pathname.startsWith(CHAT_PUBLIC_DOT_CODEX_MARKER)) {
return `${CHAT_API_RESOURCE_MARKER}${pathname.slice(CHAT_PUBLIC_DOT_CODEX_MARKER.length)}`;
}
if (pathname.startsWith(CHAT_DOT_CODEX_MARKER)) {
return `${CHAT_API_RESOURCE_MARKER}${pathname.slice(CHAT_DOT_CODEX_MARKER.length)}`;
}
return normalized;
} catch {
return '';

View File

@@ -224,7 +224,7 @@
.chat-share-page__room-list-panel--floating {
position: fixed;
z-index: 1300;
z-index: 1700;
overflow: hidden;
box-shadow:
0 18px 42px rgba(15, 23, 42, 0.18),
@@ -886,15 +886,29 @@
display: inline-flex;
align-items: center;
gap: 8px;
width: auto;
max-width: 100%;
align-self: flex-start;
min-width: 0;
flex-wrap: wrap;
flex-wrap: nowrap;
}
.chat-share-page__conversation-title.ant-typography {
margin: 0;
flex: 0 1 auto;
max-width: 100%;
min-width: 0;
font-size: 18px;
line-height: 1.35;
font-weight: 700;
color: #0f172a;
}
.chat-share-page__header-summary.ant-typography {
margin: 0;
font-size: 11px;
line-height: 1.35;
white-space: nowrap;
white-space: normal;
flex: 0 0 auto;
}
@@ -914,6 +928,55 @@
background: #ef4444;
}
.chat-share-page__status-badge {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 0;
max-width: min(100%, 96px);
min-height: 18px;
padding: 1px 6px;
border-radius: 999px;
flex: 0 0 auto;
font-size: 10px;
font-weight: 600;
line-height: 1.2;
color: #334155;
box-shadow: inset 0 0 0 1px rgba(148, 163, 184, 0.28);
}
.chat-share-page__status-badge--processing {
background: rgba(219, 234, 254, 0.92);
}
.chat-share-page__status-badge--warning {
background: rgba(254, 243, 199, 0.9);
}
.chat-share-page__status-badge--success {
background: rgba(220, 252, 231, 0.92);
}
.chat-share-page__status-badge--error {
background: rgba(254, 226, 226, 0.92);
}
.chat-share-page__status-badge--default {
background: rgba(241, 245, 249, 0.96);
}
.chat-share-page__status-badge-label {
display: block;
min-width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.chat-share-page__section-action--title-edit.ant-btn {
flex: 0 0 auto;
}
.chat-share-page__section-actions {
display: inline-flex;
align-items: center;
@@ -929,7 +992,7 @@
.chat-share-page__request-nav {
display: inline-flex;
align-items: center;
gap: 2px;
gap: 4px;
}
.chat-share-page__section-action--icon.ant-btn {
@@ -999,6 +1062,34 @@
transform: translateY(0);
}
.chat-share-page__section-action--inline.ant-btn {
height: 28px;
padding-inline: 8px;
box-shadow: none;
background: transparent;
}
.chat-share-page__section-action--inline.ant-btn .ant-btn-icon {
width: 20px;
height: 20px;
background: rgba(226, 232, 240, 0.72);
color: #475569;
box-shadow: none;
}
.chat-share-page__section-action--inline.ant-btn:hover,
.chat-share-page__section-action--inline.ant-btn:focus-visible {
background: transparent;
box-shadow: none;
transform: none;
}
.chat-share-page__section-action--inline.ant-btn:hover .ant-btn-icon,
.chat-share-page__section-action--inline.ant-btn:focus-visible .ant-btn-icon {
background: rgba(219, 234, 254, 0.92);
color: #1d4ed8;
}
.chat-share-page__tool-button-label {
font-size: 12px;
font-weight: 700;
@@ -1211,20 +1302,33 @@
}
.chat-share-page__expand-mode-filter.ant-btn {
min-width: 34px;
color: #475569;
background: transparent;
box-shadow: none;
padding-inline: 8px;
}
.chat-share-page__expand-mode-filter--active.ant-btn {
background: linear-gradient(180deg, rgba(219, 234, 254, 0.98) 0%, rgba(191, 219, 254, 0.94) 100%);
color: #1d4ed8;
box-shadow:
inset 0 0 0 1px rgba(96, 165, 250, 0.28),
0 8px 18px rgba(96, 165, 250, 0.14);
background: rgba(219, 234, 254, 0.38);
box-shadow: inset 0 0 0 1px rgba(96, 165, 250, 0.18);
}
.chat-share-page__expand-mode-filter.ant-btn:hover {
.chat-share-page__expand-mode-filter.ant-btn:hover,
.chat-share-page__expand-mode-filter.ant-btn:focus-visible {
color: #1d4ed8;
background: rgba(226, 232, 240, 0.72);
background: rgba(226, 232, 240, 0.5);
box-shadow: none;
transform: none;
}
.chat-share-page__expand-mode-filter.ant-btn:active {
transform: none;
}
.chat-share-page__expand-mode-filter.ant-btn .chat-share-page__tool-button-label {
color: inherit;
}
.chat-share-page__expand-mode-filter.ant-btn {
@@ -1232,8 +1336,9 @@
}
.chat-share-page__expand-mode-filter.ant-btn .ant-btn-icon {
color: #1d4ed8;
background: rgba(219, 234, 254, 0.96);
color: currentColor;
background: transparent;
box-shadow: none;
}
.chat-share-page__expand-mode-filter.ant-btn .anticon {
@@ -2656,67 +2761,72 @@
}
.chat-share-page__first-inquiry {
display: grid;
gap: 8px;
padding: 2px 0 12px;
border-bottom: 1px solid rgba(148, 163, 184, 0.28);
}
.chat-share-page__first-inquiry-head {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: start;
gap: 8px;
}
.chat-share-page__first-inquiry-copy {
display: grid;
gap: 8px;
min-width: 0;
}
.chat-share-page__first-inquiry-title-row {
.chat-share-page__conversation-toolbar {
display: flex;
align-items: flex-start;
gap: 6px;
min-width: 0;
justify-content: flex-end;
margin: 0 -10px 8px;
padding: 2px 10px 0;
}
.chat-share-page__first-inquiry-title-row .chat-share-page__section-action.ant-btn {
flex: 0 0 auto;
margin-top: -2px;
.chat-share-page__conversation-toolbar {
position: sticky;
top: var(--chat-share-page-conversation-toolbar-top, 52px);
z-index: 18;
background: transparent;
backdrop-filter: none;
}
.chat-share-page__first-inquiry-menu-badge {
.chat-share-page__conversation-toolbar-group {
display: inline-flex;
align-items: center;
width: fit-content;
justify-content: flex-end;
gap: 4px;
max-width: 100%;
min-height: 28px;
padding: 0 12px;
border-radius: 999px;
background: rgba(219, 234, 254, 0.94);
color: #1d4ed8;
box-shadow: inset 0 0 0 1px rgba(96, 165, 250, 0.22);
font-size: 12px;
font-weight: 700;
line-height: 1.2;
}
.chat-share-page__first-inquiry-title.ant-typography {
margin: 0;
min-width: 0;
font-size: 18px;
line-height: 1.45;
font-weight: 700;
.chat-share-page__conversation-toolbar-button.ant-btn {
min-width: 34px;
height: 34px;
padding-inline: 8px;
color: #475569;
background: transparent;
border-color: rgba(148, 163, 184, 0.22);
box-shadow: none;
backdrop-filter: none;
}
.chat-share-page__conversation-toolbar-button.ant-btn .ant-btn-icon {
color: currentColor;
background: transparent;
box-shadow: none;
}
.chat-share-page__conversation-toolbar-button.ant-btn:hover,
.chat-share-page__conversation-toolbar-button.ant-btn:focus-visible {
color: #0f172a;
overflow: hidden;
background: transparent;
border-color: rgba(100, 116, 139, 0.34);
box-shadow: none;
}
.chat-share-page__first-inquiry-head .chat-share-page__expand-mode-filter.ant-btn {
justify-self: end;
margin-top: 1px;
.chat-share-page__conversation-toolbar-button.ant-btn:active {
background: transparent;
border-color: rgba(71, 85, 105, 0.42);
box-shadow: none;
transform: none;
}
.chat-share-page__conversation-toolbar-button.ant-btn:disabled,
.chat-share-page__conversation-toolbar-button.ant-btn:disabled:hover,
.chat-share-page__conversation-toolbar-button.ant-btn:disabled:focus-visible {
color: rgba(100, 116, 139, 0.68);
background: transparent;
border-color: rgba(148, 163, 184, 0.16);
box-shadow: none;
}
.chat-share-page__conversation-toolbar .chat-share-page__conversation-toolbar-button.ant-btn .chat-share-page__tool-button-label {
color: inherit;
}
.chat-share-page__bundle-list {

View File

@@ -65,6 +65,7 @@ import { extractPreviewItems, type PreviewItem } from '../mainChatPanel/previewI
import { buildChatPath, buildPlayAppPath } from '../routes';
import type { PreviewKind } from '../mainChatPanel/previewKind';
import { normalizeChatResourceUrl } from '../mainChatPanel/chatResourceUrl';
import { forceReloadApp } from '../appUpdate';
import type {
ChatComposerAttachment,
ChatConversationSummary,
@@ -185,6 +186,7 @@ type ShareNotificationClientStatus = {
tone: ShareNotificationStatusTone;
};
type ShareProcessInspectorMode = 'default' | 'fullscreen' | 'minimized';
type ShareProcessInspectorExpandedSection = 'summary' | 'narratives' | null;
type ShareProcessChecklistStep = {
key: string;
label: string;
@@ -4030,6 +4032,7 @@ export function ChatSharePage() {
const [pendingRequestRetryIds, setPendingRequestRetryIds] = useState<string[]>([]);
const [isShareRoomListVisible, setIsShareRoomListVisible] = useState(false);
const [shareRoomListLayerStyle, setShareRoomListLayerStyle] = useState<CSSProperties | null>(null);
const [conversationToolbarStickyTop, setConversationToolbarStickyTop] = useState(52);
const [isRoomSwitching, setIsRoomSwitching] = useState(false);
const [replyReferenceRequestId, setReplyReferenceRequestId] = useState('');
const [previousQuestionModalRequestId, setPreviousQuestionModalRequestId] = useState('');
@@ -4080,8 +4083,7 @@ export function ChatSharePage() {
const [pendingShareRuntimeRequestIds, setPendingShareRuntimeRequestIds] = useState<string[]>([]);
const [activeProcessInspectorRequestId, setActiveProcessInspectorRequestId] = useState('');
const [processInspectorMode, setProcessInspectorMode] = useState<ShareProcessInspectorMode>('default');
const [isProcessInspectorSummaryCollapsed, setIsProcessInspectorSummaryCollapsed] = useState(true);
const [isProcessInspectorNarrativesCollapsed, setIsProcessInspectorNarrativesCollapsed] = useState(true);
const [processInspectorExpandedSection, setProcessInspectorExpandedSection] = useState<ShareProcessInspectorExpandedSection>(null);
const [optimisticShareRooms, setOptimisticShareRooms] = useState<ChatShareRoomSummary[]>([]);
const [shareRoomPendingCountsBySessionId, setShareRoomPendingCountsBySessionId] = useState<Record<string, ShareRoomPendingCounts>>({});
const [isLoadingShareRoomPendingCounts, setIsLoadingShareRoomPendingCounts] = useState(false);
@@ -4102,6 +4104,7 @@ export function ChatSharePage() {
const shareRoomPendingCountRefreshPromiseBySessionIdRef = useRef<Record<string, Promise<void> | null>>({});
const shareRoomPendingCountRefreshQueuedBySessionIdRef = useRef<Record<string, boolean>>({});
const conversationHeaderRef = useRef<HTMLDivElement | null>(null);
const conversationToolbarRef = useRef<HTMLDivElement | null>(null);
const roomListTriggerButtonRef = useRef<HTMLButtonElement | null>(null);
const roomListPanelRef = useRef<HTMLElement | null>(null);
const processInspectorCardRef = useRef<HTMLDivElement | null>(null);
@@ -5428,6 +5431,37 @@ export function ChatSharePage() {
};
}, [minimizedPrograms.length]);
useLayoutEffect(() => {
const headerElement = conversationHeaderRef.current;
if (!headerElement) {
return undefined;
}
const updateStickyOffset = () => {
const headerHeight = headerElement.getBoundingClientRect().height;
const nextStickyTop = Math.max(48, Math.ceil(headerHeight) + 8);
setConversationToolbarStickyTop((current) => (current === nextStickyTop ? current : nextStickyTop));
};
const resizeObserver =
typeof ResizeObserver === 'undefined'
? null
: new ResizeObserver(() => {
updateStickyOffset();
});
updateStickyOffset();
window.addEventListener('resize', updateStickyOffset);
resizeObserver?.observe(headerElement);
return () => {
window.removeEventListener('resize', updateStickyOffset);
resizeObserver?.disconnect();
};
}, []);
useLayoutEffect(() => {
if (!isShareRoomListVisible) {
setShareRoomListLayerStyle(null);
@@ -5437,7 +5471,8 @@ export function ChatSharePage() {
const updateLayerPosition = () => {
const triggerRect = roomListTriggerButtonRef.current?.getBoundingClientRect() ?? null;
const headerRect = conversationHeaderRef.current?.getBoundingClientRect() ?? null;
const anchorRect = headerRect ?? triggerRect;
const toolbarRect = conversationToolbarRef.current?.getBoundingClientRect() ?? null;
const anchorRect = triggerRect ?? headerRect ?? toolbarRect;
if (!anchorRect) {
return;
@@ -5445,14 +5480,17 @@ export function ChatSharePage() {
const viewportPadding = 8;
const availableWidth = Math.max(280, window.innerWidth - (viewportPadding * 2));
const preferredWidth = headerRect
? Math.min(Math.max(headerRect.width, 280), 420)
const preferredWidth = toolbarRect
? Math.min(Math.max(toolbarRect.width, 280), 420)
: headerRect
? Math.min(Math.max(headerRect.width, 280), 420)
: Math.min(360, availableWidth);
const width = Math.min(preferredWidth, availableWidth);
const preferredLeft = headerRect?.left ?? triggerRect?.left ?? viewportPadding;
const preferredRight = triggerRect?.right ?? toolbarRect?.right ?? headerRect?.right ?? (viewportPadding + width);
const minLeft = viewportPadding;
const maxLeft = Math.max(viewportPadding, window.innerWidth - viewportPadding - width);
const left = Math.min(Math.max(preferredLeft, viewportPadding), maxLeft);
const top = Math.max(anchorRect.bottom, triggerRect?.bottom ?? 0) + 8;
const left = Math.min(Math.max(preferredRight - width, minLeft), maxLeft);
const top = anchorRect.bottom + 8;
const maxHeight = Math.max(220, window.innerHeight - top - viewportPadding);
setShareRoomListLayerStyle({
@@ -5527,14 +5565,20 @@ export function ChatSharePage() {
setActiveProcessInspectorRequestId(requestId);
setProcessInspectorMode('default');
setIsProcessInspectorSummaryCollapsed(true);
setIsProcessInspectorNarrativesCollapsed(true);
setProcessInspectorExpandedSection(null);
}, []);
const closeProcessInspector = useCallback(() => {
setActiveProcessInspectorRequestId('');
setIsProcessInspectorSummaryCollapsed(true);
setIsProcessInspectorNarrativesCollapsed(true);
setProcessInspectorExpandedSection(null);
}, []);
const handleToggleProcessInspectorSummary = useCallback(() => {
setProcessInspectorExpandedSection((current) => (current === 'summary' ? null : 'summary'));
}, []);
const handleToggleProcessInspectorNarratives = useCallback(() => {
setProcessInspectorExpandedSection((current) => (current === 'narratives' ? null : 'narratives'));
}, []);
const handleProgramMinimizedPointerDown = useCallback((event: ReactPointerEvent<HTMLDivElement>) => {
@@ -5583,7 +5627,7 @@ export function ChatSharePage() {
return;
}
window.location.reload();
void forceReloadApp();
}, []);
const handleReloadProgram = useCallback(() => {
@@ -7461,6 +7505,8 @@ export function ChatSharePage() {
() => (activeProcessInspectorRequestId.trim() ? requestById.get(activeProcessInspectorRequestId.trim()) ?? null : null),
[activeProcessInspectorRequestId, requestById],
);
const isProcessInspectorSummaryCollapsed = processInspectorExpandedSection !== 'summary';
const isProcessInspectorNarrativesCollapsed = processInspectorExpandedSection !== 'narratives';
const activeProcessInspectorPayload = useMemo(() => {
if (!activeProcessInspectorRequest) {
return null;
@@ -7638,9 +7684,7 @@ export function ChatSharePage() {
size="small"
className="chat-share-page__process-inspector-summary-toggle"
icon={isProcessInspectorSummaryCollapsed ? <DownOutlined /> : <UpOutlined />}
onClick={() => {
setIsProcessInspectorSummaryCollapsed((current) => !current);
}}
onClick={handleToggleProcessInspectorSummary}
>
{isProcessInspectorSummaryCollapsed ? '요청 정보 보기' : '요청 정보 접기'}
</Button>
@@ -7705,9 +7749,7 @@ export function ChatSharePage() {
size="small"
className="chat-share-page__process-inspector-summary-toggle"
icon={isProcessInspectorNarrativesCollapsed ? <DownOutlined /> : <UpOutlined />}
onClick={() => {
setIsProcessInspectorNarrativesCollapsed((current) => !current);
}}
onClick={handleToggleProcessInspectorNarratives}
>
{isProcessInspectorNarrativesCollapsed ? '보기' : '접기'}
</Button>
@@ -8686,8 +8728,8 @@ export function ChatSharePage() {
key: 'conversation-refresh',
label: (
<span className="chat-share-page__settings-item">
<span className="chat-share-page__settings-item-title"> </span>
<span className="chat-share-page__settings-item-description">PWA .</span>
<span className="chat-share-page__settings-item-title"> </span>
<span className="chat-share-page__settings-item-description"> .</span>
</span>
),
icon: <ReloadOutlined />,
@@ -9249,19 +9291,46 @@ export function ChatSharePage() {
<div className={contentLayoutClassName}>
<section className="chat-share-page__panel chat-share-page__conversation-panel">
<div ref={conversationHeaderRef} className="chat-share-page__section-head">
<div className="chat-share-page__section-copy">
<div className="chat-share-page__section-copy">
<div className="chat-share-page__section-title-row">
<Title level={5}></Title>
<Title
level={5}
className="chat-share-page__conversation-title"
ellipsis={{ rows: 1, tooltip: headerTitleText.trim() || '채팅' }}
>
{headerTitleText.trim() || '채팅'}
</Title>
{canOpenSharedRoomSettings ? (
<Button
type="text"
size="small"
className="chat-share-page__section-action chat-share-page__section-action--tool chat-share-page__section-action--inline chat-share-page__section-action--title-edit"
aria-label="채팅방 이름 및 설정 편집"
title="채팅방 이름 및 설정 편집"
icon={<EditOutlined />}
onClick={() => {
openSharedRoomSettings();
}}
/>
) : null}
<span
className={`chat-share-page__live-dot ${isLiveConnected ? 'chat-share-page__live-dot--connected' : 'chat-share-page__live-dot--disconnected'}`}
aria-label={isLiveConnected ? '웹소켓 연결됨' : '웹소켓 연결 끊김'}
title={isLiveConnected ? '웹소켓 연결됨' : '웹소켓 연결 끊김'}
/>
{aggregateStatusTag ? <Tag color={aggregateStatusTag.color}>{aggregateStatusTag.label}</Tag> : null}
<Text type="secondary" className="chat-share-page__header-summary">
{headerSummaryLabel}
</Text>
{aggregateStatusTag ? (
<span
className={`chat-share-page__status-badge chat-share-page__status-badge--${aggregateStatusTag.color}`}
aria-label={aggregateStatusTag.label}
title={aggregateStatusTag.label}
>
<span className="chat-share-page__status-badge-label">{aggregateStatusTag.label}</span>
</span>
) : null}
</div>
<Text type="secondary" className="chat-share-page__header-summary">
{headerSummaryLabel}
</Text>
</div>
<div className="chat-share-page__section-actions">
{canToggleShareRoomList ? (
@@ -9278,29 +9347,6 @@ export function ChatSharePage() {
}}
/>
) : null}
<div className="chat-share-page__request-nav" aria-label="요청 이동">
<Button
type="text"
size="small"
className="chat-share-page__section-action"
icon={<LeftOutlined />}
disabled={!canMoveToPreviousRequest}
onClick={handleMoveToPreviousRequest}
>
</Button>
<Button
type="text"
size="small"
className="chat-share-page__section-action"
icon={<RightOutlined />}
iconPosition="end"
disabled={!canMoveToNextRequest}
onClick={handleMoveToNextRequest}
>
</Button>
</div>
<Dropdown
trigger={['click']}
menu={{
@@ -9323,6 +9369,64 @@ export function ChatSharePage() {
</Dropdown>
</div>
</div>
<div
ref={conversationToolbarRef}
className="chat-share-page__conversation-toolbar"
style={
{
'--chat-share-page-conversation-toolbar-top': `${conversationToolbarStickyTop}px`,
} as CSSProperties
}
>
<div className="chat-share-page__conversation-toolbar-group" aria-label="요청 이동 및 필터">
<div className="chat-share-page__request-nav" aria-label="요청 이동">
<Button
type="text"
size="small"
className="chat-share-page__section-action chat-share-page__section-action--tool chat-share-page__conversation-toolbar-button"
icon={<LeftOutlined />}
disabled={!canMoveToPreviousRequest}
onClick={handleMoveToPreviousRequest}
>
<span className="chat-share-page__tool-button-label"></span>
</Button>
<Button
type="text"
size="small"
className="chat-share-page__section-action chat-share-page__section-action--tool chat-share-page__conversation-toolbar-button"
icon={<RightOutlined />}
iconPosition="end"
disabled={!canMoveToNextRequest}
onClick={handleMoveToNextRequest}
>
<span className="chat-share-page__tool-button-label"></span>
</Button>
</div>
<Dropdown
trigger={['click']}
placement="bottomRight"
menu={{
items: shareExpandModeMenuItems,
selectable: true,
selectedKeys: [expandMode],
onClick: handleSelectExpandMode,
}}
>
<Button
type="text"
size="small"
className={`chat-share-page__section-action chat-share-page__section-action--tool chat-share-page__conversation-toolbar-button chat-share-page__expand-mode-filter${expandMode !== 'latest' ? ' chat-share-page__expand-mode-filter--active' : ''}`}
aria-label={`공유 채팅 펼치기 필터: ${getShareExpandModeLabel(expandMode)} ${requestProgressLabel}`.trim()}
title={`공유 채팅 펼치기 필터: ${getShareExpandModeLabel(expandMode)} ${requestProgressLabel}`.trim()}
icon={<FilterOutlined />}
>
<span className="chat-share-page__tool-button-label">
{expandMode === 'latest' ? '필터' : getShareExpandModeLabel(expandMode)}
</span>
</Button>
</Dropdown>
</div>
</div>
{showRoomSwitchingSkeleton ? (
<div className="chat-share-page__conversation-loading-block" role="status" aria-live="polite">
<Spin size="large" />
@@ -9339,59 +9443,6 @@ export function ChatSharePage() {
<Text type="secondary">{`${roomSwitchingStatusLabel} 불러오는 중`}</Text>
</div>
) : null}
{headerInquiryRequest ? (
<section className="chat-share-page__first-inquiry">
<div className="chat-share-page__first-inquiry-head">
<div className="chat-share-page__first-inquiry-copy">
<div className="chat-share-page__first-inquiry-title-row">
<Title
level={5}
className="chat-share-page__first-inquiry-title"
ellipsis={{ rows: 1, tooltip: headerTitleText }}
>
{headerTitleText}
</Title>
{canOpenSharedRoomSettings ? (
<Button
type="text"
size="small"
className="chat-share-page__section-action chat-share-page__section-action--tool"
aria-label="채팅방 이름 및 설정 편집"
title="채팅방 이름 및 설정 편집"
icon={<EditOutlined />}
onClick={() => {
openSharedRoomSettings();
}}
/>
) : null}
</div>
</div>
<Dropdown
trigger={['click']}
placement="bottomRight"
menu={{
items: shareExpandModeMenuItems,
selectable: true,
selectedKeys: [expandMode],
onClick: handleSelectExpandMode,
}}
>
<Button
type="text"
size="small"
className={`chat-share-page__section-action chat-share-page__section-action--tool chat-share-page__expand-mode-filter${expandMode !== 'latest' ? ' chat-share-page__expand-mode-filter--active' : ''}`}
aria-label={`공유 채팅 펼치기 필터: ${getShareExpandModeLabel(expandMode)} ${requestProgressLabel}`.trim()}
title={`공유 채팅 펼치기 필터: ${getShareExpandModeLabel(expandMode)} ${requestProgressLabel}`.trim()}
icon={<FilterOutlined />}
>
<span className="chat-share-page__tool-button-label">
{expandMode === 'latest' ? '필터' : getShareExpandModeLabel(expandMode)}
</span>
</Button>
</Dropdown>
</div>
</section>
) : null}
{expandMode === 'latest' && hiddenBeforeCount > 0 ? (
<div className="chat-share-page__omission chat-share-page__omission--collapsed chat-share-page__omission--before" aria-label={`위쪽 채팅 ${hiddenBeforeCount}건 숨김`}>
<span className="chat-share-page__omission-line" aria-hidden="true" />