Move the console onto ReUI PRO
Install ReUI (MCP, skill, @reui registry, Tailwind v4, shadcn base-nova) and move the shared UI onto it: Button, Tag, Check, Input/Textarea, Segmented, Alert, Panel, Dialog, Tooltip, Menu and Select (Popover), Toast (sonner), the Table frame (DataGrid), the Dashboard KPI strip, the shnt Ops palette, Geist and the type scale. Design only: behaviour, texts and roles are unchanged. Tests that asserted the old DOM were updated; the tests now format numbers in English wherever they run. docs/reui-migration-plan.md records the plan and its decisions. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
f3531c64f9
680 files changed
+139836
No files matched your search
@@ -0,0 +1,80 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { updateApp } from '../../api/apps'
|
||||
import { Button } from '../../ui/Button'
|
||||
import { Dialog } from '../../ui/Dialog'
|
||||
import { LabeledInput } from '../../ui/Field'
|
||||
import { error, type AlertState } from './Apps'
|
||||
import { Notifier } from '../../ui/Notifier'
|
||||
|
||||
/*
|
||||
A replica of `showUpdateAppModal` / `updateApp` (apps.js:211-218 and 381-423).
|
||||
|
||||
The name comes filled in and DISABLED (index.html:6232): updating is replacing
|
||||
the zip of an app that already exists, not renaming it. Only the file is
|
||||
validated here, just as in upstream.
|
||||
*/
|
||||
export function UpdateApp({
|
||||
open,
|
||||
onOpenChange,
|
||||
token,
|
||||
name,
|
||||
onUpdated,
|
||||
}: {
|
||||
open: boolean
|
||||
onOpenChange: (o: boolean) => void
|
||||
token: string | null
|
||||
name: string
|
||||
onUpdated: (name: string) => void
|
||||
}) {
|
||||
const [alert, setAlert] = useState<AlertState | null>(null)
|
||||
const [busy, setBusy] = useState(false)
|
||||
const fileRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
setAlert(null)
|
||||
setBusy(false)
|
||||
}
|
||||
}, [open])
|
||||
|
||||
async function update() {
|
||||
const file = fileRef.current?.files?.[0]
|
||||
if (!file) {
|
||||
setAlert({
|
||||
type: 'warning',
|
||||
title: 'Missing!',
|
||||
text: 'Please select an application zip file to update.',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
setBusy(true)
|
||||
const outcome = await updateApp(token, name, file)
|
||||
setBusy(false)
|
||||
|
||||
if (outcome.kind !== 'ok') {
|
||||
setAlert(error(outcome))
|
||||
return
|
||||
}
|
||||
onUpdated(name)
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onOpenChange={onOpenChange}
|
||||
title="Update App"
|
||||
actions={
|
||||
<>
|
||||
<Button variant="primary" disabled={busy} onClick={() => void update()}>
|
||||
Update
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Notifier notice={alert} onClose={() => setAlert(null)} />
|
||||
<LabeledInput label="App Name" value={name} disabled readOnly />
|
||||
<LabeledInput label="App Zip File" type="file" ref={fileRef} />
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user