From bbd6a240e5a6efdf29b788d92b84e21d2d65b65a Mon Sep 17 00:00:00 2001 From: Aina Sitraka <35221835+aynsix@users.noreply.github.com> Date: Thu, 6 Apr 2023 15:10:00 +0300 Subject: [PATCH] PHRAS-3823 : add permalink in report GUI (#4291) --- Phraseanet-production-client/config/config.js | 2 +- .../dist/authenticate.js | 2 +- .../dist/authenticate.min.js | 2 +- Phraseanet-production-client/dist/commons.js | 2 +- .../dist/commons.min.js | 2 +- .../Command/Report/AbstractReportCommand.php | 13 +++--------- .../Controller/Report/RootController.php | 14 +++++++++++++ .../Controller/ProdReportController.php | 1 + lib/Alchemy/Phrasea/Report/Report.php | 21 +++++++++++++++---- lib/Alchemy/Phrasea/Report/ReportRecords.php | 10 +++++---- .../Phrasea/Twig/PhraseanetExtension.php | 2 +- resources/locales/messages.de.xlf | 21 ++++++++++++------- resources/locales/messages.en.xlf | 21 ++++++++++++------- resources/locales/messages.fr.xlf | 21 ++++++++++++------- resources/locales/messages.nl.xlf | 7 ++++++- resources/locales/validators.de.xlf | 2 +- resources/locales/validators.en.xlf | 2 +- resources/locales/validators.fr.xlf | 2 +- resources/locales/validators.nl.xlf | 2 +- resources/www/report/js/report.js | 13 ++++++++++++ .../web/report/report_layout_child.html.twig | 13 ++++++++++++ 21 files changed, 122 insertions(+), 53 deletions(-) diff --git a/Phraseanet-production-client/config/config.js b/Phraseanet-production-client/config/config.js index 9755861119..f55efc74bf 100644 --- a/Phraseanet-production-client/config/config.js +++ b/Phraseanet-production-client/config/config.js @@ -13,5 +13,5 @@ module.exports = { setupDir: _root + 'tests/setup/node.js', karmaConf: _root + 'config/karma.conf.js', // change this version when you change JS file for lazy loading - assetFileVersion: 84 + assetFileVersion: 85 }; diff --git a/Phraseanet-production-client/dist/authenticate.js b/Phraseanet-production-client/dist/authenticate.js index de9fc7cd9e..4b111738fd 100644 --- a/Phraseanet-production-client/dist/authenticate.js +++ b/Phraseanet-production-client/dist/authenticate.js @@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ if (__webpack_require__.nc) { /******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ } -/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=84"; +/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=85"; /******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ script.onerror = script.onload = onScriptComplete; /******/ function onScriptComplete() { diff --git a/Phraseanet-production-client/dist/authenticate.min.js b/Phraseanet-production-client/dist/authenticate.min.js index 6505c30d9f..a3019d47bc 100644 --- a/Phraseanet-production-client/dist/authenticate.min.js +++ b/Phraseanet-production-client/dist/authenticate.min.js @@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ if (__webpack_require__.nc) { /******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ } -/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=84"; +/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=85"; /******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ script.onerror = script.onload = onScriptComplete; /******/ function onScriptComplete() { diff --git a/Phraseanet-production-client/dist/commons.js b/Phraseanet-production-client/dist/commons.js index 9dcd19cd9c..d472bf1db5 100644 --- a/Phraseanet-production-client/dist/commons.js +++ b/Phraseanet-production-client/dist/commons.js @@ -91,7 +91,7 @@ /******/ if (__webpack_require__.nc) { /******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ } -/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=84"; +/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=85"; /******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ script.onerror = script.onload = onScriptComplete; /******/ function onScriptComplete() { diff --git a/Phraseanet-production-client/dist/commons.min.js b/Phraseanet-production-client/dist/commons.min.js index 1063e2530d..d053e3089d 100644 --- a/Phraseanet-production-client/dist/commons.min.js +++ b/Phraseanet-production-client/dist/commons.min.js @@ -91,7 +91,7 @@ /******/ if (__webpack_require__.nc) { /******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ } -/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=84"; +/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=85"; /******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ script.onerror = script.onload = onScriptComplete; /******/ function onScriptComplete() { diff --git a/lib/Alchemy/Phrasea/Command/Report/AbstractReportCommand.php b/lib/Alchemy/Phrasea/Command/Report/AbstractReportCommand.php index af7486430d..a7d9879172 100644 --- a/lib/Alchemy/Phrasea/Command/Report/AbstractReportCommand.php +++ b/lib/Alchemy/Phrasea/Command/Report/AbstractReportCommand.php @@ -108,21 +108,19 @@ abstract class AbstractReportCommand extends Command .'report' . DIRECTORY_SEPARATOR . date('Ymd'); - $suffixFileName = "__" . $this->dmin . "_to_"; - $suffixFileName = !empty($this->dmax) ? $suffixFileName . $this->dmax: $suffixFileName . (new \DateTime())->format('Y-m-d'); - if ($this->isAppboxConnection) { $absoluteDirectoryPath .= 'appbox'; } else { $absoluteDirectoryPath .= 'Sbas' . $this->sbasId; } - $report->render($absoluteDirectoryPath, $suffixFileName); + $report->render($absoluteDirectoryPath); - $filePath = $absoluteDirectoryPath . DIRECTORY_SEPARATOR . $this->normalizeString($report->getName()).$suffixFileName . '.csv'; + $filePath = $absoluteDirectoryPath . DIRECTORY_SEPARATOR . $report->getFileName() . '.csv'; $attachement = new Attachment($filePath); + $suffixFileName = $report->getSuffixFileName($this->dmin, $this->dmax); $suffixFileName = str_replace("__", ' - ', $suffixFileName); $reportName = $report->getName() . str_replace("_", ' ', $suffixFileName); @@ -173,9 +171,4 @@ abstract class AbstractReportCommand extends Command return false; } - - private function normalizeString($filename) - { - return (new Slugify())->slugify($filename, '-'); - } } diff --git a/lib/Alchemy/Phrasea/Controller/Report/RootController.php b/lib/Alchemy/Phrasea/Controller/Report/RootController.php index f212a2fd75..146043240b 100644 --- a/lib/Alchemy/Phrasea/Controller/Report/RootController.php +++ b/lib/Alchemy/Phrasea/Controller/Report/RootController.php @@ -10,6 +10,7 @@ namespace Alchemy\Phrasea\Controller\Report; use Alchemy\Phrasea\Controller\Controller; +use Alchemy\Phrasea\Media\Subdef\Subdef; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -48,6 +49,7 @@ class RootController extends Controller } $granted = []; + $availableSubdefName = []; $acl = $this->getAclForUser(); foreach ($acl->get_granted_base([\ACL::CANREPORT]) as $collection) { @@ -73,6 +75,17 @@ class RootController extends Controller 'base_id' => $collection->get_base_id(), 'name' => $collection->get_name(), ]; + + if (!isset($availableSubdefName[$sbas_id])) { + foreach ($collection->get_databox()->get_subdef_structure() as $subdefGroup) { + /** @var \databox_subdef $subdef */ + foreach ($subdefGroup as $subdef) { + $availableSubdefName[$sbas_id][] = $subdef->get_name(); + } + } + + $availableSubdefName[$sbas_id] = array_unique($availableSubdefName[$sbas_id]); + } } $conf = $this->getConf(); @@ -81,6 +94,7 @@ class RootController extends Controller 'ajax_dash' => true, 'dashboard' => null, 'granted_bases' => $granted, + 'availableSubdefName' => $availableSubdefName, 'home_title' => $conf->get(['registry', 'general', 'title']), 'module' => 'report', 'module_name' => 'Report', diff --git a/lib/Alchemy/Phrasea/Report/Controller/ProdReportController.php b/lib/Alchemy/Phrasea/Report/Controller/ProdReportController.php index 90e9aa807a..2c47721c29 100644 --- a/lib/Alchemy/Phrasea/Report/Controller/ProdReportController.php +++ b/lib/Alchemy/Phrasea/Report/Controller/ProdReportController.php @@ -186,6 +186,7 @@ class ProdReportController extends Controller ); $report->setFormat(self::$mapFromExtension[$this->extension]['format']); + $report->setPermalink($request->get('permalink')); set_time_limit(600); $response = new StreamedResponse(); diff --git a/lib/Alchemy/Phrasea/Report/Report.php b/lib/Alchemy/Phrasea/Report/Report.php index b6095f1236..11894cdfeb 100644 --- a/lib/Alchemy/Phrasea/Report/Report.php +++ b/lib/Alchemy/Phrasea/Report/Report.php @@ -106,14 +106,14 @@ abstract class Report return $this->format; } - public function render($absoluteDirectoryPath = null, $suffixFileName = null) + public function render($absoluteDirectoryPath = null) { switch($this->format) { //case self::FORMAT_XLS: case self::FORMAT_CSV: case self::FORMAT_ODS: case self::FORMAT_XLSX: - $this->renderAsExcel($absoluteDirectoryPath, $suffixFileName); + $this->renderAsExcel($absoluteDirectoryPath); break; default: // should not happen since format is checked before @@ -121,9 +121,22 @@ abstract class Report } } - private function renderAsExcel($absoluteDirectoryPath = null, $suffixFileName = null) + public function getSuffixFileName($dmin, $dmax) { - $filename = $this->normalizeString($this->getName()) . $suffixFileName; + $suffixFileName = "__" . $dmin . "_to_"; + $suffixFileName = !empty($dmax) ? $suffixFileName . $dmax: $suffixFileName . (new \DateTime())->format('Y-m-d'); + + return $suffixFileName; + } + + public function getFileName() + { + return $this->normalizeString($this->getName()) . $this->getSuffixFileName($this->parms['dmin'], $this->parms['dmax']); + } + + private function renderAsExcel($absoluteDirectoryPath = null) + { + $filename = $this->getFileName(); switch($this->format) { //case self::FORMAT_XLS: // $excel = new Excel(Excel::FORMAT_XLS); diff --git a/lib/Alchemy/Phrasea/Report/ReportRecords.php b/lib/Alchemy/Phrasea/Report/ReportRecords.php index 5fe8f080f0..8718d653e8 100644 --- a/lib/Alchemy/Phrasea/Report/ReportRecords.php +++ b/lib/Alchemy/Phrasea/Report/ReportRecords.php @@ -96,14 +96,16 @@ class ReportRecords extends Report foreach($rows as $row) { if (!empty($this->permalink)) { try { + $permalinkUrl = ''; $record = $this->databox->get_record($row['record_id']); - $permalinkUrl = $record->get_subdef($this->permalink)->get_permalink()->get_url()->__toString(); + // if from GUI, check if user has access to subdef in collection + if (!isset($this->acl) || $this->acl->has_right_on_base($record->getBaseId(), \ACL::CANDWNLDPREVIEW)) { + $permalinkUrl = $record->get_subdef($this->permalink)->get_permalink()->get_url()->__toString(); + } } catch (\Exception $e) { // the record or subdef is not found - $permalinkUrl = ''; } catch (\Throwable $e) { // there is no permalink created ??? - $permalinkUrl = ''; } $row['permalink_' . $this->permalink] = $permalinkUrl; @@ -165,7 +167,7 @@ class ReportRecords extends Report $this->sqlWhere = "FALSE"; } - $this->name = "Databox"; + $this->name = "export databox content"; } } diff --git a/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php b/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php index e185c8ff0a..2361535753 100644 --- a/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php +++ b/lib/Alchemy/Phrasea/Twig/PhraseanetExtension.php @@ -60,7 +60,7 @@ class PhraseanetExtension extends \Twig_Extension { return [ // change this version when you change JS file to force the navigation to reload js file - 'assetFileVersion' => 84 + 'assetFileVersion' => 85 ]; } diff --git a/resources/locales/messages.de.xlf b/resources/locales/messages.de.xlf index 8b9f530222..3ec256d46c 100644 --- a/resources/locales/messages.de.xlf +++ b/resources/locales/messages.de.xlf @@ -1,14 +1,14 @@ - + - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.
- - + + Form/Configuration/EmailFormType.php Form/Login/PhraseaAuthenticationForm.php @@ -201,7 +201,7 @@ Bridge/Dailymotion/element_informations.html.twig - %number% documents<br/>selectionnes + selectionnes]]> ausgewählt]]> Controller/Prod/QueryController.php @@ -2540,7 +2540,7 @@ Form/Configuration/ActionsFormType.php - Display & action settings + Anzeige und Handlung-Einstellungen admin/fields/templates.html.twig @@ -12335,7 +12335,7 @@ Controller/Root/AccountController.php - phraseanet::account: << your account can be deleted via admin interface >> + >]]> Ihr Benutzerkonto kann nur durch die Administration Anwendung gelöscht werden. web/account/account.html.twig @@ -14598,6 +14598,11 @@ Vorsicht: die aktuelle Werte werden durch die neue Werte überschrieben Information über die Benutzer entsprechend %critere% module/report/nav.php + + report:: Permalink + report:: Permalink + web/report/report_layout_child.html.twig + report:: Phraseanet report Phraseanet Report @@ -15450,7 +15455,7 @@ Vorsicht: die aktuelle Werte werden durch die neue Werte überschrieben web/thesaurus/thesaurus.html.twig - thesaurus:: Supprimer cette branche ?&#10;(les termes concernes remonteront en candidats a la prochaine indexation) + web/thesaurus/thesaurus.html.twig diff --git a/resources/locales/messages.en.xlf b/resources/locales/messages.en.xlf index bbdf7b0d3d..09d0354b3a 100644 --- a/resources/locales/messages.en.xlf +++ b/resources/locales/messages.en.xlf @@ -1,14 +1,14 @@ - + - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.
- - + + Form/Configuration/EmailFormType.php Form/Login/PhraseaAuthenticationForm.php @@ -201,7 +201,7 @@ Bridge/Dailymotion/element_informations.html.twig - %number% documents<br/>selectionnes + selectionnes]]> selected]]> Controller/Prod/QueryController.php @@ -2543,7 +2543,7 @@ Form/Configuration/ActionsFormType.php - Display & action settings + Display and action settings admin/fields/templates.html.twig @@ -12338,7 +12338,7 @@ Controller/Root/AccountController.php - phraseanet::account: << your account can be deleted via admin interface >> + >]]> Your rights do not allow to perform this action. Your account can only be deleted via the Administration interface. web/account/account.html.twig @@ -14606,6 +14606,11 @@ It is possible to place several search areas Users information corresponding to %critere% module/report/nav.php + + report:: Permalink + report:: Permalink + web/report/report_layout_child.html.twig + report:: Phraseanet report Phraseanet report @@ -15458,7 +15463,7 @@ It is possible to place several search areas web/thesaurus/thesaurus.html.twig - thesaurus:: Supprimer cette branche ?&#10;(les termes concernes remonteront en candidats a la prochaine indexation) + web/thesaurus/thesaurus.html.twig diff --git a/resources/locales/messages.fr.xlf b/resources/locales/messages.fr.xlf index 99809f823a..fe20768121 100644 --- a/resources/locales/messages.fr.xlf +++ b/resources/locales/messages.fr.xlf @@ -1,14 +1,14 @@ - + - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.
- - + + Form/Configuration/EmailFormType.php Form/Login/PhraseaAuthenticationForm.php @@ -201,7 +201,7 @@ Bridge/Dailymotion/element_informations.html.twig - %number% documents<br/>selectionnes + selectionnes]]> sélectionnés]]> Controller/Prod/QueryController.php @@ -2540,7 +2540,7 @@ Form/Configuration/ActionsFormType.php - Display & action settings + Paramétrage d'affichage et d'action admin/fields/templates.html.twig @@ -12336,7 +12336,7 @@ Si vous recevez cet e-mail sans l'avoir sollicité, merci de l'ignorer ou de le Controller/Root/AccountController.php - phraseanet::account: << your account can be deleted via admin interface >> + >]]> Vos droits ne vous permettent pas de réaliser cette action, votre compte ne peut être supprimé que via l'interface d'Administration. web/account/account.html.twig @@ -14607,6 +14607,11 @@ Attention: les valeurs actuellement en place seront écrasées par ces nouvelles Information sur les utilisateurs correspondant à %critere% module/report/nav.php + + report:: Permalink + report:: Permalink + web/report/report_layout_child.html.twig + report:: Phraseanet report Phraseanet Report @@ -15459,7 +15464,7 @@ Attention: les valeurs actuellement en place seront écrasées par ces nouvelles web/thesaurus/thesaurus.html.twig - thesaurus:: Supprimer cette branche ?&#10;(les termes concernes remonteront en candidats a la prochaine indexation) + web/thesaurus/thesaurus.html.twig diff --git a/resources/locales/messages.nl.xlf b/resources/locales/messages.nl.xlf index d7b667a17f..c523a56d13 100644 --- a/resources/locales/messages.nl.xlf +++ b/resources/locales/messages.nl.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. @@ -14604,6 +14604,11 @@ report:: Information sur les utilisateurs correspondant a %critere% module/report/nav.php + + report:: Permalink + report:: Permalink + web/report/report_layout_child.html.twig + report:: Phraseanet report report:: Phraseanet report diff --git a/resources/locales/validators.de.xlf b/resources/locales/validators.de.xlf index 5cb2418873..3715302c3b 100644 --- a/resources/locales/validators.de.xlf +++ b/resources/locales/validators.de.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. diff --git a/resources/locales/validators.en.xlf b/resources/locales/validators.en.xlf index c858f4070b..18176024bf 100644 --- a/resources/locales/validators.en.xlf +++ b/resources/locales/validators.en.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. diff --git a/resources/locales/validators.fr.xlf b/resources/locales/validators.fr.xlf index 05f8dcb9aa..1506faf8e1 100644 --- a/resources/locales/validators.fr.xlf +++ b/resources/locales/validators.fr.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. diff --git a/resources/locales/validators.nl.xlf b/resources/locales/validators.nl.xlf index e68967a9db..4f9546a875 100644 --- a/resources/locales/validators.nl.xlf +++ b/resources/locales/validators.nl.xlf @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. diff --git a/resources/www/report/js/report.js b/resources/www/report/js/report.js index af439032f5..fe6ce6121a 100644 --- a/resources/www/report/js/report.js +++ b/resources/www/report/js/report.js @@ -65,6 +65,10 @@ $(document).ready(function () { form = $this.closest('form'); $(".collist", form).hide(); $(".collist-" + value, form).show(); + + // subdef list depends on selected databox + $(".subdeflist", form).hide(); + $(".subdeflist-" + value, form).show(); }); $('.collist').each(function() { @@ -76,6 +80,15 @@ $(document).ready(function () { $(".collist-" + i, form).show(); }); + $('.subdeflist').each(function() { + var $this = $(this), + form = $this.closest('form'), + i = $this.closest('form').find('.sbas_select').val() + ; + $this.hide(); + $(".subdeflist-" + i, form).show(); + }); + $('.form2').each(function() { if ($(this).html().trim() === '') $(this).hide(); diff --git a/templates/web/report/report_layout_child.html.twig b/templates/web/report/report_layout_child.html.twig index ba3cefdb89..74b3af0f11 100644 --- a/templates/web/report/report_layout_child.html.twig +++ b/templates/web/report/report_layout_child.html.twig @@ -90,6 +90,19 @@ {% endfor %} {% endblock form_records %} + +
+
{{ "report:: Permalink" | trans }}
+ +
+