diff --git a/lib/modules/tm_module/device_transfer/device_filter_screen.dart b/lib/modules/tm_module/device_transfer/device_filter_screen.dart index 5eef3a5a..899ba68d 100644 --- a/lib/modules/tm_module/device_transfer/device_filter_screen.dart +++ b/lib/modules/tm_module/device_transfer/device_filter_screen.dart @@ -75,22 +75,21 @@ class _DeviceFilterScreenState extends State { title: context.translation.filter, actions: [ if (loading == false && _showResetButton()) - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - context.translation.reset, - style: AppTextStyles.bodyText2.copyWith(color: AppColor.loadingColor(context)), - ).paddingAll(8).onPress(() { - setState(() { - startDate = null; - endDate = null; - _selectedDepartments = []; - _selectedSites = []; - }); - }), - ], - ) + TextButton( + onPressed: () { + setState(() { + startDate = null; + endDate = null; + _selectedDepartments = []; + _selectedSites = []; + }); + }, + style: TextButton.styleFrom(padding: EdgeInsets.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap), + child: Text( + 'Clear Filters', + style: AppTextStyles.bodyText2.copyWith(color: AppColor.primary10), + ), + ).paddingOnly(start: 16, end: 16) ], ), body: Column( diff --git a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart index 53a4089a..b4e06e08 100644 --- a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart +++ b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart @@ -141,24 +141,22 @@ class _AllRequestsFilterPageState extends State { title: context.translation.filter, actions: [ if (_showResetButton()) - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - context.translation.reset, - style: AppTextStyles.bodyText2.copyWith(color: AppColor.loadingColor(context)), - ).paddingAll(8).onPress(() { - Provider.of(context, listen: false).searchedModel = null; - setState(() { - search?.statuses?.clear(); - search?.typeTransaction?.clear(); - search?.startDate = null; - search?.endDate = null; - search?.isArchived = false; - }); - }), - ], - ) + TextButton( + onPressed: () { + setState(() { + search?.statuses?.clear(); + search?.typeTransaction?.clear(); + search?.startDate = null; + search?.endDate = null; + search?.isArchived = false; + }); + }, + style: TextButton.styleFrom(padding: EdgeInsets.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap), + child: Text( + 'Clear Filters', + style: AppTextStyles.bodyText2.copyWith(color: AppColor.primary10), + ), + ).paddingOnly(start: 16, end: 16) ], ), body: Column( diff --git a/lib/new_views/pages/land_page/my_request/my_requests_page.dart b/lib/new_views/pages/land_page/my_request/my_requests_page.dart index b8b0c850..c790758d 100644 --- a/lib/new_views/pages/land_page/my_request/my_requests_page.dart +++ b/lib/new_views/pages/land_page/my_request/my_requests_page.dart @@ -186,6 +186,7 @@ class _MyRequestsPageState extends State { body: Consumer(builder: (context, snapshot, _) { return Column( children: [ + if (!_filterIsEmpty()) _buildActiveFiltersChips(), if (_filterIsEmpty()) SizedBox( height: 50.toScreenHeight, @@ -255,11 +256,331 @@ class _MyRequestsPageState extends State { (_search!.sn?.value?.isNotEmpty ?? false) || (_search!.statuses?.isNotEmpty ?? false) || (_search!.startDate != null) || - (_search!.endDate != null)) { + (_search!.endDate != null) || + (_search!.selectedSortOption?.isNotEmpty ?? false)) { return false; } return true; } + + Widget _buildActiveFiltersChips() { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + decoration: BoxDecoration( + color: AppColor.background(context), + border: Border( + bottom: BorderSide(color: AppColor.borderColor(context), width: 1), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Active Filters', + style: AppTextStyles.tinyFont2.copyWith(color: AppColor.labelTextStyleColor(context), fontWeight: FontWeight.w600), + ), + Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16, + children: [ + SizedBox( + height: 40.toScreenHeight, + child: ListView.separated( + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.only(top: 8, right: 0, left: 0, bottom: 0), + itemBuilder: (cxt, index) => _getActiveFilterChips()[index], + separatorBuilder: (cxt, index) => 8.width, + itemCount: _getActiveFilterChips().length), + ).expanded, + TextButton( + onPressed: _clearAllFilters, + style: TextButton.styleFrom(padding: EdgeInsets.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap), + child: Text( + 'Clear Filters', + style: AppTextStyles.tinyFont.copyWith(color: AppColor.primary10, fontWeight: FontWeight.w500), + ), + ), + ], + ) + ], + ), + ); + } + + List _getActiveFilterChips() { + List chips = []; + + // Request Number + if (_search?.requestNumber?.value?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.woNumber}: ${_search!.requestNumber!.value}', + onDelete: () { + setState(() { + _search!.requestNumber!.value = null; + _search!.requestNumber!.controller?.clear(); + _refreshWithFilters(); + }); + }, + )); + } + + // Asset Name + if (_search?.assetName?.value?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.assetName}: ${_search!.assetName!.value}', + onDelete: () { + setState(() { + _search!.assetName!.value = null; + _search!.assetName!.controller?.clear(); + _refreshWithFilters(); + }); + }, + )); + } + + // Asset Number + if (_search?.assetNo?.value?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.assetNo}: ${_search!.assetNo!.value}', + onDelete: () { + setState(() { + _search!.assetNo!.value = null; + _search!.assetNo!.controller?.clear(); + _refreshWithFilters(); + }); + }, + )); + } + + // Manufacturer + if (_search?.manufacture?.value?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.manufacture}: ${_search!.manufacture!.value}', + onDelete: () { + setState(() { + _search!.manufacture!.value = null; + _search!.manufacture!.controller?.clear(); + _refreshWithFilters(); + }); + }, + )); + } + + // Serial Number + if (_search?.sn?.value?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.sn}: ${_search!.sn!.value}', + onDelete: () { + setState(() { + _search!.sn!.value = null; + _search!.sn!.controller?.clear(); + _refreshWithFilters(); + }); + }, + )); + } + + // Model + if (_search?.model?.value?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.model}: ${_search!.model!.value}', + onDelete: () { + setState(() { + _search!.model!.value = null; + _search!.model!.controller?.clear(); + _refreshWithFilters(); + }); + }, + )); + } + + // Statuses + if (_search?.statuses?.isNotEmpty ?? false) { + for (var statusId in _search!.statuses!) { + String statusName = _getStatusName(statusId); + chips.add(_buildFilterChip( + label: 'Status: $statusName', + onDelete: () { + setState(() { + _search!.statuses!.remove(statusId); + _refreshWithFilters(); + }); + }, + )); + } + } + + // Type Transactions + if (_search?.typeTransaction?.isNotEmpty ?? false) { + for (var typeId in _search!.typeTransaction!) { + String typeName = _getTypeName(typeId); + chips.add(_buildFilterChip( + label: 'Type: $typeName', + onDelete: () { + setState(() { + _search!.typeTransaction!.remove(typeId); + _refreshWithFilters(); + }); + }, + )); + } + } + + // Date Range + if (_search?.startDate != null || _search?.endDate != null) { + String dateLabel = 'Date: '; + if (_search!.startDate != null && _search!.endDate != null) { + dateLabel += '${_formatDate(_search!.startDate!)} - ${_formatDate(_search!.endDate!)}'; + } else if (_search!.startDate != null) { + dateLabel += 'From ${_formatDate(_search!.startDate!)}'; + } else if (_search!.endDate != null) { + dateLabel += 'To ${_formatDate(_search!.endDate!)}'; + } + + chips.add(_buildFilterChip( + label: dateLabel, + onDelete: () { + setState(() { + _search!.startDate = null; + _search!.endDate = null; + _refreshWithFilters(); + }); + }, + )); + } + + // Sort Option + if (_search?.selectedSortOption?.isNotEmpty ?? false) { + String sortLabel = 'Sort: ${_getSortLabel(_search!.selectedSortOption!)}'; + chips.add(_buildFilterChip( + label: sortLabel, + showDelete: false, + )); + } + + return chips; + } + + Widget _buildFilterChip({required String label, VoidCallback? onDelete, bool showDelete = true}) { + return Theme( + data: Theme.of(context).copyWith(splashColor: Colors.transparent, highlightColor: Colors.transparent), + child: Chip( + backgroundColor: AppColor.backgroundTabBarColor(context), + side: BorderSide(color: AppColor.border2Color(context)), + label: Text(label), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)), + labelStyle: AppTextStyles.tinyFont2.copyWith(color: AppColor.labelTextStyleColor(context)), + deleteIconColor: showDelete ? AppColor.icon2Color(context) : null, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onDeleted: showDelete ? onDelete : null, + ), + ); + } + + String _getStatusName(int statusId) { + switch (statusId) { + case 0: + return "All WO"; + case 1: + return context.translation.open; + case 2: + return context.translation.inProgress; + case 3: + return context.translation.closed; + case 4: + return context.translation.completed; + case 5: + return "Canceled"; + default: + return "Status $statusId"; + } + } + + String _getTypeName(int typeId) { + switch (typeId) { + case 1: + return context.translation.correctiveMaintenance; + case 2: + return context.translation.gasRefill; + case 3: + return context.translation.transferAsset; + case 4: + return context.translation.preventiveMaintenance; + case 5: + return context.translation.recurrentWo; + case 6: + return context.translation.taskRequest; + case 7: + return 'Recall and Alert'; + case 8: + return 'Asset Inventory'; + case 9: + return 'TRAF'; + case 10: + return 'Equipment Internal Audit'; + case 11: + return 'System Internal Audit'; + case 12: + return 'Loan Equipment'; + case 13: + return 'Asset Delivery'; + case 14: + return 'Medical Gas Inspection'; + case 15: + return 'Demo'; + case 16: + return 'Incidents'; + default: + return "Type $typeId"; + } + } + + String _formatDate(DateTime date) { + return '${date.day}/${date.month}/${date.year}'; + } + + String _getSortLabel(String sortOption) { + switch (sortOption.toLowerCase()) { + case 'ascending': + return 'Ascending'; + case 'descending': + return 'Descending'; + default: + return sortOption; + } + } + + void _clearAllFilters() { + setState(() { + _search?.requestNumber?.value = null; + _search?.requestNumber?.controller?.clear(); + _search?.assetName?.value = null; + _search?.assetName?.controller?.clear(); + _search?.assetNo?.value = null; + _search?.assetNo?.controller?.clear(); + _search?.manufacture?.value = null; + _search?.manufacture?.controller?.clear(); + _search?.sn?.value = null; + _search?.sn?.controller?.clear(); + _search?.model?.value = null; + _search?.model?.controller?.clear(); + _search?.statuses?.clear(); + _search?.typeTransaction?.clear(); + _search?.startDate = null; + _search?.endDate = null; + _search?.isArchived = false; + _search?.selectedSortOption = null; + _search = null; // Clear the entire search object + _provider?.searchedModel = null; + _refreshWithFilters(); + }); + } + + void _refreshWithFilters() { + _provider?.reset(); + _provider?.getAllRequests(context, typeTransaction: requestsList[selectedRequest].id, search: _search); + } } class Request { diff --git a/lib/views/widgets/equipment/my_assets_page.dart b/lib/views/widgets/equipment/my_assets_page.dart index ff85da41..b1d9ea91 100644 --- a/lib/views/widgets/equipment/my_assets_page.dart +++ b/lib/views/widgets/equipment/my_assets_page.dart @@ -94,7 +94,7 @@ class _MyAssetsPageState extends State { Navigator.of(context).pop(); }), Container( - height: 40, + height: 40.toScreenHeight, padding: const EdgeInsets.only(left: 16, right: 8), alignment: Alignment.center, decoration: ShapeDecoration( @@ -169,6 +169,7 @@ class _MyAssetsPageState extends State { }, child: Column( children: [ + if (!_filterIsEmpty()) _buildActiveFiltersChips(), Expanded( child: _searchableList.isEmpty ? NoDataFound(message: context.translation.noDeviceFound).center @@ -237,4 +238,299 @@ class _MyAssetsPageState extends State { ), ); } + + bool _filterIsEmpty() { + if (_searchAsset == null) return true; + if ((_searchAsset!.assetName?.isNotEmpty ?? false) || + (_searchAsset!.assetNo?.isNotEmpty ?? false) || + (_searchAsset!.assetSerialNumber?.isNotEmpty ?? false) || + (_searchAsset!.model?.isNotEmpty ?? false) || + (_searchAsset!.supplier?.isNotEmpty ?? false) || + (_searchAsset!.site?.isNotEmpty ?? false) || + (_searchAsset!.manufacturer?.isNotEmpty ?? false) || + (_searchAsset!.modelDefinition?.isNotEmpty ?? false) || + (_searchAsset!.departments?.isNotEmpty ?? false) || + (_searchAsset!.sites?.isNotEmpty ?? false) || + (_searchAsset!.supplyDateFrom != null) || + (_searchAsset!.supplyDateTo != null)) { + return false; + } + return true; + } + + Widget _buildActiveFiltersChips() { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + decoration: BoxDecoration( + color: AppColor.background(context), + border: Border( + bottom: BorderSide(color: AppColor.borderColor(context), width: 1), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Active Filters', + style: AppTextStyles.tinyFont2.copyWith( + color: AppColor.labelTextStyleColor(context), + fontWeight: FontWeight.w600, + ), + ), + Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16, + children: [ + SizedBox( + height: 40.toScreenHeight, + child: ListView.separated( + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.only(top: 8, right: 0, left: 0, bottom: 0), + itemBuilder: (cxt, index) => _getActiveFilterChips()[index], + separatorBuilder: (cxt, index) => 8.width, + itemCount: _getActiveFilterChips().length, + ), + ).expanded, + TextButton( + onPressed: _clearAllFilters, + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + child: Text( + 'Clear Filters', + style: AppTextStyles.tinyFont.copyWith( + color: AppColor.primary10, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ) + ], + ), + ); + } + + List _getActiveFilterChips() { + List chips = []; + + // Asset Name + if (_searchAsset?.assetName?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.assetName}: ${_searchAsset!.assetName}', + onDelete: () { + setState(() { + _searchAsset!.assetName = null; + _refreshWithFilters(); + }); + }, + )); + } + + // Asset Number + if (_searchAsset?.assetNo?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.assetNumber}: ${_searchAsset!.assetNo}', + onDelete: () { + setState(() { + _searchAsset!.assetNo = null; + _refreshWithFilters(); + }); + }, + )); + } + + // Serial Number + if (_searchAsset?.assetSerialNumber?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.snNumber}: ${_searchAsset!.assetSerialNumber}', + onDelete: () { + setState(() { + _searchAsset!.assetSerialNumber = null; + _refreshWithFilters(); + }); + }, + )); + } + + // Model + if (_searchAsset?.model?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.model}: ${_searchAsset!.model}', + onDelete: () { + setState(() { + _searchAsset!.model = null; + _refreshWithFilters(); + }); + }, + )); + } + + // Supplier + if (_searchAsset?.supplier?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.supplier}: ${_searchAsset!.supplier}', + onDelete: () { + setState(() { + _searchAsset!.supplier = null; + _refreshWithFilters(); + }); + }, + )); + } + + // Site (single) + if (_searchAsset?.site?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.site}: ${_searchAsset!.site}', + onDelete: () { + setState(() { + _searchAsset!.site = null; + _refreshWithFilters(); + }); + }, + )); + } + + // Manufacturer + if (_searchAsset?.manufacturer?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.manufacture}: ${_searchAsset!.manufacturer}', + onDelete: () { + setState(() { + _searchAsset!.manufacturer = null; + _refreshWithFilters(); + }); + }, + )); + } + + // Model Definition + if (_searchAsset?.modelDefinition?.isNotEmpty ?? false) { + chips.add(_buildFilterChip( + label: '${context.translation.md}: ${_searchAsset!.modelDefinition}', + onDelete: () { + setState(() { + _searchAsset!.modelDefinition = null; + _refreshWithFilters(); + }); + }, + )); + } + + // Departments (multiple) + if (_searchAsset?.departments?.isNotEmpty ?? false) { + for (var dept in _searchAsset!.departments!) { + chips.add(_buildFilterChip( + label: '${context.translation.byDepartment}: $dept', + onDelete: () { + setState(() { + _searchAsset!.departments!.remove(dept); + _refreshWithFilters(); + }); + }, + )); + } + } + + // Sites (multiple) + if (_searchAsset?.sites?.isNotEmpty ?? false) { + for (var site in _searchAsset!.sites!) { + chips.add(_buildFilterChip( + label: '${context.translation.bySite}: $site', + onDelete: () { + setState(() { + _searchAsset!.sites!.remove(site); + _refreshWithFilters(); + }); + }, + )); + } + } + + // Date Range + if (_searchAsset?.supplyDateFrom != null || _searchAsset?.supplyDateTo != null) { + String dateLabel = 'Supply Date: '; + if (_searchAsset!.supplyDateFrom != null && _searchAsset!.supplyDateTo != null) { + dateLabel += '${_formatDate(_searchAsset!.supplyDateFrom!)} - ${_formatDate(_searchAsset!.supplyDateTo!)}'; + } else if (_searchAsset!.supplyDateFrom != null) { + dateLabel += 'From ${_formatDate(_searchAsset!.supplyDateFrom!)}'; + } else if (_searchAsset!.supplyDateTo != null) { + dateLabel += 'To ${_formatDate(_searchAsset!.supplyDateTo!)}'; + } + + chips.add(_buildFilterChip( + label: dateLabel, + onDelete: () { + setState(() { + _searchAsset!.supplyDateFrom = null; + _searchAsset!.supplyDateTo = null; + _refreshWithFilters(); + }); + }, + )); + } + + return chips; + } + + Widget _buildFilterChip({required String label, required VoidCallback onDelete}) { + return Theme( + data: Theme.of(context).copyWith( + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + ), + child: Chip( + backgroundColor: AppColor.backgroundTabBarColor(context), + side: BorderSide(color: AppColor.border2Color(context)), + label: Text(label), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + labelStyle: AppTextStyles.tinyFont2.copyWith( + color: AppColor.labelTextStyleColor(context), + ), + deleteIconColor: AppColor.icon2Color(context), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onDeleted: onDelete, + ), + ); + } + + String _formatDate(String dateString) { + try { + final date = DateTime.parse(dateString); + return '${date.day}/${date.month}/${date.year}'; + } catch (e) { + return dateString; + } + } + + void _clearAllFilters() { + setState(() { + _searchAsset?.assetName = null; + _searchAsset?.assetNo = null; + _searchAsset?.assetSerialNumber = null; + _searchAsset?.model = null; + _searchAsset?.supplier = null; + _searchAsset?.site = null; + _searchAsset?.manufacturer = null; + _searchAsset?.modelDefinition = null; + _searchAsset?.departments?.clear(); + _searchAsset?.sites?.clear(); + _searchAsset?.supplyDateFrom = null; + _searchAsset?.supplyDateTo = null; + _searchAsset = null; + _refreshWithFilters(); + }); + } + + void _refreshWithFilters() { + _devicesProvider.reset(); + _devicesProvider.getAssets(search: _searchAsset); + _searchableList.clear(); + _searchableList.addAll(_devicesProvider.devices); + } }