Skip to content

Commit 8c98cf0

Browse files
BUGKillerKingzhouhe-xydtTakhoffman
authored
i18n: add zh-CN for cron page and validation errors (#29315)
* i18n: add zh-CN for cron page and validation errors * cron: treat unexpected delivery statuses as unknown * test(cron): align validation tests with i18n keys --------- Co-authored-by: 周鹤0668001310 <[email protected]> Co-authored-by: Tak Hoffman <[email protected]>
1 parent d0ca02e commit 8c98cf0

File tree

7 files changed

+705
-234
lines changed

7 files changed

+705
-234
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Docs: https://docs.openclaw.ai
77
### Changes
88

99
- Web UI/i18n: add German (`de`) locale support and auto-render language options from supported locale constants in Overview settings. (#28495) thanks @dsantoreis.
10+
- Web UI/Cron i18n: localize cron page labels, filters, form help text, and validation/error messaging in English and zh-CN. (#29315)
1011
- Discord/Thread bindings: replace fixed TTL lifecycle with inactivity (`idleHours`, default 24h) plus optional hard `maxAgeHours` lifecycle controls, and add `/session idle` + `/session max-age` commands for focused thread-bound sessions. (#27845) Thanks @osolmaz.
1112
- Android/Nodes: add `camera.list`, `device.permissions`, `device.health`, and `notifications.actions` (`open`/`dismiss`/`reply`) on Android nodes, plus first-class node-tool actions for the new device/notification commands. (#28260) Thanks @obviyus.
1213
- Android/Nodes parity: add `system.notify`, `photos.latest`, `contacts.search`/`contacts.add`, `calendar.events`/`calendar.add`, and `motion.activity`/`motion.pedometer`, with motion sensor-aware command gating and improved activity sampling reliability. (#29398) Thanks @obviyus.

ui/src/i18n/locales/en.ts

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,212 @@ export const en: TranslationMap = {
120120
ptBR: "Português (Brazilian Portuguese)",
121121
de: "Deutsch (German)",
122122
},
123+
cron: {
124+
summary: {
125+
enabled: "Enabled",
126+
yes: "Yes",
127+
no: "No",
128+
jobs: "Jobs",
129+
nextWake: "Next wake",
130+
refreshing: "Refreshing...",
131+
refresh: "Refresh",
132+
},
133+
jobs: {
134+
title: "Jobs",
135+
subtitle: "All scheduled jobs stored in the gateway.",
136+
shownOf: "{shown} shown of {total}",
137+
searchJobs: "Search jobs",
138+
searchPlaceholder: "Name, description, or agent",
139+
enabled: "Enabled",
140+
all: "All",
141+
sort: "Sort",
142+
nextRun: "Next run",
143+
recentlyUpdated: "Recently updated",
144+
name: "Name",
145+
direction: "Direction",
146+
ascending: "Ascending",
147+
descending: "Descending",
148+
noMatching: "No matching jobs.",
149+
loading: "Loading...",
150+
loadMore: "Load more jobs",
151+
},
152+
runs: {
153+
title: "Run history",
154+
subtitleAll: "Latest runs across all jobs.",
155+
subtitleJob: "Latest runs for {title}.",
156+
scope: "Scope",
157+
allJobs: "All jobs",
158+
selectedJob: "Selected job",
159+
searchRuns: "Search runs",
160+
searchPlaceholder: "Summary, error, or job",
161+
newestFirst: "Newest first",
162+
oldestFirst: "Oldest first",
163+
status: "Status",
164+
delivery: "Delivery",
165+
clear: "Clear",
166+
allStatuses: "All statuses",
167+
allDelivery: "All delivery",
168+
selectJobHint: "Select a job to inspect run history.",
169+
noMatching: "No matching runs.",
170+
loadMore: "Load more runs",
171+
runStatusOk: "OK",
172+
runStatusError: "Error",
173+
runStatusSkipped: "Skipped",
174+
runStatusUnknown: "Unknown",
175+
deliveryDelivered: "Delivered",
176+
deliveryNotDelivered: "Not delivered",
177+
deliveryUnknown: "Unknown",
178+
deliveryNotRequested: "Not requested",
179+
},
180+
form: {
181+
editJob: "Edit Job",
182+
newJob: "New Job",
183+
updateSubtitle: "Update the selected scheduled job.",
184+
createSubtitle: "Create a scheduled wakeup or agent run.",
185+
required: "Required",
186+
requiredSr: "required",
187+
basics: "Basics",
188+
basicsSub: "Name it, choose the assistant, and set enabled state.",
189+
fieldName: "Name",
190+
description: "Description",
191+
agentId: "Agent ID",
192+
namePlaceholder: "Morning brief",
193+
descriptionPlaceholder: "Optional context for this job",
194+
agentPlaceholder: "main or ops",
195+
agentHelp: "Start typing to pick a known agent, or enter a custom one.",
196+
schedule: "Schedule",
197+
scheduleSub: "Control when this job runs.",
198+
every: "Every",
199+
at: "At",
200+
cronOption: "Cron",
201+
runAt: "Run at",
202+
unit: "Unit",
203+
minutes: "Minutes",
204+
hours: "Hours",
205+
days: "Days",
206+
expression: "Expression",
207+
expressionPlaceholder: "0 7 * * *",
208+
everyAmountPlaceholder: "30",
209+
timezoneOptional: "Timezone (optional)",
210+
timezonePlaceholder: "America/Los_Angeles",
211+
timezoneHelp: "Pick a common timezone or enter any valid IANA timezone.",
212+
jitterHelp: "Need jitter? Use Advanced → Stagger window / Stagger unit.",
213+
execution: "Execution",
214+
executionSub: "Choose when to wake, and what this job should do.",
215+
session: "Session",
216+
main: "Main",
217+
isolated: "Isolated",
218+
sessionHelp: "Main posts a system event. Isolated runs a dedicated agent turn.",
219+
wakeMode: "Wake mode",
220+
now: "Now",
221+
nextHeartbeat: "Next heartbeat",
222+
wakeModeHelp: "Now triggers immediately. Next heartbeat waits for the next cycle.",
223+
payloadKind: "What should run?",
224+
systemEvent: "Post message to main timeline",
225+
agentTurn: "Run assistant task (isolated)",
226+
systemEventHelp:
227+
"Sends your text to the gateway main timeline (good for reminders/triggers).",
228+
agentTurnHelp: "Starts an assistant run in its own session using your prompt.",
229+
timeoutSeconds: "Timeout (seconds)",
230+
timeoutPlaceholder: "Optional, e.g. 90",
231+
timeoutHelp:
232+
"Optional. Leave blank to use the gateway default timeout behavior for this run.",
233+
mainTimelineMessage: "Main timeline message",
234+
assistantTaskPrompt: "Assistant task prompt",
235+
deliverySection: "Delivery",
236+
deliverySub: "Choose where run summaries are sent.",
237+
resultDelivery: "Result delivery",
238+
announceDefault: "Announce summary (default)",
239+
webhookPost: "Webhook POST",
240+
noneInternal: "None (internal)",
241+
deliveryHelp: "Announce posts a summary to chat. None keeps execution internal.",
242+
webhookUrl: "Webhook URL",
243+
channel: "Channel",
244+
webhookPlaceholder: "https://example.com/cron",
245+
channelHelp: "Choose which connected channel receives the summary.",
246+
webhookHelp: "Send run summaries to a webhook endpoint.",
247+
to: "To",
248+
toPlaceholder: "+1555... or chat id",
249+
toHelp: "Optional recipient override (chat id, phone, or user id).",
250+
advanced: "Advanced",
251+
advancedHelp:
252+
"Optional overrides for delivery guarantees, schedule jitter, and model controls.",
253+
deleteAfterRun: "Delete after run",
254+
deleteAfterRunHelp: "Best for one-shot reminders that should auto-clean up.",
255+
clearAgentOverride: "Clear agent override",
256+
clearAgentHelp: "Force this job to use the gateway default assistant.",
257+
exactTiming: "Exact timing (no stagger)",
258+
exactTimingHelp: "Run on exact cron boundaries with no spread.",
259+
staggerWindow: "Stagger window",
260+
staggerUnit: "Stagger unit",
261+
staggerPlaceholder: "30",
262+
seconds: "Seconds",
263+
model: "Model",
264+
modelPlaceholder: "openai/gpt-5.2",
265+
modelHelp: "Start typing to pick a known model, or enter a custom one.",
266+
thinking: "Thinking",
267+
thinkingPlaceholder: "low",
268+
thinkingHelp: "Use a suggested level or enter a provider-specific value.",
269+
bestEffortDelivery: "Best effort delivery",
270+
bestEffortHelp: "Do not fail the job if delivery itself fails.",
271+
cantAddYet: "Can't add job yet",
272+
fillRequired: "Fill the required fields below to enable submit.",
273+
fixFields: "Fix {count} field to continue.",
274+
fixFieldsPlural: "Fix {count} fields to continue.",
275+
saving: "Saving...",
276+
saveChanges: "Save changes",
277+
addJob: "Add job",
278+
cancel: "Cancel",
279+
},
280+
jobList: {
281+
allJobs: "all jobs",
282+
selectJob: "(select a job)",
283+
enabled: "enabled",
284+
disabled: "disabled",
285+
edit: "Edit",
286+
clone: "Clone",
287+
disable: "Disable",
288+
enable: "Enable",
289+
run: "Run",
290+
history: "History",
291+
remove: "Remove",
292+
},
293+
jobDetail: {
294+
system: "System",
295+
prompt: "Prompt",
296+
delivery: "Delivery",
297+
agent: "Agent",
298+
},
299+
jobState: {
300+
status: "Status",
301+
next: "Next",
302+
last: "Last",
303+
},
304+
runEntry: {
305+
noSummary: "No summary.",
306+
runAt: "Run at",
307+
openRunChat: "Open run chat",
308+
next: "Next {rel}",
309+
due: "Due {rel}",
310+
},
311+
errors: {
312+
nameRequired: "Name is required.",
313+
scheduleAtInvalid: "Enter a valid date/time.",
314+
everyAmountInvalid: "Interval must be greater than 0.",
315+
cronExprRequired: "Cron expression is required.",
316+
staggerAmountInvalid: "Stagger must be greater than 0.",
317+
systemTextRequired: "System text is required.",
318+
agentMessageRequired: "Agent message is required.",
319+
timeoutInvalid: "If set, timeout must be greater than 0 seconds.",
320+
webhookUrlRequired: "Webhook URL is required.",
321+
webhookUrlInvalid: "Webhook URL must start with http:// or https://.",
322+
invalidRunTime: "Invalid run time.",
323+
invalidIntervalAmount: "Invalid interval amount.",
324+
cronExprRequiredShort: "Cron expression required.",
325+
invalidStaggerAmount: "Invalid stagger amount.",
326+
systemEventTextRequired: "System event text required.",
327+
agentMessageRequiredShort: "Agent message required.",
328+
nameRequiredShort: "Name required.",
329+
},
330+
},
123331
};

0 commit comments

Comments
 (0)