Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
### Added
- Cache report data in the browser (using ETag & If-None-Match) #535
- Warn about unsaved changes before leaving a report
- OCS endpoint to create reports from CSV files via files clients

### Fixed
- Fix PHP 8.4 deprecation warnings #534 @[robertoschwald](https://github.com/robertoschwald)
Expand Down
4 changes: 2 additions & 2 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
['name' => 'report#update', 'url' => '/report/{reportId}', 'verb' => 'PUT'],
['name' => 'report#rename', 'url' => '/report/{reportId}/rename', 'verb' => 'PUT'],
['name' => 'report#createCopy', 'url' => '/report/copy', 'verb' => 'POST'],
['name' => 'report#createFromDataFile', 'url' => '/report/file', 'verb' => 'POST'],
//['name' => 'report#createFromDataFile', 'url' => '/report/file/{fileId}', 'verb' => 'POST'],
['name' => 'report#updateOptions', 'url' => '/report/{reportId}/options', 'verb' => 'POST'],
['name' => 'report#updateRefresh', 'url' => '/report/{reportId}/refresh', 'verb' => 'POST'],
['name' => 'report#updateGroup', 'url' => '/report/{reportId}/group', 'verb' => 'POST'],
Expand Down Expand Up @@ -147,4 +147,4 @@
['name' => 'whatsNew#get', 'url' => '/whatsnew', 'verb' => 'GET'],
['name' => 'whatsNew#dismiss', 'url' => '/whatsnew', 'verb' => 'POST'],
]
];
];
1 change: 1 addition & 0 deletions js/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ OCA.Analytics.Sidebar.Report = {
});
},

// not used; rework to be done as the fileId is expected now
createFromDataFile: function (file = '') {
let requestUrl = OC.generateUrl('apps/analytics/report/file');
fetch(requestUrl, {
Expand Down
3 changes: 3 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use OCA\Analytics\Search\SearchProvider;
use OCA\Analytics\Listener\ReferenceListener;
use OCA\Analytics\Reference\ReferenceProvider;
use OCA\Analytics\Capabilities;
use OCA\ShareReview\Sources\SourceEvent;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
Expand All @@ -41,6 +42,8 @@ public function register(IRegistrationContext $context): void {

$context->registerSearchProvider(SearchProvider::class);

$context->registerCapability(Capabilities::class);

// file actions are not working at the moment
// $context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalScripts::class);
$context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class);
Expand Down
42 changes: 42 additions & 0 deletions lib/Capabilities.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php
/**
* Analytics
*
* SPDX-FileCopyrightText: 2019-2024 Marcel Scherello
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Analytics;

use OCP\Capabilities\ICapability;
use OCA\Analytics\AppInfo\Application;
use OCP\IL10N;

class Capabilities implements ICapability {

public function __construct(IL10N $l10n) {
$this->l10n = $l10n;
}

/**
* Expose the endpoint to create a report from a csv file
*/
public function getCapabilities() {
return [
'declarativeui' => [
Application::APP_ID => [
'context-menu' => [
[
'name' => $this->l10n->t('Visualize data in Analytics'),
'url' => '/ocs/v2.php/apps/analytics/createFromDataFile?fileId={fileId}',
'method' => 'POST',
'mimetype_filters' => 'text/csv',
'bodyParams' => [],
'icon' => '/apps/analytics/img/app.svg'
],
],
],
],
];
}
}
59 changes: 59 additions & 0 deletions lib/Controller/ApiController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/**
* Analytics
*
* SPDX-FileCopyrightText: 2019-2024 Marcel Scherello
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Analytics\Controller;

use OCA\Analytics\Service\ReportService;
use OCP\AppFramework\Http\Attribute\ApiRoute;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\OCSController;
use OCP\IRequest;

class ApiController extends OCSController {
private ReportService $reportService;

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

/**
* Create an analytics report from an existing data file.
*
* @param int $fileId ID of the file to import
*
* @return JSONResponse HTTP 200 with a link to the created report
*
*/
#[NoAdminRequired]
#[NoCSRFRequired]
#[ApiRoute(verb: 'POST', url: '/createFromDataFile')]
public function createFromDataFile(int $fileId): JSONResponse {
$reportId = $this->reportService->createFromDataFile($fileId);
$url = '/apps/analytics/r/' . $reportId;
return new JSONResponse([
'version' => 0.1,
'root' => [
'orientation' => 'vertical',
'rows' => [
[
'children' => [
[
'element' => 'URL',
'text' => 'Analytics report created',
'url' => $url,
],
],
],
],
],
]);
}
}
49 changes: 33 additions & 16 deletions lib/Service/ReportService.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,22 +234,39 @@ public function createCopy(int $reportId, $chartoptions, $dataoptions, $filterop
* @param string $file
* @return int
*/
public function createFromDataFile($file = '') {
$this->ActivityManager->triggerEvent(0, ActivityManager::OBJECT_REPORT, ActivityManager::SUBJECT_REPORT_ADD);

if ($file !== '') {
$name = explode('.', end(explode('/', $file)))[0];
$subheader = $file;
$parent = 0;
$dataset = 0;
$type = DatasourceController::DATASET_TYPE_LOCAL_CSV;
$link = $file;
$visualization = 'table';
$chart = 'line';
$reportId = $this->ReportMapper->create($name, $subheader, $parent, $type, $dataset, $link, $visualization, $chart, '', '', '');
}
return $reportId;
}
/**
* Create a report based on a data file.
*
* @param int|string $file Path to the file or the numeric file ID
*
* @return int ID of the newly created report
*/
public function createFromDataFile($file = '') {
$this->ActivityManager->triggerEvent(0, ActivityManager::OBJECT_REPORT, ActivityManager::SUBJECT_REPORT_ADD);

$reportId = 0;

if ($file !== '') {
if (is_numeric($file)) {
$userFolder = $this->rootFolder->getUserFolder($this->userId);
$nodes = $userFolder->getById((int)$file);
if (isset($nodes[0])) {
$file = $userFolder->getRelativePath($nodes[0]->getPath());
}
}

$name = explode('.', end(explode('/', $file)))[0];
$subheader = $file;
$parent = 0;
$dataset = 0;
$type = DatasourceController::DATASET_TYPE_LOCAL_CSV;
$link = $file;
$visualization = 'table';
$chart = 'line';
$reportId = $this->ReportMapper->create($name, $subheader, $parent, $type, $dataset, $link, $visualization, $chart, '', '', '');
}
return $reportId;
}

/**
* update report details
Expand Down
59 changes: 59 additions & 0 deletions openapi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"openapi": "3.0.0",
"info": {
"title": "Analytics OCS API",
"version": "1.0.0"
},
"paths": {
"/ocs/v2.php/apps/analytics/createFromDataFile": {
"post": {
"summary": "Create analytics report from a data file",
"operationId": "createFromDataFile",
"tags": ["analytics"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"fileId": {
"type": "integer",
"description": "ID of the file to import"
}
},
"required": ["fileId"]
}
}
}
},
"responses": {
"200": {
"description": "Report created",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"version": {"type": "number"},
"root": {
"type": "object",
"properties": {
"orientation": {"type": "string"},
"rows": {
"type": "array",
"items": {"type": "object"}
}
}
}
}
}
}
}
},
"404": {"description": "File not found"}
}
}
}
}
}