Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Advanced search queries #2934

Merged
merged 12 commits into from
Apr 13, 2021
2 changes: 2 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,7 @@
['name' => 'comments_api#delete', 'url' => '/api/v{apiVersion}/cards/{cardId}/comments/{commentId}', 'verb' => 'DELETE'],

['name' => 'overview_api#upcomingCards', 'url' => '/api/v{apiVersion}/overview/upcoming', 'verb' => 'GET'],

['name' => 'search#search', 'url' => '/api/v{apiVersion}/search', 'verb' => 'GET'],
]
];
68 changes: 37 additions & 31 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,34 +1,40 @@
{
"name": "nextcloud/deck",
"type": "project",
"license": "AGPLv3",
"authors": [
{
"name": "Julius Härtl",
"email": "[email protected]"
}
],
"require": {
"cogpowered/finediff": "0.3.*"
},
"require-dev": {
"roave/security-advisories": "dev-master",
"christophwurst/nextcloud": "^21@dev",
"phpunit/phpunit": "^8",
"nextcloud/coding-standard": "^0.5.0",
"symfony/event-dispatcher": "^4.0",
"vimeo/psalm": "^4.3",
"php-parallel-lint/php-parallel-lint": "^1.2"
},
"config": {
"optimize-autoloader": true,
"classmap-authoritative": true
},
"scripts": {
"lint": "find . -name \\*.php -not -path './vendor/*' -print0 | xargs -0 -n1 php -l",
"cs:check": "php-cs-fixer fix --dry-run --diff",
"cs:fix": "php-cs-fixer fix",
"name": "nextcloud/deck",
"type": "project",
"license": "AGPLv3",
"authors": [
{
"name": "Julius Härtl",
"email": "[email protected]"
}
],
"require": {
"cogpowered/finediff": "0.3.*"
},
"require-dev": {
"roave/security-advisories": "dev-master",
"christophwurst/nextcloud": "^21@dev",
"phpunit/phpunit": "^8",
"nextcloud/coding-standard": "^0.5.0",
"symfony/event-dispatcher": "^4.0",
"vimeo/psalm": "^4.3",
"php-parallel-lint/php-parallel-lint": "^1.2"
},
"config": {
"optimize-autoloader": true,
"classmap-authoritative": true
},
"scripts": {
"lint": "find . -name \\*.php -not -path './vendor/*' -print0 | xargs -0 -n1 php -l",
"cs:check": "php-cs-fixer fix --dry-run --diff",
"cs:fix": "php-cs-fixer fix",
"psalm": "psalm",
"psalm:fix": "psalm --alter --issues=InvalidReturnType,InvalidNullableReturnType,MismatchingDocblockParamType,MismatchingDocblockReturnType,MissingParamType,InvalidFalsableReturnType"
}
"psalm:fix": "psalm --alter --issues=InvalidReturnType,InvalidNullableReturnType,MismatchingDocblockParamType,MismatchingDocblockReturnType,MissingParamType,InvalidFalsableReturnType",
"test": [
"@test:unit",
"@test:integration"
],
"test:unit": "phpunit -c tests/phpunit.xml",
"test:integration": "phpunit -c tests/phpunit.integration.xml && cd tests/integration && ./run.sh"
}
}
22 changes: 22 additions & 0 deletions docs/User_documentation_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,25 @@ The **sharing tab** allows you to add users or even groups to your boards.
**Deleted objects** allows you to return previously deleted stacks or cards.
The **Timeline** allows you to see everything that happened in your boards. Everything!

## Search

Deck provides a global search either through the unified search in the Nextcloud header or with the inline search next to the board controls.
This search allows advanced filtering of cards across all board of the logged in user.

For example the search `project tag:ToDo assigned:alice assigned:bob` will return all cards where the card title or description contains project **and** the tag ToDo is set **and** the user alice is assigned **and** the user bob is assigned.

### Supported search filters

