@promptbook/cli 0.112.0-132 → 0.112.0-133
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/agents-server/src/app/admin/api-tokens/ApiTokensClient.tsx +4 -1
- package/apps/agents-server/src/app/admin/chat-feedback/ChatFeedbackClient.tsx +3 -0
- package/apps/agents-server/src/app/admin/chat-feedback/ChatFeedbackTable.tsx +13 -8
- package/apps/agents-server/src/app/admin/chat-history/ChatHistoryClient.tsx +3 -0
- package/apps/agents-server/src/app/admin/chat-history/ChatHistoryTable.tsx +13 -8
- package/apps/agents-server/src/app/admin/custom-css/CustomCssClient.tsx +4 -0
- package/apps/agents-server/src/app/admin/custom-css/CustomCssEditorPanel.tsx +7 -1
- package/apps/agents-server/src/app/admin/custom-css/CustomCssFilesPanel.tsx +7 -1
- package/apps/agents-server/src/app/admin/custom-js/CustomJsClient.tsx +4 -0
- package/apps/agents-server/src/app/admin/custom-js/CustomJsEditorPanel.tsx +7 -1
- package/apps/agents-server/src/app/admin/custom-js/CustomJsFilesPanel.tsx +7 -1
- package/apps/agents-server/src/app/admin/files/FilesGalleryClient.tsx +4 -0
- package/apps/agents-server/src/app/admin/files/FilesGalleryGrid.tsx +9 -11
- package/apps/agents-server/src/app/admin/files/FilesGalleryTable.tsx +9 -8
- package/apps/agents-server/src/app/admin/images/ImagesGalleryClient.tsx +4 -0
- package/apps/agents-server/src/app/admin/images/ImagesGalleryGrid.tsx +16 -11
- package/apps/agents-server/src/app/admin/images/ImagesGalleryTable.tsx +18 -9
- package/apps/agents-server/src/app/admin/login-methods/shibboleth/page.tsx +9 -9
- package/apps/agents-server/src/app/admin/messages/MessagesClient.tsx +7 -6
- package/apps/agents-server/src/app/admin/servers/ServersRegistryTable.tsx +11 -10
- package/apps/agents-server/src/app/admin/task-manager/TaskManagerClient.tsx +4 -2
- package/apps/agents-server/src/app/admin/task-manager/TaskManagerTaskRow.tsx +14 -15
- package/apps/agents-server/src/app/admin/task-manager/TaskManagerTasksCard.tsx +4 -1
- package/apps/agents-server/src/app/admin/task-manager/useTaskManagerState.ts +6 -9
- package/apps/agents-server/src/app/admin/update/CustomCommitPicker.tsx +258 -0
- package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +305 -108
- package/apps/agents-server/src/app/admin/usage/UsageClient.tsx +4 -2
- package/apps/agents-server/src/app/admin/usage/UsageClientAnalyticsPanels.tsx +6 -4
- package/apps/agents-server/src/app/admin/usage/UsageClientFormatting.ts +6 -12
- package/apps/agents-server/src/app/admin/usage/UsageClientTimelineChart.tsx +6 -3
- package/apps/agents-server/src/app/admin/usage/useUsageClientState.ts +12 -4
- package/apps/agents-server/src/app/admin/users/[userId]/UserDetailClient.tsx +8 -3
- package/apps/agents-server/src/app/agents/[agentName]/AgentProfileChat.tsx +6 -20
- package/apps/agents-server/src/app/agents/[agentName]/book/useBookEditorHistory.ts +9 -2
- package/apps/agents-server/src/app/agents/[agentName]/chat/useAgentChatHistoryClientState.ts +2 -15
- package/apps/agents-server/src/app/agents/[agentName]/history/page.tsx +6 -1
- package/apps/agents-server/src/app/agents/[agentName]/integration/CalendarIntegrationSection.tsx +23 -5
- package/apps/agents-server/src/app/agents/[agentName]/timeouts/AgentTimeoutsClient.tsx +4 -2
- package/apps/agents-server/src/app/agents/[agentName]/timeouts/AgentTimeoutsFiltersCard.tsx +9 -4
- package/apps/agents-server/src/app/agents/[agentName]/timeouts/AgentTimeoutsTableCard.tsx +4 -1
- package/apps/agents-server/src/app/agents/[agentName]/timeouts/AgentTimeoutsTableRow.tsx +10 -3
- package/apps/agents-server/src/app/api/admin/update/commits/route.ts +35 -0
- package/apps/agents-server/src/app/api/admin/update/route.ts +10 -2
- package/apps/agents-server/src/app/api/internal/user-chat-jobs/run/route.ts +14 -2
- package/apps/agents-server/src/app/dashboard/page.tsx +11 -16
- package/apps/agents-server/src/app/swagger/SwaggerApiKeysPanel.tsx +4 -1
- package/apps/agents-server/src/app/system/user-memory/UserMemoryClient.tsx +4 -2
- package/apps/agents-server/src/app/system/user-wallet/UserWalletClient.tsx +3 -0
- package/apps/agents-server/src/app/system/user-wallet/UserWalletRecordsTable.tsx +5 -1
- package/apps/agents-server/src/app/system/utilities/mocked-chats/MockedChatsEditorClient.tsx +3 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/MockedChatsEditorSidebar.tsx +7 -8
- package/apps/agents-server/src/components/PrintHeader/PrintHeader.tsx +4 -2
- package/apps/agents-server/src/components/UsersList/UsersList.tsx +4 -2
- package/apps/agents-server/src/tools/createAgentProgressTools.ts +8 -6
- package/apps/agents-server/src/utils/localization/formatServerLanguageHumanReadableDate.ts +70 -0
- package/apps/agents-server/src/utils/localization/getRequestServerLanguage.ts +32 -0
- package/apps/agents-server/src/utils/userChat/createRunUserChatJobExecutionContext.ts +17 -0
- package/apps/agents-server/src/utils/userChat/createRunUserChatJobPersistenceController.ts +0 -21
- package/apps/agents-server/src/utils/userChat/persistUserChatJobProgressCard.ts +31 -0
- package/apps/agents-server/src/utils/userChat/retryUserChatJob.ts +0 -4
- package/apps/agents-server/src/utils/userChat/runUserChatJob.ts +29 -0
- package/apps/agents-server/src/utils/userChat/userChatMessageLifecycle.ts +2 -2
- package/apps/agents-server/src/utils/userChat/userChatProgressCard.ts +99 -401
- package/apps/agents-server/src/utils/vpsSelfUpdate.ts +625 -51
- package/esm/index.es.js +252 -41
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/common/buildCoderRunProgressSnapshot.d.ts +5 -1
- package/esm/scripts/run-codex-prompts/common/cliProgressDisplay.d.ts +7 -0
- package/esm/scripts/run-codex-prompts/common/coderRunEstimateCache.d.ts +31 -0
- package/esm/scripts/run-codex-prompts/common/progressFormatting.d.ts +2 -0
- package/esm/scripts/run-codex-prompts/runners/claude-code/ClaudeCodeRunner.d.ts +3 -1
- package/esm/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +7 -0
- package/esm/src/book-3.0/cliAgentEnv.d.ts +1 -1
- package/esm/src/cli/cli-commands/coder/ThinkingLevel.d.ts +1 -1
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/book-3.0/cliAgentEnv.ts +1 -1
- package/src/cli/cli-commands/agents-server/startAgentsServer.ts +1 -1
- package/src/cli/cli-commands/coder/ThinkingLevel.ts +3 -1
- package/src/other/templates/getTemplatesPipelineCollection.ts +711 -791
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -0
- package/umd/index.umd.js +254 -44
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/common/buildCoderRunProgressSnapshot.d.ts +5 -1
- package/umd/scripts/run-codex-prompts/common/cliProgressDisplay.d.ts +7 -0
- package/umd/scripts/run-codex-prompts/common/coderRunEstimateCache.d.ts +31 -0
- package/umd/scripts/run-codex-prompts/common/progressFormatting.d.ts +2 -0
- package/umd/scripts/run-codex-prompts/runners/claude-code/ClaudeCodeRunner.d.ts +3 -1
- package/umd/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +7 -0
- package/umd/src/book-3.0/cliAgentEnv.d.ts +1 -1
- package/umd/src/cli/cli-commands/coder/ThinkingLevel.d.ts +1 -1
- package/umd/src/version.d.ts +1 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
|
2
2
|
import Link from 'next/link';
|
|
3
|
+
import type { ServerLanguageCode } from '../../../languages/ServerLanguageRegistry';
|
|
3
4
|
import { buildAgentProfileHref } from '../../../utils/agentRouting/agentRouteHrefs';
|
|
5
|
+
import { formatServerLanguageHumanReadableDate } from '../../../utils/localization/formatServerLanguageHumanReadableDate';
|
|
4
6
|
import type { ImageWithAgent } from './actions';
|
|
5
7
|
import { ImagesGalleryParametersBadges } from './ImagesGalleryParametersBadges';
|
|
6
8
|
import { ImagesGalleryPromptCopyButton } from './ImagesGalleryPromptCopyButton';
|
|
@@ -18,6 +20,11 @@ type ImagesGalleryTableProps = Pick<
|
|
|
18
20
|
* Active text formatter for agent naming.
|
|
19
21
|
*/
|
|
20
22
|
readonly formatText: (text: string) => string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Active UI language used for date formatting.
|
|
26
|
+
*/
|
|
27
|
+
readonly language: ServerLanguageCode;
|
|
21
28
|
};
|
|
22
29
|
|
|
23
30
|
/**
|
|
@@ -28,19 +35,17 @@ type ImagesGalleryTableRowProps = Pick<UseImagesGalleryState, 'copiedId' | 'hand
|
|
|
28
35
|
* Image rendered in this table row.
|
|
29
36
|
*/
|
|
30
37
|
readonly image: ImageWithAgent;
|
|
31
|
-
};
|
|
32
38
|
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
+
/**
|
|
40
|
+
* Active UI language used for date formatting.
|
|
41
|
+
*/
|
|
42
|
+
readonly language: ServerLanguageCode;
|
|
43
|
+
};
|
|
39
44
|
|
|
40
45
|
/**
|
|
41
46
|
* Renders one image row inside the gallery table.
|
|
42
47
|
*/
|
|
43
|
-
function ImagesGalleryTableRow({ image, copiedId, handlePromptCopy }: ImagesGalleryTableRowProps) {
|
|
48
|
+
function ImagesGalleryTableRow({ image, language, copiedId, handlePromptCopy }: ImagesGalleryTableRowProps) {
|
|
44
49
|
return (
|
|
45
50
|
<tr className="bg-white border-b hover:bg-gray-50">
|
|
46
51
|
<td className="px-6 py-4">
|
|
@@ -94,7 +99,9 @@ function ImagesGalleryTableRow({ image, copiedId, handlePromptCopy }: ImagesGall
|
|
|
94
99
|
<span className="text-gray-400">-</span>
|
|
95
100
|
)}
|
|
96
101
|
</td>
|
|
97
|
-
<td className="px-6 py-4 whitespace-nowrap">
|
|
102
|
+
<td className="px-6 py-4 whitespace-nowrap">
|
|
103
|
+
{formatServerLanguageHumanReadableDate(image.createdAt, language)}
|
|
104
|
+
</td>
|
|
98
105
|
</tr>
|
|
99
106
|
);
|
|
100
107
|
}
|
|
@@ -106,6 +113,7 @@ function ImagesGalleryTableRow({ image, copiedId, handlePromptCopy }: ImagesGall
|
|
|
106
113
|
*/
|
|
107
114
|
export function ImagesGalleryTable({
|
|
108
115
|
formatText,
|
|
116
|
+
language,
|
|
109
117
|
images,
|
|
110
118
|
total,
|
|
111
119
|
isLoading,
|
|
@@ -137,6 +145,7 @@ export function ImagesGalleryTable({
|
|
|
137
145
|
<ImagesGalleryTableRow
|
|
138
146
|
key={image.id}
|
|
139
147
|
image={image}
|
|
148
|
+
language={language}
|
|
140
149
|
copiedId={copiedId}
|
|
141
150
|
handlePromptCopy={handlePromptCopy}
|
|
142
151
|
/>
|
|
@@ -5,6 +5,9 @@ import { $getTableName } from '../../../../database/$getTableName';
|
|
|
5
5
|
import { $provideSupabaseForServer } from '../../../../database/$provideSupabaseForServer';
|
|
6
6
|
import { ForbiddenPage } from '../../../../components/ForbiddenPage/ForbiddenPage';
|
|
7
7
|
import { isUserAdmin } from '../../../../utils/isUserAdmin';
|
|
8
|
+
import type { ServerLanguageCode } from '../../../../languages/ServerLanguageRegistry';
|
|
9
|
+
import { formatServerLanguageHumanReadableDate } from '../../../../utils/localization/formatServerLanguageHumanReadableDate';
|
|
10
|
+
import { getRequestServerLanguage } from '../../../../utils/localization/getRequestServerLanguage';
|
|
8
11
|
import {
|
|
9
12
|
getShibbolethAuthenticationAttemptTableName,
|
|
10
13
|
getShibbolethUserIdentityTableName,
|
|
@@ -112,12 +115,8 @@ async function loadShibbolethIdentitiesWithUsers(): Promise<{
|
|
|
112
115
|
/**
|
|
113
116
|
* Formats an optional date-time value for the dashboard.
|
|
114
117
|
*/
|
|
115
|
-
function formatDashboardDateTime(value: string | null | undefined): string {
|
|
116
|
-
|
|
117
|
-
return 'Never';
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return new Date(value).toLocaleString();
|
|
118
|
+
function formatDashboardDateTime(value: string | null | undefined, language: ServerLanguageCode): string {
|
|
119
|
+
return formatServerLanguageHumanReadableDate(value, language, { fallbackLabel: 'Never' });
|
|
121
120
|
}
|
|
122
121
|
|
|
123
122
|
/**
|
|
@@ -131,13 +130,14 @@ export default async function ShibbolethLoginMethodPage() {
|
|
|
131
130
|
}
|
|
132
131
|
|
|
133
132
|
const requestUrl = await getDashboardRequestUrl();
|
|
134
|
-
const [configuration, attempts, identitiesWithUsers] = await Promise.all([
|
|
133
|
+
const [configuration, attempts, identitiesWithUsers, language] = await Promise.all([
|
|
135
134
|
resolveShibbolethAuthenticationConfiguration({
|
|
136
135
|
requestUrl,
|
|
137
136
|
isIdentityProviderMetadataValidationEnabled: true,
|
|
138
137
|
}),
|
|
139
138
|
loadShibbolethAuthenticationAttempts(),
|
|
140
139
|
loadShibbolethIdentitiesWithUsers(),
|
|
140
|
+
getRequestServerLanguage(),
|
|
141
141
|
]);
|
|
142
142
|
const isWarningShown = configuration.isActive && !configuration.isConfigured;
|
|
143
143
|
|
|
@@ -286,7 +286,7 @@ export default async function ShibbolethLoginMethodPage() {
|
|
|
286
286
|
attempts.map((attempt) => (
|
|
287
287
|
<tr key={attempt.id}>
|
|
288
288
|
<td className="whitespace-nowrap py-2 pr-4 text-gray-700">
|
|
289
|
-
{formatDashboardDateTime(attempt.createdAt)}
|
|
289
|
+
{formatDashboardDateTime(attempt.createdAt, language)}
|
|
290
290
|
</td>
|
|
291
291
|
<td className="py-2 pr-4 font-medium text-gray-900">{attempt.status}</td>
|
|
292
292
|
<td className="py-2 pr-4 text-gray-700">{attempt.stage}</td>
|
|
@@ -350,7 +350,7 @@ export default async function ShibbolethLoginMethodPage() {
|
|
|
350
350
|
</td>
|
|
351
351
|
<td className="py-2 pr-4 text-gray-700">{identity.loginCount}</td>
|
|
352
352
|
<td className="whitespace-nowrap py-2 pr-4 text-gray-700">
|
|
353
|
-
{formatDashboardDateTime(identity.lastLoggedInAt)}
|
|
353
|
+
{formatDashboardDateTime(identity.lastLoggedInAt, language)}
|
|
354
354
|
</td>
|
|
355
355
|
</tr>
|
|
356
356
|
);
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { useServerLanguage } from '../../../components/ServerLanguage/ServerLanguageProvider';
|
|
4
5
|
import { Card } from '../../../components/Homepage/Card';
|
|
6
|
+
import type { ServerLanguageCode } from '../../../languages/ServerLanguageRegistry';
|
|
5
7
|
import {
|
|
6
8
|
$fetchMessages,
|
|
7
9
|
type MessageRow,
|
|
8
10
|
type MessageSendAttemptRow,
|
|
9
11
|
} from '../../../utils/messagesAdmin';
|
|
12
|
+
import { formatServerLanguageHumanReadableDate } from '../../../utils/localization/formatServerLanguageHumanReadableDate';
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* Formats date.
|
|
13
16
|
*/
|
|
14
|
-
function formatDate(dateString: string | null | undefined): string {
|
|
15
|
-
|
|
16
|
-
const date = new Date(dateString);
|
|
17
|
-
if (Number.isNaN(date.getTime())) return dateString;
|
|
18
|
-
return date.toLocaleString();
|
|
17
|
+
function formatDate(dateString: string | null | undefined, language: ServerLanguageCode): string {
|
|
18
|
+
return formatServerLanguageHumanReadableDate(dateString, language, { fallbackLabel: '-' });
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -44,6 +44,7 @@ function getStatusBadge(attempts: MessageSendAttemptRow[] | undefined) {
|
|
|
44
44
|
* Handles messages client.
|
|
45
45
|
*/
|
|
46
46
|
export function MessagesClient() {
|
|
47
|
+
const { language } = useServerLanguage();
|
|
47
48
|
const [items, setItems] = useState<MessageRow[]>([]);
|
|
48
49
|
const [total, setTotal] = useState(0);
|
|
49
50
|
const [page, setPage] = useState(1);
|
|
@@ -270,7 +271,7 @@ export function MessagesClient() {
|
|
|
270
271
|
{items.map((row) => (
|
|
271
272
|
<tr key={row.id}>
|
|
272
273
|
<td className="whitespace-nowrap px-4 py-3 text-gray-700">
|
|
273
|
-
{formatDate(row.createdAt)}
|
|
274
|
+
{formatDate(row.createdAt, language)}
|
|
274
275
|
</td>
|
|
275
276
|
<td className="whitespace-nowrap px-4 py-3 text-gray-700">
|
|
276
277
|
{row.channel}
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import { Fragment } from 'react';
|
|
4
4
|
import { ArrowRightLeft, Loader2, RefreshCcw, Save } from 'lucide-react';
|
|
5
|
-
import
|
|
5
|
+
import { useServerLanguage } from '../../../components/ServerLanguage/ServerLanguageProvider';
|
|
6
|
+
import type { ServerLanguageCode } from '../../../languages/ServerLanguageRegistry';
|
|
7
|
+
import { formatServerLanguageHumanReadableDate } from '../../../utils/localization/formatServerLanguageHumanReadableDate';
|
|
6
8
|
import {
|
|
7
9
|
MANAGED_SERVER_ENVIRONMENT_OPTIONS,
|
|
8
10
|
type ManagedServerEnvironment,
|
|
@@ -130,6 +132,7 @@ type ServersRegistryTableRowProps = {
|
|
|
130
132
|
readonly onSaveServer: (serverId: number) => Promise<void>;
|
|
131
133
|
readonly onSwitchServer: (server: ManagedServerRow) => Promise<void>;
|
|
132
134
|
readonly onUpdateServerDraft: UpdateServerDraft;
|
|
135
|
+
readonly language: ServerLanguageCode;
|
|
133
136
|
readonly server: ManagedServerRow;
|
|
134
137
|
};
|
|
135
138
|
|
|
@@ -139,13 +142,8 @@ type ServersRegistryTableRowProps = {
|
|
|
139
142
|
* @param value - ISO timestamp.
|
|
140
143
|
* @returns Human-readable local timestamp.
|
|
141
144
|
*/
|
|
142
|
-
function formatDateTime(value: string): string {
|
|
143
|
-
|
|
144
|
-
return 'N/A';
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const timestamp = moment(value);
|
|
148
|
-
return timestamp.isValid() ? timestamp.format('YYYY-MM-DD HH:mm:ss') : 'N/A';
|
|
145
|
+
function formatDateTime(value: string, language: ServerLanguageCode): string {
|
|
146
|
+
return formatServerLanguageHumanReadableDate(value, language);
|
|
149
147
|
}
|
|
150
148
|
|
|
151
149
|
/**
|
|
@@ -187,6 +185,7 @@ function ServersRegistryTableRow(props: ServersRegistryTableRowProps) {
|
|
|
187
185
|
onSaveServer,
|
|
188
186
|
onSwitchServer,
|
|
189
187
|
onUpdateServerDraft,
|
|
188
|
+
language,
|
|
190
189
|
server,
|
|
191
190
|
} = props;
|
|
192
191
|
const isCurrent = server.id === currentServerId;
|
|
@@ -264,10 +263,10 @@ function ServersRegistryTableRow(props: ServersRegistryTableRowProps) {
|
|
|
264
263
|
</div>
|
|
265
264
|
</td>
|
|
266
265
|
<td className="px-4 py-3 align-top text-xs text-gray-600">
|
|
267
|
-
<span className="whitespace-nowrap font-mono">{formatDateTime(server.createdAt)}</span>
|
|
266
|
+
<span className="whitespace-nowrap font-mono">{formatDateTime(server.createdAt, language)}</span>
|
|
268
267
|
</td>
|
|
269
268
|
<td className="px-4 py-3 align-top text-xs text-gray-600">
|
|
270
|
-
<span className="whitespace-nowrap font-mono">{formatDateTime(server.updatedAt)}</span>
|
|
269
|
+
<span className="whitespace-nowrap font-mono">{formatDateTime(server.updatedAt, language)}</span>
|
|
271
270
|
</td>
|
|
272
271
|
<td className="px-4 py-3 align-top">
|
|
273
272
|
<div className="flex flex-wrap justify-end gap-2">
|
|
@@ -409,6 +408,7 @@ function ServersRegistryTableRow(props: ServersRegistryTableRowProps) {
|
|
|
409
408
|
* @private helper component of <ServersClient/>
|
|
410
409
|
*/
|
|
411
410
|
export function ServersRegistryTable(props: ServersRegistryTableProps) {
|
|
411
|
+
const { language } = useServerLanguage();
|
|
412
412
|
const {
|
|
413
413
|
currentServerId,
|
|
414
414
|
canEdit,
|
|
@@ -495,6 +495,7 @@ export function ServersRegistryTable(props: ServersRegistryTableProps) {
|
|
|
495
495
|
onSaveServer={onSaveServer}
|
|
496
496
|
onSwitchServer={onSwitchServer}
|
|
497
497
|
onUpdateServerDraft={onUpdateServerDraft}
|
|
498
|
+
language={language}
|
|
498
499
|
server={server}
|
|
499
500
|
/>
|
|
500
501
|
</Fragment>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { Card } from '../../../components/Homepage/Card';
|
|
4
|
+
import { useServerLanguage } from '../../../components/ServerLanguage/ServerLanguageProvider';
|
|
4
5
|
import { TaskManagerFiltersCard } from './TaskManagerFiltersCard';
|
|
5
6
|
import { TaskManagerSummaryMetrics } from './TaskManagerSummaryMetrics';
|
|
6
7
|
import { TaskManagerTasksCard } from './TaskManagerTasksCard';
|
|
@@ -12,7 +13,8 @@ import { useTaskManagerState } from './useTaskManagerState';
|
|
|
12
13
|
* @private route component of AdminTaskManagerPage
|
|
13
14
|
*/
|
|
14
15
|
export function TaskManagerClient() {
|
|
15
|
-
const
|
|
16
|
+
const { language } = useServerLanguage();
|
|
17
|
+
const taskManagerState = useTaskManagerState(language);
|
|
16
18
|
|
|
17
19
|
return (
|
|
18
20
|
<div className="container mx-auto space-y-6 px-4 py-8">
|
|
@@ -53,7 +55,7 @@ export function TaskManagerClient() {
|
|
|
53
55
|
</Card>
|
|
54
56
|
) : null}
|
|
55
57
|
|
|
56
|
-
<TaskManagerTasksCard state={taskManagerState} />
|
|
58
|
+
<TaskManagerTasksCard language={language} state={taskManagerState} />
|
|
57
59
|
</div>
|
|
58
60
|
);
|
|
59
61
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { AdminChatTaskRecord } from '@/src/utils/chatTasksAdmin';
|
|
2
|
+
import type { ServerLanguageCode } from '@/src/languages/ServerLanguageRegistry';
|
|
3
|
+
import { formatServerLanguageHumanReadableDate } from '@/src/utils/localization/formatServerLanguageHumanReadableDate';
|
|
2
4
|
import type { useTaskManagerState } from './useTaskManagerState';
|
|
3
5
|
|
|
4
6
|
/**
|
|
@@ -9,6 +11,7 @@ import type { useTaskManagerState } from './useTaskManagerState';
|
|
|
9
11
|
type TaskManagerTaskRowProps = {
|
|
10
12
|
busyAction: ReturnType<typeof useTaskManagerState>['busyAction'];
|
|
11
13
|
busyTaskId: ReturnType<typeof useTaskManagerState>['busyTaskId'];
|
|
14
|
+
language: ServerLanguageCode;
|
|
12
15
|
onRunTaskAction: ReturnType<typeof useTaskManagerState>['runTaskAction'];
|
|
13
16
|
stuckThresholdMinutes: ReturnType<typeof useTaskManagerState>['stuckThresholdMinutes'];
|
|
14
17
|
task: AdminChatTaskRecord;
|
|
@@ -135,13 +138,8 @@ function formatTaskKind(kind: AdminChatTaskRecord['kind']): string {
|
|
|
135
138
|
*
|
|
136
139
|
* @private function of TaskManagerTaskRow
|
|
137
140
|
*/
|
|
138
|
-
function formatDateTime(value: string | null): string {
|
|
139
|
-
|
|
140
|
-
return '-';
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const parsed = new Date(value);
|
|
144
|
-
return Number.isNaN(parsed.getTime()) ? value : parsed.toLocaleString();
|
|
141
|
+
function formatDateTime(value: string | null, language: ServerLanguageCode): string {
|
|
142
|
+
return formatServerLanguageHumanReadableDate(value, language, { fallbackLabel: '-' });
|
|
145
143
|
}
|
|
146
144
|
|
|
147
145
|
/**
|
|
@@ -306,6 +304,7 @@ function TaskManagerTaskActions({ busyAction, isBusy, onRunTaskAction, task }: T
|
|
|
306
304
|
export function TaskManagerTaskRow({
|
|
307
305
|
busyAction,
|
|
308
306
|
busyTaskId,
|
|
307
|
+
language,
|
|
309
308
|
onRunTaskAction,
|
|
310
309
|
stuckThresholdMinutes,
|
|
311
310
|
task,
|
|
@@ -341,7 +340,7 @@ export function TaskManagerTaskRow({
|
|
|
341
340
|
<div className="font-medium text-orange-700">Cancellation requested</div>
|
|
342
341
|
) : null}
|
|
343
342
|
{task.pausedAt ? (
|
|
344
|
-
<div className="font-medium text-orange-700">Paused {formatDateTime(task.pausedAt)}</div>
|
|
343
|
+
<div className="font-medium text-orange-700">Paused {formatDateTime(task.pausedAt, language)}</div>
|
|
345
344
|
) : null}
|
|
346
345
|
</div>
|
|
347
346
|
</td>
|
|
@@ -367,10 +366,10 @@ export function TaskManagerTaskRow({
|
|
|
367
366
|
<td className="px-4 py-3 align-top">
|
|
368
367
|
<TaskInfoBlock
|
|
369
368
|
rows={[
|
|
370
|
-
{ label: 'Created', value: formatDateTime(task.createdAt) },
|
|
371
|
-
{ label: 'Started', value: formatDateTime(task.startedAt) },
|
|
372
|
-
{ label: 'Updated', value: formatDateTime(task.updatedAt) },
|
|
373
|
-
{ label: 'Finished', value: formatDateTime(task.finishedAt) },
|
|
369
|
+
{ label: 'Created', value: formatDateTime(task.createdAt, language) },
|
|
370
|
+
{ label: 'Started', value: formatDateTime(task.startedAt, language) },
|
|
371
|
+
{ label: 'Updated', value: formatDateTime(task.updatedAt, language) },
|
|
372
|
+
{ label: 'Finished', value: formatDateTime(task.finishedAt, language) },
|
|
374
373
|
]}
|
|
375
374
|
/>
|
|
376
375
|
</td>
|
|
@@ -381,7 +380,7 @@ export function TaskManagerTaskRow({
|
|
|
381
380
|
{ label: 'Queue age', value: formatDuration(getQueueAgeMs(task)) },
|
|
382
381
|
{ label: 'Runtime', value: formatDuration(getRuntimeDurationMs(task)) },
|
|
383
382
|
{ label: 'Total', value: formatDuration(getTotalDurationMs(task)) },
|
|
384
|
-
{ label: 'Heartbeat', value: formatDateTime(task.lastHeartbeatAt) },
|
|
383
|
+
{ label: 'Heartbeat', value: formatDateTime(task.lastHeartbeatAt, language) },
|
|
385
384
|
]}
|
|
386
385
|
/>
|
|
387
386
|
</td>
|
|
@@ -391,8 +390,8 @@ export function TaskManagerTaskRow({
|
|
|
391
390
|
rows={[
|
|
392
391
|
{ label: 'Queue', value: task.queueName || '-' },
|
|
393
392
|
{ label: 'Worker', value: task.workerId || '-' },
|
|
394
|
-
{ label: 'Lease expires', value: formatDateTime(task.leaseExpiresAt) },
|
|
395
|
-
{ label: 'Paused at', value: formatDateTime(task.pausedAt) },
|
|
393
|
+
{ label: 'Lease expires', value: formatDateTime(task.leaseExpiresAt, language) },
|
|
394
|
+
{ label: 'Paused at', value: formatDateTime(task.pausedAt, language) },
|
|
396
395
|
]}
|
|
397
396
|
/>
|
|
398
397
|
</td>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ServerLanguageCode } from '@/src/languages/ServerLanguageRegistry';
|
|
1
2
|
import type { useTaskManagerState } from './useTaskManagerState';
|
|
2
3
|
import { Card } from '../../../components/Homepage/Card';
|
|
3
4
|
import { TaskManagerTaskRow } from './TaskManagerTaskRow';
|
|
@@ -8,6 +9,7 @@ import { TaskManagerTaskRow } from './TaskManagerTaskRow';
|
|
|
8
9
|
* @private function of TaskManagerClient
|
|
9
10
|
*/
|
|
10
11
|
type TaskManagerTasksCardProps = {
|
|
12
|
+
language: ServerLanguageCode;
|
|
11
13
|
state: ReturnType<typeof useTaskManagerState>;
|
|
12
14
|
};
|
|
13
15
|
|
|
@@ -41,7 +43,7 @@ function resolveEmptyStateMessage(view: ReturnType<typeof useTaskManagerState>['
|
|
|
41
43
|
*
|
|
42
44
|
* @private function of TaskManagerClient
|
|
43
45
|
*/
|
|
44
|
-
export function TaskManagerTasksCard({ state }: TaskManagerTasksCardProps) {
|
|
46
|
+
export function TaskManagerTasksCard({ language, state }: TaskManagerTasksCardProps) {
|
|
45
47
|
const firstVisibleTaskIndex = Math.min((state.page - 1) * state.pageSize + 1, state.total);
|
|
46
48
|
const lastVisibleTaskIndex = Math.min(state.page * state.pageSize, state.total);
|
|
47
49
|
|
|
@@ -82,6 +84,7 @@ export function TaskManagerTasksCard({ state }: TaskManagerTasksCardProps) {
|
|
|
82
84
|
<TaskManagerTaskRow
|
|
83
85
|
key={task.id}
|
|
84
86
|
task={task}
|
|
87
|
+
language={language}
|
|
85
88
|
busyAction={state.busyAction}
|
|
86
89
|
busyTaskId={state.busyTaskId}
|
|
87
90
|
onRunTaskAction={state.runTaskAction}
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
type AdminChatTaskRecord,
|
|
10
10
|
type AdminChatTaskView,
|
|
11
11
|
} from '@/src/utils/chatTasksAdmin';
|
|
12
|
+
import type { ServerLanguageCode } from '@/src/languages/ServerLanguageRegistry';
|
|
13
|
+
import { formatServerLanguageHumanReadableDate } from '@/src/utils/localization/formatServerLanguageHumanReadableDate';
|
|
12
14
|
import { useCallback, useDeferredValue, useEffect, useMemo, useRef, useState } from 'react';
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -86,13 +88,8 @@ function parseSelectedNumber(value: string, fallback: number): number {
|
|
|
86
88
|
*
|
|
87
89
|
* @private function of TaskManagerClient
|
|
88
90
|
*/
|
|
89
|
-
function formatDateTime(value: string | null): string {
|
|
90
|
-
|
|
91
|
-
return '-';
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const parsed = new Date(value);
|
|
95
|
-
return Number.isNaN(parsed.getTime()) ? value : parsed.toLocaleString();
|
|
91
|
+
function formatDateTime(value: string | null, language: ServerLanguageCode): string {
|
|
92
|
+
return formatServerLanguageHumanReadableDate(value, language, { fallbackLabel: '-' });
|
|
96
93
|
}
|
|
97
94
|
|
|
98
95
|
/**
|
|
@@ -244,7 +241,7 @@ function resolveTaskLoadErrorMessage(loadError: unknown): string {
|
|
|
244
241
|
*
|
|
245
242
|
* @private function of TaskManagerClient
|
|
246
243
|
*/
|
|
247
|
-
export function useTaskManagerState(): UseTaskManagerStateResult {
|
|
244
|
+
export function useTaskManagerState(language: ServerLanguageCode): UseTaskManagerStateResult {
|
|
248
245
|
const [view, setView] = useState<AdminChatTaskView>('active');
|
|
249
246
|
const [page, setPage] = useState(1);
|
|
250
247
|
const [pageSize, setPageSize] = useState(50);
|
|
@@ -405,7 +402,7 @@ export function useTaskManagerState(): UseTaskManagerStateResult {
|
|
|
405
402
|
isPreviousPageDisabled: page <= 1,
|
|
406
403
|
isRefreshing,
|
|
407
404
|
lastRefreshedLabel: generatedAt
|
|
408
|
-
? `Last refreshed ${formatDateTime(generatedAt)}`
|
|
405
|
+
? `Last refreshed ${formatDateTime(generatedAt, language)}`
|
|
409
406
|
: 'Waiting for first refresh…',
|
|
410
407
|
oldestQueuedAgeLabel: counters ? formatDuration(counters.oldestQueuedAgeMs) : '...',
|
|
411
408
|
page,
|