+
+
+
+
+
diff --git a/core/src/store/index.js b/core/src/store/index.js
new file mode 100644
index 0000000000000..d263a5dc40740
--- /dev/null
+++ b/core/src/store/index.js
@@ -0,0 +1,11 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import search from './unified-search-external-filters';
+
+Vue.use(Vuex);
+
+export default new Vuex.Store({
+ modules: {
+ search,
+ },
+});
diff --git a/core/src/store/unified-search-external-filters.js b/core/src/store/unified-search-external-filters.js
new file mode 100644
index 0000000000000..b55335c4a0ae6
--- /dev/null
+++ b/core/src/store/unified-search-external-filters.js
@@ -0,0 +1,42 @@
+/*
+ * @copyright Copyright (c) 2021 Fon E. Noel NFEBE
+ *
+ * @author Fon E. Noel NFEBE
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+const state = {
+ externalFilters: [],
+}
+
+const mutations = {
+ registerExternalFilter(state, { id, label, callback, icon }) {
+ state.externalFilters.push({ id, name: label, callback, icon, isPluginFilter: true })
+ },
+}
+
+const actions = {
+ registerExternalFilter({ commit }, { id, label, callback, icon }) {
+ commit('registerExternalFilter', { id, label, callback, icon })
+ },
+}
+
+export default {
+ state,
+ mutations,
+ actions,
+}
diff --git a/core/src/unified-search.js b/core/src/unified-search.js
index f9bddff4c6837..8650a2566d89a 100644
--- a/core/src/unified-search.js
+++ b/core/src/unified-search.js
@@ -26,6 +26,7 @@ import { translate as t, translatePlural as n } from '@nextcloud/l10n'
import Vue from 'vue'
import UnifiedSearch from './views/UnifiedSearch.vue'
+import store from '../src/store/index.js'
// eslint-disable-next-line camelcase
__webpack_nonce__ = btoa(getRequestToken())
@@ -47,9 +48,24 @@ Vue.mixin({
},
})
+// Register the add/register filter action API globally
+window.OCA.Core = window.OCA.Core || {}
+window.OCA.Core.UnifiedSearch = {
+ registerFilterAction: ({ id, name, label, callback, icon }) => {
+ store.dispatch('registerExternalFilter', {
+ id,
+ name,
+ label,
+ icon,
+ callback,
+ })
+ },
+}
+
export default new Vue({
el: '#unified-search',
// eslint-disable-next-line vue/match-component-file-name
name: 'UnifiedSearchRoot',
+ store,
render: h => h(UnifiedSearch),
})
diff --git a/core/src/views/UnifiedSearchModal.vue b/core/src/views/UnifiedSearchModal.vue
index 9c719d2bcf6a3..28ca2cd588c05 100644
--- a/core/src/views/UnifiedSearchModal.vue
+++ b/core/src/views/UnifiedSearchModal.vue
@@ -1,29 +1,20 @@
-
-
+
-
-
+
@@ -152,6 +134,7 @@ import SearchResult from '../components/UnifiedSearch/SearchResult.vue'
import debounce from 'debounce'
import { emit } from '@nextcloud/event-bus'
import { useBrowserLocation } from '@vueuse/core'
+import { mapState } from 'vuex'
import { getProviders, search as unifiedSearch, getContacts } from '../services/UnifiedSearchService.js'
export default {
@@ -193,6 +176,7 @@ export default {
},
data() {
return {
+ searchScope: 'everywhere',
providers: [],
providerActionMenuIsOpen: false,
dateActionMenuIsOpen: false,
@@ -217,6 +201,9 @@ export default {
},
computed: {
+ ...mapState({
+ externalFilters: state => state.search.externalFilters,
+ }),
userContacts() {
return this.contacts
},
@@ -252,6 +239,9 @@ export default {
mounted() {
getProviders().then((providers) => {
this.providers = providers
+ this.externalFilters.forEach(filter => {
+ this.providers.push(filter)
+ })
console.debug('Search providers', this.providers)
})
getContacts({ searchTerm: '' }).then((contacts) => {
@@ -267,6 +257,16 @@ export default {
this.searching = false
return
}
+ switch (this.searchScope) {
+ case 'everywhere':
+ // Code to execute if searchScope is 'everywhere'
+ break
+ case 'conversation':
+ // Code to execute if searchScope is 'conversation'
+ break
+ default:
+ // Code to execute if searchScope is neither 'everywhere' nor 'conversation'
+ }
// Event should probably be refactored at some point to used nextcloud:unified-search.search
emit('nextcloud:unified-search.search', { query })
const newResults = []
@@ -404,6 +404,9 @@ export default {
},
addProviderFilter(providerFilter, loadMoreResultsForProvider = false) {
if (!providerFilter.id) return
+ if (providerFilter.isPluginFilter) {
+ providerFilter.callback()
+ }
this.providerResultLimit = loadMoreResultsForProvider ? this.providerResultLimit : 5
this.providerActionMenuIsOpen = false
const existingFilter = this.filteredProviders.find(existing => existing.id === providerFilter.id)
@@ -481,39 +484,39 @@ export default {
let endDate
switch (range) {
- case 'today':
- // For 'Today', both start and end are set to today
- startDate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0)
- endDate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59, 999)
- this.dateFilter.text = t('core', 'Today')
- break
- case '7days':
- // For 'Last 7 days', start date is 7 days ago, end is today
- startDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 6, 0, 0, 0, 0)
- this.dateFilter.text = t('core', 'Last 7 days')
- break
- case '30days':
- // For 'Last 30 days', start date is 30 days ago, end is today
- startDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 29, 0, 0, 0, 0)
- this.dateFilter.text = t('core', 'Last 30 days')
- break
- case 'thisyear':
- // For 'This year', start date is the first day of the year, end is the last day of the year
- startDate = new Date(today.getFullYear(), 0, 1, 0, 0, 0, 0)
- endDate = new Date(today.getFullYear(), 11, 31, 23, 59, 59, 999)
- this.dateFilter.text = t('core', 'This year')
- break
- case 'lastyear':
- // For 'Last year', start date is the first day of the previous year, end is the last day of the previous year
- startDate = new Date(today.getFullYear() - 1, 0, 1, 0, 0, 0, 0)
- endDate = new Date(today.getFullYear() - 1, 11, 31, 23, 59, 59, 999)
- this.dateFilter.text = t('core', 'Last year')
- break
- case 'custom':
- this.showDateRangeModal = true
- return
- default:
- return
+ case 'today':
+ // For 'Today', both start and end are set to today
+ startDate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0)
+ endDate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59, 999)
+ this.dateFilter.text = t('core', 'Today')
+ break
+ case '7days':
+ // For 'Last 7 days', start date is 7 days ago, end is today
+ startDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 6, 0, 0, 0, 0)
+ this.dateFilter.text = t('core', 'Last 7 days')
+ break
+ case '30days':
+ // For 'Last 30 days', start date is 30 days ago, end is today
+ startDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 29, 0, 0, 0, 0)
+ this.dateFilter.text = t('core', 'Last 30 days')
+ break
+ case 'thisyear':
+ // For 'This year', start date is the first day of the year, end is the last day of the year
+ startDate = new Date(today.getFullYear(), 0, 1, 0, 0, 0, 0)
+ endDate = new Date(today.getFullYear(), 11, 31, 23, 59, 59, 999)
+ this.dateFilter.text = t('core', 'This year')
+ break
+ case 'lastyear':
+ // For 'Last year', start date is the first day of the previous year, end is the last day of the previous year
+ startDate = new Date(today.getFullYear() - 1, 0, 1, 0, 0, 0, 0)
+ endDate = new Date(today.getFullYear() - 1, 11, 31, 23, 59, 59, 999)
+ this.dateFilter.text = t('core', 'Last year')
+ break
+ case 'custom':
+ this.showDateRangeModal = true
+ return
+ default:
+ return
}
this.dateFilter.startFrom = startDate
this.dateFilter.endAt = endDate
@@ -527,6 +530,15 @@ export default {
this.dateFilter.text = t('core', `Between ${this.dateFilter.startFrom.toLocaleDateString()} and ${this.dateFilter.endAt.toLocaleDateString()}`)
this.updateDateFilter()
},
+ setSearchScopeToConversation(event) {
+ for (const provider of this.filteredProviders) {
+ if (provider.id === 'inConversation') {
+ provider.name = `Search in talk room : ${event.displayName}`
+ break
+ }
+ }
+ console.debug('Search scope set to conversation', event)
+ },
focusInput() {
this.$refs.searchInput.$el.children[0].children[0].focus()
},
@@ -549,7 +561,7 @@ export default {
padding-block: 10px 0;
// inline padding on direct children to make sure the scrollbar is on the modal container
- > * {
+ >* {
padding-inline: 20px;
}