From 86da2adf3f03df2021ed237425931388f34978fc Mon Sep 17 00:00:00 2001 From: fenn-cs Date: Mon, 29 Jan 2024 12:20:05 +0100 Subject: [PATCH] feat(core): create filter-plugin architecture for unified search This commit introduces the mechanism for apps out of the call, to add search filters to the unified search "Places" filter selector. Signed-off-by: fenn-cs --- core/src/services/UnifiedSearchService.js | 4 +- core/src/store/index.js | 11 +++ .../store/unified-search-external-filters.js | 42 ++++++++++ core/src/unified-search.js | 16 ++++ core/src/views/UnifiedSearchModal.vue | 77 +++++++++++++++++-- 5 files changed, 142 insertions(+), 8 deletions(-) create mode 100644 core/src/store/index.js create mode 100644 core/src/store/unified-search-external-filters.js diff --git a/core/src/services/UnifiedSearchService.js b/core/src/services/UnifiedSearchService.js index 9e16fe1880c12..54cd19b6a9218 100644 --- a/core/src/services/UnifiedSearchService.js +++ b/core/src/services/UnifiedSearchService.js @@ -65,9 +65,10 @@ export async function getProviders() { * @param {string} options.until the search * @param {string} options.limit the search * @param {string} options.person the search + * @param {object} options.extraQueries additional queries to filter search results * @return {object} {request: Promise, cancel: Promise} */ -export function search({ type, query, cursor, since, until, limit, person }) { +export function search({ type, query, cursor, since, until, limit, person, extraQueries = {} }) { /** * Generate an axios cancel token */ @@ -84,6 +85,7 @@ export function search({ type, query, cursor, since, until, limit, person }) { person, // Sending which location we're currently at from: window.location.pathname.replace('/index.php', '') + window.location.search, + ...extraQueries, }, }) 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..27e947780fe9e 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.OCP = window.OCP || {} +window.OCP.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 101859f950fee..881e49d6405d6 100644 --- a/core/src/views/UnifiedSearchModal.vue +++ b/core/src/views/UnifiedSearchModal.vue @@ -18,12 +18,14 @@ :label="t('core', 'Search apps, files, tags, messages') + '...'" @update:value="debouncedFind" />
- + +