chore: test deploy snapshot
This commit is contained in:
@@ -2463,11 +2463,57 @@
|
||||
|
||||
.app-chat-preview-card--prompt .app-chat-preview-card__actions {
|
||||
flex: 0 0 auto;
|
||||
min-width: fit-content;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
flex-wrap: nowrap;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.app-chat-preview-card--prompt .app-chat-preview-card__header {
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.app-chat-preview-card--prompt .app-chat-preview-card__actions {
|
||||
width: 100%;
|
||||
flex: 1 1 100%;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.app-chat-prompt-card__submitted {
|
||||
max-width: 100%;
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.app-chat-prompt-card__selection-pill {
|
||||
max-width: 100%;
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.app-chat-prompt-card__step-header {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.app-chat-prompt-card__preview-toolbar {
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.app-chat-prompt-card__preview-title.ant-typography {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.app-chat-prompt-card__preview-modal.ant-modal {
|
||||
background:
|
||||
linear-gradient(180deg, rgba(248, 250, 252, 0.98), rgba(226, 232, 240, 0.98)),
|
||||
|
||||
@@ -173,6 +173,9 @@ type ShareSearchResult = {
|
||||
value: string;
|
||||
};
|
||||
};
|
||||
type ShareSearchIndexedResult = ShareSearchResult & {
|
||||
searchText: string;
|
||||
};
|
||||
type ShareSearchPanelMode = 'all' | 'apps';
|
||||
type ShareWorkServerVersionStatus = 'latest' | 'unknown' | 'update-available' | 'build-required';
|
||||
type ClientNotificationPermissionState = 'unsupported' | 'default' | 'granted' | 'denied';
|
||||
@@ -1923,6 +1926,10 @@ function matchesSearchKeyword(keyword: string, ...values: Array<string | null |
|
||||
return values.some((value) => normalizeSearchKeyword(value ?? '').includes(keyword));
|
||||
}
|
||||
|
||||
function buildSearchKeywordText(...values: Array<string | null | undefined>) {
|
||||
return normalizeSearchKeyword(values.filter(Boolean).join(' '));
|
||||
}
|
||||
|
||||
function buildSharePromptSelectionKey(parentRequestId: string, sourceMessageId: number, promptIndex: number, promptTitle: string, promptSignature: string) {
|
||||
return [parentRequestId.trim(), sourceMessageId, promptIndex, promptTitle.trim(), promptSignature.trim()].join('::');
|
||||
}
|
||||
@@ -8379,110 +8386,26 @@ export function ChatSharePage() {
|
||||
? renderEmbeddedSharePlayApp(programTarget.appId, closeProgramTarget, normalizedToken)
|
||||
: null;
|
||||
const isServerCommandDrawerOpen = programTarget?.appId === 'server-command';
|
||||
const searchResults = useMemo<ShareSearchResult[]>(() => {
|
||||
const keyword = normalizeSearchKeyword(searchKeyword);
|
||||
const results: ShareSearchResult[] = [];
|
||||
|
||||
if (searchPanelMode === 'apps') {
|
||||
const photoprismLauncher = buildPhotoPrismProgramTarget();
|
||||
|
||||
if (
|
||||
matchesSearchKeyword(
|
||||
keyword,
|
||||
currentShareChatTarget.label,
|
||||
currentShareChatTarget.appId,
|
||||
'공유채팅',
|
||||
'현재 토큰',
|
||||
'현재 공유토큰 열기',
|
||||
...APPS_LAUNCHER_SEARCH_TERMS,
|
||||
)
|
||||
) {
|
||||
results.push({
|
||||
key: `management-app:${SHARE_CURRENT_CHAT_APP_ID}`,
|
||||
title: currentShareChatTarget.label,
|
||||
description: `현재 공유토큰을 ${selectedAppEnvironment} 환경에서 다시 엽니다.`,
|
||||
category: 'resource',
|
||||
icon: <CommentOutlined />,
|
||||
usageBadge: resolveShareAppUsageBadge(appLaunchUsage[SHARE_CURRENT_CHAT_APP_ID]),
|
||||
resource: currentShareChatTarget,
|
||||
});
|
||||
}
|
||||
|
||||
sortedAllowedManagementApps.forEach((item) => {
|
||||
if (!matchesSearchKeyword(keyword, item.value, item.label, item.description, ...APPS_LAUNCHER_SEARCH_TERMS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
results.push({
|
||||
key: `management-app:${item.value}`,
|
||||
title: item.label,
|
||||
description: item.description,
|
||||
category: 'resource',
|
||||
icon: item.icon,
|
||||
usageBadge: resolveShareAppUsageBadge(appLaunchUsage[item.value]),
|
||||
resource: buildShareManagementProgramTarget(item.value, item.label),
|
||||
});
|
||||
});
|
||||
|
||||
sortedAllowedPlayAppEntries.forEach((entry) => {
|
||||
if (
|
||||
!matchesSearchKeyword(
|
||||
keyword,
|
||||
entry.id,
|
||||
entry.name,
|
||||
entry.searchDescription,
|
||||
...APPS_LAUNCHER_SEARCH_TERMS,
|
||||
...(entry.searchKeywords ?? []),
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
results.push({
|
||||
key: `app:${entry.id}`,
|
||||
title: entry.name,
|
||||
description: resolveSupportedEnvironmentSummary(entry),
|
||||
category: 'resource',
|
||||
icon: entry.icon,
|
||||
usageBadge: resolveShareAppUsageBadge(appLaunchUsage[entry.id]),
|
||||
appEntry: entry,
|
||||
resource:
|
||||
entry.id === 'photoprism'
|
||||
? photoprismLauncher
|
||||
: buildPlayAppProgramTarget(entry.id, entry.name),
|
||||
});
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
if (!keyword) {
|
||||
return results;
|
||||
}
|
||||
const indexedContentSearchResults = useMemo<ShareSearchIndexedResult[]>(() => {
|
||||
const results: ShareSearchIndexedResult[] = [];
|
||||
|
||||
sortedRequests.forEach((request) => {
|
||||
const requestText = buildShareVisibleText(request.userText);
|
||||
|
||||
if (matchesSearchKeyword(keyword, requestText, request.statusMessage, request.requestId)) {
|
||||
results.push({
|
||||
key: `request:${request.requestId}`,
|
||||
title: requestText || '질문',
|
||||
description: `질문 · ${formatTimeLabel(request.createdAt)}`,
|
||||
category: 'request',
|
||||
requestId: request.requestId,
|
||||
scrollTarget: {
|
||||
type: 'request',
|
||||
value: request.requestId,
|
||||
},
|
||||
});
|
||||
}
|
||||
results.push({
|
||||
key: `request:${request.requestId}`,
|
||||
title: requestText || '질문',
|
||||
description: `질문 · ${formatTimeLabel(request.createdAt)}`,
|
||||
category: 'request',
|
||||
requestId: request.requestId,
|
||||
scrollTarget: {
|
||||
type: 'request',
|
||||
value: request.requestId,
|
||||
},
|
||||
searchText: buildSearchKeywordText(requestText, request.statusMessage, request.requestId),
|
||||
});
|
||||
|
||||
buildSharePreviewItemsFromText(request.userText, normalizedToken).forEach((item) => {
|
||||
if (!matchesSearchKeyword(keyword, item.label, item.url, item.kind)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scopedUrl = resolveShareScopedResourceUrl(item.url, normalizedToken);
|
||||
results.push({
|
||||
key: `request-resource:${request.requestId}:${item.id}`,
|
||||
title: item.label,
|
||||
@@ -8492,7 +8415,7 @@ export function ChatSharePage() {
|
||||
resource: {
|
||||
key: `request-resource:${request.requestId}:${item.id}`,
|
||||
label: item.label,
|
||||
url: scopedUrl,
|
||||
url: item.url,
|
||||
kind: item.kind,
|
||||
meta: `${item.kind} resource`,
|
||||
},
|
||||
@@ -8500,6 +8423,7 @@ export function ChatSharePage() {
|
||||
type: 'request',
|
||||
value: request.requestId,
|
||||
},
|
||||
searchText: buildSearchKeywordText(item.label, item.url, item.kind),
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8509,25 +8433,20 @@ export function ChatSharePage() {
|
||||
const visibleText = buildVisibleMessageText(entry, payload);
|
||||
const requestId = entry.clientRequestId?.trim() || snapshot?.rootRequestId?.trim() || '';
|
||||
|
||||
if (matchesSearchKeyword(keyword, visibleText, entry.author, requestId)) {
|
||||
results.push({
|
||||
key: `response:${entry.id}`,
|
||||
title: visibleText || '응답',
|
||||
description: `${entry.author === 'user' ? '질문 메시지' : '응답'} · ${formatTimeLabel(entry.timestamp)}`,
|
||||
category: 'response',
|
||||
requestId: requestId || undefined,
|
||||
scrollTarget: {
|
||||
type: 'response',
|
||||
value: String(entry.id),
|
||||
},
|
||||
});
|
||||
}
|
||||
results.push({
|
||||
key: `response:${entry.id}`,
|
||||
title: visibleText || '응답',
|
||||
description: `${entry.author === 'user' ? '질문 메시지' : '응답'} · ${formatTimeLabel(entry.timestamp)}`,
|
||||
category: 'response',
|
||||
requestId: requestId || undefined,
|
||||
scrollTarget: {
|
||||
type: 'response',
|
||||
value: String(entry.id),
|
||||
},
|
||||
searchText: buildSearchKeywordText(visibleText, entry.author, requestId),
|
||||
});
|
||||
|
||||
(payload?.promptParts ?? []).forEach((prompt, promptIndex) => {
|
||||
if (!matchesSearchKeyword(keyword, buildSharePromptSearchText(prompt), requestId, entry.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
results.push({
|
||||
key: `prompt:${entry.id}:${promptIndex}`,
|
||||
title: prompt.title || 'prompt',
|
||||
@@ -8538,15 +8457,15 @@ export function ChatSharePage() {
|
||||
type: 'prompt',
|
||||
value: buildSharePromptAnchorKey(entry.id, promptIndex),
|
||||
},
|
||||
searchText: buildSearchKeywordText(buildSharePromptSearchText(prompt), requestId, String(entry.id)),
|
||||
});
|
||||
});
|
||||
|
||||
(payload?.previewItems ?? []).forEach((item) => {
|
||||
if (!requestId || !matchesSearchKeyword(keyword, item.label, item.url, item.kind)) {
|
||||
if (!requestId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scopedUrl = resolveShareScopedResourceUrl(item.url, normalizedToken);
|
||||
results.push({
|
||||
key: `response-resource:${entry.id}:${item.id}`,
|
||||
title: item.label,
|
||||
@@ -8556,7 +8475,7 @@ export function ChatSharePage() {
|
||||
resource: {
|
||||
key: `response-resource:${entry.id}:${item.id}`,
|
||||
label: item.label,
|
||||
url: scopedUrl,
|
||||
url: resolveShareScopedResourceUrl(item.url, normalizedToken),
|
||||
kind: item.kind,
|
||||
meta: `${item.kind} resource`,
|
||||
},
|
||||
@@ -8564,6 +8483,7 @@ export function ChatSharePage() {
|
||||
type: 'response',
|
||||
value: String(entry.id),
|
||||
},
|
||||
searchText: buildSearchKeywordText(item.label, item.url, item.kind),
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8571,10 +8491,6 @@ export function ChatSharePage() {
|
||||
(snapshot?.activityLogs ?? []).forEach((activity, index) => {
|
||||
const summary = summarizeActivityLogLines(activity.lines ?? []).join(' ');
|
||||
|
||||
if (!matchesSearchKeyword(keyword, activity.requestId, summary)) {
|
||||
return;
|
||||
}
|
||||
|
||||
results.push({
|
||||
key: `activity:${activity.requestId}:${index}`,
|
||||
title: summary || `활동 로그 ${index + 1}`,
|
||||
@@ -8585,13 +8501,86 @@ export function ChatSharePage() {
|
||||
type: 'activity',
|
||||
value: 'chat-share-activity-panel',
|
||||
},
|
||||
searchText: buildSearchKeywordText(activity.requestId, summary),
|
||||
});
|
||||
});
|
||||
|
||||
return results
|
||||
.filter((item) => !item.scrollTarget || item.scrollTarget.value.trim())
|
||||
.slice(0, 40);
|
||||
}, [appLaunchUsage, currentShareChatTarget, messageRenderPayloadById, normalizedToken, searchKeyword, searchPanelMode, selectedAppEnvironment, snapshot?.activityLogs, snapshot?.rootRequestId, sortedAllowedManagementApps, sortedAllowedPlayAppEntries, sortedMessages, sortedRequests]);
|
||||
return results.filter((item) => !item.scrollTarget || item.scrollTarget.value.trim());
|
||||
}, [messageRenderPayloadById, normalizedToken, snapshot?.activityLogs, snapshot?.rootRequestId, sortedMessages, sortedRequests]);
|
||||
const indexedAppSearchResults = useMemo<ShareSearchIndexedResult[]>(() => {
|
||||
const results: ShareSearchIndexedResult[] = [];
|
||||
const photoprismLauncher = buildPhotoPrismProgramTarget();
|
||||
|
||||
results.push({
|
||||
key: `management-app:${SHARE_CURRENT_CHAT_APP_ID}`,
|
||||
title: currentShareChatTarget.label,
|
||||
description: `현재 공유토큰을 ${selectedAppEnvironment} 환경에서 다시 엽니다.`,
|
||||
category: 'resource',
|
||||
icon: <CommentOutlined />,
|
||||
usageBadge: resolveShareAppUsageBadge(appLaunchUsage[SHARE_CURRENT_CHAT_APP_ID]),
|
||||
resource: currentShareChatTarget,
|
||||
searchText: buildSearchKeywordText(
|
||||
currentShareChatTarget.label,
|
||||
currentShareChatTarget.appId,
|
||||
'공유채팅',
|
||||
'현재 토큰',
|
||||
'현재 공유토큰 열기',
|
||||
...APPS_LAUNCHER_SEARCH_TERMS,
|
||||
),
|
||||
});
|
||||
|
||||
sortedAllowedManagementApps.forEach((item) => {
|
||||
results.push({
|
||||
key: `management-app:${item.value}`,
|
||||
title: item.label,
|
||||
description: item.description,
|
||||
category: 'resource',
|
||||
icon: item.icon,
|
||||
usageBadge: resolveShareAppUsageBadge(appLaunchUsage[item.value]),
|
||||
resource: buildShareManagementProgramTarget(item.value, item.label),
|
||||
searchText: buildSearchKeywordText(item.value, item.label, item.description, ...APPS_LAUNCHER_SEARCH_TERMS),
|
||||
});
|
||||
});
|
||||
|
||||
sortedAllowedPlayAppEntries.forEach((entry) => {
|
||||
results.push({
|
||||
key: `app:${entry.id}`,
|
||||
title: entry.name,
|
||||
description: resolveSupportedEnvironmentSummary(entry),
|
||||
category: 'resource',
|
||||
icon: entry.icon,
|
||||
usageBadge: resolveShareAppUsageBadge(appLaunchUsage[entry.id]),
|
||||
appEntry: entry,
|
||||
resource:
|
||||
entry.id === 'photoprism'
|
||||
? photoprismLauncher
|
||||
: buildPlayAppProgramTarget(entry.id, entry.name),
|
||||
searchText: buildSearchKeywordText(
|
||||
entry.id,
|
||||
entry.name,
|
||||
entry.searchDescription,
|
||||
...APPS_LAUNCHER_SEARCH_TERMS,
|
||||
...(entry.searchKeywords ?? []),
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
return results;
|
||||
}, [appLaunchUsage, currentShareChatTarget, selectedAppEnvironment, sortedAllowedManagementApps, sortedAllowedPlayAppEntries]);
|
||||
const searchResults = useMemo<ShareSearchResult[]>(() => {
|
||||
const keyword = normalizeSearchKeyword(searchKeyword);
|
||||
const source = searchPanelMode === 'apps' ? indexedAppSearchResults : indexedContentSearchResults;
|
||||
|
||||
if (searchPanelMode !== 'apps' && !keyword) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const filtered = keyword
|
||||
? source.filter((item) => item.searchText.includes(keyword))
|
||||
: source;
|
||||
|
||||
return filtered.slice(0, 40).map(({ searchText: _searchText, ...result }) => result);
|
||||
}, [indexedAppSearchResults, indexedContentSearchResults, searchKeyword, searchPanelMode]);
|
||||
const selectedTokenUsageSetting = shareTokenSetting;
|
||||
const tokenUsageSummaryByPeriod = useMemo(
|
||||
() =>
|
||||
|
||||
Reference in New Issue
Block a user