feat: Implement caching for selectable products and enhance product filtering in admin panels
Test Suite / test (24.15.0) (push) Has been cancelled
Test Suite / test (24.15.0) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../core/ui/product_picker_field.dart';
|
||||
import '../domain/admin_product.dart';
|
||||
|
||||
enum ProductScopeFilter { all, globalOnly, privateOnly }
|
||||
|
||||
List<String> buildLocationOptionsFromValues(Iterable<String?> values) {
|
||||
final set = <String>{};
|
||||
for (final value in values) {
|
||||
final trimmed = value?.trim();
|
||||
if (trimmed != null && trimmed.isNotEmpty) {
|
||||
set.add(trimmed);
|
||||
}
|
||||
}
|
||||
final list = set.toList()
|
||||
..sort((a, b) => a.toLowerCase().compareTo(b.toLowerCase()));
|
||||
return list;
|
||||
}
|
||||
|
||||
String? resolveLocationDropdownValue({
|
||||
required bool useManualLocation,
|
||||
required String currentValue,
|
||||
required List<String> options,
|
||||
required String manualLocationValue,
|
||||
}) {
|
||||
if (useManualLocation) return manualLocationValue;
|
||||
final value = currentValue.trim();
|
||||
if (value.isEmpty) return null;
|
||||
return options.contains(value) ? value : manualLocationValue;
|
||||
}
|
||||
|
||||
List<AdminProduct> filterSelectableAdminProducts({
|
||||
required List<AdminProduct> products,
|
||||
required int? ownerUserId,
|
||||
required int? categoryId,
|
||||
required ProductScopeFilter scopeFilter,
|
||||
required AdminProduct? selectedProduct,
|
||||
}) {
|
||||
final ownerFiltered = ownerUserId == null
|
||||
? products.where((p) => p.ownerId == null).toList()
|
||||
: products.where((p) => p.ownerId == null || p.ownerId == ownerUserId).toList();
|
||||
|
||||
final scopeFiltered = switch (scopeFilter) {
|
||||
ProductScopeFilter.all => ownerFiltered,
|
||||
ProductScopeFilter.globalOnly => ownerFiltered.where((p) => p.ownerId == null).toList(),
|
||||
ProductScopeFilter.privateOnly => ownerFiltered.where((p) => p.ownerId != null).toList(),
|
||||
};
|
||||
|
||||
final source = categoryId == null
|
||||
? scopeFiltered
|
||||
: scopeFiltered.where((p) => p.categoryId == categoryId).toList();
|
||||
|
||||
if (selectedProduct != null && !source.any((p) => p.id == selectedProduct.id)) {
|
||||
source.add(selectedProduct);
|
||||
}
|
||||
|
||||
source.sort((a, b) => a.displayName.toLowerCase().compareTo(b.displayName.toLowerCase()));
|
||||
return source;
|
||||
}
|
||||
|
||||
List<ProductOption> toProductOptions(List<AdminProduct> products) {
|
||||
return products
|
||||
.map(
|
||||
(p) => (
|
||||
id: p.id,
|
||||
name: p.ownerId == null ? p.displayName : '${p.displayName} (privat)',
|
||||
categoryId: p.categoryId,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
Widget buildCategoryPathChip(String? categoryPath, {double maxWidth = 220}) {
|
||||
final value = (categoryPath == null || categoryPath.trim().isEmpty)
|
||||
? 'okänd'
|
||||
: categoryPath.trim();
|
||||
return Tooltip(
|
||||
message: value,
|
||||
child: Chip(
|
||||
label: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: maxWidth),
|
||||
child: Text(
|
||||
value,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: false,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user