Skip to content

Commit 649e6f0

Browse files
feat: add i18n text
1 parent de8e01f commit 649e6f0

21 files changed

Lines changed: 2381 additions & 959 deletions

packages/app/src/app/components/session/artifact-markdown-editor.tsx

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Show, createEffect, createMemo, createSignal, onCleanup } from "solid-js";
2+
import { t } from "../../../i18n";
23
import { FileText, RefreshCcw, Save, X } from "lucide-solid";
34

45
import Button from "../button";
@@ -35,13 +36,13 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
3536
const [pendingReason, setPendingReason] = createSignal<"switch" | null>(null);
3637

3738
const path = createMemo(() => props.path?.trim() ?? "");
38-
const title = createMemo(() => (path() ? basename(path()) : "Artifact"));
39+
const title = createMemo(() => (path() ? basename(path()) : t("session.editor_default_title")));
3940
const dirty = createMemo(() => draft() !== original());
4041
const canWrite = createMemo(() => Boolean(props.client && props.workspaceId));
4142
const canSave = createMemo(() => dirty() && !saving() && canWrite());
4243
const writeDisabledReason = createMemo(() => {
4344
if (canWrite()) return null;
44-
return "Connect to an OpenWork server worker to edit files.";
45+
return t("session.editor_connect_hint");
4546
});
4647

4748
const resetState = () => {
@@ -69,7 +70,7 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
6970
}
7071
if (!target) return;
7172
if (!isMarkdown(target)) {
72-
setError("Only markdown files are supported.");
73+
setError(t("session.editor_toast_markdown_only"));
7374
return;
7475
}
7576

@@ -100,7 +101,7 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
100101
result = (await client.readWorkspaceFile(workspaceId, actualPath)) as OpenworkWorkspaceFileContent;
101102
} catch (second) {
102103
if (second instanceof OpenworkServerError && second.status === 404) {
103-
throw new OpenworkServerError(404, "file_not_found", "File not found (workspace root or outbox).");
104+
throw new OpenworkServerError(404, "file_not_found", t("session.editor_toast_not_found"));
104105
}
105106
throw second;
106107
}
@@ -112,7 +113,7 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
112113
setResolvedPath(actualPath);
113114
setBaseUpdatedAt(typeof result.updatedAt === "number" ? result.updatedAt : null);
114115
} catch (err) {
115-
const message = err instanceof Error ? err.message : "Failed to load file";
116+
const message = err instanceof Error ? err.message : t("session.editor_toast_load_failed");
116117
setError(message);
117118
setLoadedPath(target);
118119
} finally {
@@ -125,11 +126,11 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
125126
const workspaceId = props.workspaceId;
126127
const target = resolvedPath() ?? path();
127128
if (!client || !workspaceId || !target) {
128-
props.onToast?.("Cannot save: OpenWork server not connected");
129+
props.onToast?.(t("session.editor_toast_save_connect"));
129130
return;
130131
}
131132
if (!isMarkdown(target)) {
132-
props.onToast?.("Only markdown files are supported");
133+
props.onToast?.(t("session.editor_toast_markdown_only"));
133134
return;
134135
}
135136
if (!dirty()) return;
@@ -158,7 +159,7 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
158159
setConfirmOverwrite(true);
159160
return;
160161
}
161-
const message = err instanceof Error ? err.message : "Failed to save";
162+
const message = err instanceof Error ? err.message : t("session.editor_toast_save_failed");
162163
setError(message);
163164
props.onToast?.(message);
164165
} finally {
@@ -183,7 +184,7 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
183184
return;
184185
}
185186
// Reload is destructive; reuse the close-discard banner semantics.
186-
setError("Discard changes to reload from disk (close and reopen), or save first.");
187+
setError(t("session.editor_toast_reload_discard"));
187188
};
188189

189190
createEffect(() => {
@@ -240,7 +241,7 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
240241
<div class="text-sm font-semibold text-dls-text truncate">{title()}</div>
241242
<Show when={dirty()}>
242243
<span class="text-[10px] px-2 py-0.5 rounded-full border border-amber-7/40 bg-amber-2/30 text-amber-11">
243-
Unsaved
244+
{t("session.editor_unsaved")}
244245
</span>
245246
</Show>
246247
</div>
@@ -256,26 +257,26 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
256257
class="text-xs h-9 py-0 px-3"
257258
onClick={requestReload}
258259
disabled={loading() || saving()}
259-
title="Reload from disk"
260+
title={t("session.editor_reload_tooltip")}
260261
>
261262
<RefreshCcw size={14} class={loading() ? "animate-spin" : ""} />
262-
Reload
263+
{t("session.editor_reload")}
263264
</Button>
264265
<Button
265266
class="text-xs h-9 py-0 px-3"
266267
onClick={() => void save()}
267268
disabled={!canSave()}
268-
title={writeDisabledReason() ?? "Save (Ctrl/Cmd+S)"}
269+
title={writeDisabledReason() ?? t("session.editor_save_tooltip")}
269270
>
270271
<Save size={14} class={saving() ? "animate-pulse" : ""} />
271-
{saving() ? "Saving..." : "Save"}
272+
{saving() ? t("session.editor_saving") : t("session.editor_save")}
272273
</Button>
273274
<button
274275
type="button"
275276
class="p-2 rounded-lg text-dls-secondary hover:text-dls-text hover:bg-dls-hover"
276277
onClick={requestClose}
277-
title="Close"
278-
aria-label="Close"
278+
title={t("session.editor_close")}
279+
aria-label={t("session.editor_close")}
279280
>
280281
<X size={16} />
281282
</button>
@@ -300,10 +301,10 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
300301

301302
<Show when={confirmOverwrite()}>
302303
<div class="shrink-0 px-4 py-2 border-b border-dls-border bg-amber-2/20 text-amber-11 text-xs flex items-center justify-between gap-3">
303-
<div class="min-w-0">File changed since load. Overwrite anyway?</div>
304+
<div class="min-w-0">{t("session.editor_overwrite_prompt")}</div>
304305
<div class="shrink-0 flex items-center gap-2">
305306
<Button variant="outline" class="text-xs h-8 py-0 px-3" onClick={() => setConfirmOverwrite(false)}>
306-
Cancel
307+
{t("common.cancel")}
307308
</Button>
308309
<Button
309310
variant="danger"
@@ -313,18 +314,18 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
313314
void save({ force: true });
314315
}}
315316
>
316-
Overwrite
317+
{t("session.editor_overwrite")}
317318
</Button>
318319
</div>
319320
</div>
320321
</Show>
321322

