Fixed Edit Port Dialog on Network Map

This commit is contained in:
2026-06-06 18:30:58 +08:00
parent 65a42039ee
commit e49b52949c
4 changed files with 41 additions and 29 deletions
@@ -655,8 +655,8 @@ class _PortsList extends ConsumerWidget {
PortListTile(
port: p,
canEdit: true,
onTap: () => showPortEditDialog(
context: context,
onTap: (ctx) => showPortEditDialog(
context: ctx,
ref: ref,
deviceId: deviceId,
existing: p,
@@ -132,8 +132,8 @@ class NetworkMapDeviceScreen extends ConsumerWidget {
linkedPortLabel: otherPortLabel(port.id),
canEdit: canEdit,
onTap: canEdit
? () => showPortEditDialog(
context: context,
? (ctx) => showPortEditDialog(
context: ctx,
ref: ref,
deviceId: device.id,
existing: port,
@@ -131,18 +131,19 @@ class _PortEditDialogState extends ConsumerState<_PortEditDialog> {
return AlertDialog(
title: Text(widget.existing == null ? 'Add port' : 'Edit port'),
content: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 420),
constraints: const BoxConstraints(minWidth: 320, maxWidth: 480),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// ── Identity ─────────────────────────────────────────
TextField(
controller: _numberCtrl,
autofocus: widget.existing == null,
decoration: const InputDecoration(
labelText: 'Port number *',
helperText: 'Exactly as labeled on the device (e.g. Gi0/1, eth0, 24)',
helperText: 'e.g. Gi0/1, eth0, port24',
),
),
const SizedBox(height: 12),
@@ -161,6 +162,7 @@ class _PortEditDialogState extends ConsumerState<_PortEditDialog> {
),
const SizedBox(height: 12),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: TextField(
@@ -182,39 +184,43 @@ class _PortEditDialogState extends ConsumerState<_PortEditDialog> {
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
decoration: InputDecoration(
labelText: 'Access VLAN',
helperText: _isTrunk
? 'Disabled — trunk port'
: 'Single VLAN ID (14094)',
helperText: _isTrunk ? 'Disabled for trunk' : '14094',
),
),
),
],
),
const SizedBox(height: 12),
// ── Switching config ──────────────────────────────────
const Divider(height: 28),
SwitchListTile.adaptive(
value: _isTrunk,
onChanged: (v) => setState(() => _isTrunk = v),
contentPadding: EdgeInsets.zero,
title: const Text('Trunk port'),
subtitle: Text(
'Carries multiple VLANs',
style: tt.bodySmall,
),
subtitle: Text('Carries multiple VLANs', style: tt.bodySmall),
),
if (_isTrunk) ...[
const SizedBox(height: 4),
TextField(
controller: _trunkVlansCtrl,
decoration: const InputDecoration(
labelText: 'Allowed VLANs (comma-separated)',
helperText: 'e.g. 10, 20, 100-105',
),
),
],
AnimatedSize(
duration: const Duration(milliseconds: 200),
curve: Curves.easeInOut,
child: _isTrunk
? Padding(
padding: const EdgeInsets.only(top: 8),
child: TextField(
controller: _trunkVlansCtrl,
decoration: const InputDecoration(
labelText: 'Allowed VLANs',
helperText: 'Comma-separated, e.g. 10, 20, 100',
),
),
)
: const SizedBox.shrink(),
),
// ── Notes ─────────────────────────────────────────────
const SizedBox(height: 12),
TextField(
controller: _notesCtrl,
maxLines: 2,
minLines: 2,
maxLines: 4,
decoration: const InputDecoration(labelText: 'Notes'),
),
],
@@ -228,7 +234,13 @@ class _PortEditDialogState extends ConsumerState<_PortEditDialog> {
),
FilledButton(
onPressed: _saving ? null : _save,
child: Text(_saving ? 'Saving…' : 'Save'),
child: _saving
? const SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 2),
)
: Text(widget.existing == null ? 'Add' : 'Save'),
),
],
);
@@ -21,7 +21,7 @@ class PortListTile extends StatelessWidget {
final String? linkedDeviceName;
final String? linkedPortLabel;
final bool canEdit;
final VoidCallback? onTap;
final void Function(BuildContext)? onTap;
final void Function(BuildContext)? onConnect;
final void Function(BuildContext)? onDisconnect;
final VoidCallback? onDelete;
@@ -40,7 +40,7 @@ class PortListTile extends StatelessWidget {
];
return ListTile(
onTap: onTap,
onTap: onTap == null ? null : () => onTap!(context),
leading: CircleAvatar(
backgroundColor: isLinked
? cs.primaryContainer
@@ -75,7 +75,7 @@ class PortListTile extends StatelessWidget {
onSelected: (action) {
switch (action) {
case _PortAction.editPort:
onTap?.call();
onTap?.call(context);
case _PortAction.connect:
onConnect?.call(context);
case _PortAction.disconnect: