Skip to content

Commit ef68f35

Browse files
IM.codesclaude
andcommitted
feat: add "Upgrade All Devices" option to server context menu
- Shows when multiple servers exist - Sends upgrade command to all servers in sequence - i18n: 7 languages Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
1 parent 29b8e86 commit ef68f35

9 files changed

Lines changed: 28 additions & 1 deletion

File tree

web/src/app.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,19 @@ export function App() {
249249
}
250250
}, [trans]);
251251

252+
const handleUpgradeAll = useCallback(async () => {
253+
const results: string[] = [];
254+
for (const server of servers) {
255+
try {
256+
await apiFetch(`/api/server/${server.id}/upgrade`, { method: 'POST' });
257+
results.push(`✓ ${server.name}`);
258+
} catch {
259+
results.push(`✗ ${server.name}`);
260+
}
261+
}
262+
alert(results.join('\n'));
263+
}, [servers]);
264+
252265
const handleDeleteServer = useCallback(async (server: ServerInfo) => {
253266
try {
254267
await apiFetch(`/api/server/${server.id}`, { method: 'DELETE' });
@@ -1384,6 +1397,7 @@ export function App() {
13841397
y={serverCtxMenu.y}
13851398
onRename={() => handleRenameServer(serverCtxMenu.server)}
13861399
onUpgrade={() => handleUpgradeDaemon(serverCtxMenu.server)}
1400+
onUpgradeAll={servers.length > 1 ? handleUpgradeAll : undefined}
13871401
onDelete={() => setDeleteTarget(serverCtxMenu.server)}
13881402
onClose={() => setServerCtxMenu(null)}
13891403
/>

web/src/components/ServerContextMenu.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ interface Props {
66
y: number;
77
onRename: () => void;
88
onUpgrade: () => void;
9+
onUpgradeAll?: () => void;
910
onDelete: () => void;
1011
onClose: () => void;
1112
}
1213

13-
export function ServerContextMenu({ x, y, onRename, onUpgrade, onDelete, onClose }: Props) {
14+
export function ServerContextMenu({ x, y, onRename, onUpgrade, onUpgradeAll, onDelete, onClose }: Props) {
1415
const { t } = useTranslation();
1516
const ref = useRef<HTMLDivElement>(null);
1617

@@ -40,6 +41,11 @@ export function ServerContextMenu({ x, y, onRename, onUpgrade, onDelete, onClose
4041
<button class="server-ctx-item" onClick={() => { onClose(); onUpgrade(); }}>
4142
{t('server.upgrade_daemon')}
4243
</button>
44+
{onUpgradeAll && (
45+
<button class="server-ctx-item" onClick={() => { onClose(); onUpgradeAll(); }}>
46+
{t('server.upgrade_all')}
47+
</button>
48+
)}
4349
<div class="menu-divider" />
4450
<button class="server-ctx-item server-ctx-item-danger" onClick={() => { onClose(); onDelete(); }}>
4551
{t('server.delete')}

web/src/i18n/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
},
5050
"server": {
5151
"upgrade_daemon": "↑ Upgrade Daemon",
52+
"upgrade_all": "↑ Upgrade All Devices",
5253
"delete": "✕ Delete server",
5354
"upgrade_sent": "Upgrade command sent to \"{{name}}\". The daemon will install the latest version and restart.",
5455
"upgrade_failed": "Failed to send upgrade command. The daemon may be offline.",

web/src/i18n/locales/es.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
},
5050
"server": {
5151
"upgrade_daemon": "↑ Actualizar Daemon",
52+
"upgrade_all": "↑ Actualizar Todos",
5253
"delete": "✕ Eliminar servidor",
5354
"upgrade_sent": "Comando de actualización enviado a \"{{name}}\". El daemon instalará la última versión y se reiniciará.",
5455
"upgrade_failed": "Error al enviar el comando de actualización. El daemon puede estar desconectado.",

web/src/i18n/locales/ja.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
},
5050
"server": {
5151
"upgrade_daemon": "↑ Daemonをアップグレード",
52+
"upgrade_all": "↑ 全デバイス更新",
5253
"delete": "✕ サーバーを削除",
5354
"upgrade_sent": "「{{name}}」にアップグレードコマンドを送信しました。Daemonは最新バージョンをインストールして再起動します。",
5455
"upgrade_failed": "アップグレードコマンドの送信に失敗しました。Daemonがオフラインの可能性があります。",

web/src/i18n/locales/ko.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
},
5050
"server": {
5151
"upgrade_daemon": "↑ Daemon 업그레이드",
52+
"upgrade_all": "↑ 전체 기기 업그레이드",
5253
"delete": "✕ 서버 삭제",
5354
"upgrade_sent": "\"{{name}}\"에 업그레이드 명령이 전송되었습니다. Daemon이 최신 버전을 설치하고 재시작합니다.",
5455
"upgrade_failed": "업그레이드 명령 전송 실패. Daemon이 오프라인일 수 있습니다.",

web/src/i18n/locales/ru.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
},
5050
"server": {
5151
"upgrade_daemon": "↑ Обновить Daemon",
52+
"upgrade_all": "↑ Обновить все устройства",
5253
"delete": "✕ Удалить сервер",
5354
"upgrade_sent": "Команда обновления отправлена в \"{{name}}\". Daemon установит последнюю версию и перезапустится.",
5455
"upgrade_failed": "Не удалось отправить команду обновления. Daemon может быть отключён.",

web/src/i18n/locales/zh-CN.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
},
5050
"server": {
5151
"upgrade_daemon": "↑ 升级 Daemon",
52+
"upgrade_all": "↑ 升级全部设备",
5253
"delete": "✕ 删除 server",
5354
"upgrade_sent": "升级命令已发送到「{{name}}」,daemon 将自动安装最新版并重启。",
5455
"upgrade_failed": "发送失败,daemon 可能不在线。",

web/src/i18n/locales/zh-TW.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
},
5050
"server": {
5151
"upgrade_daemon": "↑ 升級 Daemon",
52+
"upgrade_all": "↑ 升級全部裝置",
5253
"delete": "✕ 刪除伺服器",
5354
"upgrade_sent": "升級指令已傳送至「{{name}}」,Daemon 將安裝最新版本並重新啟動。",
5455
"upgrade_failed": "傳送升級指令失敗,Daemon 可能已離線。",

0 commit comments

Comments
 (0)