322323
<Show when={confirmDiscardClose()}>
323324
<div class="shrink-0 px-4 py-2 border-b border-dls-border bg-amber-2/20 text-amber-11 text-xs flex items-center justify-between gap-3">
324-
<div class="min-w-0">Discard unsaved changes and close?</div>
325+
<div class="min-w-0">{t("session.editor_discard_prompt")}</div>
325326
<div class="shrink-0 flex items-center gap-2">
326327
<Button variant="outline" class="text-xs h-8 py-0 px-3" onClick={() => setConfirmDiscardClose(false)}>
327-
Keep
328+
{t("session.editor_keep")}
328329
</Button>
329330
<Button
330331
variant="secondary"
@@ -335,7 +336,7 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
335336
props.onClose();
336337
}}
337338
>
338-
Discard
339+
{t("session.editor_discard")}
339340
</Button>
340341
</div>
341342
</div>
@@ -344,7 +345,7 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
344345
<Show when={pendingPath() && pendingReason() === "switch"}>
345346
<div class="shrink-0 px-4 py-2 border-b border-dls-border bg-amber-2/20 text-amber-11 text-xs flex items-center justify-between gap-3">
346347
<div class="min-w-0 truncate" title={pendingPath() ?? ""}>
347-
Switch to {pendingPath()}
348+
{t("session.editor_switch_prompt").replace("{path}", pendingPath() ?? "")}
348349
</div>
349350
<div class="shrink-0 flex items-center gap-2">
350351
<Button
@@ -355,7 +356,7 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
355356
setPendingReason(null);
356357
}}
357358
>
358-
Cancel
359+
{t("common.cancel")}
359360
</Button>
360361
<Button
361362
variant="secondary"
@@ -369,10 +370,10 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
369370
if (next) void load(next);
370371
}}
371372
>
372-
Discard & switch
373+
{t("session.editor_discard_switch")}
373374
</Button>
374375
<Button class="text-xs h-8 py-0 px-3" onClick={() => void save()} disabled={!canSave()}>
375-
Save & switch
376+
{t("session.editor_save_switch")}
376377
</Button>
377378
</div>
378379
</div>
@@ -383,7 +384,7 @@ export default function ArtifactMarkdownEditor(props: ArtifactMarkdownEditorProp
383384
value={draft()}
384385
onChange={setDraft}
385386
placeholder=""
386-
ariaLabel="Artifact editor"
387+
ariaLabel={t("session.editor_aria_label")}
387388
class="h-full"
388389
autofocus
389390
/>

packages/app/src/app/components/session/artifacts-panel.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { For, Show, createMemo, createSignal } from "solid-js";
2+
import { t } from "../../../i18n";
23
import { Paperclip } from "lucide-solid";
34

45
export type ArtifactsPanelProps = {
@@ -99,7 +100,7 @@ export default function ArtifactsPanel(props: ArtifactsPanelProps) {
99100
<Paperclip size={14} class="text-dls-secondary" />
100101
<div class="min-w-0">
101102
<div class="text-[11px] font-bold tracking-tight text-dls-secondary uppercase">
102-
Artifacts
103+
{t("session.artifacts_title")}
103104
</div>
104105
</div>
105106
</div>
@@ -111,7 +112,7 @@ export default function ArtifactsPanel(props: ArtifactsPanelProps) {
111112
<div class="mt-2 space-y-1">
112113
<Show
113114
when={visibleArtifacts().length > 0}
114-
fallback={<div class="text-xs text-dls-secondary px-1 py-1">No artifacts yet.</div>}
115+
fallback={<div class="text-xs text-dls-secondary px-1 py-1">{t("session.artifacts_empty")}</div>}
115116
>
116117
<For each={visibleArtifacts()}>
117118
{(artifact) => {
@@ -123,7 +124,7 @@ export default function ArtifactsPanel(props: ArtifactsPanelProps) {
123124
const openable = () => (md() ? canOpenMarkdown() : img() ? canOpenImage() : false);
124125
const tooltip = () => {
125126
if (md()) return display();
126-
if (img() && !canOpenImage()) return `${display()} (image preview coming soon)`;
127+
if (img() && !canOpenImage()) return `${display()} (${t("session.artifacts_image_preview_soon")})`;
127128
return display();
128129
};
129130
return (
@@ -173,7 +174,7 @@ export default function ArtifactsPanel(props: ArtifactsPanelProps) {
173174
class="w-full mt-1 rounded-lg px-2 py-1.5 text-xs text-dls-secondary hover:text-dls-text hover:bg-dls-active transition-colors"
174175
onClick={() => setShowAll((prev) => !prev)}
175176
>
176-
{showAll() ? "Show fewer" : `Show ${hiddenCount()} more`}
177+
{showAll() ? t("session.artifacts_show_fewer") : t("session.artifacts_show_more").replace("{count}", String(hiddenCount()))}
177178
</button>
178179
</Show>
179180
</div>

0 commit comments

Comments
 (0)