94 lines
2.9 KiB
Dart
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),
|
|
),
|
|
);
|
|
}
|