From 23700d0adf2a9c71c7abcd6abb874f3c96af1033 Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Tue, 19 Dec 2023 10:19:52 +0300 Subject: [PATCH] Enhancements on Asset Details Screen (SHOW MODEL NAME & FIX DATES FORMAT) --- lib/controllers/api_routes/urls.dart | 1 + lib/extensions/string_extensions.dart | 9 ++ lib/l10n/app_ar.arb | 7 +- lib/l10n/app_en.arb | 7 +- lib/main.dart | 2 + .../commissioning_status_provider.dart | 36 +++++++ .../device_transfer/asset_filter_screen.dart | 13 ++- .../widgets/equipment/asset_detail_page.dart | 96 +++++++++---------- .../equipment/asset_item_listview.dart | 2 + ...dart => commissioning_status_buttons.dart} | 46 ++++++--- 10 files changed, 145 insertions(+), 74 deletions(-) create mode 100644 lib/providers/service_request_providers/commissioning_status_provider.dart rename lib/views/widgets/equipment/{equipment_status_buttons.dart => commissioning_status_buttons.dart} (69%) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index c3690601..b209b104 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -47,6 +47,7 @@ class URLs { static get getRepairLocation => "$_baseUrl/Lookups/GetLookup?lookupEnum=504"; static get equipmentStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=601"; + static get commissioningStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=601"; static get getDateOperators => "$_baseUrl/Lookups/GetLookup?lookupEnum=200"; diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 6c1a9a7d..5a656ca5 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -14,4 +14,13 @@ extension StringExtensions on String { return "null"; } } + + String get toAssetDetailsFormat { + try { + DateTime dateTime = DateTime.tryParse(this); + return DateFormat('dd MMM, yyyy').format(dateTime); + } catch (e) { + return "-"; + } + } } diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index fee6f5e8..5a40d2d9 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -89,6 +89,7 @@ "maintenanceIssueRequired": "مطلوب مسألة صيانة", "maxImagesNumberIs5": "أقصى عدد للصورة 5", "model": "نموذج", + "modelNo": "رقم النموذج", "nameExist": "الاسم موجود", "newServiceRequest": "طلب خدمة جديدة", "newWord": "جديد", @@ -288,6 +289,7 @@ "supplier" : "المزود", "md": "تعريف النموذج", "snNumber" : "الرقم التسلسلي", + "snNo" : "الرقم التسلسلي", "oracleCode" : "رمز اوراكل", "filter" : "تصفية", "byDepartment" : "حسب القسم", @@ -376,5 +378,8 @@ "recentActivities" : "الأنشطة الحالية", "problemDesc" : "وصف المشكلة", "source": "المصدر", - "costCodeName" : "اسم رمز التكلفة" + "costCodeName" : "اسم رمز التكلفة", + "installationDate" : "تاريخ التثبيت", + "nextPmDate" : "موعد الزيارة الوقائية التالية", + "lastPmDate" : "موعد الزيارة الوقائية الأخيرة" } \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 93773057..c240db97 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -89,6 +89,7 @@ "maintenanceIssueRequired": "maintenance Issue Required", "maxImagesNumberIs5": "Maximum Images Number Is 5", "model": "Model", + "modelNo": "Model No.", "nameExist": "Name Exist", "newServiceRequest": "New Service Request", "newWord": "New", @@ -293,6 +294,7 @@ "supplier" : "Supplier", "md": "MD", "snNumber" : "SN Number", + "snNo" : "SN No.", "oracleCode" : "Oracle Code", "filter" : "Filter", "byDepartment" : "By Department", @@ -379,5 +381,8 @@ "recentActivities" : "Recent Activities", "problemDesc" : "Problem Description", "source": "Source", - "costCodeName" : "Cost Code Name" + "costCodeName" : "Cost Code Name", + "installationDate" : "Installation Date", + "nextPmDate" : "Next PM Date", + "lastPmDate" : "Last PM Date" } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 5c35ee08..a2babaf6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -59,6 +59,7 @@ import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/providers/ppm_checklist_status_provider.dart'; import 'package:test_sa/providers/ppm_device_status_provider.dart'; import 'package:test_sa/providers/ppm_visit_status_provider.dart'; +import 'package:test_sa/providers/service_request_providers/commissioning_status_provider.dart'; import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart'; import 'package:test_sa/providers/service_request_providers/first_action_provider.dart'; import 'package:test_sa/providers/service_request_providers/priority_provider.dart'; @@ -181,6 +182,7 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (_) => ServiceReportAssistantsEmployeeProvider()), ChangeNotifierProvider(create: (_) => PriorityProvider()), ChangeNotifierProvider(create: (_) => EquipmentStatusProvider()), + ChangeNotifierProvider(create: (_) => CommissioningStatusProvider()), ChangeNotifierProvider(create: (_) => RequestedThroughProvider()), ChangeNotifierProvider(create: (_) => TypeOfRequestProvider()), ChangeNotifierProvider(create: (_) => FirstActionStatusProvider()), diff --git a/lib/providers/service_request_providers/commissioning_status_provider.dart b/lib/providers/service_request_providers/commissioning_status_provider.dart new file mode 100644 index 00000000..648e82a0 --- /dev/null +++ b/lib/providers/service_request_providers/commissioning_status_provider.dart @@ -0,0 +1,36 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; +import 'package:test_sa/providers/loading_list_notifier.dart'; + +import '../../controllers/api_routes/api_manager.dart'; +import '../../controllers/api_routes/urls.dart'; +import '../../models/lookup.dart'; + +class CommissioningStatusProvider extends LoadingListNotifier { + @override + Future getDate() async { + if (loading == true) return -2; + loading = true; + notifyListeners(); + loading = true; + notifyListeners(); + try { + Response response = await ApiManager.instance.get(URLs.commissioningStatus); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List categoriesListJson = json.decode(response.body)["data"]; + items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList(); + } + loading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + loading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } +} diff --git a/lib/views/pages/device_transfer/asset_filter_screen.dart b/lib/views/pages/device_transfer/asset_filter_screen.dart index 0eb69164..39c75fc8 100644 --- a/lib/views/pages/device_transfer/asset_filter_screen.dart +++ b/lib/views/pages/device_transfer/asset_filter_screen.dart @@ -5,8 +5,10 @@ import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/new_models/department.dart'; import 'package:test_sa/models/new_models/site.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; import 'package:test_sa/providers/department_provider.dart'; @@ -16,7 +18,7 @@ import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; import '../../../models/device/asset_search.dart'; import '../../../new_views/common_widgets/app_lazy_loading.dart'; import '../../../new_views/common_widgets/default_app_bar.dart'; -import '../../widgets/equipment/equipment_status_buttons.dart'; +import '../../widgets/equipment/commissioning_status_buttons.dart'; class AssetFilterScreen extends StatefulWidget { static const String id = "asset_filter_screen"; @@ -30,10 +32,10 @@ class AssetFilterScreen extends StatefulWidget { class _AssetFilterScreenState extends State { AssetSearch filter; + Lookup _commissioningStatus; Site _site; Department _department; String startDate, endDate; - int initialValue; bool loading = false; @override @@ -68,7 +70,7 @@ class _AssetFilterScreenState extends State { children: [ Text( context.translation.reset, - style: AppTextStyles.bodyText2.copyWith(color: const Color(0xFF4A8DB7)), + style: AppTextStyles.bodyText2.copyWith(color: AppColor.primary50), ).paddingAll(8).onPress(() { setState(() { startDate = null; @@ -88,13 +90,14 @@ class _AssetFilterScreenState extends State { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ /// todo : TBD - EquipmentStatusButtons( + CommissioningStatusButtons( + initialValue: _commissioningStatus, onSelect: (value) { if (value == null) { /// the selected value is [All Assets] } + _commissioningStatus = value; }, - initialvalue: initialValue, ), 16.height, SingleItemDropDownMenu( diff --git a/lib/views/widgets/equipment/asset_detail_page.dart b/lib/views/widgets/equipment/asset_detail_page.dart index b488e213..fedd440d 100644 --- a/lib/views/widgets/equipment/asset_detail_page.dart +++ b/lib/views/widgets/equipment/asset_detail_page.dart @@ -4,6 +4,7 @@ import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/providers/api/devices_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/device/asset_by_id_model.dart'; @@ -12,6 +13,7 @@ import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/failed_loading.dart'; import '../../../new_views/app_style/app_color.dart'; +import '../requests/request_status.dart'; class AssetDetailPage extends StatefulWidget { static const String id = "/asset-details"; @@ -71,7 +73,7 @@ class _AssetDetailPageState extends State { width: 95, height: 95, decoration: ShapeDecoration( - color: const Color(0xFFEAF1F4), + color: AppColor.neutral30, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), @@ -87,64 +89,52 @@ class _AssetDetailPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - _assetProvider.assetById?.modelDefinition?.assetName ?? "-".heading5(context), - ), + if (_assetProvider.assetById.commissioningStatus != null) + StatusLabel( + label: _assetProvider.assetById.commissioningStatus.name, + textColor: AppColor.getRequestStatusTextColorByName(context, _assetProvider.assetById.commissioningStatus.name), + backgroundColor: AppColor.getRequestStatusColorByName(context, _assetProvider.assetById.commissioningStatus.name), + ), + if (_assetProvider.assetById.commissioningStatus != null) 8.height, + (_assetProvider.assetById?.modelDefinition?.assetName ?? "-").heading5(context), 8.height, - "${context.translation.assetNumber}: ${_assetProvider.assetById.multiAssets.first.assetNumber}".bodyText(context), - "${context.translation.model}: ${_assetProvider.assetById.modelDefinition.modelDefCode}".bodyText(context), - Text( - "${context.translation.serialNo}: ${_assetProvider.assetById.multiAssets.first.assetSerialNo}", - maxLines: 2, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : Color(0xFF757575)), - ), - Text( - "MD: ${_assetProvider.assetById.department.departmentName ?? "-"}", - maxLines: 2, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : Color(0xFF757575)), - ), - Text( - "Supplier: ${_assetProvider.assetById.supplier?.suppliername ?? "-"}", - maxLines: 2, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : Color(0xFF757575)), - ), - Text( - "Manufacturer: ${_assetProvider.assetById.modelDefinition.manufacturerName}", - maxLines: 2, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : Color(0xFF757575)), - ), - Text( - "Location: ${_assetProvider.assetById.site.custName}", - maxLines: 2, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : Color(0xFF757575)), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "${context.translation.assetNo}: ${_assetProvider.assetById.multiAssets.first.assetNumber}".bodyText(context), + "${context.translation.modelNo}: ${_assetProvider.assetById.modelDefinition.modelDefCode}".bodyText(context), + "${context.translation.supplier}: ${_assetProvider.assetById.supplier?.suppliername ?? "-"}".bodyText(context), + "${context.translation.manufacture}: ${_assetProvider.assetById.modelDefinition.manufacturerName}".bodyText(context), + "${context.translation.location}: ${_assetProvider.assetById.site.custName}".bodyText(context), + ], + ).expanded, + 8.width, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + /// TODO: theres no [ORACLE CODE] available to preview + // "${context.translation.oracleCode}: ${"-"}".bodyText(context), + "${context.translation.snNo}: ${_assetProvider.assetById.multiAssets.first.assetSerialNo}".bodyText(context), + "${context.translation.site}: ${_assetProvider.assetById?.site?.custName ?? "-"}".bodyText(context), + "${context.translation.md}: ${_assetProvider.assetById?.modelDefinition?.modelName ?? "-"}".bodyText(context), + ], + ).expanded, + ], ), 8.height, - const Divider(color: Color(0xFFEAF1F4), height: 1, thickness: 1), + const Divider(color: AppColor.neutral30, height: 1, thickness: 1), 8.height, - Text( - "Installation Date: ${_assetProvider.assetById.installationDate ?? "-"}", - maxLines: 2, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : Color(0xFF757575)), - ), - Text( - "Next PM Date: ${_assetProvider.assetById.installationDate ?? "-"}", - maxLines: 2, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : Color(0xFF757575)), - ), - Text( - "Last PM Date: ${_assetProvider.assetById.installationDate ?? "-"}", - maxLines: 2, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : Color(0xFF757575)), - ), + "${context.translation.installationDate}: ${_assetProvider.assetById.installationDate.toAssetDetailsFormat ?? "-"}".bodyText(context), + "${context.translation.nextPmDate}: ${_assetProvider.assetById.installationDate.toAssetDetailsFormat}".bodyText(context), + "${context.translation.lastPmDate}: ${_assetProvider.assetById.installationDate.toAssetDetailsFormat}".bodyText(context), if ((_assetProvider.assetById.modelDefinition.assetDescription ?? "").isNotEmpty) ...[ 8.height, - const Divider(color: Color(0xFFEAF1F4), height: 1, thickness: 1), + const Divider(color: AppColor.neutral30, height: 1, thickness: 1), 8.height, - Text( - _assetProvider.assetById.modelDefinition.assetDescription ?? "-", - maxLines: 2, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : Color(0xFF757575)), - ), + _assetProvider.assetById.modelDefinition.assetDescription.bodyText(context), ] ], ) @@ -152,7 +142,7 @@ class _AssetDetailPageState extends State { ).toShadowContainer(context), ); } - return Center(child: ALoading()); + return const Center(child: ALoading()); }, ), ); diff --git a/lib/views/widgets/equipment/asset_item_listview.dart b/lib/views/widgets/equipment/asset_item_listview.dart index 7a49b22f..134bf0cd 100644 --- a/lib/views/widgets/equipment/asset_item_listview.dart +++ b/lib/views/widgets/equipment/asset_item_listview.dart @@ -39,6 +39,7 @@ class AssetItemListView extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ device.modelDefinition.assetName.heading6(context), + 8.height, "${context.translation.assetNumber} : ${device.assetNumber}".bodyText(context), "${context.translation.model} : ${device.modelDefinition.modelDefCode}".bodyText(context), ], @@ -47,6 +48,7 @@ class AssetItemListView extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, children: [ "${context.translation.serialNo} : ${device.assetSerialNo}".bodyText(context).expanded, + 4.width, Row( mainAxisSize: MainAxisSize.min, children: [ diff --git a/lib/views/widgets/equipment/equipment_status_buttons.dart b/lib/views/widgets/equipment/commissioning_status_buttons.dart similarity index 69% rename from lib/views/widgets/equipment/equipment_status_buttons.dart rename to lib/views/widgets/equipment/commissioning_status_buttons.dart index 9e1b6b0e..4a7f8040 100644 --- a/lib/views/widgets/equipment/equipment_status_buttons.dart +++ b/lib/views/widgets/equipment/commissioning_status_buttons.dart @@ -8,29 +8,47 @@ import 'package:test_sa/extensions/widget_extensions.dart'; import '../../../models/lookup.dart'; import '../../../new_views/app_style/app_color.dart'; -import '../../../providers/service_request_providers/equipment_status_provider.dart'; +import '../../../providers/service_request_providers/commissioning_status_provider.dart'; -class EquipmentStatusButtons extends StatefulWidget { +class CommissioningStatusButtons extends StatefulWidget { final Function(Lookup) onSelect; - int initialvalue; + final Lookup initialValue; - EquipmentStatusButtons({Key key, this.onSelect, this.initialvalue}) : super(key: key); + CommissioningStatusButtons({Key key, this.onSelect, this.initialValue}) : super(key: key); @override - State createState() => _EquipmentStatusButtonsState(); + State createState() => _CommissioningStatusButtonsState(); } -class _EquipmentStatusButtonsState extends State { - //int _selectedEquipmentStatusIndex = 0; +class _CommissioningStatusButtonsState extends State { + int _selectedIndex = 0; @override void initState() { super.initState(); WidgetsFlutterBinding.ensureInitialized().addPostFrameCallback((timeStamp) { - Provider.of(context, listen: false).getDate(); + final provider = Provider.of(context, listen: false); + provider.getDate().then((value) { + if (widget.initialValue != null) _selectedIndex = provider.items.indexOf(widget.initialValue); + setState(() {}); + }); }); } + @override + void didUpdateWidget(covariant CommissioningStatusButtons oldWidget) { + if (widget.initialValue != oldWidget.initialValue) { + final provider = Provider.of(context, listen: false); + if (widget.initialValue != null) { + _selectedIndex = provider.items.indexOf(widget.initialValue); + } else { + _selectedIndex = 0; + } + setState(() {}); + } + super.didUpdateWidget(oldWidget); + } + @override Widget build(BuildContext context) { return Column( @@ -38,7 +56,7 @@ class _EquipmentStatusButtonsState extends State { children: [ context.translation.jopStatus.heading5(context).paddingOnly(start: 16, end: 16), 8.height, - Consumer( + Consumer( builder: (context, snapshot, _) { return snapshot.loading ? Shimmer( @@ -62,9 +80,9 @@ class _EquipmentStatusButtonsState extends State { padding: EdgeInsetsDirectional.only(start: 16.toScreenWidth), itemBuilder: (context, index) => Container( margin: EdgeInsets.symmetric(horizontal: 4.toScreenWidth), - padding: EdgeInsets.symmetric(vertical: 8.toScreenHeight, horizontal: (widget.initialvalue == index ? 12 : 8).toScreenWidth), + padding: EdgeInsets.symmetric(vertical: 8.toScreenHeight, horizontal: (_selectedIndex == index ? 12 : 8).toScreenWidth), alignment: Alignment.center, - foregroundDecoration: widget.initialvalue != index + foregroundDecoration: _selectedIndex != index ? null : ShapeDecoration( color: (context.isDark ? AppColor.neutral30 : AppColor.neutral50).withOpacity(0.1), @@ -74,9 +92,9 @@ class _EquipmentStatusButtonsState extends State { ), ), decoration: ShapeDecoration( - color: widget.initialvalue == index ? AppColor.selectedButtonColor(context) : AppColor.unSelectedButtonColor(context), + color: _selectedIndex == index ? AppColor.selectedButtonColor(context) : AppColor.unSelectedButtonColor(context), shape: RoundedRectangleBorder( - side: widget.initialvalue == index ? BorderSide(width: 1, color: AppColor.blueStatus(context)) : BorderSide.none, + side: _selectedIndex == index ? BorderSide(width: 1, color: AppColor.blueStatus(context)) : BorderSide.none, borderRadius: BorderRadius.circular(7), ), shadows: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 14, offset: const Offset(0, 0), spreadRadius: 0)], @@ -84,7 +102,7 @@ class _EquipmentStatusButtonsState extends State { child: (index == 0 ? "All Assets" : snapshot.items[index - 1].name).tinyFont(context).custom(color: AppColor.filterButtonTextColor(context)), ).onPress(() { setState(() { - widget.initialvalue = index; + _selectedIndex = index; }); widget.onSelect(index == 0 ? null : snapshot.items[index - 1]); }),