Browse Source

Move unified search to OCS api

Signed-off-by: Joas Schilling <coding@schilljs.com>
tags/v20.0.0beta4
Joas Schilling 3 years ago
parent
commit
fea294bb29
No account linked to committer's email address

+ 10
- 10
core/Controller/UnifiedSearchController.php View File



use OC\Search\SearchComposer; use OC\Search\SearchComposer;
use OC\Search\SearchQuery; use OC\Search\SearchQuery;
use OCP\AppFramework\Controller;
use OCP\AppFramework\OCSController;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\DataResponse;
use OCP\IRequest; use OCP\IRequest;
use OCP\IUserSession; use OCP\IUserSession;
use OCP\Route\IRouter; use OCP\Route\IRouter;
use OCP\Search\ISearchQuery; use OCP\Search\ISearchQuery;
use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Exception\ResourceNotFoundException;


class UnifiedSearchController extends Controller {
class UnifiedSearchController extends OCSController {


/** @var SearchComposer */ /** @var SearchComposer */
private $composer; private $composer;
* *
* @param string $from the url the user is currently at * @param string $from the url the user is currently at
* *
* @return JSONResponse
* @return DataResponse
*/ */
public function getProviders(string $from = ''): JSONResponse {
public function getProviders(string $from = ''): DataResponse {
[$route, $parameters] = $this->getRouteInformation($from); [$route, $parameters] = $this->getRouteInformation($from);


return new JSONResponse(
return new DataResponse(
$this->composer->getProviders($route, $parameters) $this->composer->getProviders($route, $parameters)
); );
} }
* @param int|string|null $cursor * @param int|string|null $cursor
* @param string $from * @param string $from
* *
* @return JSONResponse
* @return DataResponse
*/ */
public function search(string $providerId, public function search(string $providerId,
string $term = '', string $term = '',
?int $sortOrder = null, ?int $sortOrder = null,
?int $limit = null, ?int $limit = null,
$cursor = null, $cursor = null,
string $from = ''): JSONResponse {
string $from = ''): DataResponse {
if (empty(trim($term))) { if (empty(trim($term))) {
return new JSONResponse(null, Http::STATUS_BAD_REQUEST);
return new DataResponse(null, Http::STATUS_BAD_REQUEST);
} }
[$route, $routeParameters] = $this->getRouteInformation($from); [$route, $routeParameters] = $this->getRouteInformation($from);


return new JSONResponse(
return new DataResponse(
$this->composer->search( $this->composer->search(
$this->userSession->getUser(), $this->userSession->getUser(),
$providerId, $providerId,

+ 1
- 1
core/js/dist/unified-search.js
File diff suppressed because it is too large
View File


+ 1
- 1
core/js/dist/unified-search.js.map
File diff suppressed because it is too large
View File


+ 5
- 3
core/routes.php View File

['name' => 'RecommendedApps#index', 'url' => '/core/apps/recommended', 'verb' => 'GET'], ['name' => 'RecommendedApps#index', 'url' => '/core/apps/recommended', 'verb' => 'GET'],
['name' => 'Svg#getSvgFromCore', 'url' => '/svg/core/{folder}/{fileName}', 'verb' => 'GET'], ['name' => 'Svg#getSvgFromCore', 'url' => '/svg/core/{folder}/{fileName}', 'verb' => 'GET'],
['name' => 'Svg#getSvgFromApp', 'url' => '/svg/{app}/{fileName}', 'verb' => 'GET'], ['name' => 'Svg#getSvgFromApp', 'url' => '/svg/{app}/{fileName}', 'verb' => 'GET'],
['name' => 'UnifiedSearch#getProviders', 'url' => '/search/providers', 'verb' => 'GET'],
['name' => 'UnifiedSearch#search', 'url' => '/search/providers/{providerId}/search', 'verb' => 'GET'],
['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'], ['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'],
['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'], ['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'],
['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'], ['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'],


['root' => '/collaboration', 'name' => 'CollaborationResources#removeResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'DELETE'], ['root' => '/collaboration', 'name' => 'CollaborationResources#removeResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'DELETE'],
['root' => '/collaboration', 'name' => 'CollaborationResources#getCollectionsByResource', 'url' => '/resources/{resourceType}/{resourceId}', 'verb' => 'GET'], ['root' => '/collaboration', 'name' => 'CollaborationResources#getCollectionsByResource', 'url' => '/resources/{resourceType}/{resourceId}', 'verb' => 'GET'],
['root' => '/collaboration', 'name' => 'CollaborationResources#createCollectionOnResource', 'url' => '/resources/{baseResourceType}/{baseResourceId}', 'verb' => 'POST']
['root' => '/collaboration', 'name' => 'CollaborationResources#createCollectionOnResource', 'url' => '/resources/{baseResourceType}/{baseResourceId}', 'verb' => 'POST'],

// Unified search
['root' => '/search', 'name' => 'UnifiedSearch#getProviders', 'url' => '/providers', 'verb' => 'GET'],
['root' => '/search', 'name' => 'UnifiedSearch#search', 'url' => '/providers/{providerId}/search', 'verb' => 'GET'],


], ],
]); ]);

+ 6
- 5
core/src/services/UnifiedSearchService.js View File

* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */


import { generateUrl } from '@nextcloud/router'
import { generateOcsUrl } from '@nextcloud/router'
import { loadState } from '@nextcloud/initial-state' import { loadState } from '@nextcloud/initial-state'
import axios from '@nextcloud/axios' import axios from '@nextcloud/axios'


*/ */
export async function getTypes() { export async function getTypes() {
try { try {
const { data } = await axios.get(generateUrl('/search/providers'), {
const { data } = await axios.get(generateOcsUrl('search', 2) + 'providers', {
params: { params: {
// Sending which location we're currently at // Sending which location we're currently at
from: window.location.pathname.replace('/index.php', '') + window.location.search, from: window.location.pathname.replace('/index.php', '') + window.location.search,
}, },
}) })
if (Array.isArray(data) && data.length > 0) {
if ('ocs' in data && 'data' in data.ocs && Array.isArray(data.ocs.data) && data.ocs.data.length > 0) {
// Providers are sorted by the api based on their order key // Providers are sorted by the api based on their order key
return data
return data.ocs.data
} }
} catch (error) { } catch (error) {
console.error(error) console.error(error)
* @returns {Promise} * @returns {Promise}
*/ */
export function search(type, query, cursor) { export function search(type, query, cursor) {
return axios.get(generateUrl(`/search/providers/${type}/search?term=${query}`), {
return axios.get(generateOcsUrl('search', 2) + `providers/${type}/search`, {
params: { params: {
term: query,
cursor, cursor,
// Sending which location we're currently at // Sending which location we're currently at
from: window.location.pathname.replace('/index.php', '') + window.location.search, from: window.location.pathname.replace('/index.php', '') + window.location.search,

+ 11
- 11
core/src/views/UnifiedSearch.vue View File

const request = await search(type, query) const request = await search(type, query)


// Process results // Process results
if (request.data.entries.length > 0) {
this.$set(this.results, type, request.data.entries)
if (request.data.ocs.data.entries.length > 0) {
this.$set(this.results, type, request.data.ocs.data.entries)
} else { } else {
this.$delete(this.results, type) this.$delete(this.results, type)
} }


// Save cursor if any // Save cursor if any
if (request.data.cursor) {
this.$set(this.cursors, type, request.data.cursor)
} else if (!request.data.isPaginated) {
if (request.data.ocs.data.cursor) {
this.$set(this.cursors, type, request.data.ocs.data.cursor)
} else if (!request.data.ocs.data.isPaginated) {
// If no cursor and no pagination, we save the default amount // If no cursor and no pagination, we save the default amount
// provided by server's initial state `defaultLimit` // provided by server's initial state `defaultLimit`
this.$set(this.limits, type, this.defaultLimit) this.$set(this.limits, type, this.defaultLimit)
} }


// Check if we reached end of pagination // Check if we reached end of pagination
if (request.data.entries.length < this.defaultLimit) {
if (request.data.ocs.data.entries.length < this.defaultLimit) {
this.$set(this.reached, type, true) this.$set(this.reached, type, true)
} }


const request = await search(type, this.query, this.cursors[type]) const request = await search(type, this.query, this.cursors[type])


// Save cursor if any // Save cursor if any
if (request.data.cursor) {
this.$set(this.cursors, type, request.data.cursor)
if (request.data.ocs.data.cursor) {
this.$set(this.cursors, type, request.data.ocs.data.cursor)
} }


if (request.data.entries.length > 0) {
this.results[type].push(...request.data.entries)
if (request.data.ocs.data.entries.length > 0) {
this.results[type].push(...request.data.ocs.data.entries)
} }


// Check if we reached end of pagination // Check if we reached end of pagination
if (request.data.entries.length < this.defaultLimit) {
if (request.data.ocs.data.entries.length < this.defaultLimit) {
this.$set(this.reached, type, true) this.$set(this.reached, type, true)
} }
} else } else

Loading…
Cancel
Save