Skip to content

Commit

Permalink
Search on current folder
Browse files Browse the repository at this point in the history
While api not implemented on our Reva banckend
  • Loading branch information
diocas committed Jun 1, 2023
1 parent 808848f commit f22428c
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 14 deletions.
4 changes: 3 additions & 1 deletion packages/web-app-files/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import SpaceProjects from './views/spaces/Projects.vue'
import translations from '../l10n/translations.json'
import quickActions from './quickActions'
import store from './store'
import { SDKSearch } from './search'
import { FilterSearch, SDKSearch } from './search'
import { eventBus } from 'web-pkg/src/services/eventBus'
import { archiverService, thumbnailService, Registry } from './services'
import fileSideBars from './fileSideBars'
Expand Down Expand Up @@ -129,10 +129,12 @@ export default {
quickActions,
translations,
ready({ router, store }) {
Registry.filterSearch = new FilterSearch(store, router)
Registry.sdkSearch = new SDKSearch(store, router)

// when discussing the boot process of applications we need to implement a
// registry that does not rely on call order, aka first register "on" and only after emit.
eventBus.publish('app.search.register.provider', Registry.filterSearch)
eventBus.publish('app.search.register.provider', Registry.sdkSearch)

archiverService.initialize(
Expand Down
48 changes: 48 additions & 0 deletions packages/web-app-files/src/mixins/filesListFilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Registry } from '../services'
import { mapMutations } from 'vuex'
import { onBeforeUnmount } from 'vue'

export default {
mounted() {
const { filterSearch } = Registry

if (!filterSearch || !filterSearch.available) {
return
}

const resetEventToken = filterSearch.subscribe('reset', () => {
this.CLEAR_FILES_SEARCHED()
})

const updateTermEventToken = filterSearch.subscribe('updateTerm', (term) => {
if (!term) {
this.CLEAR_FILES_SEARCHED()
}
})

const activateEventToken = filterSearch.subscribe('activate', ({ resources }) => {
this.LOAD_FILES_SEARCHED(resources)
})

onBeforeUnmount(() => {
filterSearch.unsubscribe('reset', resetEventToken)
filterSearch.unsubscribe('updateTerm', updateTermEventToken)
filterSearch.unsubscribe('activate', activateEventToken)
})
},
watch: {
$route: {
handler: function (to, from) {
if (to.name === from?.name && to.params?.item === from?.params?.item) {
return
}

this.CLEAR_FILES_SEARCHED()
},
immediate: true
}
},
methods: {
...mapMutations('Files', ['CLEAR_FILES_SEARCHED', 'LOAD_FILES_SEARCHED'])
}
}
53 changes: 53 additions & 0 deletions packages/web-app-files/src/search/filter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { SearchProvider, SearchList, SearchPreview } from 'web-app-search/src/types'
import Preview from './preview'
import { EventBus } from 'web-pkg/src/services/eventBus'
import { filterResources } from '../../helpers/resource'
import { Store } from 'vuex'
import { Router } from 'vue-router'
import { isLocationSpacesActive } from '../../router'

function $gettext(msg) {
return msg
}
export default class Provider extends EventBus implements SearchProvider {
public readonly id: string
public readonly displayName: string
public readonly previewSearch: SearchPreview
public readonly listSearch: SearchList
private readonly store: Store<any>
private readonly router: Router

constructor(store: Store<any>, router: Router) {
super()

this.id = 'files.filter'
this.displayName = $gettext('In this folder')
this.store = store
this.router = router
this.previewSearch = new Preview(store, router)
}

public activate(term: string): void {
if (!term) {
return
}

const resources = filterResources(this.store.getters['Files/files'], term)
this.publish('activate', { term, resources })
}

public reset(): void {
this.publish('reset')
}

public updateTerm(term: string): void {
this.publish('updateTerm', term)
}

public get available(): boolean {
return (
isLocationSpacesActive(this.router, 'files-spaces-generic') &&
!isLocationSpacesActive(this.router, 'files-spaces-projects')
)
}
}
46 changes: 46 additions & 0 deletions packages/web-app-files/src/search/filter/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { SearchPreview, SearchResult } from 'web-app-search/src/types'
import PreviewComponent from '../../components/Search/Preview.vue'
import { filterResources } from '../../helpers/resource'
import { Store } from 'vuex'
import { Component, unref } from 'vue'
import { Router } from 'vue-router'

export default class Preview implements SearchPreview {
public readonly component: Component
private readonly router: Router
private readonly store: Store<any>

constructor(store: Store<any>, router: Router) {
this.component = PreviewComponent
this.router = router
this.store = store
}

public search(term: string): Promise<SearchResult> {
if (!term) {
return Promise.resolve({
totalResults: null,
values: []
})
}
// no cache required, the filtering is client only and fast enough to recalculate the set
// of results every time on the fly
const resources: any[] = filterResources(this.store.getters['Files/files'], term, 5)
const areHiddenFilesShown = this.store.state.Files?.areHiddenFilesShown

const searchResult = resources.reduce((acc, resource) => {
// filter results if hidden files shouldn't be shown due to settings
if (!resource.name.startsWith('.') || areHiddenFilesShown) {
acc.push({ id: resource.id, data: { ...resource, storageId: 'eos' } })
}

return acc
}, [])

return Promise.resolve({ totalResults: searchResult.length, values: searchResult })
}

public get available(): boolean {
return unref(this.router.currentRoute).name !== 'search-provider-list'
}
}
1 change: 1 addition & 0 deletions packages/web-app-files/src/search/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default as SDKSearch } from './sdk'
export { default as FilterSearch } from './filter'
3 changes: 2 additions & 1 deletion packages/web-app-files/src/services/registry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SDKSearch } from '../search'
import { FilterSearch, SDKSearch } from '../search'

