Files
recipe-app/flutter/lib/features/admin/presentation/admin_form_shared.dart
T
Nils-Johan Gynther a4f65c6065
Test Suite / test (24.15.0) (push) Has been cancelled
feat: Implement caching for selectable products and enhance product filtering in admin panels
2026-05-11 18:42:35 +02:00

94 lines
2.9 KiB
Dart

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),
),
);
}