From e49b52949c0699753cfbb314829eb01d91f70f7b Mon Sep 17 00:00:00 2001 From: Marc Rejohn Castillano Date: Sat, 6 Jun 2026 18:30:58 +0800 Subject: [PATCH] Fixed Edit Port Dialog on Network Map --- .../network_map_device_edit_screen.dart | 4 +- .../network_map_device_screen.dart | 4 +- .../network_map/widgets/port_edit_dialog.dart | 56 +++++++++++-------- .../network_map/widgets/port_list_tile.dart | 6 +- 4 files changed, 41 insertions(+), 29 deletions(-) diff --git a/lib/screens/network_map/network_map_device_edit_screen.dart b/lib/screens/network_map/network_map_device_edit_screen.dart index 26ec3366..2eaf839a 100644 --- a/lib/screens/network_map/network_map_device_edit_screen.dart +++ b/lib/screens/network_map/network_map_device_edit_screen.dart @@ -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, diff --git a/lib/screens/network_map/network_map_device_screen.dart b/lib/screens/network_map/network_map_device_screen.dart index 66e99cd9..d9880929 100644 --- a/lib/screens/network_map/network_map_device_screen.dart +++ b/lib/screens/network_map/network_map_device_screen.dart @@ -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, diff --git a/lib/screens/network_map/widgets/port_edit_dialog.dart b/lib/screens/network_map/widgets/port_edit_dialog.dart index 625033bb..ac7b1bf0 100644 --- a/lib/screens/network_map/widgets/port_edit_dialog.dart +++ b/lib/screens/network_map/widgets/port_edit_dialog.dart @@ -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 (1–4094)', + helperText: _isTrunk ? 'Disabled for trunk' : '1–4094', ), ), ), ], ), - 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'), ), ], ); diff --git a/lib/screens/network_map/widgets/port_list_tile.dart b/lib/screens/network_map/widgets/port_list_tile.dart index a8735d93..f2fa2e18 100644 --- a/lib/screens/network_map/widgets/port_list_tile.dart +++ b/lib/screens/network_map/widgets/port_list_tile.dart @@ -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: