Improve Filters (work in progress)

feature/top10
Aurelien Hubert 7 years ago
parent 9e4f108a59
commit 536ce246b1
  1. 15
      app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt
  2. 10
      app/src/main/java/net/pokeranalytics/android/ui/activity/FilterDetailsActivity.kt
  3. 13
      app/src/main/java/net/pokeranalytics/android/ui/activity/FiltersActivity.kt
  4. 2
      app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt
  5. 60
      app/src/main/java/net/pokeranalytics/android/ui/fragment/FilterDetailsFragment.kt
  6. 79
      app/src/main/java/net/pokeranalytics/android/ui/fragment/FiltersFragment.kt
  7. 16
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt

@ -2,9 +2,8 @@ package net.pokeranalytics.android.model.realm
import io.realm.* import io.realm.*
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
import net.pokeranalytics.android.exceptions.PokerAnalyticsException
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.exceptions.PokerAnalyticsException
import net.pokeranalytics.android.model.filter.Filterable import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.filter.QueryType import net.pokeranalytics.android.model.filter.QueryType
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
@ -64,6 +63,18 @@ open class Filter(entity:Filterable) : RealmObject() {
} }
companion object { companion object {
// Create a new instance
fun newInstance(realm: Realm) : Filter {
val filter = Filter()
return realm.copyToRealm(filter)
}
// Get a filter by its id
fun getFilterBydId(realm: Realm, filterId: String) : Filter? {
return realm.where<Filter>().equalTo("id", filterId).findFirst()
}
@TestOnly @TestOnly
inline fun <reified T : Filterable> queryOn(realm: Realm, queries: List<QueryType>): RealmResults<T> { inline fun <reified T : Filterable> queryOn(realm: Realm, queries: List<QueryType>): RealmResults<T> {
var realmQuery = realm.where<T>() var realmQuery = realm.where<T>()

@ -11,6 +11,7 @@ import net.pokeranalytics.android.ui.fragment.FilterDetailsFragment
class FilterDetailsActivity : PokerAnalyticsActivity() { class FilterDetailsActivity : PokerAnalyticsActivity() {
enum class IntentKey(val keyName: String) { enum class IntentKey(val keyName: String) {
FILTER_ID("FILTER_ID"),
FILTER_CATEGORY_ORDINAL("FILTER_CATEGORY_ORDINAL") FILTER_CATEGORY_ORDINAL("FILTER_CATEGORY_ORDINAL")
} }
@ -18,8 +19,9 @@ class FilterDetailsActivity : PokerAnalyticsActivity() {
/** /**
* Default constructor * Default constructor
*/ */
fun newInstance(context: Context, filterCategoryOrdinal: Int) { fun newInstance(context: Context, filterId: String, filterCategoryOrdinal: Int) {
val intent = Intent(context, FilterDetailsActivity::class.java) val intent = Intent(context, FilterDetailsActivity::class.java)
intent.putExtra(IntentKey.FILTER_ID.keyName, filterId)
intent.putExtra(IntentKey.FILTER_CATEGORY_ORDINAL.keyName, filterCategoryOrdinal) intent.putExtra(IntentKey.FILTER_CATEGORY_ORDINAL.keyName, filterCategoryOrdinal)
context.startActivity(intent) context.startActivity(intent)
} }
@ -27,8 +29,9 @@ class FilterDetailsActivity : PokerAnalyticsActivity() {
/** /**
* Create a new instance for result * Create a new instance for result
*/ */
fun newInstanceForResult(fragment: Fragment, filterCategoryOrdinal: Int, requestCode: Int) { fun newInstanceForResult(fragment: Fragment, filterId: String, filterCategoryOrdinal: Int, requestCode: Int) {
val intent = Intent(fragment.requireContext(), FilterDetailsActivity::class.java) val intent = Intent(fragment.requireContext(), FilterDetailsActivity::class.java)
intent.putExtra(IntentKey.FILTER_ID.keyName, filterId)
intent.putExtra(IntentKey.FILTER_CATEGORY_ORDINAL.keyName, filterCategoryOrdinal) intent.putExtra(IntentKey.FILTER_CATEGORY_ORDINAL.keyName, filterCategoryOrdinal)
fragment.startActivityForResult(intent, requestCode) fragment.startActivityForResult(intent, requestCode)
} }
@ -53,12 +56,13 @@ class FilterDetailsActivity : PokerAnalyticsActivity() {
val fragmentManager = supportFragmentManager val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction() val fragmentTransaction = fragmentManager.beginTransaction()
val filterId = intent.getStringExtra(IntentKey.FILTER_ID.keyName)
val filterCategoryOrdinal = intent.getIntExtra(IntentKey.FILTER_CATEGORY_ORDINAL.keyName, 0) val filterCategoryOrdinal = intent.getIntExtra(IntentKey.FILTER_CATEGORY_ORDINAL.keyName, 0)
fragment = FilterDetailsFragment() fragment = FilterDetailsFragment()
fragmentTransaction.add(R.id.container, fragment) fragmentTransaction.add(R.id.container, fragment)
fragmentTransaction.commit() fragmentTransaction.commit()
fragment.setData(filterCategoryOrdinal) fragment.setData(filterId, filterCategoryOrdinal)
} }

@ -11,8 +11,7 @@ import net.pokeranalytics.android.ui.fragment.FiltersFragment
class FiltersActivity : PokerAnalyticsActivity() { class FiltersActivity : PokerAnalyticsActivity() {
enum class IntentKey(val keyName: String) { enum class IntentKey(val keyName: String) {
DATA_TYPE("DATA_TYPE"), FILTER_ID("FILTER_ID");
PRIMARY_KEY("PRIMARY_KEY");
} }
private lateinit var fragment: FiltersFragment private lateinit var fragment: FiltersFragment
@ -21,8 +20,11 @@ class FiltersActivity : PokerAnalyticsActivity() {
/** /**
* Default constructor * Default constructor
*/ */
fun newInstance(context: Context) { fun newInstance(context: Context, filterId: String? = null) {
val intent = Intent(context, FiltersActivity::class.java) val intent = Intent(context, FiltersActivity::class.java)
filterId?.let {
intent.putExtra(IntentKey.FILTER_ID.keyName, it)
}
context.startActivity(intent) context.startActivity(intent)
} }
@ -52,14 +54,13 @@ class FiltersActivity : PokerAnalyticsActivity() {
val fragmentManager = supportFragmentManager val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction() val fragmentTransaction = fragmentManager.beginTransaction()
val filterId = intent.getStringExtra(IntentKey.FILTER_ID.keyName)
fragment = FiltersFragment() fragment = FiltersFragment()
fragmentTransaction.add(R.id.container, fragment) fragmentTransaction.add(R.id.container, fragment)
fragmentTransaction.commit() fragmentTransaction.commit()
//TODO: send primary key fragment.setData(filterId)
fragment.setData("")
} }
} }

@ -61,7 +61,7 @@ class HomeActivity : PokerAnalyticsActivity() {
menuInflater.inflate(R.menu.home_menu, menu) menuInflater.inflate(R.menu.home_menu, menu)
this.homeMenu = menu this.homeMenu = menu
//TODO: Change filter button visibility //TODO: Change filter button visibility
homeMenu?.findItem(R.id.filter)?.isVisible = false homeMenu?.findItem(R.id.filter)?.isVisible = true
return super.onCreateOptionsMenu(menu) return super.onCreateOptionsMenu(menu)
} }

@ -1,15 +1,18 @@
package net.pokeranalytics.android.ui.fragment package net.pokeranalytics.android.ui.fragment
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.RealmObject
import kotlinx.android.synthetic.main.fragment_filter_details.* import kotlinx.android.synthetic.main.fragment_filter_details.*
import kotlinx.android.synthetic.main.fragment_filter_details.view.* import kotlinx.android.synthetic.main.fragment_filter_details.view.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.ui.activity.FilterDetailsActivity
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
@ -26,21 +29,18 @@ import java.util.*
open class FilterDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate { open class FilterDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate {
lateinit var parentActivity: PokerAnalyticsActivity lateinit var parentActivity: PokerAnalyticsActivity
lateinit var item: RealmObject
lateinit var rowRepresentableAdapter: RowRepresentableAdapter lateinit var rowRepresentableAdapter: RowRepresentableAdapter
private var currentFilter: Filter? = null
private var rows: ArrayList<RowRepresentable> = ArrayList() private var rows: ArrayList<RowRepresentable> = ArrayList()
private var rowsForFilterSubcategoryRow: HashMap<FilterSectionRow, ArrayList<RowRepresentable>> = HashMap() private var rowsForFilterSubcategoryRow: HashMap<FilterSectionRow, ArrayList<RowRepresentable>> = HashMap()
private var primaryKey: String? = null
private var filterMenu: Menu? = null private var filterMenu: Menu? = null
private var filterCategoryRow: FilterCategoryRow? = null private var filterCategoryRow: FilterCategoryRow? = null
private val selectedRows = ArrayList<FilterElementRow>()
private var isUpdating = false
val selectedRows = ArrayList<FilterElementRow>() private var shouldOpenKeyboard = true
var isUpdating = false
var shouldOpenKeyboard = true
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_filter_details, container, false) return inflater.inflate(R.layout.fragment_filter_details, container, false)
@ -125,6 +125,8 @@ open class FilterDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresenta
parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true) parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
setHasOptionsMenu(true) setHasOptionsMenu(true)
this.appBar.toolbar.title = getString(R.string.filter)
val viewManager = LinearLayoutManager(requireContext()) val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply { recyclerView.apply {
@ -140,7 +142,9 @@ open class FilterDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresenta
Timber.d("initData") Timber.d("initData")
this.appBar.toolbar.title = getString(R.string.filter) primaryKey?.let {
currentFilter = Filter.getFilterBydId(getRealm(), it)
}
filterCategoryRow?.let { filterCategoryRow?.let {
@ -150,19 +154,15 @@ open class FilterDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresenta
this.rowsForFilterSubcategoryRow.clear() this.rowsForFilterSubcategoryRow.clear()
this.rows.addAll(it.filterElements) this.rows.addAll(it.filterElements)
//TODO
/*
var filter = Filter()
this.rows.forEach {element -> this.rows.forEach {element ->
if (filter.isFilterElementExists(element as FilterElementRow)) { if (element is FilterElementRow && currentFilter?.contains(element) == true) {
this.selectedRows.add(element) this.selectedRows.add(element)
} }
} }
*/
this.rowRepresentableAdapter = RowRepresentableAdapter(this, this) this.rowRepresentableAdapter = RowRepresentableAdapter(this, this)
this.recyclerView.adapter = rowRepresentableAdapter this.recyclerView.adapter = rowRepresentableAdapter
} }
} }
@ -170,38 +170,34 @@ open class FilterDetailsFragment : PokerAnalyticsFragment(), StaticRowRepresenta
* Save data * Save data
*/ */
private fun saveData() { private fun saveData() {
//TODO: Save currentFilter details data
Timber.d("Save data for filter: ${currentFilter?.id}")
val realm = getRealm()
realm.beginTransaction()
currentFilter?.createOrUpdateFilterElements(selectedRows)
realm.commitTransaction()
//TODO: Save filter details data finishActivityWithResult(currentFilter?.id)
Timber.d("Save filter details data")
finishActivityWithResult("")
} }
/** /**
* Finish the activity with a result * Finish the activity with a result
*/ */
private fun finishActivityWithResult(uniqueIdentifier: String) { private fun finishActivityWithResult(uniqueIdentifier: String?) {
/*
val intent = Intent() val intent = Intent()
intent.putExtra(EditableDataActivity.IntentKey.DATA_TYPE.keyName, dataType) intent.putExtra(FilterDetailsActivity.IntentKey.FILTER_ID.keyName, uniqueIdentifier)
intent.putExtra(EditableDataActivity.IntentKey.PRIMARY_KEY.keyName, uniqueIdentifier)
activity?.setResult(RESULT_OK, intent) activity?.setResult(RESULT_OK, intent)
*/
activity?.finish() activity?.finish()
} }
/** /**
* Set fragment data * Set fragment data
*/ */
fun setData(filterCategory: Int) { fun setData(primaryKey: String, filterCategory: Int) {
this.filterCategoryRow = FilterCategoryRow.values()[filterCategory]
/*
this.dataType = dataType
this.liveDataType = LiveData.numericValues()[dataType]
this.primaryKey = primaryKey this.primaryKey = primaryKey
*/ this.filterCategoryRow = FilterCategoryRow.values()[filterCategory]
} }
} }

@ -1,10 +1,11 @@
package net.pokeranalytics.android.ui.fragment package net.pokeranalytics.android.ui.fragment
import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.* import android.view.*
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.RealmObject import io.realm.kotlin.where
import kotlinx.android.synthetic.main.fragment_editable_data.* import kotlinx.android.synthetic.main.fragment_editable_data.*
import kotlinx.android.synthetic.main.fragment_filters.view.* import kotlinx.android.synthetic.main.fragment_filters.view.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
@ -16,6 +17,8 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow import net.pokeranalytics.android.ui.view.rowrepresentable.FilterCategoryRow
import timber.log.Timber import timber.log.Timber
@ -26,18 +29,18 @@ open class FiltersFragment : PokerAnalyticsFragment(), StaticRowRepresentableDat
const val REQUEST_CODE_FILTER_DETAILS = 100 const val REQUEST_CODE_FILTER_DETAILS = 100
} }
lateinit var parentActivity: PokerAnalyticsActivity private val categories = FilterCategoryRow.values()
lateinit var item: RealmObject
lateinit var rowRepresentableAdapter: RowRepresentableAdapter
private lateinit var parentActivity: PokerAnalyticsActivity
private lateinit var rowRepresentableAdapter: RowRepresentableAdapter
private var currentFilter: Filter? = null
private var rows: ArrayList<RowRepresentable> = ArrayList() private var rows: ArrayList<RowRepresentable> = ArrayList()
private var filterMenu: Menu? = null private var filterMenu: Menu? = null
private var primaryKey: String? = null private var primaryKey: String? = null
private var selectedRow: RowRepresentable? = null private var selectedRow: RowRepresentable? = null
private var isUpdating = false
private var filter: Filter? = null
var isUpdating = false
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_filters, container, false) return inflater.inflate(R.layout.fragment_filters, container, false)
@ -52,9 +55,26 @@ open class FiltersFragment : PokerAnalyticsFragment(), StaticRowRepresentableDat
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_FILTER_DETAILS) { if (requestCode == REQUEST_CODE_FILTER_DETAILS && resultCode == Activity.RESULT_OK) {
Timber.d("onActivityResult: $requestCode") Timber.d("onActivityResult: $requestCode")
if (data != null && data.hasExtra(FilterDetailsActivity.IntentKey.FILTER_ID.keyName)) {
val filterId = data.getStringExtra(FilterDetailsActivity.IntentKey.FILTER_ID.keyName)
Timber.d("Updated filter: ${filterId}")
}
//TODO: Improve that
rows.clear()
for (category in categories) {
var filtersSelected = ""
currentFilter?.countBy(category)?.let { nbFilters ->
if (nbFilters > 0) {
filtersSelected = nbFilters.toString()
}
}
rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE_ARROW, category.resId, value = filtersSelected, isSelectable = true))
}
rowRepresentableAdapter.notifyDataSetChanged()
// TODO: Update the selected row here... // TODO: Update the selected row here...
selectedRow?.let { selectedRow?.let {
@ -92,18 +112,16 @@ open class FiltersFragment : PokerAnalyticsFragment(), StaticRowRepresentableDat
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
super.onRowSelected(position, row, fromAction) super.onRowSelected(position, row, fromAction)
if (row is FilterCategoryRow) {
selectedRow = row selectedRow = row
FilterDetailsActivity.newInstanceForResult(this, row.ordinal, REQUEST_CODE_FILTER_DETAILS) currentFilter?.id?.let { filterId ->
FilterDetailsActivity.newInstanceForResult(this, filterId, categories[position].ordinal, REQUEST_CODE_FILTER_DETAILS)
} }
} }
//TODO //TODO
/* /*
override fun stringForRow(row: RowRepresentable): String { override fun stringForRow(row: RowRepresentable): String {
return this.filter?.numberOfElementIn(row as FilterCategoryRow).toString() return this.currentFilter?.numberOfElementIn(row as FilterCategoryRow).toString()
} }
*/ */
@ -120,6 +138,8 @@ open class FiltersFragment : PokerAnalyticsFragment(), StaticRowRepresentableDat
parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true) parentActivity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
setHasOptionsMenu(true) setHasOptionsMenu(true)
this.appBar.toolbar.title = getString(R.string.filter)
val viewManager = LinearLayoutManager(requireContext()) val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply { recyclerView.apply {
@ -133,9 +153,32 @@ open class FiltersFragment : PokerAnalyticsFragment(), StaticRowRepresentableDat
*/ */
private fun initData() { private fun initData() {
this.appBar.toolbar.title = getString(R.string.filter) val realm = getRealm()
//TODO: Remove that
val filters = realm.where<Filter>().findAll()
Timber.d("Filters: ${filters.size}")
primaryKey?.let {
currentFilter = Filter.getFilterBydId(realm, it)
} ?: run {
realm.beginTransaction()
currentFilter = Filter.newInstance(realm)
realm.commitTransaction()
}
rows.clear()
for (category in categories) {
var filtersSelected = ""
currentFilter?.countBy(category)?.let { nbFilters ->
if (nbFilters > 0) {
filtersSelected = nbFilters.toString()
}
}
rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE_ARROW, category.resId, value = filtersSelected, isSelectable = true))
}
rows.addAll(FilterCategoryRow.values()) //rows.addAll(FilterCategoryRow.values())
this.rowRepresentableAdapter = RowRepresentableAdapter(this, this) this.rowRepresentableAdapter = RowRepresentableAdapter(this, this)
this.recyclerView.adapter = rowRepresentableAdapter this.recyclerView.adapter = rowRepresentableAdapter
@ -155,7 +198,7 @@ open class FiltersFragment : PokerAnalyticsFragment(), StaticRowRepresentableDat
*/ */
private fun saveData() { private fun saveData() {
// TODO: Save the filter object here // TODO: Save the currentFilter object here
// Maybe we don't need to do anything because the object is already up to date // Maybe we don't need to do anything because the object is already up to date
finishActivityWithResult("") finishActivityWithResult("")
@ -166,7 +209,7 @@ open class FiltersFragment : PokerAnalyticsFragment(), StaticRowRepresentableDat
*/ */
private fun deleteData() { private fun deleteData() {
// TODO: Delete the filter object here // TODO: Delete the currentFilter object here
} }

@ -4,7 +4,6 @@ import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow.* import net.pokeranalytics.android.ui.view.rowrepresentable.FilterSectionRow.*
import timber.log.Timber
enum class FilterCategoryRow(override val resId: Int?, override val viewType: Int = RowViewType.TITLE_VALUE_ARROW.ordinal) : RowRepresentable { enum class FilterCategoryRow(override val resId: Int?, override val viewType: Int = RowViewType.TITLE_VALUE_ARROW.ordinal) : RowRepresentable {
GENERAL(R.string.general), GENERAL(R.string.general),
@ -23,24 +22,9 @@ enum class FilterCategoryRow(override val resId: Int?, override val viewType: In
val filterElements: List<RowRepresentable> val filterElements: List<RowRepresentable>
get() { get() {
val data = ArrayList<RowRepresentable>()
for (section in filterSectionRows) {
if (section.filterElements.isNotEmpty()) {
//data.add(section)
section.filterElements.forEach {
Timber.d("filterElements: $it")
}
data.addAll(section.filterElements)
}
}
return data
/*
return filterSectionRows.flatMap { return filterSectionRows.flatMap {
it.filterElements it.filterElements
} }
*/
} }
val filterSectionRows: List<FilterSectionRow> val filterSectionRows: List<FilterSectionRow>

Loading…
Cancel
Save