Skip to content

Commit

Permalink
Mobileapps 924 (#38)
Browse files Browse the repository at this point in the history
* Mobileapps 841 (#48)

* added apply and show results for advance search

* Mobileapps 842 (#49)

* reset filters and showing results for advance search
  • Loading branch information
aman-alfresco authored Nov 5, 2021
1 parent c5a10bd commit 2385483
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 59 deletions.
18 changes: 18 additions & 0 deletions data/src/main/kotlin/com/alfresco/content/data/SearchRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package com.alfresco.content.data
import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceManager
import com.alfresco.content.apis.AdvanceSearchInclude
import com.alfresco.content.apis.AppConfigApi
import com.alfresco.content.apis.QueriesApi
import com.alfresco.content.apis.SearchApi
import com.alfresco.content.apis.SearchInclude
import com.alfresco.content.apis.advanceSearch
import com.alfresco.content.apis.recentFiles
import com.alfresco.content.apis.simpleSearch
import com.alfresco.content.models.AppConfigModel
Expand All @@ -33,6 +35,7 @@ class SearchRepository(val session: Session = SessionManager.requireSession) {
terms: String,
nodeId: String?,
filters: SearchFilters,
advanceSearchFilters: AdvanceSearchFilters,
skipCount: Int,
maxItems: Int
) = if (filters.contains(SearchFilter.Libraries)) {
Expand All @@ -43,6 +46,16 @@ class SearchRepository(val session: Session = SessionManager.requireSession) {
maxItems
)
)
} else if (advanceSearchFilters.isNotEmpty()) {
ResponsePaging.with(
searchService.advanceSearch(
terms,
if (filters.contains(SearchFilter.Contextual)) nodeId else null,
skipCount,
maxItems,
includeFrom(advanceSearchFilters)
)
)
} else {
ResponsePaging.with(
searchService.simpleSearch(
Expand All @@ -64,6 +77,11 @@ class SearchRepository(val session: Session = SessionManager.requireSession) {
}
}

private fun includeFrom(advanceSearchFilters: AdvanceSearchFilters) =
advanceSearchFilters.mapTo(mutableSetOf()) {
AdvanceSearchInclude(name = it.name, query = it.query)
}

suspend fun getRecents(skipCount: Int, maxItems: Int) =
ResponsePaging.with(
searchService.recentFiles(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.alfresco.content.search

import android.os.Parcelable
import com.alfresco.content.data.SearchFilter
import com.alfresco.content.models.CategoriesItem
import kotlinx.parcelize.Parcelize

Expand Down Expand Up @@ -28,5 +29,33 @@ data class SearchChipCategory(
selectedQuery = query
)
}

/**
* returns the contextual searchChipCategory object
*/
fun withContextual(name: String, contextual: SearchFilter): SearchChipCategory {
return SearchChipCategory(
category = CategoriesItem(
name = name, expanded = null,
component = null, enabled = null,
id = contextual.toString()
),
isSelected = true,
selectedName = contextual.name,
selectedQuery = "+TYPE:'${contextual.name}'"
)
}

/**
* returns the default searchChipCategory object
*/
fun resetData(searchChipCategory: SearchChipCategory): SearchChipCategory {
return SearchChipCategory(
category = searchChipCategory.category,
isSelected = searchChipCategory.category.component == null,
selectedName = "",
selectedQuery = ""
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ import androidx.navigation.fragment.findNavController
import com.airbnb.epoxy.AsyncEpoxyController
import com.airbnb.mvrx.MavericksView
import com.airbnb.mvrx.withState
import com.alfresco.Logger
import com.alfresco.content.data.AdvanceSearchFilter
import com.alfresco.content.data.SearchFilter
import com.alfresco.content.data.and
import com.alfresco.content.data.emptyAdvanceFilters
import com.alfresco.content.data.emptyFilters
import com.alfresco.content.fragmentViewModelWithArgs
import com.alfresco.content.getLocalizedName
import com.alfresco.content.hideSoftInput
import com.alfresco.content.models.CategoriesItem
import com.alfresco.content.search.components.ComponentBuilder
import com.alfresco.content.search.components.ComponentMetaData
import com.alfresco.content.search.databinding.FragmentSearchBinding
Expand Down Expand Up @@ -106,21 +106,19 @@ class SearchFragment : Fragment(), MavericksView {
private fun setAdvanceSearchFiltersData() {
withState(viewModel) {
if (viewModel.isShowAdvanceFilterView(it.listSearchFilters)) {
binding.rlDropDownSearch.visibility = View.VISIBLE
binding.parentAdvanceSearch.visibility = View.VISIBLE
binding.chipGroup.visibility = View.GONE
setupDropDown()
} else {
binding.rlDropDownSearch.visibility = View.GONE
binding.parentAdvanceSearch.visibility = View.GONE
binding.chipGroup.visibility = View.VISIBLE
setupChips()
}
}
}

override fun invalidate() = withState(viewModel) { state ->

setSearchFilterLocalizedName(state)

epoxyController.requestModelBuild()
}

Expand Down Expand Up @@ -204,18 +202,45 @@ class SearchFragment : Fragment(), MavericksView {
searchFilterPopup.setAdapter(adapter)

withState(viewModel) { state ->
if (state.selectedFilterIndex == -1)
viewModel.copyFilterIndex(viewModel.getDefaultSearchFilterIndex(state.listSearchFilters))
var index = state.selectedFilterIndex
if (state.selectedFilterIndex == -1) {
index = viewModel.getDefaultSearchFilterIndex(state.listSearchFilters)
viewModel.copyFilterIndex(index)
}
when (searchFilters?.get(index)?.resetButton) {
true -> binding.actionReset.visibility = View.VISIBLE
false -> binding.actionReset.visibility = View.GONE
}
}

searchFilterPopup.setOnItemClickListener { _: AdapterView<*>?, _: View?, position: Int, _: Long ->
viewModel.copyFilterIndex(position)
viewModel.updateSearchChipCategoryList(position)
setSelectedFilterData()
searchFilterPopup.dismiss()
withState(viewModel) { state ->
if (state.selectedFilterIndex != position) {
viewModel.isRefreshSearch = true
viewModel.copyFilterIndex(position)
viewModel.updateSearchChipCategoryList(position)
setSelectedFilterData()

val listSearchChip = mutableListOf<SearchChipCategory>()
if (state.isContextual)
listSearchChip.add(
SearchChipCategory.withContextual(
getString(R.string.search_chip_contextual, state.contextTitle),
SearchFilter.Contextual
)
)
applyAdvanceFilters(position, listSearchChip)
}
searchFilterPopup.dismiss()
}
}

binding.rlDropDownSearch.setOnClickListener { searchFilterPopup.show() }
binding.actionReset.setOnClickListener { resetAllFilters() }
}

private fun resetAllFilters() = withState(viewModel) { state ->
val listReset = viewModel.resetChips(state)
applyAdvanceFilters(state.selectedFilterIndex, listReset)
}

private fun setSearchFilterLocalizedName(state: SearchResultsState) {
Expand Down Expand Up @@ -292,14 +317,12 @@ class SearchFragment : Fragment(), MavericksView {

if (filterIndex != -1) {
val searchChipCategory = state.listSearchCategoryChips?.toMutableList()

var contextualSearchChipCategory: SearchChipCategory? = null
if (state.filters.contains(SearchFilter.Contextual)) {

contextualSearchChipCategory = SearchChipCategory(
CategoriesItem(
name = getString(R.string.search_chip_contextual, state.contextTitle), expanded = null,
component = null, enabled = null, id = SearchFilter.Contextual.toString()
), true
contextualSearchChipCategory = SearchChipCategory.withContextual(
getString(R.string.search_chip_contextual, state.contextTitle),
SearchFilter.Contextual
)
}
if (!searchChipCategory.isNullOrEmpty()) {
Expand All @@ -316,6 +339,14 @@ class SearchFragment : Fragment(), MavericksView {
clickListener { model, _, chipView, _ ->
if (model.data().category.component != null)
onChipClicked(model.data(), chipView)
else {
val result: ComponentMetaData = if (state.isContextual && (chipView as FilterChip).isChecked) {
ComponentMetaData(SearchFilter.Contextual.name, "+TYPE:'${SearchFilter.Contextual.name}'")
} else
ComponentMetaData("", "")
val resultList = viewModel.updateChipComponentResult(state, model.data(), result)
applyAdvanceFilters(state.selectedFilterIndex, resultList)
}
}
}
}
Expand All @@ -333,9 +364,9 @@ class SearchFragment : Fragment(), MavericksView {
}
viewLifecycleOwner.lifecycleScope.launch {
val result = showComponentSheetDialog(requireContext(), data)
Logger.d("component result = ", result)
if (result != null) {
viewModel.updateChipComponentResult(state, data, result)
val resultList = viewModel.updateChipComponentResult(state, data, result)
applyAdvanceFilters(state.selectedFilterIndex, resultList)
} else {
val isSelected = data.selectedName.isNotEmpty()
viewModel.updateSelected(state, data, isSelected)
Expand Down Expand Up @@ -384,4 +415,13 @@ class SearchFragment : Fragment(), MavericksView {
}
resultsFragment.setFilters(filter)
}

private fun applyAdvanceFilters(position: Int, list: MutableList<SearchChipCategory>) {
val advanceSearchFilter = emptyAdvanceFilters()

advanceSearchFilter.addAll(viewModel.initAdvanceFilters(position))

list.forEach { if (it.isSelected) advanceSearchFilter.add(AdvanceSearchFilter(it.selectedQuery, it.selectedName)) }
resultsFragment.setFilters(advanceSearchFilter)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,16 @@ class SearchViewModel(
private val searchEvents: MutableStateFlow<SearchParams>
private val appConfigModel: AppConfigModel
private var params: SearchParams
var isRefreshSearch = false

init {
setState { copy(filters = defaultFilters(state)) }

appConfigModel = repository.getAppConfig()
// TODO: move search params to state object
params = SearchParams("", state.contextId, defaultFilters(state), defaultAdvanceFilters(state), 0)
liveSearchEvents = MutableStateFlow(params)
searchEvents = MutableStateFlow(params)
appConfigModel = repository.getAppConfig()

setState { copy(listSearchFilters = appConfigModel.search) }

Expand All @@ -62,7 +63,7 @@ class SearchViewModel(
searchEvents
).filter {
it.terms.length >= MIN_QUERY_LENGTH
}.executeOnLatest({ repository.search(it.terms, it.contextId, it.filters, it.skipCount, it.maxItems) }) {
}.executeOnLatest({ repository.search(it.terms, it.contextId, it.filters, it.advanceSearchFilter, it.skipCount, it.maxItems) }) {
if (it is Loading) {
copy(request = it)
} else {
Expand Down Expand Up @@ -168,10 +169,25 @@ class SearchViewModel(
private fun defaultAdvanceFilters(state: SearchResultsState): AdvanceSearchFilters {
val list = emptyAdvanceFilters()
if (state.isContextual)
AdvanceSearchFilter(SearchFilter.Contextual.name, SearchFilter.Contextual.name)
list.add(AdvanceSearchFilter("+TYPE:'${SearchFilter.Contextual.name}'", SearchFilter.Contextual.name))
val index = appConfigModel.search?.indexOfFirst { it.default == true }
if (index != null)
list.addAll(initAdvanceFilters(index))
return list
}

list.add(AdvanceSearchFilter(SearchFilter.Files.name, SearchFilter.Files.name))
list.add(AdvanceSearchFilter(SearchFilter.Folders.name, SearchFilter.Folders.name))
/**
* default filters for the advance search
*/
fun initAdvanceFilters(index: Int): AdvanceSearchFilters {
val list = emptyAdvanceFilters()
if (appConfigModel.search?.size ?: 0 >= index) {
appConfigModel.search?.get(index)?.filterQueries?.filter { it.query != null }?.map { obj ->
obj.query?.let { query ->
list.add(AdvanceSearchFilter(query = query, name = query))
}
}
}
return list
}

Expand Down Expand Up @@ -200,13 +216,17 @@ class SearchViewModel(
if (advanceSearchFilter != params.advanceSearchFilter) {
params = params.copy(advanceSearchFilter = advanceSearchFilter)
refresh()
} else if (isRefreshSearch) {
params = params.copy(advanceSearchFilter = emptyAdvanceFilters())
refresh()
isRefreshSearch = false
}
}

/**
* update chip component data after apply or reset the component
*/
fun updateChipComponentResult(state: SearchResultsState, model: SearchChipCategory, metaData: ComponentMetaData) {
fun updateChipComponentResult(state: SearchResultsState, model: SearchChipCategory, metaData: ComponentMetaData): MutableList<SearchChipCategory> {
val list = mutableListOf<SearchChipCategory>()

state.listSearchCategoryChips?.forEach { obj ->
Expand All @@ -224,6 +244,21 @@ class SearchViewModel(
}

setState { copy(listSearchCategoryChips = list) }

return list
}

/**
* reset all the selected filters to default values
*/
fun resetChips(state: SearchResultsState): MutableList<SearchChipCategory> {
val list = mutableListOf<SearchChipCategory>()
state.listSearchCategoryChips?.forEach { obj ->
list.add(SearchChipCategory.resetData(obj))
}
setState { copy(listSearchCategoryChips = list) }

return list
}

/**
Expand All @@ -232,7 +267,7 @@ class SearchViewModel(
fun updateSelected(state: SearchResultsState, model: SearchChipCategory, isSelected: Boolean) {
val list = mutableListOf<SearchChipCategory>()

state.listSearchCategoryChips?.forEachIndexed { index, obj ->
state.listSearchCategoryChips?.forEach { obj ->
if (obj == model) {
list.add(
SearchChipCategory(
Expand Down
Loading

0 comments on commit 2385483

Please sign in to comment.