| Filter | Operators | Query |
| ----------- | ----------------- | ------------------------------------------------------------ |
| title | `:` | text token used for a case-insentitive search on the cards title |
| description | `:` | text token used for a case-insentitive search on the cards description |
| list | `:` | text token used for a case-insentitive search on the cards list name |
| tag | `:` | text token used for a case-insentitive search on the assigned tags |
| date | `:` | 'overdue', 'today', 'week', 'month', 'none' |
| | `>` `<` `>=` `<=` | Compare the card due date to the passed date (see [supported date formats](https://www.php.net/manual/de/datetime.formats.php)) Card due dates are always considered UTC for comparison |
| assigned | `:` | id or displayname of a user or group for a search on the assigned users or groups |

Other text tokens will be used to perform a case-insensitive search on the card title and description

In addition wuotes can be used to pass a query with spaces, e.g. `"Exact match with spaces"` or `title:"My card"`.
6 changes: 3 additions & 3 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
use OCA\Deck\Middleware\DefaultBoardMiddleware;
use OCA\Deck\Middleware\ExceptionMiddleware;
use OCA\Deck\Notification\Notifier;
use OCA\Deck\Search\CardCommentProvider;
use OCA\Deck\Search\DeckProvider;
use OCA\Deck\Service\PermissionService;
use OCA\Deck\Sharing\DeckShareProvider;
Expand Down Expand Up @@ -95,9 +96,7 @@ public function boot(IBootContext $context): void {
$context->injectFn(Closure::fromCallable([$this, 'registerCollaborationResources']));

$context->injectFn(function (IManager $shareManager) {
if (method_exists($shareManager, 'registerShareProvider')) {
$shareManager->registerShareProvider(DeckShareProvider::class);
}
$shareManager->registerShareProvider(DeckShareProvider::class);
});

$context->injectFn(function (Listener $listener, IEventDispatcher $eventDispatcher) {
Expand All @@ -122,6 +121,7 @@ public function register(IRegistrationContext $context): void {
});

$context->registerSearchProvider(DeckProvider::class);
$context->registerSearchProvider(CardCommentProvider::class);
$context->registerDashboardWidget(DeckWidget::class);

$context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class);
Expand Down
59 changes: 59 additions & 0 deletions lib/Controller/SearchController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/*
* @copyright Copyright (c) 2021 Julius Härtl <[email protected]>
*
* @author Julius Härtl <[email protected]>
*
* @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 <http://www.gnu.org/licenses/>.
*
*/

declare(strict_types=1);


namespace OCA\Deck\Controller;

use OCA\Deck\Db\Card;
use OCA\Deck\Service\SearchService;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\IRequest;

class SearchController extends OCSController {

/**
* @var SearchService
*/
private $searchService;

public function __construct(string $appName, IRequest $request, SearchService $searchService) {
parent::__construct($appName, $request);
$this->searchService = $searchService;
}

/**
* @NoAdminRequired
*/
public function search(string $term, ?int $limit = null, ?int $cursor = null): DataResponse {
$cards = $this->searchService->searchCards($term, $limit, $cursor);
return new DataResponse(array_map(function (Card $card) {
$json = $card->jsonSerialize();
$json['relatedStack'] = $card->getRelatedStack();
$json['relatedBoard'] = $card->getRelatedBoard();
return $json;
}, $cards));
}
}
8 changes: 8 additions & 0 deletions lib/Db/Card.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class Card extends RelationalEntity {
protected $notified = false;
protected $deletedAt = 0;
protected $commentsUnread = 0;

protected $relatedStack = null;
protected $relatedBoard = null;

private $databaseType = 'sqlite';

Expand All @@ -73,6 +76,9 @@ public function __construct() {
$this->addRelation('participants');
$this->addRelation('commentsUnread');
$this->addResolvable('owner');

$this->addRelation('relatedStack');
$this->addRelation('relatedBoard');
}

public function setDatabaseType($type) {
Expand Down Expand Up @@ -119,6 +125,8 @@ public function jsonSerialize() {
$json['duedate'] = $this->getDuedate(true);
unset($json['notified']);
unset($json['descriptionPrev']);
unset($json['relatedStack']);
unset($json['relatedBoard']);
return $json;
}

Expand Down
Loading