diff --git a/android/app/src/main/java/com/example/petstoremobile/adapters/ServiceAdapter.java b/android/app/src/main/java/com/example/petstoremobile/adapters/ServiceAdapter.java index 15bc005d..8ac809d2 100644 --- a/android/app/src/main/java/com/example/petstoremobile/adapters/ServiceAdapter.java +++ b/android/app/src/main/java/com/example/petstoremobile/adapters/ServiceAdapter.java @@ -1,30 +1,65 @@ package com.example.petstoremobile.adapters; import android.view.LayoutInflater; +import android.view.View; import android.view.ViewGroup; + import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; + import com.example.petstoremobile.databinding.ItemServiceBinding; import com.example.petstoremobile.dtos.ServiceDTO; +import com.example.petstoremobile.utils.BulkDeleteHandler; +import com.example.petstoremobile.utils.SelectionHelper; + import java.util.List; -public class ServiceAdapter extends RecyclerView.Adapter { +/** + * Adapter class for displaying a list of services in a RecyclerView. + */ +public class ServiceAdapter extends RecyclerView.Adapter implements BulkDeleteHandler.SelectableAdapter { - private List serviceList; - private OnServiceClickListener serviceClickListener; + private final List serviceList; + private final OnServiceClickListener clickListener; + private final SelectionHelper selectionHelper; - // Interface for service click on recycler view + /** + * Interface for handling clicks on service items. + */ public interface OnServiceClickListener { void onServiceClick(int position); + void onSelectionChanged(int count); } - //Constructor - public ServiceAdapter(List serviceList, OnServiceClickListener serviceClickListener) { - this.serviceList = serviceList; - this.serviceClickListener = serviceClickListener; + public ServiceAdapter(List serviceList, OnServiceClickListener clickListener) { + this.serviceList = serviceList; + this.clickListener = clickListener; + this.selectionHelper = new SelectionHelper(new SelectionHelper.SelectionListener() { + @Override + public void onSelectionChanged(int count) { + clickListener.onSelectionChanged(count); + } + + @Override + public void onSelectionModeToggle(boolean selectionMode) { + notifyDataSetChanged(); + } + }); } - // Get the controls of each row in recycler view + @Override + public List getSelectedIds() { + return selectionHelper.getSelectedIds(); + } + + @Override + public void clearSelection() { + selectionHelper.clearSelection(); + } + + /** + * ViewHolder class for service items. + */ public static class ServiceViewHolder extends RecyclerView.ViewHolder { final ItemServiceBinding binding; @@ -50,15 +85,37 @@ public class ServiceAdapter extends RecyclerView.Adapter serviceClickListener.onServiceClick(position)); + // Bulk delete selection mode + if (selectionHelper.isInSelectionMode()) { + binding.cbSelectService.setVisibility(View.VISIBLE); + binding.cbSelectService.setChecked(selectionHelper.isSelected(service.getServiceId())); + } else { + binding.cbSelectService.setVisibility(View.GONE); + binding.cbSelectService.setChecked(false); + } + + holder.itemView.setOnClickListener(v -> { + if (selectionHelper.isInSelectionMode()) { + selectionHelper.toggleSelection(service.getServiceId()); + notifyItemChanged(position); + } else { + clickListener.onServiceClick(position); + } + }); + + holder.itemView.setOnLongClickListener(v -> { + if (!selectionHelper.isInSelectionMode()) { + selectionHelper.startSelection(service.getServiceId()); + } + return true; + }); } @Override public int getItemCount() { return serviceList.size(); } -} \ No newline at end of file +} diff --git a/android/app/src/main/java/com/example/petstoremobile/adapters/SupplierAdapter.java b/android/app/src/main/java/com/example/petstoremobile/adapters/SupplierAdapter.java index ce41d60e..d932044b 100644 --- a/android/app/src/main/java/com/example/petstoremobile/adapters/SupplierAdapter.java +++ b/android/app/src/main/java/com/example/petstoremobile/adapters/SupplierAdapter.java @@ -1,27 +1,56 @@ package com.example.petstoremobile.adapters; import android.view.LayoutInflater; +import android.view.View; import android.view.ViewGroup; + import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; + import com.example.petstoremobile.databinding.ItemSupplierBinding; import com.example.petstoremobile.dtos.SupplierDTO; +import com.example.petstoremobile.utils.BulkDeleteHandler; +import com.example.petstoremobile.utils.SelectionHelper; + import java.util.List; -public class SupplierAdapter extends RecyclerView.Adapter { +public class SupplierAdapter extends RecyclerView.Adapter implements BulkDeleteHandler.SelectableAdapter { - private List supplierList; - private OnSupplierClickListener supplierClickListener; + private final List supplierList; + private final OnSupplierClickListener supplierClickListener; + private final SelectionHelper selectionHelper; // Interface for supplier click on recycler view public interface OnSupplierClickListener { void onSupplierClick(int position); + void onSelectionChanged(int count); } //Constructor public SupplierAdapter(List supplierList, OnSupplierClickListener supplierClickListener) { this.supplierList = supplierList; this.supplierClickListener = supplierClickListener; + this.selectionHelper = new SelectionHelper(new SelectionHelper.SelectionListener() { + @Override + public void onSelectionChanged(int count) { + supplierClickListener.onSelectionChanged(count); + } + + @Override + public void onSelectionModeToggle(boolean selectionMode) { + notifyDataSetChanged(); + } + }); + } + + @Override + public List getSelectedIds() { + return selectionHelper.getSelectedIds(); + } + + @Override + public void clearSelection() { + selectionHelper.clearSelection(); } // Get the controls of each row in recycler view @@ -53,12 +82,35 @@ public class SupplierAdapter extends RecyclerView.Adapter supplierClickListener.onSupplierClick(position)); + holder.itemView.setOnClickListener(v -> { + if (selectionHelper.isInSelectionMode()) { + selectionHelper.toggleSelection(supplier.getSupId()); + notifyItemChanged(position); + } else { + supplierClickListener.onSupplierClick(position); + } + }); + + holder.itemView.setOnLongClickListener(v -> { + if (!selectionHelper.isInSelectionMode()) { + selectionHelper.startSelection(supplier.getSupId()); + } + return true; + }); } @Override public int getItemCount() { return supplierList.size(); } -} \ No newline at end of file +} diff --git a/android/app/src/main/java/com/example/petstoremobile/api/ServiceApi.java b/android/app/src/main/java/com/example/petstoremobile/api/ServiceApi.java index b659a95f..43014a53 100644 --- a/android/app/src/main/java/com/example/petstoremobile/api/ServiceApi.java +++ b/android/app/src/main/java/com/example/petstoremobile/api/ServiceApi.java @@ -1,5 +1,6 @@ package com.example.petstoremobile.api; +import com.example.petstoremobile.dtos.BulkDeleteRequest; import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.ServiceDTO; @@ -7,6 +8,7 @@ import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.DELETE; import retrofit2.http.GET; +import retrofit2.http.HTTP; import retrofit2.http.POST; import retrofit2.http.PUT; import retrofit2.http.Path; @@ -38,4 +40,8 @@ public interface ServiceApi { // Delete service @DELETE("api/v1/services/{id}") Call deleteService(@Path("id") Long id); + + // Bulk delete services + @HTTP(method = "DELETE", path = "api/v1/services", hasBody = true) + Call bulkDeleteServices(@Body BulkDeleteRequest request); } diff --git a/android/app/src/main/java/com/example/petstoremobile/api/SupplierApi.java b/android/app/src/main/java/com/example/petstoremobile/api/SupplierApi.java index 9f870a51..38e7675c 100644 --- a/android/app/src/main/java/com/example/petstoremobile/api/SupplierApi.java +++ b/android/app/src/main/java/com/example/petstoremobile/api/SupplierApi.java @@ -1,5 +1,6 @@ package com.example.petstoremobile.api; +import com.example.petstoremobile.dtos.BulkDeleteRequest; import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.SupplierDTO; @@ -7,6 +8,7 @@ import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.DELETE; import retrofit2.http.GET; +import retrofit2.http.HTTP; import retrofit2.http.POST; import retrofit2.http.PUT; import retrofit2.http.Path; @@ -38,4 +40,8 @@ public interface SupplierApi { // Delete supplier @DELETE("api/v1/suppliers/{id}") Call deleteSupplier(@Path("id") Long id); + + // Bulk delete suppliers + @HTTP(method = "DELETE", path = "api/v1/suppliers", hasBody = true) + Call bulkDeleteSuppliers(@Body BulkDeleteRequest request); } diff --git a/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/ServiceFragment.java b/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/ServiceFragment.java index bda282ce..0923e4b1 100644 --- a/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/ServiceFragment.java +++ b/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/ServiceFragment.java @@ -1,14 +1,6 @@ package com.example.petstoremobile.fragments.listfragments; import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.navigation.fragment.NavHostFragment; -import androidx.recyclerview.widget.LinearLayoutManager; - import android.text.Editable; import android.text.TextWatcher; import android.util.Log; @@ -17,11 +9,21 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.fragment.NavHostFragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import com.example.petstoremobile.R; import com.example.petstoremobile.adapters.ServiceAdapter; import com.example.petstoremobile.databinding.FragmentServiceBinding; import com.example.petstoremobile.dtos.ServiceDTO; import com.example.petstoremobile.fragments.ListFragment; +import com.example.petstoremobile.utils.BulkDeleteHandler; +import com.example.petstoremobile.utils.Resource; import com.example.petstoremobile.viewmodels.ServiceViewModel; import java.util.ArrayList; @@ -29,16 +31,28 @@ import java.util.List; import dagger.hilt.android.AndroidEntryPoint; +/** + * Fragment class for displaying a list of services in a RecyclerView. + */ @AndroidEntryPoint public class ServiceFragment extends Fragment implements ServiceAdapter.OnServiceClickListener { + private static final String TAG = "ServiceFragment"; + private static final int PAGE_SIZE = 20; + private FragmentServiceBinding binding; - private List serviceList = new ArrayList<>(); + private final List serviceList = new ArrayList<>(); private ServiceAdapter adapter; private ServiceViewModel viewModel; + private BulkDeleteHandler bulkDeleteHandler; + + // Pagination + private int currentPage = 0; + private boolean isLastPage = false; + private boolean isLoading = false; /** - * Initializes the fragment and its associated ServiceViewModel. + * Initializes the fragment and its associated ViewModel. */ @Override public void onCreate(@Nullable Bundle savedInstanceState) { @@ -58,12 +72,11 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic setupSearch(); setupSwipeRefresh(); setupFilterToggle(); - loadServiceData(); + setupBulkDelete(); + loadServices(true); - //Add button to opens the add dialog - binding.fabAddService.setOnClickListener(v -> openServiceDetails(-1)); + binding.fabAddService.setOnClickListener(v -> openDetail(null)); - //Make the hamburger button open the drawer from listFragment binding.btnHamburger.setOnClickListener(v -> { Fragment parent = getParentFragment(); if (parent != null) { @@ -77,6 +90,19 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic return binding.getRoot(); } + private void setupBulkDelete() { + bulkDeleteHandler = new BulkDeleteHandler( + this, + binding.layoutBulkDelete, + binding.tvSelectionCount, + binding.btnBulkDelete, + adapter, + "service", + viewModel::bulkDeleteServices, + () -> loadServices(true) + ); + } + @Override public void onDestroyView() { super.onDestroyView(); @@ -95,100 +121,121 @@ public class ServiceFragment extends Fragment implements ServiceAdapter.OnServic binding.layoutFilter.setVisibility(View.GONE); binding.btnToggleFilter.setImageResource(android.R.drawable.ic_menu_search); - // Reset search when closing + // Reset filters when closing binding.etSearchService.setText(""); } }); } /** - * Configures the search bar for filtering. + * Sets up the search bar for filtering. */ private void setupSearch() { binding.etSearchService.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) { - loadServiceData(); + loadServices(true); } @Override public void afterTextChanged(Editable s) {} }); } /** - * Sets up the SwipeRefreshLayout to allow manual reloading of service data. + * Initializes the RecyclerView with a layout manager and adapter. + */ + private void setupRecyclerView() { + adapter = new ServiceAdapter(serviceList, this); + binding.recyclerViewServices.setLayoutManager(new LinearLayoutManager(getContext())); + binding.recyclerViewServices.setAdapter(adapter); + + binding.recyclerViewServices.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + if (dy <= 0) return; + LinearLayoutManager lm = (LinearLayoutManager) binding.recyclerViewServices.getLayoutManager(); + if (lm == null) return; + int visible = lm.getChildCount(); + int total = lm.getItemCount(); + int firstVis = lm.findFirstVisibleItemPosition(); + if (!isLoading && !isLastPage && (visible + firstVis) >= total - 3) { + loadServices(false); + } + } + }); + } + + /** + * Sets up the SwipeRefreshLayout. */ private void setupSwipeRefresh() { - binding.swipeRefreshService.setOnRefreshListener(this::loadServiceData); + binding.swipeRefreshService.setOnRefreshListener(() -> loadServices(true)); } /** - * Navigates to the service detail screen for editing an existing service or adding a new one. + * Fetches a page of services from the API. */ - private void openServiceDetails(int position) { - //Make a bundle to pass data to the detail fragment - Bundle args = new Bundle(); + private void loadServices(boolean reset) { + if (isLoading) return; - //if editing a service, add the service id to the bundle - if (position != -1) { - ServiceDTO service = serviceList.get(position); - args.putLong("serviceId", service.getServiceId()); + if (reset) { + currentPage = 0; + isLastPage = false; } - NavHostFragment.findNavController(this).navigate(R.id.nav_service_detail, args); - } - - /** - * Handles item click in the service list. - */ - @Override - public void onServiceClick(int position) { - openServiceDetails(position); - } - - /** - * Fetches all service data from the server through the ViewModel and updates the UI. - */ - private void loadServiceData() { - String query = binding.etSearchService != null ? binding.etSearchService.getText().toString().trim() : ""; + String query = binding.etSearchService.getText().toString().trim(); if (query.isEmpty()) query = null; - //Load services from the backend with query and default sort - viewModel.getAllServices(0, 100, query, "serviceName").observe(getViewLifecycleOwner(), resource -> { + viewModel.getAllServices(currentPage, PAGE_SIZE, query, "serviceName").observe(getViewLifecycleOwner(), resource -> { if (resource == null) return; - // Check the status to see if the resource is loaded and display the data switch (resource.status) { case LOADING: - // Show loading indicator + isLoading = true; binding.swipeRefreshService.setRefreshing(true); break; case SUCCESS: - // Hide loading indicator and display data + isLoading = false; binding.swipeRefreshService.setRefreshing(false); if (resource.data != null) { - serviceList.clear(); + if (reset) serviceList.clear(); serviceList.addAll(resource.data.getContent()); adapter.notifyDataSetChanged(); + isLastPage = resource.data.isLast(); + if (!isLastPage) currentPage++; } break; case ERROR: - // Hide loading indicator and toast error message + isLoading = false; binding.swipeRefreshService.setRefreshing(false); - if (getContext() != null) { - Toast.makeText(getContext(), "Failed to load services: " + resource.message, Toast.LENGTH_SHORT).show(); - } - Log.e("ServiceFragment", "Error loading services: " + resource.message); + Log.e(TAG, "Error: " + resource.message); + Toast.makeText(getContext(), "Failed to load services: " + resource.message, Toast.LENGTH_SHORT).show(); break; } }); } /** - * Initializes the RecyclerView with a layout manager and adapter for services. + * Navigates to the service detail screen. */ - private void setupRecyclerView() { - adapter = new ServiceAdapter(serviceList, this); - binding.recyclerViewServices.setLayoutManager(new LinearLayoutManager(getContext())); - binding.recyclerViewServices.setAdapter(adapter); + private void openDetail(ServiceDTO service) { + Bundle args = new Bundle(); + if (service != null) { + args.putLong("serviceId", service.getServiceId()); + } + NavHostFragment.findNavController(this).navigate(R.id.nav_service_detail, args); + } + + @Override + public void onServiceClick(int position) { + if (position >= 0 && position < serviceList.size()) { + openDetail(serviceList.get(position)); + } + } + + @Override + public void onSelectionChanged(int count) { + if (bulkDeleteHandler != null) { + bulkDeleteHandler.onSelectionChanged(count); + } } } diff --git a/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/SupplierFragment.java b/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/SupplierFragment.java index 3d2e038d..6d6f28ac 100644 --- a/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/SupplierFragment.java +++ b/android/app/src/main/java/com/example/petstoremobile/fragments/listfragments/SupplierFragment.java @@ -22,6 +22,8 @@ import com.example.petstoremobile.adapters.SupplierAdapter; import com.example.petstoremobile.databinding.FragmentSupplierBinding; import com.example.petstoremobile.dtos.SupplierDTO; import com.example.petstoremobile.fragments.ListFragment; +import com.example.petstoremobile.utils.BulkDeleteHandler; +import com.example.petstoremobile.utils.Resource; import com.example.petstoremobile.viewmodels.SupplierViewModel; import java.util.ArrayList; @@ -36,6 +38,7 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp private List supplierList = new ArrayList<>(); private SupplierAdapter adapter; private SupplierViewModel viewModel; + private BulkDeleteHandler bulkDeleteHandler; /** * Initializes the fragment and its associated SupplierViewModel. @@ -58,6 +61,7 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp setupSearch(); setupSwipeRefresh(); setupFilterToggle(); + setupBulkDelete(); loadSupplierData(); //Add button to opens the add dialog @@ -77,6 +81,19 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp return binding.getRoot(); } + private void setupBulkDelete() { + bulkDeleteHandler = new BulkDeleteHandler( + this, + binding.layoutBulkDelete, + binding.tvSelectionCount, + binding.btnBulkDelete, + adapter, + "supplier", + viewModel::bulkDeleteSuppliers, + this::loadSupplierData + ); + } + @Override public void onDestroyView() { super.onDestroyView(); @@ -146,6 +163,13 @@ public class SupplierFragment extends Fragment implements SupplierAdapter.OnSupp openSupplierDetails(position); } + @Override + public void onSelectionChanged(int count) { + if (bulkDeleteHandler != null) { + bulkDeleteHandler.onSelectionChanged(count); + } + } + /** * Fetches all supplier data from the server through the ViewModel and updates the UI. */ diff --git a/android/app/src/main/java/com/example/petstoremobile/repositories/ServiceRepository.java b/android/app/src/main/java/com/example/petstoremobile/repositories/ServiceRepository.java index 7787c36a..bd5f3ebc 100644 --- a/android/app/src/main/java/com/example/petstoremobile/repositories/ServiceRepository.java +++ b/android/app/src/main/java/com/example/petstoremobile/repositories/ServiceRepository.java @@ -3,6 +3,7 @@ package com.example.petstoremobile.repositories; import androidx.lifecycle.LiveData; import com.example.petstoremobile.api.ServiceApi; +import com.example.petstoremobile.dtos.BulkDeleteRequest; import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.ServiceDTO; import com.example.petstoremobile.utils.Resource; @@ -54,4 +55,11 @@ public class ServiceRepository extends BaseRepository { public LiveData> deleteService(Long id) { return executeCall(serviceApi.deleteService(id)); } + + /** + * Sends a request to the API to delete multiple services. + */ + public LiveData> bulkDeleteServices(BulkDeleteRequest request) { + return executeCall(serviceApi.bulkDeleteServices(request)); + } } diff --git a/android/app/src/main/java/com/example/petstoremobile/repositories/SupplierRepository.java b/android/app/src/main/java/com/example/petstoremobile/repositories/SupplierRepository.java index e4eb4c0c..7aef86a2 100644 --- a/android/app/src/main/java/com/example/petstoremobile/repositories/SupplierRepository.java +++ b/android/app/src/main/java/com/example/petstoremobile/repositories/SupplierRepository.java @@ -3,6 +3,7 @@ package com.example.petstoremobile.repositories; import androidx.lifecycle.LiveData; import com.example.petstoremobile.api.SupplierApi; +import com.example.petstoremobile.dtos.BulkDeleteRequest; import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.SupplierDTO; import com.example.petstoremobile.utils.Resource; @@ -54,4 +55,11 @@ public class SupplierRepository extends BaseRepository { public LiveData> deleteSupplier(Long id) { return executeCall(supplierApi.deleteSupplier(id)); } + + /** + * Sends a request to the API to delete multiple supplier records. + */ + public LiveData> bulkDeleteSuppliers(BulkDeleteRequest request) { + return executeCall(supplierApi.bulkDeleteSuppliers(request)); + } } diff --git a/android/app/src/main/java/com/example/petstoremobile/viewmodels/ServiceViewModel.java b/android/app/src/main/java/com/example/petstoremobile/viewmodels/ServiceViewModel.java index 142ac85b..3b74b047 100644 --- a/android/app/src/main/java/com/example/petstoremobile/viewmodels/ServiceViewModel.java +++ b/android/app/src/main/java/com/example/petstoremobile/viewmodels/ServiceViewModel.java @@ -3,11 +3,14 @@ package com.example.petstoremobile.viewmodels; import androidx.lifecycle.LiveData; import androidx.lifecycle.ViewModel; +import com.example.petstoremobile.dtos.BulkDeleteRequest; import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.ServiceDTO; import com.example.petstoremobile.repositories.ServiceRepository; import com.example.petstoremobile.utils.Resource; +import java.util.List; + import javax.inject.Inject; import dagger.hilt.android.lifecycle.HiltViewModel; @@ -55,4 +58,11 @@ public class ServiceViewModel extends ViewModel { public LiveData> deleteService(Long id) { return repository.deleteService(id); } + + /** + * Deletes multiple services. + */ + public LiveData> bulkDeleteServices(List ids) { + return repository.bulkDeleteServices(new BulkDeleteRequest(ids)); + } } diff --git a/android/app/src/main/java/com/example/petstoremobile/viewmodels/SupplierViewModel.java b/android/app/src/main/java/com/example/petstoremobile/viewmodels/SupplierViewModel.java index a89426de..dbffaffc 100644 --- a/android/app/src/main/java/com/example/petstoremobile/viewmodels/SupplierViewModel.java +++ b/android/app/src/main/java/com/example/petstoremobile/viewmodels/SupplierViewModel.java @@ -3,11 +3,14 @@ package com.example.petstoremobile.viewmodels; import androidx.lifecycle.LiveData; import androidx.lifecycle.ViewModel; +import com.example.petstoremobile.dtos.BulkDeleteRequest; import com.example.petstoremobile.dtos.PageResponse; import com.example.petstoremobile.dtos.SupplierDTO; import com.example.petstoremobile.repositories.SupplierRepository; import com.example.petstoremobile.utils.Resource; +import java.util.List; + import javax.inject.Inject; import dagger.hilt.android.lifecycle.HiltViewModel; @@ -55,4 +58,11 @@ public class SupplierViewModel extends ViewModel { public LiveData> deleteSupplier(Long id) { return repository.deleteSupplier(id); } + + /** + * Deletes multiple supplier records. + */ + public LiveData> bulkDeleteSuppliers(List ids) { + return repository.bulkDeleteSuppliers(new BulkDeleteRequest(ids)); + } } diff --git a/android/app/src/main/res/layout/fragment_inventory.xml b/android/app/src/main/res/layout/fragment_inventory.xml index 8197078e..66cb7c0e 100644 --- a/android/app/src/main/res/layout/fragment_inventory.xml +++ b/android/app/src/main/res/layout/fragment_inventory.xml @@ -106,6 +106,7 @@ + android:paddingBottom="4dp" + android:visibility="gone"> + android:textColor="@color/white"/>