mirror of
https://github.com/nextcloud/server.git
synced 2026-06-10 09:13:19 -04:00
Merge pull request #53996 from nextcloud/feat/unified_search/online_providers
feat(UnifiedSearch): Online search providers support, toggle option
This commit is contained in:
commit
92e282af0b
13 changed files with 92 additions and 6 deletions
|
|
@ -87,6 +87,7 @@ namespace OC\Core;
|
|||
* name: string,
|
||||
* icon: string,
|
||||
* order: int,
|
||||
* isExternalProvider: bool,
|
||||
* triggers: list<string>,
|
||||
* filters: array<string, string>,
|
||||
* inAppSearch: bool,
|
||||
|
|
|
|||
|
|
@ -1045,6 +1045,7 @@
|
|||
"name",
|
||||
"icon",
|
||||
"order",
|
||||
"isExternalProvider",
|
||||
"triggers",
|
||||
"filters",
|
||||
"inAppSearch"
|
||||
|
|
@ -1066,6 +1067,9 @@
|
|||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"isExternalProvider": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"triggers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
|
|
|||
|
|
@ -1045,6 +1045,7 @@
|
|||
"name",
|
||||
"icon",
|
||||
"order",
|
||||
"isExternalProvider",
|
||||
"triggers",
|
||||
"filters",
|
||||
"inAppSearch"
|
||||
|
|
@ -1066,6 +1067,9 @@
|
|||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"isExternalProvider": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"triggers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
|
|
|||
|
|
@ -86,6 +86,13 @@
|
|||
<IconFilter :size="20" />
|
||||
</template>
|
||||
</NcButton>
|
||||
<NcCheckboxRadioSwitch v-if="hasExternalResources"
|
||||
v-model="searchExternalResources"
|
||||
type="switch"
|
||||
class="unified-search-modal__search-external-resources"
|
||||
:class="{'unified-search-modal__search-external-resources--aligned': localSearch}">
|
||||
{{ t('core', 'Search connected services') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
</div>
|
||||
<div class="unified-search-modal__filters-applied">
|
||||
<FilterChip v-for="filter in filters"
|
||||
|
|
@ -172,6 +179,7 @@ import NcButton from '@nextcloud/vue/components/NcButton'
|
|||
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
|
||||
import NcInputField from '@nextcloud/vue/components/NcInputField'
|
||||
import NcDialog from '@nextcloud/vue/components/NcDialog'
|
||||
import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
|
||||
|
||||
import CustomDateRangeModal from './CustomDateRangeModal.vue'
|
||||
import FilterChip from './SearchFilterChip.vue'
|
||||
|
|
@ -198,6 +206,7 @@ export default defineComponent({
|
|||
NcEmptyContent,
|
||||
NcDialog,
|
||||
NcInputField,
|
||||
NcCheckboxRadioSwitch,
|
||||
SearchableList,
|
||||
SearchResult,
|
||||
},
|
||||
|
|
@ -264,6 +273,7 @@ export default defineComponent({
|
|||
showDateRangeModal: false,
|
||||
internalIsVisible: this.open,
|
||||
initialized: false,
|
||||
searchExternalResources: false,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -301,6 +311,10 @@ export default defineComponent({
|
|||
debouncedFilterContacts() {
|
||||
return debounce(this.filterContacts, 300)
|
||||
},
|
||||
|
||||
hasExternalResources() {
|
||||
return this.providers.some(provider => provider.isExternalProvider)
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
|
|
@ -338,6 +352,12 @@ export default defineComponent({
|
|||
this.$emit('update:query', this.searchQuery)
|
||||
},
|
||||
},
|
||||
|
||||
searchExternalResources() {
|
||||
if (this.searchQuery) {
|
||||
this.find(this.searchQuery)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
|
|
@ -418,6 +438,14 @@ export default defineComponent({
|
|||
unifiedSearchLogger.debug('Limiting search to', params.limit)
|
||||
}
|
||||
|
||||
const shouldSkipSearch = !this.searchExternalResources && provider.isExternalProvider
|
||||
const wasManuallySelected = this.filteredProviders.some(filteredProvider => filteredProvider.id === provider.id)
|
||||
// if the provider is an external resource and the user has not manually selected it, skip the search
|
||||
if (shouldSkipSearch && !wasManuallySelected) {
|
||||
this.searching = false
|
||||
return
|
||||
}
|
||||
|
||||
const request = unifiedSearch(params).request
|
||||
|
||||
request().then((response) => {
|
||||
|
|
@ -742,6 +770,21 @@ export default defineComponent({
|
|||
padding-top: 4px;
|
||||
}
|
||||
|
||||
&__search-external-resources {
|
||||
:deep(span.checkbox-content) {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
:deep(.checkbox-content__icon) {
|
||||
margin: auto !important;
|
||||
}
|
||||
|
||||
&--aligned {
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&__filters-applied {
|
||||
padding-top: 4px;
|
||||
display: flex;
|
||||
|
|
|
|||
4
dist/core-common.js
vendored
4
dist/core-common.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-common.js.map
vendored
2
dist/core-common.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/core-unified-search.js
vendored
4
dist/core-unified-search.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-unified-search.js.map
vendored
2
dist/core-unified-search.js.map
vendored
File diff suppressed because one or more lines are too long
|
|
@ -739,6 +739,7 @@ return array(
|
|||
'OCP\\SabrePluginEvent' => $baseDir . '/lib/public/SabrePluginEvent.php',
|
||||
'OCP\\SabrePluginException' => $baseDir . '/lib/public/SabrePluginException.php',
|
||||
'OCP\\Search\\FilterDefinition' => $baseDir . '/lib/public/Search/FilterDefinition.php',
|
||||
'OCP\\Search\\IExternalProvider' => $baseDir . '/lib/public/Search/IExternalProvider.php',
|
||||
'OCP\\Search\\IFilter' => $baseDir . '/lib/public/Search/IFilter.php',
|
||||
'OCP\\Search\\IFilterCollection' => $baseDir . '/lib/public/Search/IFilterCollection.php',
|
||||
'OCP\\Search\\IFilteringProvider' => $baseDir . '/lib/public/Search/IFilteringProvider.php',
|
||||
|
|
|
|||
|
|
@ -780,6 +780,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OCP\\SabrePluginEvent' => __DIR__ . '/../../..' . '/lib/public/SabrePluginEvent.php',
|
||||
'OCP\\SabrePluginException' => __DIR__ . '/../../..' . '/lib/public/SabrePluginException.php',
|
||||
'OCP\\Search\\FilterDefinition' => __DIR__ . '/../../..' . '/lib/public/Search/FilterDefinition.php',
|
||||
'OCP\\Search\\IExternalProvider' => __DIR__ . '/../../..' . '/lib/public/Search/IExternalProvider.php',
|
||||
'OCP\\Search\\IFilter' => __DIR__ . '/../../..' . '/lib/public/Search/IFilter.php',
|
||||
'OCP\\Search\\IFilterCollection' => __DIR__ . '/../../..' . '/lib/public/Search/IFilterCollection.php',
|
||||
'OCP\\Search\\IFilteringProvider' => __DIR__ . '/../../..' . '/lib/public/Search/IFilteringProvider.php',
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use OCP\IAppConfig;
|
|||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
use OCP\Search\FilterDefinition;
|
||||
use OCP\Search\IExternalProvider;
|
||||
use OCP\Search\IFilter;
|
||||
use OCP\Search\IFilteringProvider;
|
||||
use OCP\Search\IInAppSearch;
|
||||
|
|
@ -178,6 +179,7 @@ class SearchComposer {
|
|||
if ($order === null) {
|
||||
return;
|
||||
}
|
||||
$isExternalProvider = $provider instanceof IExternalProvider ? $provider->isExternalProvider() : false;
|
||||
$triggers = [$provider->getId()];
|
||||
if ($provider instanceof IFilteringProvider) {
|
||||
$triggers += $provider->getAlternateIds();
|
||||
|
|
@ -192,6 +194,7 @@ class SearchComposer {
|
|||
'name' => $provider->getName(),
|
||||
'icon' => $this->fetchIcon($appId, $provider->getId()),
|
||||
'order' => $order,
|
||||
'isExternalProvider' => $isExternalProvider,
|
||||
'triggers' => array_values($triggers),
|
||||
'filters' => $this->getFiltersType($filters, $provider->getId()),
|
||||
'inAppSearch' => $provider instanceof IInAppSearch,
|
||||
|
|
|
|||
25
lib/public/Search/IExternalProvider.php
Normal file
25
lib/public/Search/IExternalProvider.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCP\Search;
|
||||
|
||||
/**
|
||||
* Interface for search providers that forward user queries to external services.
|
||||
*
|
||||
* @since 32.0.0
|
||||
*/
|
||||
interface IExternalProvider extends IProvider {
|
||||
/**
|
||||
* Indicates whether this search provider queries external (3rd-party) resources.
|
||||
* This is used by the Unified Search modal filter (toggle switch). By default, searching through external providers is disabled.
|
||||
*
|
||||
* @return bool default false
|
||||
*
|
||||
* @since 32.0.0
|
||||
*/
|
||||
public function isExternalProvider(): bool;
|
||||
}
|
||||
|
|
@ -1083,6 +1083,7 @@
|
|||
"name",
|
||||
"icon",
|
||||
"order",
|
||||
"isExternalProvider",
|
||||
"triggers",
|
||||
"filters",
|
||||
"inAppSearch"
|
||||
|
|
@ -1104,6 +1105,9 @@
|
|||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"isExternalProvider": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"triggers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
|
|
|||
Loading…
Reference in a new issue