11import { Show , createEffect , createMemo , createSignal , onCleanup } from "solid-js" ;
2+ import { t } from "../../../i18n" ;
23import { FileText , RefreshCcw , Save , X } from "lucide-solid" ;
34
45import 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 />
0 commit comments