mirror of
https://github.com/nextcloud/server.git
synced 2026-02-27 18:37:17 +01:00
Show mime icon, bump bundles, make the SearchResultEntry class non-abstract, Fix header search icon, various fixes
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
This commit is contained in:
@@ -21,8 +21,7 @@ return array(
|
||||
'OCA\\Comments\\Listener\\LoadSidebarScripts' => $baseDir . '/../lib/Listener/LoadSidebarScripts.php',
|
||||
'OCA\\Comments\\Notification\\Listener' => $baseDir . '/../lib/Notification/Listener.php',
|
||||
'OCA\\Comments\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php',
|
||||
'OCA\\Comments\\Search\\CommentsSearchResultEntry' => $baseDir . '/../lib/Search/CommentsSearchResultEntry.php',
|
||||
'OCA\\Comments\\Search\\CommentsSearchProvider' => $baseDir . '/../lib/Search/CommentsSearchProvider.php',
|
||||
'OCA\\Comments\\Search\\LegacyProvider' => $baseDir . '/../lib/Search/LegacyProvider.php',
|
||||
'OCA\\Comments\\Search\\Provider' => $baseDir . '/../lib/Search/Provider.php',
|
||||
'OCA\\Comments\\Search\\Result' => $baseDir . '/../lib/Search/Result.php',
|
||||
);
|
||||
|
||||
@@ -36,9 +36,8 @@ class ComposerStaticInitComments
|
||||
'OCA\\Comments\\Listener\\LoadSidebarScripts' => __DIR__ . '/..' . '/../lib/Listener/LoadSidebarScripts.php',
|
||||
'OCA\\Comments\\Notification\\Listener' => __DIR__ . '/..' . '/../lib/Notification/Listener.php',
|
||||
'OCA\\Comments\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php',
|
||||
'OCA\\Comments\\Search\\CommentsSearchResultEntry' => __DIR__ . '/..' . '/../lib/Search/CommentsSearchResultEntry.php',
|
||||
'OCA\\Comments\\Search\\CommentsSearchProvider' => __DIR__ . '/..' . '/../lib/Search/CommentsSearchProvider.php',
|
||||
'OCA\\Comments\\Search\\LegacyProvider' => __DIR__ . '/..' . '/../lib/Search/LegacyProvider.php',
|
||||
'OCA\\Comments\\Search\\Provider' => __DIR__ . '/..' . '/../lib/Search/Provider.php',
|
||||
'OCA\\Comments\\Search\\Result' => __DIR__ . '/..' . '/../lib/Search/Result.php',
|
||||
);
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -37,7 +37,7 @@ use OCA\Comments\Listener\LoadAdditionalScripts;
|
||||
use OCA\Comments\Listener\LoadSidebarScripts;
|
||||
use OCA\Comments\Notification\Notifier;
|
||||
use OCA\Comments\Search\LegacyProvider;
|
||||
use OCA\Comments\Search\Provider;
|
||||
use OCA\Comments\Search\CommentsSearchProvider;
|
||||
use OCA\Files\Event\LoadAdditionalScriptsEvent;
|
||||
use OCA\Files\Event\LoadSidebar;
|
||||
use OCP\AppFramework\App;
|
||||
@@ -74,7 +74,7 @@ class Application extends App implements IBootstrap {
|
||||
CommentsEntityEvent::EVENT_ENTITY,
|
||||
CommentsEntityEventListener::class
|
||||
);
|
||||
$context->registerSearchProvider(Provider::class);
|
||||
$context->registerSearchProvider(CommentsSearchProvider::class);
|
||||
}
|
||||
|
||||
public function boot(IBootContext $context): void {
|
||||
|
||||
@@ -32,10 +32,11 @@ use OCP\IUserManager;
|
||||
use OCP\Search\IProvider;
|
||||
use OCP\Search\ISearchQuery;
|
||||
use OCP\Search\SearchResult;
|
||||
use OCP\Search\SearchResultEntry;
|
||||
use function array_map;
|
||||
use function pathinfo;
|
||||
|
||||
class Provider implements IProvider {
|
||||
class CommentsSearchProvider implements IProvider {
|
||||
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
@@ -59,14 +60,30 @@ class Provider implements IProvider {
|
||||
$this->legacyProvider = $legacyProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getId(): string {
|
||||
return 'comments';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getName(): string {
|
||||
return $this->l10n->t('Comments');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOrder(): int {
|
||||
return 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function search(IUser $user, ISearchQuery $query): SearchResult {
|
||||
return SearchResult::complete(
|
||||
$this->l10n->t('Comments'),
|
||||
@@ -77,7 +94,7 @@ class Provider implements IProvider {
|
||||
$avatarUrl = $isUser
|
||||
? $this->urlGenerator->linkToRoute('core.avatar.getAvatar', ['userId' => $result->authorId, 'size' => 42])
|
||||
: $this->urlGenerator->linkToRoute('core.GuestAvatar.getAvatar', ['guestName' => $result->authorId, 'size' => 42]);
|
||||
return new CommentsSearchResultEntry(
|
||||
return new SearchResultEntry(
|
||||
$avatarUrl,
|
||||
$result->name,
|
||||
$path,
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @author 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @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/>.
|
||||
*/
|
||||
|
||||
namespace OCA\Comments\Search;
|
||||
|
||||
use OCP\Search\ASearchResultEntry;
|
||||
|
||||
class CommentsSearchResultEntry extends ASearchResultEntry {
|
||||
}
|
||||
@@ -212,11 +212,8 @@ return array(
|
||||
'OCA\\DAV\\RootCollection' => $baseDir . '/../lib/RootCollection.php',
|
||||
'OCA\\DAV\\Search\\ACalendarSearchProvider' => $baseDir . '/../lib/Search/ACalendarSearchProvider.php',
|
||||
'OCA\\DAV\\Search\\ContactsSearchProvider' => $baseDir . '/../lib/Search/ContactsSearchProvider.php',
|
||||
'OCA\\DAV\\Search\\ContactsSearchResultEntry' => $baseDir . '/../lib/Search/ContactsSearchResultEntry.php',
|
||||
'OCA\\DAV\\Search\\EventsSearchProvider' => $baseDir . '/../lib/Search/EventsSearchProvider.php',
|
||||
'OCA\\DAV\\Search\\EventsSearchResultEntry' => $baseDir . '/../lib/Search/EventsSearchResultEntry.php',
|
||||
'OCA\\DAV\\Search\\TasksSearchProvider' => $baseDir . '/../lib/Search/TasksSearchProvider.php',
|
||||
'OCA\\DAV\\Search\\TasksSearchResultEntry' => $baseDir . '/../lib/Search/TasksSearchResultEntry.php',
|
||||
'OCA\\DAV\\Server' => $baseDir . '/../lib/Server.php',
|
||||
'OCA\\DAV\\Settings\\CalDAVSettings' => $baseDir . '/../lib/Settings/CalDAVSettings.php',
|
||||
'OCA\\DAV\\Storage\\PublicOwnerWrapper' => $baseDir . '/../lib/Storage/PublicOwnerWrapper.php',
|
||||
|
||||
@@ -227,11 +227,8 @@ class ComposerStaticInitDAV
|
||||
'OCA\\DAV\\RootCollection' => __DIR__ . '/..' . '/../lib/RootCollection.php',
|
||||
'OCA\\DAV\\Search\\ACalendarSearchProvider' => __DIR__ . '/..' . '/../lib/Search/ACalendarSearchProvider.php',
|
||||
'OCA\\DAV\\Search\\ContactsSearchProvider' => __DIR__ . '/..' . '/../lib/Search/ContactsSearchProvider.php',
|
||||
'OCA\\DAV\\Search\\ContactsSearchResultEntry' => __DIR__ . '/..' . '/../lib/Search/ContactsSearchResultEntry.php',
|
||||
'OCA\\DAV\\Search\\EventsSearchProvider' => __DIR__ . '/..' . '/../lib/Search/EventsSearchProvider.php',
|
||||
'OCA\\DAV\\Search\\EventsSearchResultEntry' => __DIR__ . '/..' . '/../lib/Search/EventsSearchResultEntry.php',
|
||||
'OCA\\DAV\\Search\\TasksSearchProvider' => __DIR__ . '/..' . '/../lib/Search/TasksSearchProvider.php',
|
||||
'OCA\\DAV\\Search\\TasksSearchResultEntry' => __DIR__ . '/..' . '/../lib/Search/TasksSearchResultEntry.php',
|
||||
'OCA\\DAV\\Server' => __DIR__ . '/..' . '/../lib/Server.php',
|
||||
'OCA\\DAV\\Settings\\CalDAVSettings' => __DIR__ . '/..' . '/../lib/Settings/CalDAVSettings.php',
|
||||
'OCA\\DAV\\Storage\\PublicOwnerWrapper' => __DIR__ . '/..' . '/../lib/Storage/PublicOwnerWrapper.php',
|
||||
|
||||
@@ -32,6 +32,7 @@ use OCP\IUser;
|
||||
use OCP\Search\IProvider;
|
||||
use OCP\Search\ISearchQuery;
|
||||
use OCP\Search\SearchResult;
|
||||
use OCP\Search\SearchResultEntry;
|
||||
use Sabre\VObject\Component\VCard;
|
||||
use Sabre\VObject\Reader;
|
||||
|
||||
@@ -92,6 +93,13 @@ class ContactsSearchProvider implements IProvider {
|
||||
return $this->l10n->t('Contacts');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOrder(): int {
|
||||
return 7;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -116,7 +124,7 @@ class ContactsSearchProvider implements IProvider {
|
||||
'offset' => $query->getCursor(),
|
||||
]
|
||||
);
|
||||
$formattedResults = \array_map(function (array $contactRow) use ($addressBooksById):ContactsSearchResultEntry {
|
||||
$formattedResults = \array_map(function (array $contactRow) use ($addressBooksById):SearchResultEntry {
|
||||
$addressBook = $addressBooksById[$contactRow['addressbookid']];
|
||||
|
||||
/** @var VCard $vCard */
|
||||
@@ -130,7 +138,7 @@ class ContactsSearchProvider implements IProvider {
|
||||
$subline = $this->generateSubline($vCard);
|
||||
$resourceUrl = $this->getDeepLinkToContactsApp($addressBook['uri'], (string) $vCard->UID);
|
||||
|
||||
return new ContactsSearchResultEntry($thumbnailUrl, $title, $subline, $resourceUrl, 'icon-contacts-dark', true);
|
||||
return new SearchResultEntry($thumbnailUrl, $title, $subline, $resourceUrl, 'icon-contacts-dark', true);
|
||||
}, $searchResults);
|
||||
|
||||
return SearchResult::paginated(
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2020, Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
namespace OCA\DAV\Search;
|
||||
|
||||
use OCP\Search\ASearchResultEntry;
|
||||
|
||||
class ContactsSearchResultEntry extends ASearchResultEntry {
|
||||
}
|
||||
@@ -28,6 +28,7 @@ use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCP\IUser;
|
||||
use OCP\Search\ISearchQuery;
|
||||
use OCP\Search\SearchResult;
|
||||
use OCP\Search\SearchResultEntry;
|
||||
use Sabre\VObject\Component;
|
||||
use Sabre\VObject\DateTimeParser;
|
||||
use Sabre\VObject\Property;
|
||||
@@ -78,6 +79,13 @@ class EventsSearchProvider extends ACalendarSearchProvider {
|
||||
return $this->l10n->t('Events');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOrder(): int {
|
||||
return 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -102,7 +110,7 @@ class EventsSearchProvider extends ACalendarSearchProvider {
|
||||
'offset' => $query->getCursor(),
|
||||
]
|
||||
);
|
||||
$formattedResults = \array_map(function (array $eventRow) use ($calendarsById, $subscriptionsById):EventsSearchResultEntry {
|
||||
$formattedResults = \array_map(function (array $eventRow) use ($calendarsById, $subscriptionsById):SearchResultEntry {
|
||||
$component = $this->getPrimaryComponent($eventRow['calendardata'], self::$componentType);
|
||||
$title = (string)($component->SUMMARY ?? $this->l10n->t('Untitled event'));
|
||||
$subline = $this->generateSubline($component);
|
||||
@@ -114,7 +122,7 @@ class EventsSearchProvider extends ACalendarSearchProvider {
|
||||
}
|
||||
$resourceUrl = $this->getDeepLinkToCalendarApp($calendar['principaluri'], $calendar['uri'], $eventRow['uri']);
|
||||
|
||||
return new EventsSearchResultEntry('', $title, $subline, $resourceUrl, 'icon-calendar-dark', false);
|
||||
return new SearchResultEntry('', $title, $subline, $resourceUrl, 'icon-calendar-dark', false);
|
||||
}, $searchResults);
|
||||
|
||||
return SearchResult::paginated(
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2020, Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
namespace OCA\DAV\Search;
|
||||
|
||||
use OCP\Search\ASearchResultEntry;
|
||||
|
||||
class EventsSearchResultEntry extends ASearchResultEntry {
|
||||
}
|
||||
@@ -28,6 +28,7 @@ use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCP\IUser;
|
||||
use OCP\Search\ISearchQuery;
|
||||
use OCP\Search\SearchResult;
|
||||
use OCP\Search\SearchResultEntry;
|
||||
use Sabre\VObject\Component;
|
||||
|
||||
/**
|
||||
@@ -70,6 +71,13 @@ class TasksSearchProvider extends ACalendarSearchProvider {
|
||||
return $this->l10n->t('Tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOrder(): int {
|
||||
return 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -94,7 +102,7 @@ class TasksSearchProvider extends ACalendarSearchProvider {
|
||||
'offset' => $query->getCursor(),
|
||||
]
|
||||
);
|
||||
$formattedResults = \array_map(function (array $taskRow) use ($calendarsById, $subscriptionsById):TasksSearchResultEntry {
|
||||
$formattedResults = \array_map(function (array $taskRow) use ($calendarsById, $subscriptionsById):SearchResultEntry {
|
||||
$component = $this->getPrimaryComponent($taskRow['calendardata'], self::$componentType);
|
||||
$title = (string)($component->SUMMARY ?? $this->l10n->t('Untitled task'));
|
||||
$subline = $this->generateSubline($component);
|
||||
@@ -106,7 +114,7 @@ class TasksSearchProvider extends ACalendarSearchProvider {
|
||||
}
|
||||
$resourceUrl = $this->getDeepLinkToTasksApp($calendar['uri'], $taskRow['uri']);
|
||||
|
||||
return new TasksSearchResultEntry('', $title, $subline, $resourceUrl, 'icon-checkmark', false);
|
||||
return new SearchResultEntry('', $title, $subline, $resourceUrl, 'icon-checkmark', false);
|
||||
}, $searchResults);
|
||||
|
||||
return SearchResult::paginated(
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2020, Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
namespace OCA\DAV\Search;
|
||||
|
||||
use OCP\Search\ASearchResultEntry;
|
||||
|
||||
class TasksSearchResultEntry extends ASearchResultEntry {
|
||||
}
|
||||
@@ -26,13 +26,13 @@ namespace OCA\DAV\Tests\unit;
|
||||
|
||||
use OCA\DAV\CardDAV\CardDavBackend;
|
||||
use OCA\DAV\Search\ContactsSearchProvider;
|
||||
use OCA\DAV\Search\ContactsSearchResultEntry;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
use OCP\Search\ISearchQuery;
|
||||
use OCP\Search\SearchResult;
|
||||
use OCP\Search\SearchResultEntry;
|
||||
use Sabre\VObject\Reader;
|
||||
use Test\TestCase;
|
||||
|
||||
@@ -216,20 +216,20 @@ class ContactsSearchProviderTest extends TestCase {
|
||||
$result1 = $data['entries'][1];
|
||||
$result1Data = $result1->jsonSerialize();
|
||||
|
||||
$this->assertInstanceOf(ContactsSearchResultEntry::class, $result0);
|
||||
$this->assertInstanceOf(SearchResultEntry::class, $result0);
|
||||
$this->assertEquals('', $result0Data['thumbnailUrl']);
|
||||
$this->assertEquals('FN of Test', $result0Data['title']);
|
||||
$this->assertEquals('subline', $result0Data['subline']);
|
||||
$this->assertEquals('deep-link-to-contacts', $result0Data['resourceUrl']);
|
||||
$this->assertEquals('icon-contacts-dark', $result0Data['iconClass']);
|
||||
$this->assertEquals('icon-contacts-dark', $result0Data['icon']);
|
||||
$this->assertTrue($result0Data['rounded']);
|
||||
|
||||
$this->assertInstanceOf(ContactsSearchResultEntry::class, $result1);
|
||||
$this->assertInstanceOf(SearchResultEntry::class, $result1);
|
||||
$this->assertEquals('absolute-thumbnail-url?photo', $result1Data['thumbnailUrl']);
|
||||
$this->assertEquals('FN of Test2', $result1Data['title']);
|
||||
$this->assertEquals('subline', $result1Data['subline']);
|
||||
$this->assertEquals('deep-link-to-contacts', $result1Data['resourceUrl']);
|
||||
$this->assertEquals('icon-contacts-dark', $result1Data['iconClass']);
|
||||
$this->assertEquals('icon-contacts-dark', $result1Data['icon']);
|
||||
$this->assertTrue($result1Data['rounded']);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ namespace OCA\DAV\Tests\unit\Search;
|
||||
|
||||
use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCA\DAV\Search\EventsSearchProvider;
|
||||
use OCA\DAV\Search\EventsSearchResultEntry;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
use OCP\Search\ISearchQuery;
|
||||
use OCP\Search\SearchResult;
|
||||
use OCP\Search\SearchResultEntry;
|
||||
use Sabre\VObject\Reader;
|
||||
use Test\TestCase;
|
||||
|
||||
@@ -392,28 +392,28 @@ class EventsSearchProviderTest extends TestCase {
|
||||
$result2 = $data['entries'][2];
|
||||
$result2Data = $result2->jsonSerialize();
|
||||
|
||||
$this->assertInstanceOf(EventsSearchResultEntry::class, $result0);
|
||||
$this->assertInstanceOf(SearchResultEntry::class, $result0);
|
||||
$this->assertEmpty($result0Data['thumbnailUrl']);
|
||||
$this->assertEquals('Untitled event', $result0Data['title']);
|
||||
$this->assertEquals('subline', $result0Data['subline']);
|
||||
$this->assertEquals('deep-link-to-calendar', $result0Data['resourceUrl']);
|
||||
$this->assertEquals('icon-calendar-dark', $result0Data['iconClass']);
|
||||
$this->assertEquals('icon-calendar-dark', $result0Data['icon']);
|
||||
$this->assertFalse($result0Data['rounded']);
|
||||
|
||||
$this->assertInstanceOf(EventsSearchResultEntry::class, $result1);
|
||||
$this->assertInstanceOf(SearchResultEntry::class, $result1);
|
||||
$this->assertEmpty($result1Data['thumbnailUrl']);
|
||||
$this->assertEquals('Test Europe Berlin', $result1Data['title']);
|
||||
$this->assertEquals('subline', $result1Data['subline']);
|
||||
$this->assertEquals('deep-link-to-calendar', $result1Data['resourceUrl']);
|
||||
$this->assertEquals('icon-calendar-dark', $result1Data['iconClass']);
|
||||
$this->assertEquals('icon-calendar-dark', $result1Data['icon']);
|
||||
$this->assertFalse($result1Data['rounded']);
|
||||
|
||||
$this->assertInstanceOf(EventsSearchResultEntry::class, $result2);
|
||||
$this->assertInstanceOf(SearchResultEntry::class, $result2);
|
||||
$this->assertEmpty($result2Data['thumbnailUrl']);
|
||||
$this->assertEquals('Test Europe Berlin', $result2Data['title']);
|
||||
$this->assertEquals('subline', $result2Data['subline']);
|
||||
$this->assertEquals('deep-link-to-calendar', $result2Data['resourceUrl']);
|
||||
$this->assertEquals('icon-calendar-dark', $result2Data['iconClass']);
|
||||
$this->assertEquals('icon-calendar-dark', $result2Data['icon']);
|
||||
$this->assertFalse($result2Data['rounded']);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ namespace OCA\DAV\Tests\unit\Search;
|
||||
|
||||
use OCA\DAV\CalDAV\CalDavBackend;
|
||||
use OCA\DAV\Search\TasksSearchProvider;
|
||||
use OCA\DAV\Search\TasksSearchResultEntry;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
use OCP\Search\ISearchQuery;
|
||||
use OCP\Search\SearchResult;
|
||||
use OCP\Search\SearchResultEntry;
|
||||
use Sabre\VObject\Reader;
|
||||
use Test\TestCase;
|
||||
|
||||
@@ -276,28 +276,28 @@ class TasksSearchProviderTest extends TestCase {
|
||||
$result2 = $data['entries'][2];
|
||||
$result2Data = $result2->jsonSerialize();
|
||||
|
||||
$this->assertInstanceOf(TasksSearchResultEntry::class, $result0);
|
||||
$this->assertInstanceOf(SearchResultEntry::class, $result0);
|
||||
$this->assertEmpty($result0Data['thumbnailUrl']);
|
||||
$this->assertEquals('Untitled task', $result0Data['title']);
|
||||
$this->assertEquals('subline', $result0Data['subline']);
|
||||
$this->assertEquals('deep-link-to-tasks', $result0Data['resourceUrl']);
|
||||
$this->assertEquals('icon-checkmark', $result0Data['iconClass']);
|
||||
$this->assertEquals('icon-checkmark', $result0Data['icon']);
|
||||
$this->assertFalse($result0Data['rounded']);
|
||||
|
||||
$this->assertInstanceOf(TasksSearchResultEntry::class, $result1);
|
||||
$this->assertInstanceOf(SearchResultEntry::class, $result1);
|
||||
$this->assertEmpty($result1Data['thumbnailUrl']);
|
||||
$this->assertEquals('Task title', $result1Data['title']);
|
||||
$this->assertEquals('subline', $result1Data['subline']);
|
||||
$this->assertEquals('deep-link-to-tasks', $result1Data['resourceUrl']);
|
||||
$this->assertEquals('icon-checkmark', $result1Data['iconClass']);
|
||||
$this->assertEquals('icon-checkmark', $result1Data['icon']);
|
||||
$this->assertFalse($result1Data['rounded']);
|
||||
|
||||
$this->assertInstanceOf(TasksSearchResultEntry::class, $result2);
|
||||
$this->assertInstanceOf(SearchResultEntry::class, $result2);
|
||||
$this->assertEmpty($result2Data['thumbnailUrl']);
|
||||
$this->assertEquals('Task title', $result2Data['title']);
|
||||
$this->assertEquals('subline', $result2Data['subline']);
|
||||
$this->assertEquals('deep-link-to-tasks', $result2Data['resourceUrl']);
|
||||
$this->assertEquals('icon-checkmark', $result2Data['iconClass']);
|
||||
$this->assertEquals('icon-checkmark', $result2Data['icon']);
|
||||
$this->assertFalse($result2Data['rounded']);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ return array(
|
||||
'OCA\\Files\\Migration\\Version11301Date20191205150729' => $baseDir . '/../lib/Migration/Version11301Date20191205150729.php',
|
||||
'OCA\\Files\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php',
|
||||
'OCA\\Files\\Search\\FilesSearchProvider' => $baseDir . '/../lib/Search/FilesSearchProvider.php',
|
||||
'OCA\\Files\\Search\\FilesSearchResultEntry' => $baseDir . '/../lib/Search/FilesSearchResultEntry.php',
|
||||
'OCA\\Files\\Service\\DirectEditingService' => $baseDir . '/../lib/Service/DirectEditingService.php',
|
||||
'OCA\\Files\\Service\\OwnershipTransferService' => $baseDir . '/../lib/Service/OwnershipTransferService.php',
|
||||
'OCA\\Files\\Service\\TagService' => $baseDir . '/../lib/Service/TagService.php',
|
||||
|
||||
@@ -63,7 +63,6 @@ class ComposerStaticInitFiles
|
||||
'OCA\\Files\\Migration\\Version11301Date20191205150729' => __DIR__ . '/..' . '/../lib/Migration/Version11301Date20191205150729.php',
|
||||
'OCA\\Files\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php',
|
||||
'OCA\\Files\\Search\\FilesSearchProvider' => __DIR__ . '/..' . '/../lib/Search/FilesSearchProvider.php',
|
||||
'OCA\\Files\\Search\\FilesSearchResultEntry' => __DIR__ . '/..' . '/../lib/Search/FilesSearchResultEntry.php',
|
||||
'OCA\\Files\\Service\\DirectEditingService' => __DIR__ . '/..' . '/../lib/Service/DirectEditingService.php',
|
||||
'OCA\\Files\\Service\\OwnershipTransferService' => __DIR__ . '/..' . '/../lib/Service/OwnershipTransferService.php',
|
||||
'OCA\\Files\\Service\\TagService' => __DIR__ . '/..' . '/../lib/Service/TagService.php',
|
||||
|
||||
@@ -27,12 +27,14 @@ namespace OCA\Files\Search;
|
||||
|
||||
use OC\Search\Provider\File;
|
||||
use OC\Search\Result\File as FileResult;
|
||||
use OCP\Files\IMimeTypeDetector;
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
use OCP\Search\IProvider;
|
||||
use OCP\Search\ISearchQuery;
|
||||
use OCP\Search\SearchResult;
|
||||
use OCP\Search\SearchResultEntry;
|
||||
|
||||
class FilesSearchProvider implements IProvider {
|
||||
|
||||
@@ -45,37 +47,58 @@ class FilesSearchProvider implements IProvider {
|
||||
/** @var IURLGenerator */
|
||||
private $urlGenerator;
|
||||
|
||||
/** @var IMimeTypeDetector */
|
||||
private $mimeTypeDetector;
|
||||
|
||||
public function __construct(File $fileSearch,
|
||||
IL10N $l10n,
|
||||
IURLGenerator $urlGenerator) {
|
||||
IURLGenerator $urlGenerator,
|
||||
IMimeTypeDetector $mimeTypeDetector) {
|
||||
$this->l10n = $l10n;
|
||||
$this->fileSearch = $fileSearch;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->mimeTypeDetector = $mimeTypeDetector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getId(): string {
|
||||
return 'files';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getName(): string {
|
||||
return $this->l10n->t('Files');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOrder(): int {
|
||||
return 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function search(IUser $user, ISearchQuery $query): SearchResult {
|
||||
return SearchResult::complete(
|
||||
$this->l10n->t('Files'),
|
||||
array_map(function (FileResult $result) {
|
||||
// Generate thumbnail url
|
||||
$thumbnailUrl = $result->type === 'folder'
|
||||
? ''
|
||||
: $this->urlGenerator->linkToRoute('core.Preview.getPreviewByFileId', ['x' => 32, 'y' => 32, 'fileId' => $result->id]);
|
||||
$thumbnailUrl = $result->has_preview
|
||||
? $this->urlGenerator->linkToRoute('core.Preview.getPreviewByFileId', ['x' => 32, 'y' => 32, 'fileId' => $result->id])
|
||||
: '';
|
||||
|
||||
return new FilesSearchResultEntry(
|
||||
return new SearchResultEntry(
|
||||
$thumbnailUrl,
|
||||
$result->name,
|
||||
$this->formatSubline($result),
|
||||
$result->link,
|
||||
$result->type === 'folder' ? 'icon-folder' : 'icon-filetype-file'
|
||||
$result->type === 'folder' ? 'icon-folder' : $this->mimeTypeDetector->mimeTypeIcon($result->mime_type)
|
||||
);
|
||||
}, $this->fileSearch->search($query->getTerm()))
|
||||
);
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @author 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @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/>.
|
||||
*/
|
||||
|
||||
namespace OCA\Files\Search;
|
||||
|
||||
use OCP\Search\ASearchResultEntry;
|
||||
|
||||
class FilesSearchResultEntry extends ASearchResultEntry {
|
||||
public function __construct(string $thumbnailUrl,
|
||||
string $filename,
|
||||
string $path,
|
||||
string $url,
|
||||
string $icon) {
|
||||
parent::__construct($thumbnailUrl, $filename, $path, $url, $icon, false);
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,6 @@ return array(
|
||||
'OCA\\Settings\\Hooks' => $baseDir . '/../lib/Hooks.php',
|
||||
'OCA\\Settings\\Mailer\\NewUserMailHelper' => $baseDir . '/../lib/Mailer/NewUserMailHelper.php',
|
||||
'OCA\\Settings\\Middleware\\SubadminMiddleware' => $baseDir . '/../lib/Middleware/SubadminMiddleware.php',
|
||||
'OCA\\Settings\\Search\\SectionResult' => $baseDir . '/../lib/Search/SectionResult.php',
|
||||
'OCA\\Settings\\Search\\SectionSearch' => $baseDir . '/../lib/Search/SectionSearch.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Additional' => $baseDir . '/../lib/Sections/Admin/Additional.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Groupware' => $baseDir . '/../lib/Sections/Admin/Groupware.php',
|
||||
|
||||
@@ -46,7 +46,6 @@ class ComposerStaticInitSettings
|
||||
'OCA\\Settings\\Hooks' => __DIR__ . '/..' . '/../lib/Hooks.php',
|
||||
'OCA\\Settings\\Mailer\\NewUserMailHelper' => __DIR__ . '/..' . '/../lib/Mailer/NewUserMailHelper.php',
|
||||
'OCA\\Settings\\Middleware\\SubadminMiddleware' => __DIR__ . '/..' . '/../lib/Middleware/SubadminMiddleware.php',
|
||||
'OCA\\Settings\\Search\\SectionResult' => __DIR__ . '/..' . '/../lib/Search/SectionResult.php',
|
||||
'OCA\\Settings\\Search\\SectionSearch' => __DIR__ . '/..' . '/../lib/Search/SectionSearch.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Additional' => __DIR__ . '/..' . '/../lib/Sections/Admin/Additional.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Groupware' => __DIR__ . '/..' . '/../lib/Sections/Admin/Groupware.php',
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Settings\Search;
|
||||
|
||||
use OCP\Search\ASearchResultEntry;
|
||||
|
||||
class SectionResult extends ASearchResultEntry {
|
||||
}
|
||||
@@ -30,7 +30,7 @@ use OCP\IUser;
|
||||
use OCP\Search\IProvider;
|
||||
use OCP\Search\ISearchQuery;
|
||||
use OCP\Search\SearchResult;
|
||||
use OCP\Settings\IIconSection;
|
||||
use OCP\Search\SearchResultEntry;
|
||||
use OCP\Settings\ISection;
|
||||
use OCP\Settings\IManager;
|
||||
|
||||
@@ -38,10 +38,13 @@ class SectionSearch implements IProvider {
|
||||
|
||||
/** @var IManager */
|
||||
protected $settingsManager;
|
||||
|
||||
/** @var IGroupManager */
|
||||
protected $groupManager;
|
||||
|
||||
/** @var IURLGenerator */
|
||||
protected $urlGenerator;
|
||||
|
||||
/** @var IL10N */
|
||||
protected $l;
|
||||
|
||||
@@ -69,6 +72,13 @@ class SectionSearch implements IProvider {
|
||||
return $this->l->t('Settings');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOrder(): int {
|
||||
return 20;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -115,16 +125,20 @@ class SectionSearch implements IProvider {
|
||||
continue;
|
||||
}
|
||||
|
||||
$iconUrl = '';
|
||||
if ($section instanceof IIconSection) {
|
||||
$iconUrl = $section->getIcon();
|
||||
}
|
||||
/**
|
||||
* We can't use the icon URL at the moment as they don't invert correctly for dark theme
|
||||
* $iconUrl = '';
|
||||
* if ($section instanceof IIconSection) {
|
||||
* $iconUrl = $section->getIcon();
|
||||
* }
|
||||
*/
|
||||
|
||||
$result[] = new SectionResult(
|
||||
$iconUrl,
|
||||
$result[] = new SearchResultEntry(
|
||||
'',
|
||||
$section->getName(),
|
||||
$subline,
|
||||
$this->urlGenerator->linkToRouteAbsolute($routeName, ['section' => $section->getID()])
|
||||
$this->urlGenerator->linkToRouteAbsolute($routeName, ['section' => $section->getID()]),
|
||||
'icon-settings'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
2
core/js/dist/files_client.js
vendored
2
core/js/dist/files_client.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/files_client.js.map
vendored
2
core/js/dist/files_client.js.map
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/files_fileinfo.js
vendored
2
core/js/dist/files_fileinfo.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/files_fileinfo.js.map
vendored
2
core/js/dist/files_fileinfo.js.map
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/files_iedavclient.js
vendored
2
core/js/dist/files_iedavclient.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/files_iedavclient.js.map
vendored
2
core/js/dist/files_iedavclient.js.map
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/install.js
vendored
2
core/js/dist/install.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/install.js.map
vendored
2
core/js/dist/install.js.map
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/login.js
vendored
2
core/js/dist/login.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/login.js.map
vendored
2
core/js/dist/login.js.map
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/main.js
vendored
2
core/js/dist/main.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/main.js.map
vendored
2
core/js/dist/main.js.map
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/maintenance.js
vendored
2
core/js/dist/maintenance.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/maintenance.js.map
vendored
2
core/js/dist/maintenance.js.map
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/recommendedapps.js
vendored
2
core/js/dist/recommendedapps.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/recommendedapps.js.map
vendored
2
core/js/dist/recommendedapps.js.map
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/unified-search.js
vendored
2
core/js/dist/unified-search.js
vendored
File diff suppressed because one or more lines are too long
2
core/js/dist/unified-search.js.map
vendored
2
core/js/dist/unified-search.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -2,22 +2,28 @@
|
||||
<a :href="resourceUrl || '#'"
|
||||
class="unified-search__result"
|
||||
:class="{
|
||||
'unified-search__result--focused': focused
|
||||
'unified-search__result--focused': focused,
|
||||
}"
|
||||
@click="reEmitEvent"
|
||||
@focus="reEmitEvent">
|
||||
|
||||
<!-- Icon describing the result -->
|
||||
<div class="unified-search__result-icon"
|
||||
:class="{
|
||||
'unified-search__result-icon--rounded': rounded,
|
||||
'unified-search__result-icon--no-preview': !hasValidThumbnail && !loaded,
|
||||
'unified-search__result-icon--with-thumbnail': hasValidThumbnail && loaded,
|
||||
[iconClass]: true
|
||||
[icon]: !loaded && !isIconUrl,
|
||||
}"
|
||||
:style="{
|
||||
backgroundImage: isIconUrl ? `url(${icon})` : '',
|
||||
}"
|
||||
role="img">
|
||||
|
||||
<img v-if="hasValidThumbnail"
|
||||
v-show="loaded"
|
||||
:src="thumbnailUrl"
|
||||
:alt="t('core', 'Thumbnail for {result}', {result: title})"
|
||||
alt=""
|
||||
@error="onError"
|
||||
@load="onLoad">
|
||||
</div>
|
||||
@@ -59,7 +65,7 @@ export default {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
iconClass: {
|
||||
icon: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
@@ -90,6 +96,24 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isIconUrl() {
|
||||
// If we're facing an absolute url
|
||||
if (this.icon.startsWith('/')) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Otherwise, let's check if this is a valid url
|
||||
try {
|
||||
// eslint-disable-next-line no-new
|
||||
new URL(this.icon)
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
// Make sure to reset state on change even when vue recycle the component
|
||||
thumbnailUrl() {
|
||||
@@ -148,6 +172,7 @@ $margin: 10px;
|
||||
width: $clickable-area;
|
||||
height: $clickable-area;
|
||||
border-radius: var(--border-radius);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 32px;
|
||||
&--rounded {
|
||||
@@ -195,7 +220,7 @@ $margin: 10px;
|
||||
&-line-two {
|
||||
overflow: hidden;
|
||||
flex: 1 1 100%;
|
||||
margin: 0;
|
||||
margin: 1px 0;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
// Use the same color as the `a`
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<svg
|
||||
class="unified-search__result-placeholder"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="url(#unified-search__result-placeholder-gradient)">
|
||||
<defs>
|
||||
<linearGradient id="unified-search__result-placeholder-gradient">
|
||||
<stop offset="0%" stop-color="#ededed"><animate attributeName="stop-color"
|
||||
values="#ededed; #ededed; #cccccc; #cccccc; #ededed"
|
||||
dur="2s"
|
||||
repeatCount="indefinite" /></stop>
|
||||
<stop offset="100%" stop-color="#cccccc"><animate attributeName="stop-color"
|
||||
values="#cccccc; #ededed; #ededed; #cccccc; #cccccc"
|
||||
dur="2s"
|
||||
repeatCount="indefinite" /></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect class="unified-search__result-placeholder-icon" />
|
||||
<rect class="unified-search__result-placeholder-line-one" />
|
||||
<rect class="unified-search__result-placeholder-line-two" :style="{width: `calc(${randWidth}%)`}" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SearchResultPlaceholder',
|
||||
|
||||
data() {
|
||||
return {
|
||||
randWidth: Math.floor(Math.random() * 20) + 30,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$clickable-area: 44px;
|
||||
$margin: 10px;
|
||||
|
||||
.unified-search__result-placeholder {
|
||||
width: calc(100% - 2 * #{$margin});
|
||||
height: $clickable-area;
|
||||
margin: $margin;
|
||||
|
||||
&-icon {
|
||||
width: $clickable-area;
|
||||
height: $clickable-area;
|
||||
rx: var(--border-radius);
|
||||
ry: var(--border-radius);
|
||||
}
|
||||
|
||||
&-line-one,
|
||||
&-line-two {
|
||||
width: calc(100% - #{$margin + $clickable-area});
|
||||
height: 1em;
|
||||
x: $margin + $clickable-area;
|
||||
}
|
||||
|
||||
&-line-one {
|
||||
y: 5px;
|
||||
}
|
||||
|
||||
&-line-two {
|
||||
y: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -24,15 +24,18 @@ import { loadState } from '@nextcloud/initial-state'
|
||||
import axios from '@nextcloud/axios'
|
||||
|
||||
export const defaultLimit = loadState('unified-search', 'limit-default')
|
||||
export const activeApp = loadState('core', 'active-app')
|
||||
|
||||
/**
|
||||
* Get the list of available search providers
|
||||
*
|
||||
* @returns {Array}
|
||||
*/
|
||||
export async function getTypes() {
|
||||
try {
|
||||
const { data } = await axios.get(generateUrl('/search/providers'))
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
return data
|
||||
return sortProviders(data)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
@@ -40,6 +43,29 @@ export async function getTypes() {
|
||||
return []
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the providers by the current active app
|
||||
*
|
||||
* @param {Array} providers the providers list
|
||||
* @returns {Array}
|
||||
*/
|
||||
export function sortProviders(providers) {
|
||||
providers.sort((a, b) => {
|
||||
if (a.id.startsWith(activeApp) && b.id.startsWith(activeApp)) {
|
||||
return a.order - b.order
|
||||
}
|
||||
|
||||
if (a.id.startsWith(activeApp)) {
|
||||
return -1
|
||||
}
|
||||
if (b.id.startsWith(activeApp)) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
return providers
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of available search providers
|
||||
*
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
@close="onClose">
|
||||
<!-- Header icon -->
|
||||
<template #trigger>
|
||||
<span class="icon-search-white" />
|
||||
<Magnify class="unified-search__trigger" :size="20" fill-color="var(--color-primary-text)" />
|
||||
</template>
|
||||
|
||||
<!-- Search input -->
|
||||
@@ -36,17 +36,20 @@
|
||||
v-model="query"
|
||||
class="unified-search__input"
|
||||
type="search"
|
||||
:placeholder="t('core', 'Search for {types} …', { types: typesNames.join(', ') })"
|
||||
:placeholder="t('core', 'Search {types} …', { types: typesNames.join(', ').toLowerCase() })"
|
||||
@input="onInputDebounced"
|
||||
@keypress.enter.prevent.stop="onInputEnter">
|
||||
</div>
|
||||
|
||||
<EmptyContent v-if="isLoading" icon="icon-loading">
|
||||
{{ t('core', 'Searching …') }}
|
||||
</EmptyContent>
|
||||
<template v-if="!hasResults">
|
||||
<!-- Loading placeholders -->
|
||||
<ul v-if="isLoading">
|
||||
<li v-for="placeholder in [1, 2, 3]" :key="placeholder">
|
||||
<SearchResultPlaceholder />
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<template v-else-if="!hasResults">
|
||||
<EmptyContent v-if="isValidQuery && isDoneSearching" icon="icon-search">
|
||||
<EmptyContent v-else-if="isValidQuery && isDoneSearching" icon="icon-search">
|
||||
{{ t('core', 'No results for {query}', {query}) }}
|
||||
</EmptyContent>
|
||||
|
||||
@@ -64,7 +67,7 @@
|
||||
|
||||
<!-- Grouped search results -->
|
||||
<template v-else>
|
||||
<ul v-for="(list, type, typesIndex) in results"
|
||||
<ul v-for="(list, type, typesIndex) in orderedResults"
|
||||
:key="type"
|
||||
class="unified-search__results"
|
||||
:class="`unified-search__results-${type}`"
|
||||
@@ -94,13 +97,14 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getTypes, search, defaultLimit } from '../services/UnifiedSearchService'
|
||||
import { getTypes, search, defaultLimit, activeApp } from '../services/UnifiedSearchService'
|
||||
import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'
|
||||
|
||||
import Magnify from 'vue-material-design-icons/Magnify'
|
||||
import debounce from 'debounce'
|
||||
|
||||
import HeaderMenu from '../components/HeaderMenu'
|
||||
import SearchResult from '../components/UnifiedSearch/SearchResult'
|
||||
import SearchResultPlaceholder from '../components/UnifiedSearch/SearchResultPlaceholder'
|
||||
|
||||
const minSearchLength = 2
|
||||
|
||||
@@ -110,7 +114,9 @@ export default {
|
||||
components: {
|
||||
EmptyContent,
|
||||
HeaderMenu,
|
||||
Magnify,
|
||||
SearchResult,
|
||||
SearchResultPlaceholder,
|
||||
},
|
||||
|
||||
data() {
|
||||
@@ -126,6 +132,7 @@ export default {
|
||||
query: '',
|
||||
focused: null,
|
||||
|
||||
activeApp,
|
||||
defaultLimit,
|
||||
minSearchLength,
|
||||
|
||||
@@ -155,6 +162,32 @@ export default {
|
||||
return Object.keys(this.results).length !== 0
|
||||
},
|
||||
|
||||
/**
|
||||
* Order results by putting the active app first
|
||||
* @returns {Object}
|
||||
*/
|
||||
orderedResults() {
|
||||
const ordered = {}
|
||||
Object.keys(this.results)
|
||||
.sort((a, b) => {
|
||||
if (a.startsWith(activeApp) && b.startsWith(activeApp)) {
|
||||
return this.typesMap[a].order - this.typesMap[b].order
|
||||
}
|
||||
if (a.startsWith(activeApp)) {
|
||||
return -1
|
||||
}
|
||||
if (b.startsWith(activeApp)) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
.forEach(type => {
|
||||
ordered[type] = this.results[type]
|
||||
})
|
||||
|
||||
return ordered
|
||||
},
|
||||
|
||||
/**
|
||||
* Is the current search too short
|
||||
* @returns {boolean}
|
||||
@@ -176,7 +209,7 @@ export default {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isDoneSearching() {
|
||||
return Object.values(this.reached).indexOf(false) === -1
|
||||
return Object.values(this.reached).every(state => state === false)
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -184,7 +217,7 @@ export default {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isLoading() {
|
||||
return Object.values(this.loading).indexOf(true) !== -1
|
||||
return Object.values(this.loading).some(state => state === true)
|
||||
},
|
||||
},
|
||||
|
||||
@@ -465,6 +498,11 @@ $margin: 10px;
|
||||
$input-padding: 6px;
|
||||
|
||||
.unified-search {
|
||||
&__trigger {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
&__input-wrapper {
|
||||
position: sticky;
|
||||
// above search results
|
||||
@@ -479,7 +517,14 @@ $input-padding: 6px;
|
||||
height: 34px;
|
||||
margin: $margin;
|
||||
padding: $input-padding;
|
||||
text-overflow: ellipsis;
|
||||
&,
|
||||
&[placeholder],
|
||||
&::placeholder {
|
||||
overflow: hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&__results {
|
||||
@@ -488,7 +533,7 @@ $input-padding: 6px;
|
||||
margin: $margin;
|
||||
margin-left: $margin + $input-padding;
|
||||
content: attr(aria-label);
|
||||
color: var(--color-primary);
|
||||
color: var(--color-primary-element);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -439,13 +439,13 @@ return array(
|
||||
'OCP\\Route\\IRouter' => $baseDir . '/lib/public/Route/IRouter.php',
|
||||
'OCP\\SabrePluginEvent' => $baseDir . '/lib/public/SabrePluginEvent.php',
|
||||
'OCP\\SabrePluginException' => $baseDir . '/lib/public/SabrePluginException.php',
|
||||
'OCP\\Search\\ASearchResultEntry' => $baseDir . '/lib/public/Search/ASearchResultEntry.php',
|
||||
'OCP\\Search\\IProvider' => $baseDir . '/lib/public/Search/IProvider.php',
|
||||
'OCP\\Search\\ISearchQuery' => $baseDir . '/lib/public/Search/ISearchQuery.php',
|
||||
'OCP\\Search\\PagedProvider' => $baseDir . '/lib/public/Search/PagedProvider.php',
|
||||
'OCP\\Search\\Provider' => $baseDir . '/lib/public/Search/Provider.php',
|
||||
'OCP\\Search\\Result' => $baseDir . '/lib/public/Search/Result.php',
|
||||
'OCP\\Search\\SearchResult' => $baseDir . '/lib/public/Search/SearchResult.php',
|
||||
'OCP\\Search\\SearchResultEntry' => $baseDir . '/lib/public/Search/SearchResultEntry.php',
|
||||
'OCP\\Security\\CSP\\AddContentSecurityPolicyEvent' => $baseDir . '/lib/public/Security/CSP/AddContentSecurityPolicyEvent.php',
|
||||
'OCP\\Security\\Events\\GenerateSecurePasswordEvent' => $baseDir . '/lib/public/Security/Events/GenerateSecurePasswordEvent.php',
|
||||
'OCP\\Security\\Events\\ValidatePasswordPolicyEvent' => $baseDir . '/lib/public/Security/Events/ValidatePasswordPolicyEvent.php',
|
||||
|
||||
@@ -468,13 +468,13 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
||||
'OCP\\Route\\IRouter' => __DIR__ . '/../../..' . '/lib/public/Route/IRouter.php',
|
||||
'OCP\\SabrePluginEvent' => __DIR__ . '/../../..' . '/lib/public/SabrePluginEvent.php',
|
||||
'OCP\\SabrePluginException' => __DIR__ . '/../../..' . '/lib/public/SabrePluginException.php',
|
||||
'OCP\\Search\\ASearchResultEntry' => __DIR__ . '/../../..' . '/lib/public/Search/ASearchResultEntry.php',
|
||||
'OCP\\Search\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Search/IProvider.php',
|
||||
'OCP\\Search\\ISearchQuery' => __DIR__ . '/../../..' . '/lib/public/Search/ISearchQuery.php',
|
||||
'OCP\\Search\\PagedProvider' => __DIR__ . '/../../..' . '/lib/public/Search/PagedProvider.php',
|
||||
'OCP\\Search\\Provider' => __DIR__ . '/../../..' . '/lib/public/Search/Provider.php',
|
||||
'OCP\\Search\\Result' => __DIR__ . '/../../..' . '/lib/public/Search/Result.php',
|
||||
'OCP\\Search\\SearchResult' => __DIR__ . '/../../..' . '/lib/public/Search/SearchResult.php',
|
||||
'OCP\\Search\\SearchResultEntry' => __DIR__ . '/../../..' . '/lib/public/Search/SearchResultEntry.php',
|
||||
'OCP\\Security\\CSP\\AddContentSecurityPolicyEvent' => __DIR__ . '/../../..' . '/lib/public/Security/CSP/AddContentSecurityPolicyEvent.php',
|
||||
'OCP\\Security\\Events\\GenerateSecurePasswordEvent' => __DIR__ . '/../../..' . '/lib/public/Security/Events/GenerateSecurePasswordEvent.php',
|
||||
'OCP\\Security\\Events\\ValidatePasswordPolicyEvent' => __DIR__ . '/../../..' . '/lib/public/Security/Events/ValidatePasswordPolicyEvent.php',
|
||||
|
||||
@@ -79,12 +79,7 @@ class NavigationManager implements INavigationManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new navigation entry
|
||||
*
|
||||
* @param array|\Closure $entry Array containing: id, name, order, icon and href key
|
||||
* The use of a closure is preferred, because it will avoid
|
||||
* loading the routing of your app, unless required.
|
||||
* @return void
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function add($entry) {
|
||||
if ($entry instanceof \Closure) {
|
||||
@@ -106,10 +101,7 @@ class NavigationManager implements INavigationManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of navigation entries
|
||||
*
|
||||
* @param string $type type of the navigation entries
|
||||
* @return array
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getAll(string $type = 'link'): array {
|
||||
$this->init();
|
||||
@@ -171,19 +163,14 @@ class NavigationManager implements INavigationManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current navigation entry of the currently running app
|
||||
* @param string $id of the app entry to activate (from added $entry)
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setActiveEntry($id) {
|
||||
$this->activeEntry = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the active Menu entry
|
||||
* @return string id or empty string
|
||||
*
|
||||
* This function returns the id of the active navigation entry (set by
|
||||
* setActiveEntry
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getActiveEntry() {
|
||||
return $this->activeEntry;
|
||||
|
||||
@@ -39,7 +39,7 @@ class File extends \OCP\Search\Provider {
|
||||
/**
|
||||
* Search for files and folders matching the given query
|
||||
* @param string $query
|
||||
* @return \OCP\Search\Result
|
||||
* @return \OCP\Search\Result[]
|
||||
* @deprecated 20.0.0
|
||||
*/
|
||||
public function search($query) {
|
||||
|
||||
@@ -28,6 +28,8 @@ namespace OC\Search\Result;
|
||||
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\IPreview;
|
||||
use OCP\IUserSession;
|
||||
|
||||
/**
|
||||
* A found file
|
||||
@@ -78,6 +80,14 @@ class File extends \OCP\Search\Result {
|
||||
*/
|
||||
public $permissions;
|
||||
|
||||
/**
|
||||
* Has a preview
|
||||
*
|
||||
* @var string
|
||||
* @deprecated 20.0.0
|
||||
*/
|
||||
public $has_preview;
|
||||
|
||||
/**
|
||||
* Create a new file search result
|
||||
* @param FileInfo $data file data given by provider
|
||||
@@ -101,6 +111,7 @@ class File extends \OCP\Search\Result {
|
||||
$this->size = $data->getSize();
|
||||
$this->modified = $data->getMtime();
|
||||
$this->mime_type = $data->getMimetype();
|
||||
$this->has_preview = $this->hasPreview($data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,9 +129,21 @@ class File extends \OCP\Search\Result {
|
||||
*/
|
||||
protected function getRelativePath($path) {
|
||||
if (!isset(self::$userFolderCache)) {
|
||||
$user = \OC::$server->getUserSession()->getUser()->getUID();
|
||||
self::$userFolderCache = \OC::$server->getUserFolder($user);
|
||||
$userSession = \OC::$server->get(IUserSession::class);
|
||||
$userID = $userSession->getUser()->getUID();
|
||||
self::$userFolderCache = \OC::$server->getUserFolder($userID);
|
||||
}
|
||||
return self::$userFolderCache->getRelativePath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the preview available
|
||||
* @param FileInfo $data
|
||||
* @return bool
|
||||
* @deprecated 20.0.0
|
||||
*/
|
||||
protected function hasPreview($data) {
|
||||
$previewManager = \OC::$server->get(IPreview::class);
|
||||
return $previewManager->isAvailable($data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,22 +107,31 @@ class SearchComposer {
|
||||
|
||||
/**
|
||||
* Get a list of all provider IDs & Names for the consecutive calls to `search`
|
||||
* Sort the list by the order property
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProviders(): array {
|
||||
$this->loadLazyProviders();
|
||||
|
||||
/**
|
||||
* Return an array with the IDs, but strip the associative keys
|
||||
*/
|
||||
return array_values(
|
||||
$providers = array_values(
|
||||
array_map(function (IProvider $provider) {
|
||||
return [
|
||||
'id' => $provider->getId(),
|
||||
'name' => $provider->getName()
|
||||
'name' => $provider->getName(),
|
||||
'order' => $provider->getOrder()
|
||||
];
|
||||
}, $this->providers));
|
||||
}, $this->providers)
|
||||
);
|
||||
|
||||
usort($providers, function ($provider1, $provider2) {
|
||||
return $provider1['order'] <=> $provider2['order'];
|
||||
});
|
||||
|
||||
/**
|
||||
* Return an array with the IDs, but strip the associative keys
|
||||
*/
|
||||
return $providers;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,6 +52,7 @@ use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\Defaults;
|
||||
use OCP\IConfig;
|
||||
use OCP\IInitialStateService;
|
||||
use OCP\INavigationManager;
|
||||
use OCP\Support\Subscription\IRegistry;
|
||||
use OCP\Util;
|
||||
|
||||
@@ -64,6 +65,9 @@ class TemplateLayout extends \OC_Template {
|
||||
/** @var IInitialStateService */
|
||||
private $initialState;
|
||||
|
||||
/** @var INavigationManager */
|
||||
private $navigationManager;
|
||||
|
||||
/**
|
||||
* @param string $renderAs
|
||||
* @param string $appId application id
|
||||
@@ -74,7 +78,7 @@ class TemplateLayout extends \OC_Template {
|
||||
$this->config = \OC::$server->get(IConfig::class);
|
||||
|
||||
/** @var IInitialStateService */
|
||||
$this->initialState = \OC::$server->get(InitialStateService::class);
|
||||
$this->initialState = \OC::$server->get(IInitialStateService::class);
|
||||
|
||||
if (Util::isIE()) {
|
||||
Util::addStyle('ie');
|
||||
@@ -82,6 +86,9 @@ class TemplateLayout extends \OC_Template {
|
||||
|
||||
// Decide which page we show
|
||||
if ($renderAs === TemplateResponse::RENDER_AS_USER) {
|
||||
/** @var INavigationManager */
|
||||
$this->navigationManager = \OC::$server->get(INavigationManager::class);
|
||||
|
||||
parent::__construct('core', 'layout.user');
|
||||
if (in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) {
|
||||
$this->assign('bodyid', 'body-settings');
|
||||
@@ -89,16 +96,19 @@ class TemplateLayout extends \OC_Template {
|
||||
$this->assign('bodyid', 'body-user');
|
||||
}
|
||||
|
||||
$this->initialState->provideInitialState('core', 'active-app', $this->navigationManager->getActiveEntry());
|
||||
$this->initialState->provideInitialState('unified-search', 'limit-default', SearchQuery::LIMIT_DEFAULT);
|
||||
Util::addScript('dist/unified-search', null, true);
|
||||
|
||||
// Add navigation entry
|
||||
$this->assign('application', '');
|
||||
$this->assign('appid', $appId);
|
||||
$navigation = \OC::$server->getNavigationManager()->getAll();
|
||||
|
||||
$navigation = $this->navigationManager->getAll();
|
||||
$this->assign('navigation', $navigation);
|
||||
$settingsNavigation = \OC::$server->getNavigationManager()->getAll('settings');
|
||||
$settingsNavigation = $this->navigationManager->getAll('settings');
|
||||
$this->assign('settingsnavigation', $settingsNavigation);
|
||||
|
||||
foreach ($navigation as $entry) {
|
||||
if ($entry['active']) {
|
||||
$this->assign('application', $entry['name']);
|
||||
|
||||
@@ -81,6 +81,13 @@ interface INavigationManager {
|
||||
*/
|
||||
public function setActiveEntry($appId);
|
||||
|
||||
/**
|
||||
* Get the current navigation entry of the currently running app
|
||||
* @return string
|
||||
* @since 20.0.0
|
||||
*/
|
||||
public function getActiveEntry();
|
||||
|
||||
/**
|
||||
* Get a list of navigation entries
|
||||
*
|
||||
|
||||
@@ -64,6 +64,16 @@ interface IProvider {
|
||||
*/
|
||||
public function getName(): string;
|
||||
|
||||
/**
|
||||
* Get the search provider order
|
||||
* The lower the int, the higher it will be sorted (0 will be before 10)
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 20.0.0
|
||||
*/
|
||||
public function getOrder(): int;
|
||||
|
||||
/**
|
||||
* Find matching search entries in an app
|
||||
*
|
||||
|
||||
@@ -38,7 +38,7 @@ final class SearchResult implements JsonSerializable {
|
||||
/** @var bool */
|
||||
private $isPaginated;
|
||||
|
||||
/** @var ASearchResultEntry[] */
|
||||
/** @var SearchResultEntry[] */
|
||||
private $entries;
|
||||
|
||||
/** @var int|string|null */
|
||||
@@ -47,7 +47,7 @@ final class SearchResult implements JsonSerializable {
|
||||
/**
|
||||
* @param string $name the translated name of the result section or group, e.g. "Mail"
|
||||
* @param bool $isPaginated
|
||||
* @param ASearchResultEntry[] $entries
|
||||
* @param SearchResultEntry[] $entries
|
||||
* @param null $cursor
|
||||
*
|
||||
* @since 20.0.0
|
||||
@@ -63,7 +63,7 @@ final class SearchResult implements JsonSerializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ASearchResultEntry[] $entries
|
||||
* @param SearchResultEntry[] $entries
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
@@ -78,7 +78,7 @@ final class SearchResult implements JsonSerializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ASearchResultEntry[] $entries
|
||||
* @param SearchResultEntry[] $entries
|
||||
* @param int|string $cursor
|
||||
*
|
||||
* @return static
|
||||
|
||||
@@ -34,7 +34,7 @@ use JsonSerializable;
|
||||
* The app providing the results has to extend this class for customization. In
|
||||
* most cases apps do not have to add any additional code.
|
||||
*
|
||||
* @example ``class MailResultEntry extends ASearchResultEntry {}`
|
||||
* @example ``class MailResultEntry extends SearchResultEntry {}`
|
||||
*
|
||||
* This approach was chosen over a final class as it allows Nextcloud to later
|
||||
* add new optional properties of an entry without having to break the usage of
|
||||
@@ -42,7 +42,7 @@ use JsonSerializable;
|
||||
*
|
||||
* @since 20.0.0
|
||||
*/
|
||||
abstract class ASearchResultEntry implements JsonSerializable {
|
||||
class SearchResultEntry implements JsonSerializable {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
@@ -72,7 +72,7 @@ abstract class ASearchResultEntry implements JsonSerializable {
|
||||
* @var string
|
||||
* @since 20.0.0
|
||||
*/
|
||||
protected $iconClass;
|
||||
protected $icon;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
@@ -85,7 +85,7 @@ abstract class ASearchResultEntry implements JsonSerializable {
|
||||
* @param string $title a main title of the entry
|
||||
* @param string $subline the secondary line of the entry
|
||||
* @param string $resourceUrl the URL where the user can find the detail, like a deep link inside the app
|
||||
* @param string $iconClass the icon class fallback
|
||||
* @param string $icon the icon class or url to the icon
|
||||
* @param boolean $rounded is the thumbnail rounded
|
||||
*
|
||||
* @since 20.0.0
|
||||
@@ -94,13 +94,13 @@ abstract class ASearchResultEntry implements JsonSerializable {
|
||||
string $title,
|
||||
string $subline,
|
||||
string $resourceUrl,
|
||||
string $iconClass = '',
|
||||
string $icon = '',
|
||||
bool $rounded = false) {
|
||||
$this->thumbnailUrl = $thumbnailUrl;
|
||||
$this->title = $title;
|
||||
$this->subline = $subline;
|
||||
$this->resourceUrl = $resourceUrl;
|
||||
$this->iconClass = $iconClass;
|
||||
$this->icon = $icon;
|
||||
$this->rounded = $rounded;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ abstract class ASearchResultEntry implements JsonSerializable {
|
||||
'title' => $this->title,
|
||||
'subline' => $this->subline,
|
||||
'resourceUrl' => $this->resourceUrl,
|
||||
'iconClass' => $this->iconClass,
|
||||
'icon' => $this->icon,
|
||||
'rounded' => $this->rounded,
|
||||
];
|
||||
}
|
||||
5
package-lock.json
generated
5
package-lock.json
generated
@@ -9888,6 +9888,11 @@
|
||||
"resolved": "https://registry.npmjs.org/vue-localstorage/-/vue-localstorage-0.6.2.tgz",
|
||||
"integrity": "sha512-29YQVVkIdoS6BZBCJAyu9d0OR0eKSm5gk5OjsLssV1+NM4zJnf9cxhN1AVeXkUHJLqOonECweuaR8PZ2x307dw=="
|
||||
},
|
||||
"vue-material-design-icons": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-material-design-icons/-/vue-material-design-icons-4.8.0.tgz",
|
||||
"integrity": "sha512-NNbwK/a14mk92ofBvJa6oBdWi+SO2f27pimoCWziirrbN5Nmt9q0pzELOfvqyy0ncoMJ2BLkd8KfQuXIAhL3Fw=="
|
||||
},
|
||||
"vue-multiselect": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-2.1.6.tgz",
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
"vue-clipboard2": "^0.3.1",
|
||||
"vue-infinite-loading": "^2.4.5",
|
||||
"vue-localstorage": "^0.6.2",
|
||||
"vue-material-design-icons": "^4.8.0",
|
||||
"vue-multiselect": "^2.1.6",
|
||||
"vue-router": "^3.3.4",
|
||||
"vuex": "^3.5.1",
|
||||
|
||||
@@ -81,7 +81,9 @@ module.exports = []
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
exclude: /node_modules/,
|
||||
exclude: BabelLoaderExcludeNodeModulesExcept([
|
||||
'vue-material-design-icons',
|
||||
]),
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
|
||||
Reference in New Issue
Block a user