Implement tender workflows and dashboard integration
continuous-integration/drone/push Build encountered an error
continuous-integration/drone/push Build encountered an error
This commit is contained in:
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:tm_app/core/utils/device_utils.dart';
|
||||
import 'package:tm_app/core/utils/logger.dart';
|
||||
import 'package:tm_app/core/network/app_exceptions.dart';
|
||||
import 'package:tm_app/data/repositories/tenders_repository.dart';
|
||||
import 'package:tm_app/data/services/model/feedback_data/feedback_data.dart';
|
||||
import 'package:tm_app/data/services/model/feedback_response/feedback_response.dart';
|
||||
@@ -36,6 +37,12 @@ class TendersViewModel with ChangeNotifier {
|
||||
String? get searchQuery => _searchQuery;
|
||||
|
||||
List<FeedbackData> feedbacks = [];
|
||||
final Set<String> _hydratedFeedbackTenderIds = <String>{};
|
||||
final Set<String> _feedbackHydrationsInFlight = <String>{};
|
||||
final Set<String> _feedbackRequestsInFlight = <String>{};
|
||||
|
||||
bool isFeedbackLoading(String tenderId) =>
|
||||
_feedbackRequestsInFlight.contains(tenderId);
|
||||
|
||||
static const int _pageSize = 10;
|
||||
|
||||
@@ -207,8 +214,7 @@ class TendersViewModel with ChangeNotifier {
|
||||
_currentOffset = meta!.offset!;
|
||||
}
|
||||
final tenders = _tendersResponse?.data?.tenders ?? [];
|
||||
_hasMoreData =
|
||||
meta?.hasMore ?? (tenders.length >= _pageSize);
|
||||
_hasMoreData = meta?.hasMore ?? (tenders.length >= _pageSize);
|
||||
if (tenders.isNotEmpty) {
|
||||
if (fetchAllFeedbacks) {
|
||||
for (final tender in tenders) {
|
||||
@@ -263,8 +269,13 @@ class TendersViewModel with ChangeNotifier {
|
||||
data: result.value.data?.copyWith(tenders: combined),
|
||||
);
|
||||
final newMeta = result.value.meta;
|
||||
_hasMoreData =
|
||||
newMeta?.hasMore ?? (newTenders.length >= _pageSize);
|
||||
_hasMoreData = newMeta?.hasMore ?? (newTenders.length >= _pageSize);
|
||||
for (final tender in newTenders) {
|
||||
final id = tender.id;
|
||||
if (id != null && !_hydratedFeedbackTenderIds.contains(id)) {
|
||||
getTenderFeedback(id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_hasMoreData = false;
|
||||
}
|
||||
@@ -283,14 +294,18 @@ class TendersViewModel with ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<void> getTenderFeedback(String tenderId) async {
|
||||
_errorMessage = null;
|
||||
notifyListeners();
|
||||
if (_hydratedFeedbackTenderIds.contains(tenderId) ||
|
||||
_feedbackHydrationsInFlight.contains(tenderId)) {
|
||||
return;
|
||||
}
|
||||
_feedbackHydrationsInFlight.add(tenderId);
|
||||
|
||||
final result = await _tendersRepository.getTenderFeedback(
|
||||
tenderId: tenderId,
|
||||
);
|
||||
switch (result) {
|
||||
case Ok<FeedbackResponse>():
|
||||
_hydratedFeedbackTenderIds.add(tenderId);
|
||||
_feedbackData = result.value.data;
|
||||
if (_feedbackData != null) {
|
||||
final index = feedbacks.indexWhere(
|
||||
@@ -311,19 +326,33 @@ class TendersViewModel with ChangeNotifier {
|
||||
}
|
||||
break;
|
||||
case Error<FeedbackResponse>():
|
||||
_errorMessage = result.error.toString();
|
||||
if (result.error is NotFoundException) {
|
||||
// A 404 is the expected representation of neutral feedback state.
|
||||
feedbacks.removeWhere((feedback) => feedback.tenderId == tenderId);
|
||||
_hydratedFeedbackTenderIds.add(tenderId);
|
||||
} else {
|
||||
_feedbackErrorMessage = result.error.toString();
|
||||
}
|
||||
break;
|
||||
}
|
||||
_feedbackHydrationsInFlight.remove(tenderId);
|
||||
notifyListeners();
|
||||
_errorMessage = null;
|
||||
notifyListeners();
|
||||
if (_feedbackErrorMessage != null) {
|
||||
_feedbackErrorMessage = null;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> toogleFeedback({
|
||||
Future<void> toggleFeedback({
|
||||
required String tenderId,
|
||||
required String feedbackType,
|
||||
}) async {
|
||||
if (_feedbackRequestsInFlight.contains(tenderId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_feedbackErrorMessage = null;
|
||||
_feedbackRequestsInFlight.add(tenderId);
|
||||
|
||||
final existingFeedback = getFeedbackForTender(tenderId);
|
||||
final existingFeedbackIndex = feedbacks.indexWhere(
|
||||
@@ -335,13 +364,13 @@ class TendersViewModel with ChangeNotifier {
|
||||
if (existingFeedback == null) {
|
||||
optimisticFeedback = FeedbackData(
|
||||
companyId: null,
|
||||
createdAt: DateTime.now().millisecondsSinceEpoch,
|
||||
createdAt: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
customerId: null,
|
||||
feedbackType: feedbackType,
|
||||
id: null,
|
||||
tenderId: tenderId,
|
||||
tender: null,
|
||||
updatedAt: DateTime.now().millisecondsSinceEpoch,
|
||||
updatedAt: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
);
|
||||
feedbacks.add(optimisticFeedback);
|
||||
} else {
|
||||
@@ -353,7 +382,7 @@ class TendersViewModel with ChangeNotifier {
|
||||
} else {
|
||||
optimisticFeedback = existingFeedback.copyWith(
|
||||
feedbackType: feedbackType,
|
||||
updatedAt: DateTime.now().millisecondsSinceEpoch,
|
||||
updatedAt: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
);
|
||||
if (existingFeedbackIndex != -1) {
|
||||
feedbacks[existingFeedbackIndex] = optimisticFeedback;
|
||||
@@ -371,9 +400,13 @@ class TendersViewModel with ChangeNotifier {
|
||||
switch (result) {
|
||||
case Ok<FeedbackResponse>():
|
||||
_feedbackData = result.value.data;
|
||||
if (_feedbackData != null) {
|
||||
final responseType = _feedbackData?.feedbackType;
|
||||
if (responseType == 'unlike' || responseType == 'undislike') {
|
||||
feedbacks.removeWhere((feedback) => feedback.tenderId == tenderId);
|
||||
_feedbackData = null;
|
||||
} else if (_feedbackData != null) {
|
||||
final index = feedbacks.indexWhere(
|
||||
(f) => f.tender == _feedbackData!.tender,
|
||||
(feedback) => feedback.tenderId == tenderId,
|
||||
);
|
||||
if (index != -1) {
|
||||
feedbacks[index] = _feedbackData!;
|
||||
@@ -383,6 +416,7 @@ class TendersViewModel with ChangeNotifier {
|
||||
} else {
|
||||
feedbacks.removeWhere((f) => f.tenderId == tenderId);
|
||||
}
|
||||
_hydratedFeedbackTenderIds.add(tenderId);
|
||||
break;
|
||||
case Error<FeedbackResponse>():
|
||||
if (existingFeedback == null) {
|
||||
@@ -401,13 +435,24 @@ class TendersViewModel with ChangeNotifier {
|
||||
break;
|
||||
}
|
||||
|
||||
_feedbackRequestsInFlight.remove(tenderId);
|
||||
notifyListeners();
|
||||
_feedbackErrorMessage = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Kept temporarily for callers compiled against the old misspelled API.
|
||||
@Deprecated('Use toggleFeedback')
|
||||
Future<void> toogleFeedback({
|
||||
required String tenderId,
|
||||
required String feedbackType,
|
||||
}) => toggleFeedback(tenderId: tenderId, feedbackType: feedbackType);
|
||||
|
||||
void clearFeedbacks() {
|
||||
feedbacks.clear();
|
||||
_hydratedFeedbackTenderIds.clear();
|
||||
_feedbackHydrationsInFlight.clear();
|
||||
_feedbackRequestsInFlight.clear();
|
||||
_feedbackData = null;
|
||||
_feedbackErrorMessage = null;
|
||||
notifyListeners();
|
||||
|
||||
Reference in New Issue
Block a user