Skip to content

Commit

Permalink
Hlm 2094 fix project sync dialog (#159)
Browse files Browse the repository at this point in the history
* [hlm-2094]: Update sync dialog

* [hlm-2094]: Fix project selection logic

* [hlm-2094]: Update project_selection.dart

* [hlm-2094]: Update digit_dialog.dart

* [hlm-2094]: Update project_selection.dart

* [hlm-2094]: Fix back button on project selection

* [hlm-2094]: Fix navigate back without submit

* [hlm-2094]: Reset boundary bloc on logout

* [hlm-2094]: Update stock_reconciliation.dart
  • Loading branch information
ajilo-eGov authored May 9, 2023
1 parent 9cbcee0 commit 91b2929
Show file tree
Hide file tree
Showing 16 changed files with 857 additions and 801 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,19 @@ class BoundaryBloc extends Bloc<BoundaryEvent, BoundaryState> {
super.initialState, {
required this.boundaryRepository,
}) {
on(_handleReset);
on(_handleSearch);
on(_handleSelect);
on(_handleSubmit);
}

Future<void> _handleReset(
BoundaryResetEvent event,
BoundaryEmitter emit,
) async {
emit(const BoundaryState());
}

FutureOr<void> _handleSearch(
BoundarySearchEvent event,
BoundaryEmitter emit,
Expand Down Expand Up @@ -100,6 +108,8 @@ class BoundaryBloc extends Bloc<BoundaryEvent, BoundaryState> {

@freezed
class BoundaryEvent with _$BoundaryEvent {
const factory BoundaryEvent.reset() = BoundaryResetEvent;

const factory BoundaryEvent.search({required String code}) =
BoundarySearchEvent;

Expand Down
200 changes: 112 additions & 88 deletions apps/health_campaign_field_worker_app/lib/blocs/project/project.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class ProjectBloc extends Bloc<ProjectEvent, ProjectState> {
required this.productVariantLocalRepository,
required this.productVariantRemoteRepository,
}) : localSecureStore = localSecureStore ?? LocalSecureStore.instance,
super(const ProjectsEmptyState()) {
super(const ProjectState()) {
on(_handleProjectInit);
on(_handleProjectSelection);
}
Expand All @@ -99,77 +99,107 @@ class ProjectBloc extends Bloc<ProjectEvent, ProjectState> {
ProjectInitializeEvent event,
ProjectEmitter emit,
) async {
emit(const ProjectLoadingState());
emit(const ProjectState(
loading: true,
projects: [],
selectedProject: null,
));

final connectivityResult = await (Connectivity().checkConnectivity());

switch (connectivityResult) {
case ConnectivityResult.wifi:
case ConnectivityResult.mobile:
final userObject = await localSecureStore.userRequestModel;
final uuid = userObject?.uuid;
AppLogger.instance.info(
'Connectivity Result: $connectivityResult',
title: 'ProjectBloc',
);

List<ProjectStaffModel> projectStaffList =
await projectStaffRemoteRepository.search(
ProjectStaffSearchModel(staffId: uuid),
);
final isOnline = connectivityResult == ConnectivityResult.wifi ||
connectivityResult == ConnectivityResult.mobile;

projectStaffList.removeDuplicates((e) => e.id);

if (projectStaffList.isEmpty) {
emit(const ProjectsEmptyState());
} else {
List<ProjectModel> projects = [];

for (final projectStaff in projectStaffList) {
await projectStaffLocalRepository.create(
projectStaff,
createOpLog: false,
);

final staffProjects = await projectRemoteRepository.search(
ProjectSearchModel(
id: projectStaff.projectId,
tenantId: projectStaff.tenantId,
),
);

projects.addAll(staffProjects);
}

projects.removeDuplicates((e) => e.id);

for (final project in projects) {
await projectLocalRepository.create(
project,
createOpLog: false,
);
}

if (projects.isNotEmpty) {
await _loadProjectFacilities(projects);
await _loadProductVariants(projects);
await _loadServiceDefinition(projects);
}

emit(ProjectSelectionFetchedState(projects: projects));
}
break;
default:
final projects = await projectLocalRepository.search(
ProjectSearchModel(
tenantId: envConfig.variables.tenantId,
),
);
if (isOnline) {
await _loadOnline(emit);
} else {
await _loadOffline(emit);
}
}

final selectedProject = await localSecureStore.selectedProject;
emit(
ProjectSelectionFetchedState(
projects: projects,
selectedProject: selectedProject,
),
);
FutureOr<void> _loadOnline(ProjectEmitter emit) async {
final userObject = await localSecureStore.userRequestModel;
final uuid = userObject?.uuid;

List<ProjectStaffModel> projectStaffList =
await projectStaffRemoteRepository.search(
ProjectStaffSearchModel(staffId: uuid),
);

projectStaffList.removeDuplicates((e) => e.id);

if (projectStaffList.isEmpty) {
emit(const ProjectState(
projects: [],
loading: false,
selectedProject: null,
));

return;
}

List<ProjectModel> projects = [];

for (final projectStaff in projectStaffList) {
await projectStaffLocalRepository.create(
projectStaff,
createOpLog: false,
);

final staffProjects = await projectRemoteRepository.search(
ProjectSearchModel(
id: projectStaff.projectId,
tenantId: projectStaff.tenantId,
),
);

projects.addAll(staffProjects);
}

projects.removeDuplicates((e) => e.id);

for (final project in projects) {
await projectLocalRepository.create(
project,
createOpLog: false,
);
}

if (projects.isNotEmpty) {
await _loadProjectFacilities(projects);
await _loadProductVariants(projects);
await _loadServiceDefinition(projects);
}

emit(ProjectState(
projects: projects,
loading: false,
selectedProject: projects.length == 1 ? projects.first : null,
));
}

FutureOr<void> _loadOffline(ProjectEmitter emit) async {
final projects = await projectLocalRepository.search(
ProjectSearchModel(
tenantId: envConfig.variables.tenantId,
),
);

projects.removeDuplicates((element) => element.id);

final selectedProject = await localSecureStore.selectedProject;
emit(
ProjectState(
loading: false,
projects: projects,
selectedProject: selectedProject,
),
);
}

FutureOr<void> _loadProjectFacilities(List<ProjectModel> projects) async {
Expand Down Expand Up @@ -262,6 +292,8 @@ class ProjectBloc extends Bloc<ProjectEvent, ProjectState> {
ProjectSelectProjectEvent event,
ProjectEmitter emit,
) async {
emit(state.copyWith(loading: true));

final List<BoundaryModel> boundaries =
await boundaryRemoteRepository.search(
BoundarySearchModel(
Expand All @@ -270,23 +302,12 @@ class ProjectBloc extends Bloc<ProjectEvent, ProjectState> {
),
);

await boundaryLocalRepository.bulkCreate(boundaries);
await localSecureStore.setSelectedProject(event.model);

await state.maybeMap(
orElse: () {
return;
},
fetched: (value) async {
final initial = DateTime.now();
await boundaryLocalRepository.bulkCreate(boundaries);
final end = DateTime.now();
AppLogger.instance.debug(
'${end.difference(initial).inMilliseconds}',
title: 'Boundary Duration',
);
emit(value.copyWith(selectedProject: event.model));
},
);
emit(state.copyWith(
selectedProject: event.model,
loading: false,
));
}
}

Expand All @@ -300,14 +321,17 @@ class ProjectEvent with _$ProjectEvent {

@freezed
class ProjectState with _$ProjectState {
const factory ProjectState.uninitialized() = ProjectUninitializedState;
const ProjectState._();

const factory ProjectState.loading() = ProjectLoadingState;
const factory ProjectState({
@Default([]) List<ProjectModel> projects,
ProjectModel? selectedProject,
@Default(false) bool loading,
}) = _ProjectState;

const factory ProjectState.empty() = ProjectsEmptyState;
bool get isEmpty => projects.isEmpty;

const factory ProjectState.fetched({
required List<ProjectModel> projects,
ProjectModel? selectedProject,
}) = ProjectSelectionFetchedState;
bool get isNotEmpty => !isEmpty;

bool get hasSelectedProject => selectedProject != null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ class AuthenticatedPageWrapper extends StatelessWidget {
actions: [
BlocBuilder<BoundaryBloc, BoundaryState>(
builder: (ctx, state) {
BoundaryModel? selectedBoundary;
try {
selectedBoundary = ctx.boundary;
} catch (_) {
debugPrint('');
final selectedBoundary = ctx.boundaryOrNull;

if (selectedBoundary == null) {
return const SizedBox.shrink();
}
final boundaryName =
selectedBoundary?.name ?? selectedBoundary?.code;
if (boundaryName == null) return const SizedBox.shrink();

final boundaryName = selectedBoundary.name ??
selectedBoundary.code ??
'No boundary name';

final theme = Theme.of(context);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import '../blocs/boundary/boundary.dart';
import '../models/data_model.dart';

class BoundarySelectionPage extends StatelessWidget {
class BoundarySelectionPage extends StatefulWidget {
const BoundarySelectionPage({Key? key}) : super(key: key);

@override
State<BoundarySelectionPage> createState() => _BoundarySelectionPageState();
}

class _BoundarySelectionPageState extends State<BoundarySelectionPage> {
bool shouldPop = false;

@override
Widget build(BuildContext context) {
return BlocBuilder<BoundaryBloc, BoundaryState>(
builder: (context, state) {
final selectedBoundary = state.selectedBoundaryMap.entries
.lastWhereOrNull((element) => element.value != null);

return WillPopScope(
onWillPop: () async {
return selectedBoundary != null;
},
child: Scaffold(
return WillPopScope(
onWillPop: () async => shouldPop,
child: BlocBuilder<BoundaryBloc, BoundaryState>(
builder: (context, state) {
final selectedBoundary = state.selectedBoundaryMap.entries
.lastWhereOrNull((element) => element.value != null);

return Scaffold(
body: Builder(
builder: (context) {
if (state.loading) {
Expand Down Expand Up @@ -97,11 +102,19 @@ class BoundarySelectionPage extends StatelessWidget {
child: DigitElevatedButton(
onPressed: selectedBoundary == null
? null
: () {
: () async {
setState(() {
shouldPop = true;
});

context.read<BoundaryBloc>().add(
const BoundarySubmitEvent(),
);
context.router.pop();

Future.delayed(
const Duration(milliseconds: 100),
() => context.router.pop(),
);
},
child: const Text('Submit'),
),
Expand All @@ -111,9 +124,9 @@ class BoundarySelectionPage extends StatelessWidget {
);
},
),
),
);
},
);
},
),
);
}
}
Loading

0 comments on commit 91b2929

Please sign in to comment.