From d05b7da8bc569524b6e09c4a9aaa4602c817dea3 Mon Sep 17 00:00:00 2001 From: Nils-Johan Gynther Date: Mon, 11 May 2026 19:30:42 +0200 Subject: [PATCH] feat: Add isPrivate field to AdminProduct and update filtering logic in admin panels --- .../lib/features/admin/data/admin_repository.dart | 1 + .../lib/features/admin/domain/admin_product.dart | 3 +++ .../admin/presentation/admin_form_shared.dart | 14 +++++++++----- .../admin/presentation/admin_inventory_panel.dart | 3 ++- .../admin/presentation/admin_pantry_panel.dart | 3 ++- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/flutter/lib/features/admin/data/admin_repository.dart b/flutter/lib/features/admin/data/admin_repository.dart index 0d0fa2bf..b1938e91 100644 --- a/flutter/lib/features/admin/data/admin_repository.dart +++ b/flutter/lib/features/admin/data/admin_repository.dart @@ -240,6 +240,7 @@ class AdminRepository { name: product.name, canonicalName: product.canonicalName, ownerId: product.ownerId, + isPrivate: true, categoryId: product.categoryId, categoryPath: product.categoryPath, status: 'private', diff --git a/flutter/lib/features/admin/domain/admin_product.dart b/flutter/lib/features/admin/domain/admin_product.dart index 361fdbd6..bc4deef0 100644 --- a/flutter/lib/features/admin/domain/admin_product.dart +++ b/flutter/lib/features/admin/domain/admin_product.dart @@ -4,6 +4,7 @@ class AdminProduct { final String? canonicalName; final String? normalizedName; final int? ownerId; + final bool? isPrivate; final int? categoryId; final String? categoryPath; final bool? isActive; @@ -16,6 +17,7 @@ class AdminProduct { this.canonicalName, this.normalizedName, this.ownerId, + this.isPrivate, this.categoryId, this.categoryPath, this.isActive, @@ -46,6 +48,7 @@ class AdminProduct { canonicalName: json['canonicalName']?.toString(), normalizedName: json['normalizedName']?.toString(), ownerId: ((json['owner'] as Map?)?['id'] as num?)?.toInt(), + isPrivate: json['isPrivate'] as bool?, categoryId: (json['categoryId'] as num?)?.toInt(), categoryPath: names.isEmpty ? null : names.join(' > '), isActive: json['isActive'] as bool?, diff --git a/flutter/lib/features/admin/presentation/admin_form_shared.dart b/flutter/lib/features/admin/presentation/admin_form_shared.dart index 3eecacae..2df954a2 100644 --- a/flutter/lib/features/admin/presentation/admin_form_shared.dart +++ b/flutter/lib/features/admin/presentation/admin_form_shared.dart @@ -38,13 +38,17 @@ List filterSelectableAdminProducts({ required AdminProduct? selectedProduct, }) { final ownerFiltered = ownerUserId == null - ? products.where((p) => p.ownerId == null).toList() - : products.where((p) => p.ownerId == null || p.ownerId == ownerUserId).toList(); + ? products.where((p) => p.isPrivate != true).toList() + : products + .where( + (p) => p.isPrivate != true || 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(), + ProductScopeFilter.globalOnly => ownerFiltered.where((p) => p.isPrivate != true).toList(), + ProductScopeFilter.privateOnly => ownerFiltered.where((p) => p.isPrivate == true).toList(), }; final source = categoryId == null @@ -64,7 +68,7 @@ List toProductOptions(List products) { .map( (p) => ( id: p.id, - name: p.ownerId == null ? p.displayName : '${p.displayName} (privat)', + name: p.isPrivate == true ? '${p.displayName} (privat)' : p.displayName, categoryId: p.categoryId, ), ) diff --git a/flutter/lib/features/admin/presentation/admin_inventory_panel.dart b/flutter/lib/features/admin/presentation/admin_inventory_panel.dart index 38b98cc0..78c6bafe 100644 --- a/flutter/lib/features/admin/presentation/admin_inventory_panel.dart +++ b/flutter/lib/features/admin/presentation/admin_inventory_panel.dart @@ -854,6 +854,7 @@ class _InventoryFormDialogState extends State<_InventoryFormDialog> { name: initial.productName, canonicalName: initial.productCanonicalName, ownerId: initial.userId, + isPrivate: null, categoryId: initial.categoryId, categoryPath: initial.categoryPath, status: 'private', @@ -943,7 +944,7 @@ class _InventoryFormDialogState extends State<_InventoryFormDialog> { if (value == null) { _productScopeFilter = ProductScopeFilter.globalOnly; final selected = _productById(_productId); - if (selected?.ownerId != null) { + if (selected?.isPrivate == true) { _productId = null; } } diff --git a/flutter/lib/features/admin/presentation/admin_pantry_panel.dart b/flutter/lib/features/admin/presentation/admin_pantry_panel.dart index 7a5ebc33..b4821ebd 100644 --- a/flutter/lib/features/admin/presentation/admin_pantry_panel.dart +++ b/flutter/lib/features/admin/presentation/admin_pantry_panel.dart @@ -565,6 +565,7 @@ class _PantryFormDialogState extends State<_PantryFormDialog> { name: initial.productName, canonicalName: initial.productCanonicalName, ownerId: initial.userId, + isPrivate: null, categoryId: initial.categoryId, categoryPath: initial.categoryPath, status: 'private', @@ -645,7 +646,7 @@ class _PantryFormDialogState extends State<_PantryFormDialog> { if (value == null) { _productScopeFilter = ProductScopeFilter.globalOnly; final selected = _productById(_productId); - if (selected?.ownerId != null) { + if (selected?.isPrivate == true) { _productId = null; } }