Add editable name field to generic integrations (#13)

* Add editable display-name field to generic integrations

Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4

* Surface the new-integration name field as a labeled input

The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Samuel James 2026-06-20 07:40:03 -04:00 committed by GitHub
parent 7de7c1c84e
commit 39c94e4045
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -747,7 +747,8 @@ function IntegrationsSection() {
setStatusMsg((prev) => ({ ...prev, [rowKey]: '' })) setStatusMsg((prev) => ({ ...prev, [rowKey]: '' }))
try { try {
const { config, secrets } = buildPayload(def, editDrafts[existing.id] ?? {}) const { config, secrets } = buildPayload(def, editDrafts[existing.id] ?? {})
const { integration } = await api.updateIntegration(existing.id, { config, secrets }) const name = editDrafts[existing.id]?.__name?.trim()
const { integration } = await api.updateIntegration(existing.id, { ...(name ? { name } : {}), config, secrets })
setIntegrations((prev) => (prev ?? []).map((i) => (i.id === integration.id ? integration : i))) setIntegrations((prev) => (prev ?? []).map((i) => (i.id === integration.id ? integration : i)))
setStatusMsg((prev) => ({ ...prev, [rowKey]: 'Saved' })) setStatusMsg((prev) => ({ ...prev, [rowKey]: 'Saved' }))
} catch (err) { } catch (err) {
@ -763,7 +764,8 @@ function IntegrationsSection() {
setStatusMsg((prev) => ({ ...prev, [rowKey]: '' })) setStatusMsg((prev) => ({ ...prev, [rowKey]: '' }))
try { try {
const { config, secrets } = buildPayload(def, draft.values) const { config, secrets } = buildPayload(def, draft.values)
const { integration } = await api.createIntegration({ type: def.type, name: def.name, config, secrets }) const name = draft.values.__name?.trim() || def.name
const { integration } = await api.createIntegration({ type: def.type, name, config, secrets })
setIntegrations((prev) => [...(prev ?? []), integration]) setIntegrations((prev) => [...(prev ?? []), integration])
removeNewDraft(draft.id) removeNewDraft(draft.id)
} catch (err) { } catch (err) {
@ -879,7 +881,11 @@ function IntegrationsSection() {
boxShadow: online ? '0 0 6px rgba(46,204,113,0.6)' : 'none', boxShadow: online ? '0 0 6px rgba(46,204,113,0.6)' : 'none',
}} }}
/> />
<span style={{ fontSize: '13px', color: '#E8E6E0', fontWeight: 600 }}>{existing.name || def.name}</span> <input
value={draft.__name ?? existing.name ?? def.name}
onChange={(e) => setEditField(existing.id, '__name', e.target.value)}
style={{ fontSize: '13px', color: '#E8E6E0', fontWeight: 600, backgroundColor: 'transparent', border: 'none', outline: 'none', padding: 0, width: '160px' }}
/>
{existing.config.baseUrl || existing.config.hostname ? ( {existing.config.baseUrl || existing.config.hostname ? (
<span style={{ fontSize: '11px', color: '#7A7D85' }}>{existing.config.baseUrl || existing.config.hostname}</span> <span style={{ fontSize: '11px', color: '#7A7D85' }}>{existing.config.baseUrl || existing.config.hostname}</span>
) : null} ) : null}
@ -952,6 +958,17 @@ function IntegrationsSection() {
</button> </button>
</div> </div>
</div> </div>
<div className="grid grid-cols-3 gap-4" style={{ marginBottom: '16px' }}>
<div>
<label style={labelStyle}>Name</label>
<input
style={inputStyle}
value={draft.values.__name ?? ''}
onChange={(e) => setNewDraftField(draft.id, '__name', e.target.value)}
placeholder={def.name}
/>
</div>
</div>
{renderFields( {renderFields(
def, def,
rowKey, rowKey,