From dc269bec004a76182af8148f4dda1f957313efc9 Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Fri, 22 May 2026 12:08:10 -0400 Subject: [PATCH] =?UTF-8?q?fix:=20make=20Settings=20S3=20form=20functional?= =?UTF-8?q?=20=E2=80=94=20load=20from=20API,=20save=20&=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/web-ui/public/screens-admin.jsx | 151 ++++++++++++----------- 1 file changed, 78 insertions(+), 73 deletions(-) diff --git a/services/web-ui/public/screens-admin.jsx b/services/web-ui/public/screens-admin.jsx index dbef83f..b7a8c7b 100644 --- a/services/web-ui/public/screens-admin.jsx +++ b/services/web-ui/public/screens-admin.jsx @@ -614,6 +614,37 @@ function DetailRow({ k, v, mono }) { } function Settings() { + const [s3, setS3] = React.useState({ s3_endpoint: '', s3_bucket: '', s3_access_key: '', s3_secret_key: '', s3_region: 'us-east-1' }); + const [s3Loading, setS3Loading] = React.useState(true); + const [s3Saving, setS3Saving] = React.useState(false); + const [s3Testing, setS3Testing] = React.useState(false); + const [s3Msg, setS3Msg] = React.useState(null); + const [secretExists, setSecretExists] = React.useState(false); + + React.useEffect(() => { + window.ZAMPP_API.fetch('/settings/s3') + .then(data => { + setS3({ s3_endpoint: data.s3_endpoint || '', s3_bucket: data.s3_bucket || '', s3_access_key: data.s3_access_key || '', s3_secret_key: '', s3_region: data.s3_region || 'us-east-1' }); + setSecretExists(!!data.s3_secret_key_exists); + setS3Loading(false); + }) + .catch(() => setS3Loading(false)); + }, []); + + const saveS3 = () => { + setS3Saving(true); setS3Msg(null); + window.ZAMPP_API.fetch('/settings/s3', { method: 'PUT', body: JSON.stringify(s3) }) + .then(() => { setS3Saving(false); setS3Msg({ ok: true, text: 'Saved and applied.' }); if (s3.s3_secret_key) setSecretExists(true); }) + .catch(e => { setS3Saving(false); setS3Msg({ ok: false, text: e.message }); }); + }; + + const testS3 = () => { + setS3Testing(true); setS3Msg(null); + window.ZAMPP_API.fetch('/settings/s3/test', { method: 'POST', body: JSON.stringify(s3) }) + .then(r => { setS3Testing(false); setS3Msg({ ok: r.ok !== false, text: r.message || 'Connection OK' }); }) + .catch(e => { setS3Testing(false); setS3Msg({ ok: false, text: e.message }); }); + }; + return (
@@ -621,72 +652,56 @@ function Settings() { System configuration · changes apply without restart
-
+
-
+
connected} + tag={secretExists ? connected : not configured} > - -
- - -
- - Show} /> -
- - -
-
- GPUs available} - > - -
- - -
-
- - -
-
- -
-
- setup needed} - > - - -
- -
+ {s3Loading ? ( +
Loading…
+ ) : (<> + + setS3(p => ({...p, s3_endpoint: e.target.value}))} placeholder="https://s3.example.com" /> + +
+ + setS3(p => ({...p, s3_region: e.target.value}))} placeholder="us-east-1" /> + + + setS3(p => ({...p, s3_bucket: e.target.value}))} placeholder="my-bucket" /> + +
+ + setS3(p => ({...p, s3_access_key: e.target.value}))} placeholder="Access key ID" /> + + + setS3(p => ({...p, s3_secret_key: e.target.value}))} placeholder={secretExists ? '(saved — type to replace)' : 'Secret key'} /> + + {s3Msg && ( +
+ {s3Msg.text} +
+ )} +
+ + +
+ )}
@@ -695,6 +710,15 @@ function Settings() { ); } +function SField({ label, children }) { + return ( +
+ + {children} +
+ ); +} + function SettingsCard({ icon, title, sub, tag, children }) { return (
@@ -711,23 +735,4 @@ function SettingsCard({ icon, title, sub, tag, children }) { ); } -function Field({ label, value, mono, select, placeholder, right }) { - return ( -
- -
- {select ? ( -
- {value || placeholder} - -
- ) : ( - - )} - {right} -
-
- ); -} - Object.assign(window, { Users, Tokens, Containers, Cluster, Settings });