This commit is contained in:
2026-05-27 16:00:50 +02:00
parent f6ecb33729
commit b6e5f9acbe
8 changed files with 232 additions and 134 deletions

View File

@@ -1,4 +1,3 @@
import 'package:collection/collection.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
@@ -11,55 +10,60 @@ part 'task_form_state.dart';
class TaskFormCubit extends Cubit<TaskFormState> {
final TaskRepository _taskRepository = GetIt.I.get<TaskRepository>();
final TaskModel? _initialTask;
final String? _initialTaskId;
// Cache in memoria proveniente dallo StaffCubit!
final List<StaffMemberModel> _globalStaff;
final String currentCompanyId = GetIt.I
.get<SessionCubit>()
.state
.company!
.id!;
final String? currentStoreId = GetIt.I
.get<SessionCubit>()
.state
.currentStore
?.id;
final String currentCompanyId = GetIt.I<SessionCubit>().state.company!.id!;
final String? currentStoreId = GetIt.I<SessionCubit>().state.currentStore?.id;
TaskFormCubit({
required List<StaffMemberModel> globalStaff, // Iniettiamo la lista qui
TaskModel? initialTask,
String? initialTaskId,
required List<StaffMemberModel> globalStaff,
TaskModel? initialTask, // Arriva dalla navigazione interna (extra)
String? initialTaskId, // Arriva dal Deep Link (parametro URL)
}) : _globalStaff = globalStaff,
_initialTask = initialTask,
_initialTaskId = initialTaskId,
super(const TaskFormState()) {
_initForm(task: initialTask, initialTaskId: initialTaskId);
_initForm(initialTask, initialTaskId);
}
// --- 1. INIZIALIZZAZIONE SINCRONA ---
void _initForm({TaskModel? task, String? initialTaskId}) {
final isGlobalMode = task != null
? task.storeId == null
: currentStoreId == null;
Future<void> _initForm(TaskModel? task, String? taskId) async {
// 1. Mettiamo subito il form in caricamento
emit(state.copyWith(status: TaskFormStatus.loading));
// MAGIA: Estraiamo gli ID dagli oggetti staff, o facciamo fallback su assignedToIds se c'è
TaskModel? taskToLoad = task;
// 2. SCENARIO DEEP LINK: Non abbiamo l'oggetto, ma abbiamo un ID valido
if (taskToLoad == null && taskId != null && taskId != 'new') {
try {
taskToLoad = await _taskRepository.getTaskById(taskId);
} catch (e) {
emit(
state.copyWith(
status: TaskFormStatus.failure,
errorMessage: 'Impossibile caricare il task dal link: $e',
),
);
return; // Ci fermiamo qui
}
}
// 3. Popoliamo lo stato con i dati (sia che arrivino dall'extra, sia dal DB, sia nulli)
final isGlobalMode = taskToLoad != null
? taskToLoad.storeId == null
: currentStoreId == null;
final existingStaffIds =
task?.assignedToStaff.map((s) => s.id!).toList() ??
task?.assignedToIds ??
taskToLoad?.assignedToStaff.map((s) => s.id!).toList() ??
taskToLoad?.assignedToIds ??
[];
emit(
state.copyWith(
id: task?.id,
title: task?.title ?? '',
description: task?.description ?? '',
dueDate: task?.dueDate,
taskStatus: task?.status ?? TaskStatus.open,
id: taskToLoad?.id,
title: taskToLoad?.title ?? '',
description: taskToLoad?.description ?? '',
dueDate: taskToLoad?.dueDate,
taskStatus: taskToLoad?.status ?? TaskStatus.open,
isGlobal: isGlobalMode,
selectedStaffIds:
existingStaffIds, // Ora non si perde più i dipendenti!
selectedStaffIds: existingStaffIds,
status: TaskFormStatus.initial, // Caricamento finito, form pronto!
),
);
@@ -78,16 +82,28 @@ class TaskFormCubit extends Cubit<TaskFormState> {
}
void _updateStaffScope(bool isGlobal) {
// 1. Filtriamo in memoria
// 1. Filtriamo in memoria: cerchiamo nell'array degli ID!
final filteredStaff = isGlobal
? _globalStaff
: _globalStaff.where((s) => s.store?.id == currentStoreId).toList();
: _globalStaff
.where((s) => s.assignedStoreIds.contains(currentStoreId))
.toList();
// 2. Raggruppiamo per nome negozio (usando groupBy del pacchetto collection)
final groupedStaff = groupBy(
filteredStaff,
(StaffMemberModel s) => s.store?.name ?? 'Direzione / HQ',
);
// 2. Raggruppamento M2M (Ciclo manuale)
final Map<String, List<StaffMemberModel>> groupedStaff = {};
for (final staff in filteredStaff) {
// Se non ha nessun negozio assegnato, finisce in Direzione
if (staff.assignedStores.isEmpty) {
groupedStaff.putIfAbsent('Direzione / HQ', () => []).add(staff);
} else {
// Se ha più negozi, clona la sua presenza in ogni gruppo!
for (final store in staff.assignedStores) {
final storeName = store.name;
groupedStaff.putIfAbsent(storeName, () => []).add(staff);
}
}
}
// 3. Emettiamo il nuovo stato all'istante
emit(