feat: Refactor routing and navigation structure with StatefulShellRoute
Test Suite / test (24.15.0) (push) Has been cancelled
Test Suite / test (24.15.0) (push) Has been cancelled
- Introduced a new function `_shellBranchIndexForPath` to determine the index of the shell branch based on the path. - Replaced `ShellRoute` with `StatefulShellRoute.indexedStack` for better state management during navigation. - Updated `AppShell` to handle navigation path changes and integrate with the new routing structure. - Organized routes into `StatefulShellBranch` for better modularity and clarity. - Enhanced admin panel functionality with improved alias management and UI updates. - Added new methods in `ReceiptImportSessionNotifier` for managing selected items and edits more efficiently. - Improved UI components in receipt import and admin panels for better performance and user experience. - Added PageStorageKeys to various ListViews to maintain scroll positions across navigation. - Documented performance goals and profiling strategies in a new PERFORMANCE.md file.
This commit is contained in:
@@ -166,6 +166,49 @@ class _AdminAliasesPanelState extends ConsumerState<AdminAliasesPanel> {
|
||||
alias.displayProductName.toLowerCase().contains(query);
|
||||
}).toList();
|
||||
|
||||
Widget buildAliasCard(ReceiptAlias alias) {
|
||||
return Card(
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.link_outlined),
|
||||
title: Text(alias.receiptName, style: const TextStyle(fontWeight: FontWeight.w500)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'→ ${alias.displayProductName}',
|
||||
style: const TextStyle(fontWeight: FontWeight.w400),
|
||||
),
|
||||
Text(
|
||||
'Produkt-ID: ${alias.productId}',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: IconButton(
|
||||
onPressed: () => _removeAlias(alias),
|
||||
icon: const Icon(Icons.delete_outline),
|
||||
tooltip: 'Ta bort alias',
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildAliasList({EdgeInsetsGeometry padding = EdgeInsets.zero}) {
|
||||
return ListView.builder(
|
||||
padding: padding,
|
||||
itemCount: filteredAliases.length,
|
||||
itemBuilder: (context, index) {
|
||||
final alias = filteredAliases[index];
|
||||
return buildAliasCard(alias);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
final content = Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -230,51 +273,37 @@ class _AdminAliasesPanelState extends ConsumerState<AdminAliasesPanel> {
|
||||
onChanged: (value) => setState(() => _search = value),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
if (filteredAliases.isEmpty)
|
||||
const Text('Inga alias hittades.')
|
||||
else
|
||||
...filteredAliases.map(
|
||||
(alias) => Card(
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.link_outlined),
|
||||
title: Text(alias.receiptName, style: const TextStyle(fontWeight: FontWeight.w500)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'→ ${alias.displayProductName}',
|
||||
style: const TextStyle(fontWeight: FontWeight.w400),
|
||||
),
|
||||
Text(
|
||||
'Produkt-ID: ${alias.productId}',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: IconButton(
|
||||
onPressed: () => _removeAlias(alias),
|
||||
icon: const Icon(Icons.delete_outline),
|
||||
tooltip: 'Ta bort alias',
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (filteredAliases.isEmpty) const Text('Inga alias hittades.'),
|
||||
],
|
||||
);
|
||||
|
||||
if (!widget.embedded) {
|
||||
if (filteredAliases.isEmpty) {
|
||||
return ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [content],
|
||||
);
|
||||
}
|
||||
return ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [content],
|
||||
children: [
|
||||
content,
|
||||
const SizedBox(height: 8),
|
||||
...filteredAliases.map(buildAliasCard),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return content;
|
||||
if (filteredAliases.isEmpty) return content;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
content,
|
||||
const SizedBox(height: 8),
|
||||
Expanded(child: buildAliasList()),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,8 +93,8 @@ class _AdminPendingProductsPanelState
|
||||
}
|
||||
|
||||
final content = ListView.builder(
|
||||
shrinkWrap: widget.embedded,
|
||||
physics: widget.embedded ? const NeverScrollableScrollPhysics() : null,
|
||||
shrinkWrap: false,
|
||||
physics: null,
|
||||
itemCount: _products.length,
|
||||
itemBuilder: (context, index) {
|
||||
final product = _products[index];
|
||||
@@ -148,7 +148,7 @@ class _AdminPendingProductsPanelState
|
||||
style: theme.textTheme.bodyMedium,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
content,
|
||||
Expanded(child: content),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -738,7 +738,10 @@ class _AdminProductsPanelState extends ConsumerState<AdminProductsPanel> {
|
||||
);
|
||||
}
|
||||
|
||||
return content;
|
||||
return ListView(
|
||||
padding: EdgeInsets.zero,
|
||||
children: [content],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -328,10 +328,8 @@ class _AdminUsersPanelState extends ConsumerState<AdminUsersPanel> {
|
||||
}
|
||||
|
||||
final list = ListView.builder(
|
||||
shrinkWrap: widget.embedded,
|
||||
physics: widget.embedded
|
||||
? const NeverScrollableScrollPhysics()
|
||||
: null,
|
||||
shrinkWrap: false,
|
||||
physics: null,
|
||||
padding: widget.embedded
|
||||
? EdgeInsets.zero
|
||||
: const EdgeInsets.fromLTRB(16, 8, 16, 80),
|
||||
@@ -376,7 +374,7 @@ class _AdminUsersPanelState extends ConsumerState<AdminUsersPanel> {
|
||||
label: Text(context.l10n.adminNewUser),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
list,
|
||||
Expanded(child: list),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user