diff options
Diffstat (limited to 'apps/dashboard/lib/Controller/DashboardApiController.php')
-rw-r--r-- | apps/dashboard/lib/Controller/DashboardApiController.php | 212 |
1 files changed, 155 insertions, 57 deletions
diff --git a/apps/dashboard/lib/Controller/DashboardApiController.php b/apps/dashboard/lib/Controller/DashboardApiController.php index 1062cf1bdba..d31cede85b7 100644 --- a/apps/dashboard/lib/Controller/DashboardApiController.php +++ b/apps/dashboard/lib/Controller/DashboardApiController.php @@ -3,91 +3,91 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2021 Julien Veyssier <eneiluj@posteo.net> - * - * @author Julien Veyssier <eneiluj@posteo.net> - * - * @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/>. - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Dashboard\Controller; -use OCP\AppFramework\OCSController; +use OCA\Dashboard\ResponseDefinitions; +use OCA\Dashboard\Service\DashboardService; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\ApiRoute; +use OCP\AppFramework\Http\Attribute\NoAdminRequired; +use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\OCSController; +use OCP\Dashboard\IAPIWidget; +use OCP\Dashboard\IAPIWidgetV2; use OCP\Dashboard\IButtonWidget; use OCP\Dashboard\IIconWidget; -use OCP\Dashboard\IOptionWidget; use OCP\Dashboard\IManager; +use OCP\Dashboard\IOptionWidget; +use OCP\Dashboard\IReloadableWidget; use OCP\Dashboard\IWidget; use OCP\Dashboard\Model\WidgetButton; +use OCP\Dashboard\Model\WidgetItem; + use OCP\Dashboard\Model\WidgetOptions; use OCP\IConfig; use OCP\IRequest; -use OCP\Dashboard\IAPIWidget; -use OCP\Dashboard\Model\WidgetItem; - +/** + * @psalm-import-type DashboardWidget from ResponseDefinitions + * @psalm-import-type DashboardWidgetItem from ResponseDefinitions + * @psalm-import-type DashboardWidgetItems from ResponseDefinitions + */ class DashboardApiController extends OCSController { - /** @var IManager */ - private $dashboardManager; - /** @var IConfig */ - private $config; - /** @var string|null */ - private $userId; - public function __construct( string $appName, IRequest $request, - IManager $dashboardManager, - IConfig $config, - ?string $userId + private IManager $dashboardManager, + private IConfig $config, + private ?string $userId, + private DashboardService $service, ) { parent::__construct($appName, $request); + } + + /** + * @param string[] $widgetIds Limit widgets to given ids + * @return IWidget[] + */ + private function getShownWidgets(array $widgetIds): array { + if (empty($widgetIds)) { + $systemDefault = $this->config->getAppValue('dashboard', 'layout', 'recommendations,spreed,mail,calendar'); + $widgetIds = explode(',', $this->config->getUserValue($this->userId, 'dashboard', 'layout', $systemDefault)); + } - $this->dashboardManager = $dashboardManager; - $this->config = $config; - $this->userId = $userId; + return array_filter( + $this->dashboardManager->getWidgets(), + static function (IWidget $widget) use ($widgetIds) { + return in_array($widget->getId(), $widgetIds); + }, + ); } /** - * Example request with Curl: - * curl -u user:passwd http://my.nc/ocs/v2.php/apps/dashboard/api/v1/widget-items -H Content-Type:application/json -X GET -d '{"sinceIds":{"github_notifications":"2021-03-22T15:01:10Z"}}' + * Get the items for the widgets * - * @param array $sinceIds Array indexed by widget Ids, contains date/id from which we want the new items + * @param array<string, string> $sinceIds Array indexed by widget Ids, contains date/id from which we want the new items * @param int $limit Limit number of result items per widget - * @param string[] $widgets Limit results to specific widgets + * @psalm-param int<1, 30> $limit + * @param list<string> $widgets Limit results to specific widgets + * @return DataResponse<Http::STATUS_OK, array<string, list<DashboardWidgetItem>>, array{}> * - * @NoAdminRequired - * @NoCSRFRequired + * 200: Widget items returned */ + #[NoAdminRequired] + #[NoCSRFRequired] + #[ApiRoute(verb: 'GET', url: '/api/v1/widget-items')] public function getWidgetItems(array $sinceIds = [], int $limit = 7, array $widgets = []): DataResponse { - $showWidgets = $widgets; $items = []; - - if (empty($showWidgets)) { - $systemDefault = $this->config->getAppValue('dashboard', 'layout', 'recommendations,spreed,mail,calendar'); - $showWidgets = explode(',', $this->config->getUserValue($this->userId, 'dashboard', 'layout', $systemDefault)); - } - - $widgets = $this->dashboardManager->getWidgets(); + $widgets = $this->getShownWidgets($widgets); foreach ($widgets as $widget) { - if ($widget instanceof IAPIWidget && in_array($widget->getId(), $showWidgets)) { - $items[$widget->getId()] = array_map(function (WidgetItem $item) { + if ($widget instanceof IAPIWidget) { + $items[$widget->getId()] = array_map(static function (WidgetItem $item) { return $item->jsonSerialize(); }, $widget->getItems($this->userId, $sinceIds[$widget->getId()] ?? null, $limit)); } @@ -97,12 +97,43 @@ class DashboardApiController extends OCSController { } /** - * Example request with Curl: - * curl -u user:passwd http://my.nc/ocs/v2.php/apps/dashboard/api/v1/widgets + * Get the items for the widgets + * + * @param array<string, string> $sinceIds Array indexed by widget Ids, contains date/id from which we want the new items + * @param int $limit Limit number of result items per widget, not more than 30 are allowed + * @psalm-param int<1, 30> $limit + * @param list<string> $widgets Limit results to specific widgets + * @return DataResponse<Http::STATUS_OK, array<string, DashboardWidgetItems>, array{}> + * + * 200: Widget items returned + */ + #[NoAdminRequired] + #[NoCSRFRequired] + #[ApiRoute(verb: 'GET', url: '/api/v2/widget-items')] + public function getWidgetItemsV2(array $sinceIds = [], int $limit = 7, array $widgets = []): DataResponse { + $items = []; + $widgets = $this->getShownWidgets($widgets); + foreach ($widgets as $widget) { + if ($widget instanceof IAPIWidgetV2) { + $items[$widget->getId()] = $widget + ->getItemsV2($this->userId, $sinceIds[$widget->getId()] ?? null, $limit) + ->jsonSerialize(); + } + } + + return new DataResponse($items); + } + + /** + * Get the widgets * - * @NoAdminRequired - * @NoCSRFRequired + * @return DataResponse<Http::STATUS_OK, array<string, DashboardWidget>, array{}> + * + * 200: Widgets returned */ + #[NoAdminRequired] + #[NoCSRFRequired] + #[ApiRoute(verb: 'GET', url: '/api/v1/widgets')] public function getWidgets(): DataResponse { $widgets = $this->dashboardManager->getWidgets(); @@ -116,6 +147,8 @@ class DashboardApiController extends OCSController { 'icon_url' => ($widget instanceof IIconWidget) ? $widget->getIconUrl() : '', 'widget_url' => $widget->getUrl(), 'item_icons_round' => $options->withRoundItemIcons(), + 'item_api_versions' => [], + 'reload_interval' => 0, ]; if ($widget instanceof IButtonWidget) { $data += [ @@ -128,9 +161,74 @@ class DashboardApiController extends OCSController { }, $widget->getWidgetButtons($this->userId)), ]; } + if ($widget instanceof IReloadableWidget) { + $data['reload_interval'] = $widget->getReloadInterval(); + } + if ($widget instanceof IAPIWidget) { + $data['item_api_versions'][] = 1; + } + if ($widget instanceof IAPIWidgetV2) { + $data['item_api_versions'][] = 2; + } return $data; }, $widgets); return new DataResponse($items); } + + /** + * Get the layout + * + * @return DataResponse<Http::STATUS_OK, array{layout: list<string>}, array{}> + * + * 200: Layout returned + */ + #[NoAdminRequired] + #[ApiRoute(verb: 'GET', url: '/api/v3/layout')] + public function getLayout(): DataResponse { + return new DataResponse(['layout' => $this->service->getLayout()]); + } + + /** + * Update the layout + * + * @param list<string> $layout The new layout + * @return DataResponse<Http::STATUS_OK, array{layout: list<string>}, array{}> + * + * 200: Statuses updated successfully + */ + #[NoAdminRequired] + #[ApiRoute(verb: 'POST', url: '/api/v3/layout')] + public function updateLayout(array $layout): DataResponse { + $this->config->setUserValue($this->userId, 'dashboard', 'layout', implode(',', $layout)); + return new DataResponse(['layout' => $layout]); + } + + /** + * Get the statuses + * + * @return DataResponse<Http::STATUS_OK, array{statuses: list<string>}, array{}> + * + * 200: Statuses returned + */ + #[NoAdminRequired] + #[ApiRoute(verb: 'GET', url: '/api/v3/statuses')] + public function getStatuses(): DataResponse { + return new DataResponse(['statuses' => $this->service->getStatuses()]); + } + + /** + * Update the statuses + * + * @param list<string> $statuses The new statuses + * @return DataResponse<Http::STATUS_OK, array{statuses: list<string>}, array{}> + * + * 200: Statuses updated successfully + */ + #[NoAdminRequired] + #[ApiRoute(verb: 'POST', url: '/api/v3/statuses')] + public function updateStatuses(array $statuses): DataResponse { + $this->config->setUserValue($this->userId, 'dashboard', 'statuses', implode(',', $statuses)); + return new DataResponse(['statuses' => $statuses]); + } } |