From 5b59ff5f5eda2b86ffadba7e2e05f3db238af776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Sa=CC=81nchez?= Date: Thu, 21 Nov 2019 08:22:55 +0100 Subject: [PATCH 01/11] Implement event filter by value in ProgramEventDetailRepository --- .../ProgramEventDetailRepository.java | 6 +- .../ProgramEventDetailRepositoryImpl.java | 61 ++++++++++++++++--- dhis2-android-sdk | 2 +- dhis2-rule-engine | 2 +- 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepository.java b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepository.java index e1e0ef4293..6261f2349e 100644 --- a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepository.java +++ b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepository.java @@ -12,6 +12,7 @@ import org.hisp.dhis.android.core.category.CategoryOptionCombo; import org.hisp.dhis.android.core.common.FeatureType; import org.hisp.dhis.android.core.common.State; +import org.hisp.dhis.android.core.dataelement.DataElement; import org.hisp.dhis.android.core.event.EventStatus; import org.hisp.dhis.android.core.period.DatePeriod; import org.hisp.dhis.android.core.program.Program; @@ -29,7 +30,7 @@ public interface ProgramEventDetailRepository { @NonNull - LiveData> filteredProgramEvents(List dateFilter, List orgUnitFilter, List catOptionComboUid, List eventStatus, List states); + LiveData> filteredProgramEvents(List dateFilter, List orgUnitFilter, List catOptionComboUid, List eventStatus, List states, Pair valueFilter); @NonNull Flowable> filteredEventsForMap(List dateFilter, List orgUnitFilter, List catOptionComboUid, List eventStatus, List states); @@ -41,6 +42,9 @@ public interface ProgramEventDetailRepository { Single>> catOptionCombos(); + @NonNull + Observable> textTypeDataElements(); + Single hasAccessToAllCatOptions(); Flowable getInfoForEvent(String eventUid); diff --git a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java index 1fe916a763..fc12e829f8 100644 --- a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java +++ b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java @@ -2,9 +2,11 @@ import static android.text.TextUtils.isEmpty; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import android.database.Cursor; + +import com.mapbox.geojson.BoundingBox; +import com.mapbox.geojson.FeatureCollection; +import com.squareup.sqlbrite2.BriteDatabase; import org.dhis2.data.tuples.Pair; import org.dhis2.utils.DateUtils; @@ -29,20 +31,21 @@ import org.hisp.dhis.android.core.program.Program; import org.hisp.dhis.android.core.program.ProgramStageDataElement; import org.hisp.dhis.android.core.trackedentity.TrackedEntityDataValue; +import org.jetbrains.annotations.NotNull; -import com.mapbox.geojson.BoundingBox; -import com.mapbox.geojson.FeatureCollection; -import com.squareup.sqlbrite2.BriteDatabase; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.paging.DataSource; import androidx.paging.LivePagedListBuilder; import androidx.paging.PagedList; - import io.reactivex.Flowable; import io.reactivex.Observable; import io.reactivex.Single; +import timber.log.Timber; /** * QUADRAM. Created by ppajuelo on 02/11/2017. @@ -63,7 +66,10 @@ public class ProgramEventDetailRepositoryImpl implements ProgramEventDetailRepos @NonNull @Override public LiveData> filteredProgramEvents(List dateFilter, List orgUnitFilter, List catOptCombList, - List eventStatus, List states) { + List eventStatus, List states, Pair valueFilter) { + + List uIds = getEventUIdsFilteredByValue(valueFilter); + EventCollectionRepository eventRepo = d2.eventModule().events().byProgramUid().eq(programUid); if (!dateFilter.isEmpty()) eventRepo = eventRepo.byEventDate().inDatePeriods(dateFilter); @@ -75,6 +81,9 @@ public LiveData> filteredProgramEvents(List transformToProgramEventModel(event)); return new LivePagedListBuilder(new DataSource.Factory() { @@ -85,6 +94,36 @@ public DataSource create() { }, 20).build(); } + @NotNull + private List getEventUIdsFilteredByValue( + Pair valueFilter) { + + List uids = new ArrayList<>(); + + if (valueFilter != null && !valueFilter.val0().isEmpty() && !valueFilter.val1().isEmpty()) { + + String QUERY = "SELECT Event.uid FROM Event " + + "LEFT OUTER JOIN TrackedEntityDataValue AS Value ON Value.event = Event.uid " + + "WHERE Value.dataElement = '" + valueFilter.val0() + "' AND Value.value like '%" + + valueFilter.val1()+ "%'"; + + try (Cursor uIdsCursor = briteDatabase.query(QUERY)) { + if (uIdsCursor != null) { + uIdsCursor.moveToFirst(); + for (int i = 0; i < uIdsCursor.getCount(); i++) { + uids.add(uIdsCursor.getString(0)); + uIdsCursor.moveToNext(); + } + } + } catch (Exception e) { + Timber.e(e); + } + } + + return uids; + } + + @NonNull @Override public Flowable> filteredEventsForMap(List dateFilter, List orgUnitFilter, List catOptCombList, @@ -246,6 +285,12 @@ public Single>> catOptionCombos() )); } + @NonNull + @Override + public Observable> textTypeDataElements() { + return d2.dataElementModule().dataElements().byValueType().eq(ValueType.TEXT).get().toObservable(); + } + @Override public Single hasAccessToAllCatOptions() { return d2.programModule().programs().uid(programUid).get() diff --git a/dhis2-android-sdk b/dhis2-android-sdk index 630c65bff1..056d6e33d3 160000 --- a/dhis2-android-sdk +++ b/dhis2-android-sdk @@ -1 +1 @@ -Subproject commit 630c65bff12e45771f445af69481634ac76f4194 +Subproject commit 056d6e33d3204f8514bf438bc3af6876feeb9a4e diff --git a/dhis2-rule-engine b/dhis2-rule-engine index 187c97f620..a11bc28025 160000 --- a/dhis2-rule-engine +++ b/dhis2-rule-engine @@ -1 +1 @@ -Subproject commit 187c97f6204ca0c5af7aeb8908a164364fdb9c19 +Subproject commit a11bc28025b2eaba6b592e7ecc421ca91e769cd5 From ba6443a5f56216a487e57d8d25edaaca8f3767b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Sa=CC=81nchez?= Date: Thu, 21 Nov 2019 11:18:42 +0100 Subject: [PATCH 02/11] Add value Filter to Filters and FilterManager --- .../main/program/ProgramPresenter.kt | 2 + .../ProgramEventDetailActivity.java | 7 ++ .../ProgramEventDetailContract.java | 9 +-- .../ProgramEventDetailPresenter.java | 14 +++- .../dhis2/utils/filters/FilterManager.java | 24 ++++++- .../java/org/dhis2/utils/filters/Filters.java | 2 +- .../dhis2/utils/filters/FiltersAdapter.java | 9 +++ .../utils/filters/TextValuesFilterHolder.java | 65 +++++++++++++++++++ 8 files changed, 124 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/org/dhis2/utils/filters/TextValuesFilterHolder.java diff --git a/app/src/main/java/org/dhis2/usescases/main/program/ProgramPresenter.kt b/app/src/main/java/org/dhis2/usescases/main/program/ProgramPresenter.kt index f2d9773746..194562e543 100644 --- a/app/src/main/java/org/dhis2/usescases/main/program/ProgramPresenter.kt +++ b/app/src/main/java/org/dhis2/usescases/main/program/ProgramPresenter.kt @@ -22,6 +22,8 @@ class ProgramPresenter internal constructor( private val programQueries = PublishProcessor.create, List>>() fun init() { + FilterManager.getInstance().clearTextValues() + val loadingProcessor = PublishProcessor.create() disposable.add( diff --git a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailActivity.java b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailActivity.java index 72281f0a70..de1caa1c14 100644 --- a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailActivity.java +++ b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailActivity.java @@ -60,6 +60,7 @@ import org.hisp.dhis.android.core.category.CategoryCombo; import org.hisp.dhis.android.core.category.CategoryOptionCombo; import org.hisp.dhis.android.core.common.FeatureType; +import org.hisp.dhis.android.core.dataelement.DataElement; import org.hisp.dhis.android.core.program.Program; import java.lang.reflect.Field; @@ -136,6 +137,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { filtersAdapter = new FiltersAdapter(); filtersAdapter.addEventStatus(); + //filtersAdapter.addFilterByTextValue(); try { binding.filterLayout.setAdapter(filtersAdapter); @@ -303,6 +305,11 @@ public void setCatOptionComboFilter(Pair textTypeDataElementsFilter) { + + } + @Override public void showPeriodRequest(FilterManager.PeriodRequest periodRequest) { if (periodRequest == FilterManager.PeriodRequest.FROM_TO) { diff --git a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailContract.java b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailContract.java index d52419c4fc..77d8973955 100644 --- a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailContract.java +++ b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailContract.java @@ -1,8 +1,5 @@ package org.dhis2.usescases.programEventDetail; -import androidx.lifecycle.LiveData; -import androidx.paging.PagedList; - import com.mapbox.geojson.BoundingBox; import com.mapbox.geojson.FeatureCollection; import com.mapbox.mapboxsdk.geometry.LatLng; @@ -13,11 +10,13 @@ import org.hisp.dhis.android.core.category.CategoryCombo; import org.hisp.dhis.android.core.category.CategoryOptionCombo; import org.hisp.dhis.android.core.common.FeatureType; -import org.hisp.dhis.android.core.period.DatePeriod; +import org.hisp.dhis.android.core.dataelement.DataElement; import org.hisp.dhis.android.core.program.Program; import java.util.List; +import androidx.lifecycle.LiveData; +import androidx.paging.PagedList; import io.reactivex.functions.Consumer; /** @@ -44,6 +43,8 @@ public interface View extends AbstractActivityContracts.View { void setCatOptionComboFilter(Pair> categoryOptionCombos); + void setTextTypeDataElementsFilter(List textTypeDataElementsFilter); + void openOrgUnitTreeSelector(); Consumer> setMap(); diff --git a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailPresenter.java b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailPresenter.java index ee205e0d29..03736931ff 100644 --- a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailPresenter.java +++ b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailPresenter.java @@ -51,6 +51,8 @@ public class ProgramEventDetailPresenter implements ProgramEventDetailContract.P @Override public void init(ProgramEventDetailContract.View view) { + FilterManager.getInstance().setTexValueFilter(Pair.create("LJHNsKzZ8Mg", "Jorge")); + this.view = view; compositeDisposable = new CompositeDisposable(); @@ -101,6 +103,15 @@ public void init(ProgramEventDetailContract.View view) { ) ); + compositeDisposable.add( + eventRepository.textTypeDataElements() + .subscribeOn(schedulerProvider.io()) + .observeOn(schedulerProvider.ui()) + .subscribe(view::setTextTypeDataElementsFilter, + Timber::e + ) + ); + compositeDisposable.add( FilterManager.getInstance().asFlowable() .startWith(FilterManager.getInstance()) @@ -109,7 +120,8 @@ public void init(ProgramEventDetailContract.View view) { filterManager.getOrgUnitUidsFilters(), filterManager.getCatOptComboFilters(), filterManager.getEventStatusFilters(), - filterManager.getStateFilters() + filterManager.getStateFilters(), + filterManager.getTexValueFilter() )) .subscribeOn(schedulerProvider.computation()) .observeOn(schedulerProvider.ui()) diff --git a/app/src/main/java/org/dhis2/utils/filters/FilterManager.java b/app/src/main/java/org/dhis2/utils/filters/FilterManager.java index a36ad3ec48..7c6af2621d 100644 --- a/app/src/main/java/org/dhis2/utils/filters/FilterManager.java +++ b/app/src/main/java/org/dhis2/utils/filters/FilterManager.java @@ -10,7 +10,7 @@ import org.hisp.dhis.android.core.period.DatePeriod; import java.util.ArrayList; -import java.util.Collections; +import org.dhis2.data.tuples.Pair; import java.util.List; import io.reactivex.Flowable; @@ -37,12 +37,14 @@ public enum PeriodRequest { private List periodFilters; private List catOptComboFilters; private List eventStatusFilters; + private Pair textValueFilter; private ObservableField ouFiltersApplied; private ObservableField stateFiltersApplied; private ObservableField periodFiltersApplied; private ObservableField catOptCombFiltersApplied; private ObservableField eventStatusFiltersApplied; + private ObservableField textValueFiltersApplied; private FlowableProcessor filterProcessor; private FlowableProcessor ouTreeProcessor; @@ -70,12 +72,14 @@ public void reset() { periodFilters = null; catOptComboFilters = new ArrayList<>(); eventStatusFilters = new ArrayList<>(); + textValueFilter = null; ouFiltersApplied = new ObservableField<>(0); stateFiltersApplied = new ObservableField<>(0); periodFiltersApplied = new ObservableField<>(0); catOptCombFiltersApplied = new ObservableField<>(0); eventStatusFiltersApplied = new ObservableField<>(0); + textValueFiltersApplied = new ObservableField<>(0); filterProcessor = PublishProcessor.create(); ouTreeProcessor = PublishProcessor.create(); @@ -160,6 +164,8 @@ public ObservableField observeField(Filters filter) { return catOptCombFiltersApplied; case EVENT_STATUS: return eventStatusFiltersApplied; + case TEXT_VALUE: + return textValueFiltersApplied; default: return new ObservableField<>(0); } @@ -187,7 +193,9 @@ public int getTotalFilters() { int periodIsApplying = periodFilters == null ? 0 : 1; int eventStatusApplying = eventStatusFilters.isEmpty() ? 0 : 1; int catComboApplying = catOptComboFilters.isEmpty() ? 0 : 1; - return ouIsApplying + stateIsApplying + periodIsApplying + eventStatusApplying + catComboApplying; + int textValueApplying = textValueFilter == null || textValueFilter.val0().isEmpty() ? 0 : 1; + return ouIsApplying + stateIsApplying + periodIsApplying + + eventStatusApplying + catComboApplying + textValueApplying; } public List getPeriodFilters() { @@ -212,6 +220,10 @@ public List getStateFilters() { public List getEventStatusFilters(){ return eventStatusFilters; } + public Pair getTexValueFilter(){ return textValueFilter; } + + public void setTexValueFilter(Pair filter){ textValueFilter = filter; } + public void addPeriodRequest(PeriodRequest periodRequest) { periodRequestProcessor.onNext(periodRequest); } @@ -254,6 +266,12 @@ public void clearEventStatus(){ filterProcessor.onNext(this); } + public void clearTextValues() { + textValueFilter = null; + eventStatusFiltersApplied.set(0); + filterProcessor.onNext(this); + } + public void clearAllFilters(){ eventStatusFilters.clear(); catOptComboFilters.clear(); @@ -261,12 +279,14 @@ public void clearAllFilters(){ ouFilters.clear(); periodFilters = null; periodIdSelected = 0; + textValueFilter = null; eventStatusFiltersApplied.set(eventStatusFilters.size()); catOptCombFiltersApplied.set(catOptComboFilters.size()); stateFiltersApplied.set(stateFilters.size()); ouFiltersApplied.set(ouFilters.size()); periodFiltersApplied.set(0); + textValueFiltersApplied.set(0); filterProcessor.onNext(this); } diff --git a/app/src/main/java/org/dhis2/utils/filters/Filters.java b/app/src/main/java/org/dhis2/utils/filters/Filters.java index d011d25f68..9dda9190ff 100644 --- a/app/src/main/java/org/dhis2/utils/filters/Filters.java +++ b/app/src/main/java/org/dhis2/utils/filters/Filters.java @@ -1,6 +1,6 @@ package org.dhis2.utils.filters; public enum Filters { - PERIOD, ORG_UNIT, SYNC_STATE, CAT_OPT_COMB, EVENT_STATUS //TODO: Include Event, Enrollment and attributes Filters + PERIOD, ORG_UNIT, SYNC_STATE, CAT_OPT_COMB, EVENT_STATUS, TEXT_VALUE //TODO: Include Event, Enrollment and attributes Filters } diff --git a/app/src/main/java/org/dhis2/utils/filters/FiltersAdapter.java b/app/src/main/java/org/dhis2/utils/filters/FiltersAdapter.java index b6d543829c..458abf9b55 100644 --- a/app/src/main/java/org/dhis2/utils/filters/FiltersAdapter.java +++ b/app/src/main/java/org/dhis2/utils/filters/FiltersAdapter.java @@ -15,6 +15,7 @@ import org.dhis2.databinding.ItemFilterStatusBinding; import org.hisp.dhis.android.core.category.CategoryCombo; import org.hisp.dhis.android.core.category.CategoryOptionCombo; +import org.hisp.dhis.android.core.dataelement.DataElement; import java.util.ArrayList; import java.util.List; @@ -24,6 +25,7 @@ public class FiltersAdapter extends RecyclerView.Adapter { private List filtersList; private ObservableField openedFilter; private Pair> catCombData; + private List textTypeDataElements; public FiltersAdapter() { this.filtersList = new ArrayList<>(); @@ -83,4 +85,11 @@ public void addEventStatus(){ } } + public void addFilterByTextValue(List textTypeDataElements) { + if(!filtersList.contains(Filters.EVENT_STATUS)) { + filtersList.add(Filters.EVENT_STATUS); + this.textTypeDataElements = textTypeDataElements; + notifyDataSetChanged(); + } + } } diff --git a/app/src/main/java/org/dhis2/utils/filters/TextValuesFilterHolder.java b/app/src/main/java/org/dhis2/utils/filters/TextValuesFilterHolder.java new file mode 100644 index 0000000000..825f08364f --- /dev/null +++ b/app/src/main/java/org/dhis2/utils/filters/TextValuesFilterHolder.java @@ -0,0 +1,65 @@ +package org.dhis2.utils.filters; + +import android.view.View; +import android.widget.AdapterView; + +import org.dhis2.R; +import org.dhis2.data.tuples.Pair; +import org.dhis2.databinding.ItemFilterCatOptCombBinding; +import org.dhis2.utils.CatComboAdapter; +import org.dhis2.utils.filters.cat_opt_comb.CatOptCombFilterAdapter; +import org.hisp.dhis.android.core.category.CategoryCombo; +import org.hisp.dhis.android.core.category.CategoryOptionCombo; + +import java.util.List; + +import androidx.annotation.NonNull; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.databinding.ObservableField; + +class TextValuesFilterHolder extends FilterHolder { + + private final Pair> catComboData; + + TextValuesFilterHolder(@NonNull ItemFilterCatOptCombBinding binding, ObservableField openedFilter, Pair> catCombData) { + super(binding, openedFilter); + filterType = Filters.CAT_OPT_COMB; + this.catComboData = catCombData; + } + + @Override + public void bind() { + super.bind(); + filterIcon.setImageDrawable(AppCompatResources.getDrawable(itemView.getContext(), R.drawable.ic_filter_sync)); + filterTitle.setText(catComboData.val0().displayName()); + + ItemFilterCatOptCombBinding localBinding = (ItemFilterCatOptCombBinding) binding; + + + CatOptCombFilterAdapter adapter = new CatOptCombFilterAdapter(); + localBinding.filterCatOptComb.catCombOptRecycler.setAdapter(adapter); + + CatComboAdapter spinnerAdapter = new CatComboAdapter(itemView.getContext(), + R.layout.spinner_layout, + R.id.spinner_text, + catComboData.val1(), + catComboData.val0().displayName(), + R.color.white_faf); + + localBinding.filterCatOptComb.catOptCombSpinner.setAdapter(spinnerAdapter); + localBinding.filterCatOptComb.catOptCombSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView adapterView, View view, int position, long l) { + if (position != 0) { + FilterManager.getInstance().addCatOptCombo(catComboData.val1().get(position - 1)); + adapter.notifyDataSetChanged(); + } + } + + @Override + public void onNothingSelected(AdapterView adapterView) { + + } + }); + } +} From 71e640aac2b88c088d0e1be33ceeb636d450a27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Sa=CC=81nchez?= Date: Thu, 21 Nov 2019 14:05:47 +0100 Subject: [PATCH 03/11] Implement method to retrieve TextTypeDataElements --- .../ProgramEventDetailRepositoryImpl.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java index fc12e829f8..35cd2b258f 100644 --- a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java +++ b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java @@ -288,7 +288,29 @@ public Single>> catOptionCombos() @NonNull @Override public Observable> textTypeDataElements() { - return d2.dataElementModule().dataElements().byValueType().eq(ValueType.TEXT).get().toObservable(); + //TODO: review this queries using rxjava in a better way + List programStageUIds = + d2.programModule().programs().uid(programUid).get() + .flatMap(program -> d2.programModule().programStages().byProgramUid() + .eq(program.uid()).get()) + .toObservable().flatMap(programStages -> + Observable.fromIterable(programStages) + .map(item -> item.uid()) + .toList().toObservable()).blockingFirst(); + + List programStagesDataElementsUIds = + d2.programModule().programStageDataElements().byProgramStage().in(programStageUIds).get() + .toObservable().flatMap(programStageDataElements -> + Observable.fromIterable(programStageDataElements) + .map(item -> item.dataElement().uid()) + .toList().toObservable()).blockingFirst(); + + + return d2.dataElementModule().dataElements() + .byValueType().eq(ValueType.TEXT) + .byUid().in(programStagesDataElementsUIds) + .byOptionSetUid().isNull() + .get().toObservable(); } @Override From b995efafaf8b307e3e12d2d4f01af5a0667e27f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Sa=CC=81nchez?= Date: Thu, 21 Nov 2019 18:02:17 +0100 Subject: [PATCH 04/11] Implement presentation changes to add filter by text value --- .../ProgramEventDetailActivity.java | 4 +- .../ProgramEventDetailPresenter.java | 2 - .../ProgramEventDetailRepositoryImpl.java | 1 - .../org/dhis2/utils/DataElementsAdapter.java | 68 ++++++++++++++ .../dhis2/utils/filters/FilterManager.java | 12 ++- .../dhis2/utils/filters/FiltersAdapter.java | 9 +- .../utils/filters/TextValueFilterHolder.java | 90 +++++++++++++++++++ .../utils/filters/TextValuesFilterHolder.java | 65 -------------- app/src/main/res/layout/filter_value.xml | 52 +++++++++++ app/src/main/res/layout/item_filter_value.xml | 44 +++++++++ .../res/layout/spinner_dataelement_layout.xml | 26 ++++++ app/src/main/res/values/strings.xml | 1 + 12 files changed, 299 insertions(+), 75 deletions(-) create mode 100644 app/src/main/java/org/dhis2/utils/DataElementsAdapter.java create mode 100644 app/src/main/java/org/dhis2/utils/filters/TextValueFilterHolder.java delete mode 100644 app/src/main/java/org/dhis2/utils/filters/TextValuesFilterHolder.java create mode 100644 app/src/main/res/layout/filter_value.xml create mode 100644 app/src/main/res/layout/item_filter_value.xml create mode 100644 app/src/main/res/layout/spinner_dataelement_layout.xml diff --git a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailActivity.java b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailActivity.java index de1caa1c14..8abca9269e 100644 --- a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailActivity.java +++ b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailActivity.java @@ -137,7 +137,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { filtersAdapter = new FiltersAdapter(); filtersAdapter.addEventStatus(); - //filtersAdapter.addFilterByTextValue(); + try { binding.filterLayout.setAdapter(filtersAdapter); @@ -307,7 +307,7 @@ public void setCatOptionComboFilter(Pair textTypeDataElementsFilter) { - + filtersAdapter.addTextValueFilter(textTypeDataElementsFilter); } @Override diff --git a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailPresenter.java b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailPresenter.java index 03736931ff..f585e6f2a1 100644 --- a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailPresenter.java +++ b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailPresenter.java @@ -51,8 +51,6 @@ public class ProgramEventDetailPresenter implements ProgramEventDetailContract.P @Override public void init(ProgramEventDetailContract.View view) { - FilterManager.getInstance().setTexValueFilter(Pair.create("LJHNsKzZ8Mg", "Jorge")); - this.view = view; compositeDisposable = new CompositeDisposable(); diff --git a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java index 35cd2b258f..7a8cc6904f 100644 --- a/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java +++ b/app/src/main/java/org/dhis2/usescases/programEventDetail/ProgramEventDetailRepositoryImpl.java @@ -288,7 +288,6 @@ public Single>> catOptionCombos() @NonNull @Override public Observable> textTypeDataElements() { - //TODO: review this queries using rxjava in a better way List programStageUIds = d2.programModule().programs().uid(programUid).get() .flatMap(program -> d2.programModule().programStages().byProgramUid() diff --git a/app/src/main/java/org/dhis2/utils/DataElementsAdapter.java b/app/src/main/java/org/dhis2/utils/DataElementsAdapter.java new file mode 100644 index 0000000000..f5817e3ced --- /dev/null +++ b/app/src/main/java/org/dhis2/utils/DataElementsAdapter.java @@ -0,0 +1,68 @@ +package org.dhis2.utils; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; + +import org.dhis2.databinding.SpinnerDataelementLayoutBinding; +import org.hisp.dhis.android.core.dataelement.DataElement; + +import java.util.List; + +import androidx.annotation.ColorRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +/** + * Created by ppajuelo on 12/02/2018. + * + */ + +public class DataElementsAdapter extends ArrayAdapter { + + private final List dataElements; + private @ColorRes int textColor; + private final String defaultText; + + public DataElementsAdapter(@NonNull Context context, int resource, int textViewResourceId, + @NonNull List objects, String defaultText, + @ColorRes int textColor) { + super(context, resource, textViewResourceId, objects); + this.dataElements = objects; + this.defaultText = defaultText; + this.textColor = textColor; + } + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); + SpinnerDataelementLayoutBinding binding = SpinnerDataelementLayoutBinding.inflate(inflater,parent,false); + if (position != 0) + binding.setDataElement(dataElements.get(position - 1)); + //binding.setDefaultTitle(defaultText); + binding.spinnerText.setTextColor(ContextCompat.getColor(binding.spinnerText.getContext(), textColor)); + return binding.getRoot(); + + } + + @Override + public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); + SpinnerDataelementLayoutBinding binding = SpinnerDataelementLayoutBinding.inflate(inflater, parent, false); + if (position != 0) + binding.setDataElement(dataElements.get(position - 1)); + + //binding.setDefaultTitle(defaultText); + return binding.getRoot(); + } + + @Override + public int getCount() { + return super.getCount() + 1; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/dhis2/utils/filters/FilterManager.java b/app/src/main/java/org/dhis2/utils/filters/FilterManager.java index 7c6af2621d..0bd32a31ed 100644 --- a/app/src/main/java/org/dhis2/utils/filters/FilterManager.java +++ b/app/src/main/java/org/dhis2/utils/filters/FilterManager.java @@ -222,7 +222,15 @@ public List getStateFilters() { public Pair getTexValueFilter(){ return textValueFilter; } - public void setTexValueFilter(Pair filter){ textValueFilter = filter; } + public void setTexValueFilter(Pair filter){ + if (filter.val0().isEmpty() || filter.val1().isEmpty()){ + clearTextValues(); + } else { + textValueFilter = filter; + stateFiltersApplied.set(1); + filterProcessor.onNext(this); + } + } public void addPeriodRequest(PeriodRequest periodRequest) { periodRequestProcessor.onNext(periodRequest); @@ -267,7 +275,7 @@ public void clearEventStatus(){ } public void clearTextValues() { - textValueFilter = null; + textValueFilter = Pair.create("",""); eventStatusFiltersApplied.set(0); filterProcessor.onNext(this); } diff --git a/app/src/main/java/org/dhis2/utils/filters/FiltersAdapter.java b/app/src/main/java/org/dhis2/utils/filters/FiltersAdapter.java index 458abf9b55..c91ec89de4 100644 --- a/app/src/main/java/org/dhis2/utils/filters/FiltersAdapter.java +++ b/app/src/main/java/org/dhis2/utils/filters/FiltersAdapter.java @@ -13,6 +13,7 @@ import org.dhis2.databinding.ItemFilterPeriodBinding; import org.dhis2.databinding.ItemFilterStateBinding; import org.dhis2.databinding.ItemFilterStatusBinding; +import org.dhis2.databinding.ItemFilterValueBinding; import org.hisp.dhis.android.core.category.CategoryCombo; import org.hisp.dhis.android.core.category.CategoryOptionCombo; import org.hisp.dhis.android.core.dataelement.DataElement; @@ -50,6 +51,8 @@ public FilterHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) return new CatOptCombFilterHolder(ItemFilterCatOptCombBinding.inflate(inflater, parent, false), openedFilter, catCombData); case EVENT_STATUS: return new StatusEventFilterHolder(ItemFilterStatusBinding.inflate(inflater, parent, false), openedFilter); + case TEXT_VALUE: + return new TextValueFilterHolder(ItemFilterValueBinding.inflate(inflater, parent, false), openedFilter, textTypeDataElements); default: throw new IllegalArgumentException("Unsupported filter value"); } @@ -85,9 +88,9 @@ public void addEventStatus(){ } } - public void addFilterByTextValue(List textTypeDataElements) { - if(!filtersList.contains(Filters.EVENT_STATUS)) { - filtersList.add(Filters.EVENT_STATUS); + public void addTextValueFilter(List textTypeDataElements) { + if(!filtersList.contains(Filters.TEXT_VALUE)) { + filtersList.add(Filters.TEXT_VALUE); this.textTypeDataElements = textTypeDataElements; notifyDataSetChanged(); } diff --git a/app/src/main/java/org/dhis2/utils/filters/TextValueFilterHolder.java b/app/src/main/java/org/dhis2/utils/filters/TextValueFilterHolder.java new file mode 100644 index 0000000000..dc2c9988aa --- /dev/null +++ b/app/src/main/java/org/dhis2/utils/filters/TextValueFilterHolder.java @@ -0,0 +1,90 @@ +package org.dhis2.utils.filters; + +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; + +import org.dhis2.R; +import org.dhis2.data.tuples.Pair; +import org.dhis2.databinding.ItemFilterValueBinding; +import org.dhis2.utils.DataElementsAdapter; +import org.hisp.dhis.android.core.dataelement.DataElement; + +import java.util.List; + +import androidx.annotation.NonNull; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.databinding.ObservableField; + +class TextValueFilterHolder extends FilterHolder { + + private final List textDataElements; + + Pair textValueFilter = Pair.create("",""); + + + TextValueFilterHolder(@NonNull ItemFilterValueBinding binding, + ObservableField openedFilter, + List textDataElements) { + super(binding, openedFilter); + filterType = Filters.CAT_OPT_COMB; + this.textDataElements = textDataElements; + } + + @Override + public void bind() { + super.bind(); + filterIcon.setImageDrawable(AppCompatResources.getDrawable(itemView.getContext(), R.drawable.ic_form_text)); + filterTitle.setText(R.string.filters_title_value); + + ItemFilterValueBinding localBinding = (ItemFilterValueBinding) binding; + + + DataElementsAdapter dataElementsAdapter = new DataElementsAdapter(itemView.getContext(), + R.layout.spinner_layout, + R.id.spinner_text, + textDataElements, + "-", + R.color.white_faf); + + localBinding.filterValue.dataElementsSpinner.setAdapter(dataElementsAdapter); + localBinding.filterValue.dataElementsSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView adapterView, View view, int position, long l) { + if (position != 0) { + DataElement dataelement = textDataElements.get(position - 1); + textValueFilter = Pair.create(dataelement.uid(),textValueFilter.val1()); + FilterManager.getInstance().setTexValueFilter(textValueFilter); + } + } + + @Override + public void onNothingSelected(AdapterView adapterView) { + Log.d("",""); + } + }); + + localBinding.filterValue.valueEditText.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) { + textValueFilter = Pair.create(textValueFilter.val0(),s.toString()); + + if (!textValueFilter.val0().isEmpty()){ + FilterManager.getInstance().setTexValueFilter(textValueFilter); + } + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + } +} diff --git a/app/src/main/java/org/dhis2/utils/filters/TextValuesFilterHolder.java b/app/src/main/java/org/dhis2/utils/filters/TextValuesFilterHolder.java deleted file mode 100644 index 825f08364f..0000000000 --- a/app/src/main/java/org/dhis2/utils/filters/TextValuesFilterHolder.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.dhis2.utils.filters; - -import android.view.View; -import android.widget.AdapterView; - -import org.dhis2.R; -import org.dhis2.data.tuples.Pair; -import org.dhis2.databinding.ItemFilterCatOptCombBinding; -import org.dhis2.utils.CatComboAdapter; -import org.dhis2.utils.filters.cat_opt_comb.CatOptCombFilterAdapter; -import org.hisp.dhis.android.core.category.CategoryCombo; -import org.hisp.dhis.android.core.category.CategoryOptionCombo; - -import java.util.List; - -import androidx.annotation.NonNull; -import androidx.appcompat.content.res.AppCompatResources; -import androidx.databinding.ObservableField; - -class TextValuesFilterHolder extends FilterHolder { - - private final Pair> catComboData; - - TextValuesFilterHolder(@NonNull ItemFilterCatOptCombBinding binding, ObservableField openedFilter, Pair> catCombData) { - super(binding, openedFilter); - filterType = Filters.CAT_OPT_COMB; - this.catComboData = catCombData; - } - - @Override - public void bind() { - super.bind(); - filterIcon.setImageDrawable(AppCompatResources.getDrawable(itemView.getContext(), R.drawable.ic_filter_sync)); - filterTitle.setText(catComboData.val0().displayName()); - - ItemFilterCatOptCombBinding localBinding = (ItemFilterCatOptCombBinding) binding; - - - CatOptCombFilterAdapter adapter = new CatOptCombFilterAdapter(); - localBinding.filterCatOptComb.catCombOptRecycler.setAdapter(adapter); - - CatComboAdapter spinnerAdapter = new CatComboAdapter(itemView.getContext(), - R.layout.spinner_layout, - R.id.spinner_text, - catComboData.val1(), - catComboData.val0().displayName(), - R.color.white_faf); - - localBinding.filterCatOptComb.catOptCombSpinner.setAdapter(spinnerAdapter); - localBinding.filterCatOptComb.catOptCombSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView adapterView, View view, int position, long l) { - if (position != 0) { - FilterManager.getInstance().addCatOptCombo(catComboData.val1().get(position - 1)); - adapter.notifyDataSetChanged(); - } - } - - @Override - public void onNothingSelected(AdapterView adapterView) { - - } - }); - } -} diff --git a/app/src/main/res/layout/filter_value.xml b/app/src/main/res/layout/filter_value.xml new file mode 100644 index 0000000000..7ddb27471e --- /dev/null +++ b/app/src/main/res/layout/filter_value.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_filter_value.xml b/app/src/main/res/layout/item_filter_value.xml new file mode 100644 index 0000000000..6097f49255 --- /dev/null +++ b/app/src/main/res/layout/item_filter_value.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/spinner_dataelement_layout.xml b/app/src/main/res/layout/spinner_dataelement_layout.xml new file mode 100644 index 0000000000..ac8d711477 --- /dev/null +++ b/app/src/main/res/layout/spinner_dataelement_layout.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 86200e5b42..baccc9c9bf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -582,6 +582,7 @@ Period Org. Unit Status + Value State Today Yesterday From 787a8ef3888862c91b864ec3790c2ee15abba51b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Sa=CC=81nchez?= Date: Mon, 25 Nov 2019 08:58:45 +0100 Subject: [PATCH 05/11] Create underline spinner style --- .../java/org/dhis2/utils/DataElementsAdapter.java | 5 ----- app/src/main/res/layout/filter_value.xml | 12 +++++++----- .../main/res/layout/spinner_dataelement_layout.xml | 4 +++- app/src/main/res/values-v21/styles.xml | 4 ++++ app/src/main/res/values/styles.xml | 2 ++ 5 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 app/src/main/res/values-v21/styles.xml diff --git a/app/src/main/java/org/dhis2/utils/DataElementsAdapter.java b/app/src/main/java/org/dhis2/utils/DataElementsAdapter.java index f5817e3ced..7a73d98e9f 100644 --- a/app/src/main/java/org/dhis2/utils/DataElementsAdapter.java +++ b/app/src/main/java/org/dhis2/utils/DataElementsAdapter.java @@ -16,11 +16,6 @@ import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; -/** - * Created by ppajuelo on 12/02/2018. - * - */ - public class DataElementsAdapter extends ArrayAdapter { private final List dataElements; diff --git a/app/src/main/res/layout/filter_value.xml b/app/src/main/res/layout/filter_value.xml index 7ddb27471e..2bfa4c2934 100644 --- a/app/src/main/res/layout/filter_value.xml +++ b/app/src/main/res/layout/filter_value.xml @@ -26,26 +26,28 @@ android:orientation="horizontal" android:visibility="@{currentFilter == filterType ? View.VISIBLE : View.GONE}"> - + android:backgroundTint="@color/white" + style="@style/spinner"/> diff --git a/app/src/main/res/layout/spinner_dataelement_layout.xml b/app/src/main/res/layout/spinner_dataelement_layout.xml index ac8d711477..f2dda462af 100644 --- a/app/src/main/res/layout/spinner_dataelement_layout.xml +++ b/app/src/main/res/layout/spinner_dataelement_layout.xml @@ -1,6 +1,7 @@ + xmlns:tools="http://schemas.android.com/tools" + xmlns:app="http://schemas.android.com/apk/res-auto"> @@ -23,4 +24,5 @@ android:textSize="16sp" tools:drawableEnd="@drawable/ic_arrow_drop_down_black_24dp" tools:text="nameddddddddddddddddddddddddddddddddddddddddddddddddddddddd" /> + \ No newline at end of file diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml new file mode 100644 index 0000000000..02afbff715 --- /dev/null +++ b/app/src/main/res/values-v21/styles.xml @@ -0,0 +1,4 @@ + + + +