export default class Registry {
static filterSearch: FilterSearch
static sdkSearch: SDKSearch
}
4 changes: 3 additions & 1 deletion packages/web-app-files/src/views/spaces/GenericSpace.vue
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ import { CreateTargetRouteOptions } from 'web-app-files/src/helpers/folderLink/t
import SingleSharedFile from './SingleSharedFile.vue'
import Home from './Home.vue'
import MixinFilesListFilter from '../../mixins/filesListFilter'
const visibilityObserver = new VisibilityObserver()
export default defineComponent({
Expand All @@ -214,7 +216,7 @@ export default defineComponent({
Home
},
mixins: [MixinAccessibleBreadcrumb, MixinFileActions],
mixins: [MixinAccessibleBreadcrumb, MixinFileActions, MixinFilesListFilter],
props: {
space: {
Expand Down
16 changes: 5 additions & 11 deletions packages/web-app-search/src/portals/SearchBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,7 @@
<oc-list>
<li class="oc-text-truncate oc-flex oc-flex-between oc-text-muted provider-details">
<span class="display-name">{{ provider.displayName }}</span>
<span>
<router-link
class="more-results"
:to="getMoreResultsLinkForProvider(provider)"
@click="hideOptionsDrop"
>
<span>{{ getMoreResultsDetailsTextForProvider(provider) }}</span>
</router-link>
</span>
<span>{{ getMoreResultsDetailsTextForProvider(provider) }}</span>
</li>
<li
v-for="providerSearchResultValue in getSearchResultForProvider(provider).values"
Expand Down Expand Up @@ -248,6 +240,8 @@ export default defineComponent({
this.$refs.optionsDrop.hide()
},
onKeyUpEnter() {
// Do not show the results page for local filter provider
return
this.$refs.optionsDrop.hide()
if (this.term && this.activePreviewIndex === null) {
Expand Down Expand Up @@ -334,8 +328,8 @@ export default defineComponent({
}
const translated = this.$ngettext(
'Show %{totalResults} result',
'Show %{totalResults} results',
'%{totalResults} result',
'%{totalResults} results',
searchResult.totalResults
)
Expand Down

0 comments on commit f22428c

Please sign in to comment.