Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zhang <peter@innocraft.com>2021-11-13 02:49:08 +0300
committerGitHub <noreply@github.com>2021-11-13 02:49:08 +0300
commitbf341b7c0ba46691bf3e475ebaa58391363cd7ec (patch)
tree232d4a0ec7aa3b8c801592872eb2d2523dc66f0e /plugins/Feedback
parent9c58f4e71db9133b2c83d51cf700e818ec5ff7e4 (diff)
add feedback question, remove other related. (#18262)
* remove feedback links remove feedback links * update screen shot update screen shot * add feedback question add feedback question * update close to icon update close to icon * built vue files * remove in line css remove in line css, change to less file * move translation key to plugin move translation key to plugin * remove feedback popup remove feedback popup * update remove some test and feedback related update remove some test and feedback related * add draft tests add draft tests * update feedback add php and UI tests update feedback add php and UI tests * update test screen shots update test screen shots * Update demo.twig add heart to demo page * add feedback back in extend the modal add feedback back in extend the modal * update coreHome update coreHome * update screen shots update screen shots * Update FeedbackQuestion_spec.js update js tests * update test update test * built vue files * update screenshot and js tests update screenshot and js tests * Update FeedbackQuestion_spec.js test success * update screenshot update screenshot * update tests update tests * fix test error fix test error * Removing the refer us popup * Readding accidentally removed language files * update test * update test * remove refer us * update feedback umd js update feedback umd js * merge Andy branch merge Andy branch and update screen shots * revert language changes revert language changes * revert language changes revert language changes * revert language file revert language file * revert unrelated lang change revert unrelated lang change * revert lang change revert lang change * revert lang change revert lang change * Delete ControllerTest.php remove controller test not in used * Update core/Piwik.php Co-authored-by: Ben Burgess <88810029+bx80@users.noreply.github.com> * Update plugins/Morpheus/javascripts/piwikHelper.js Co-authored-by: Ben Burgess <88810029+bx80@users.noreply.github.com> * update a big that cancel and reopen it again update a bug that cancel and reopen it again * update compare error update compare error * Update plugins/Feedback/FeedbackReminder.php Co-authored-by: Stefan Giehl <stefan@matomo.org> * update feedback show logic update feedback show logic * Update FeedbackQuestion_spec.js update tests * Update Feedback.php remove comments * Update .gitignore * update vue build file update vue build file * built vue files * update vue build file update vue build file * add close button add close button * add close button add close button * update screenshot update screenshot * remove umd remove umd * git add corehome git add corehome * revert all the umd file revert all the umd file * built vue files * built vue files * Update plugins/Feedback/lang/en.json Co-authored-by: Stefan Giehl <stefan@matomo.org> * update per review update per review * built vue files * set auto focus on modal open set auto focus on modal open * built vue files * Update FeedbackQuestion.vue add please write in english * built vue files * remove please write in English remove please write in English * built vue files * update tests and question tests update tests and question tests * set cookie in the test set cookie in the test * Update page-renderer.js add setCookie to tests * update test only load 1 update test only load 1 * built vue files * Update FeedbackQuestion_feedback_popup.png update screen shot * Update piwikHelper.js update button css * update screen shot update screen shot * Update plugins/Feedback/Feedback.php Co-authored-by: Stefan Giehl <stefan@matomo.org> * Update plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.vue Co-authored-by: Stefan Giehl <stefan@matomo.org> * Update plugins/Feedback/API.php Co-authored-by: Stefan Giehl <stefan@matomo.org> * Update plugins/Feedback/API.php Co-authored-by: Stefan Giehl <stefan@matomo.org> * Update core/Plugin/API.php Co-authored-by: Stefan Giehl <stefan@matomo.org> * update cookie and tests update cookie and tests * built vue files * test setcookie in tests test setcookie in tests * update tests update tests * update tests update tests * Update FeedbackQuestion_spec.js update cookie test * extend setCookie in test extend setCookie in test * update elints format update elints format * built vue files * test set cookie test set cookie * built vue files * Update FeedbackQuestion_spec.js set cookie after goto URL * Update FeedbackQuestion_spec.js int to string * update set cookie update set cookie * update test URL update test URL Co-authored-by: peterhashair <peterhashair@users.noreply.github.com> Co-authored-by: Andrew Davis <andrew.affinity@gmail.com> Co-authored-by: Ben Burgess <88810029+bx80@users.noreply.github.com> Co-authored-by: Stefan Giehl <stefan@matomo.org>
Diffstat (limited to 'plugins/Feedback')
-rw-r--r--plugins/Feedback/API.php60
-rw-r--r--plugins/Feedback/Controller.php38
-rw-r--r--plugins/Feedback/Feedback.php135
-rw-r--r--plugins/Feedback/ReferReminder.php34
-rw-r--r--plugins/Feedback/angularjs/feedback-popup/feedback-popup.controller.js42
-rw-r--r--plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.html20
-rw-r--r--plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.js38
-rw-r--r--plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.less25
-rw-r--r--plugins/Feedback/angularjs/feedback-popup/review-links.directive.html40
-rw-r--r--plugins/Feedback/angularjs/refer-banner/refer-banner.controller.js110
-rw-r--r--plugins/Feedback/angularjs/refer-banner/refer-banner.directive.html44
-rw-r--r--plugins/Feedback/angularjs/refer-banner/refer-banner.directive.js28
-rw-r--r--plugins/Feedback/angularjs/refer-banner/refer-banner.directive.less48
-rw-r--r--plugins/Feedback/images/facebook_logo.svg1
-rw-r--r--plugins/Feedback/images/linkedin_logo.svg1
-rw-r--r--plugins/Feedback/images/mastodon_logo.svg1
-rw-r--r--plugins/Feedback/images/twitter_logo.svg1
-rw-r--r--plugins/Feedback/lang/en.json19
-rw-r--r--plugins/Feedback/templates/feedbackPopup.twig1
-rw-r--r--plugins/Feedback/templates/feedbackQuestionBanner.twig1
-rw-r--r--plugins/Feedback/templates/index.twig4
-rw-r--r--plugins/Feedback/templates/referBanner.twig1
-rw-r--r--plugins/Feedback/tests/Fixtures/FeedbackQuestionBannerFixture.php (renamed from plugins/Feedback/tests/Fixtures/FeedbackPopupFixture.php)2
-rw-r--r--plugins/Feedback/tests/Fixtures/ReferBannerFixture.php25
-rw-r--r--plugins/Feedback/tests/Integration/ControllerTest.php116
-rw-r--r--plugins/Feedback/tests/Integration/FeedbackTest.php41
-rw-r--r--plugins/Feedback/tests/Integration/ReferBannerTest.php119
-rw-r--r--plugins/Feedback/tests/UI/FeedbackPopup_spec.js46
-rw-r--r--plugins/Feedback/tests/UI/FeedbackQuestion_spec.js52
-rw-r--r--plugins/Feedback/tests/UI/ReferBanner_spec.js30
-rw-r--r--plugins/Feedback/tests/UI/expected-screenshots/FeedbackForm_show.png4
-rw-r--r--plugins/Feedback/tests/UI/expected-screenshots/FeedbackPopup_feedback_popup.png3
-rw-r--r--plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_banner.png3
-rw-r--r--plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_failed.png3
-rw-r--r--plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_popup.png3
-rw-r--r--plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_success.png3
-rw-r--r--plugins/Feedback/tests/UI/expected-screenshots/ReferBannerTest_feedback_popup.png3
-rw-r--r--plugins/Feedback/vue/dist/Feedback.umd.js276
-rw-r--r--plugins/Feedback/vue/dist/Feedback.umd.min.js10
-rw-r--r--plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.adapter.ts19
-rw-r--r--plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.less34
-rw-r--r--plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.vue169
-rw-r--r--plugins/Feedback/vue/src/RateFeature/RateFeature.vue3
-rw-r--r--plugins/Feedback/vue/src/ReviewLinks/ReviewLinks.vue90
-rw-r--r--plugins/Feedback/vue/src/index.ts3
45 files changed, 683 insertions, 1066 deletions
diff --git a/plugins/Feedback/API.php b/plugins/Feedback/API.php
index 11ec8bc7f7..1619d46544 100644
--- a/plugins/Feedback/API.php
+++ b/plugins/Feedback/API.php
@@ -10,6 +10,8 @@ namespace Piwik\Plugins\Feedback;
use Piwik\Common;
use Piwik\Config;
use Piwik\Container\StaticContainer;
+use Piwik\DataTable\Renderer\Json;
+use Piwik\Date;
use Piwik\IP;
use Piwik\Mail;
use Piwik\Piwik;
@@ -60,6 +62,64 @@ class API extends \Piwik\Plugin\API
$this->sendMail($subject, $body);
}
+ /**
+ * Sends feedback for a specific feature to the Matomo team or alternatively to the email address configured in the
+ * config: "feedback_email_address".
+ *
+ * @param $question
+ * @param string|bool $message A message containing the actual feedback
+ * @throws \Piwik\NoAccessException
+ * @throws \Exception
+ */
+ public function sendFeedbackForSurvey($question, $message = false)
+ {
+ Piwik::checkUserIsNotAnonymous();
+ Piwik::checkUserHasSomeViewAccess();
+
+ if ($message == '' || strlen($message) < 10) {
+ return Piwik::translate("Feedback_MessageBodyValidationError");
+ }
+
+ $featureName = $this->getEnglishTranslationForFeatureName($question);
+ $body = sprintf("Question: %s\n", $featureName);
+ $feedbackMessage = "";
+
+ if (!empty($message) && $message !== 'undefined') {
+ $feedbackMessage = sprintf("Answer:\n%s\n", trim($message));
+ }
+
+ $body .= $feedbackMessage ? $feedbackMessage : " \n";
+
+ $subject = sprintf("%s for %s %s",
+ empty($like) ? "-1" : "+1",
+ $featureName,
+ empty($feedbackMessage) ? "" : "(w/ feedback Survey)"
+ );
+
+ $this->sendMail($subject, $body);
+
+ //if feedback is sent set next one to 6 month.
+ $nextReminder = Date::now()->getStartOfDay()->addMonth(6)->toString('Y-m-d');
+ $feedbackReminder = new FeedbackReminder();
+ $feedbackReminder->setUserOption($nextReminder);
+
+ return 'success';
+
+ }
+
+ public function updateFeedbackReminderDate()
+ {
+ Piwik::checkUserIsNotAnonymous();
+
+ //push reminder for 6 month
+ $nextReminder = Date::now()->getStartOfDay()->addMonth(6)->toString('Y-m-d');
+ $feedbackReminder = new FeedbackReminder();
+ $feedbackReminder->setUserOption($nextReminder);
+
+ Json::sendHeaderJSON();
+ return json_encode(['Next reminder date: ' . $nextReminder]);
+ }
+
private function sendMail($subject, $body)
{
$feedbackEmailAddress = Config::getInstance()->General['feedback_email_address'];
diff --git a/plugins/Feedback/Controller.php b/plugins/Feedback/Controller.php
index 5fa8a94023..9464f855f1 100644
--- a/plugins/Feedback/Controller.php
+++ b/plugins/Feedback/Controller.php
@@ -14,8 +14,6 @@ use Piwik\Piwik;
use Piwik\Common;
use Piwik\Version;
use Piwik\Container\StaticContainer;
-use Piwik\Plugins\Feedback\ReferReminder;
-use Piwik\Plugins\Feedback\FeedbackReminder;
use Piwik\DataTable\Renderer\Json;
class Controller extends \Piwik\Plugin\Controller
@@ -30,40 +28,4 @@ class Controller extends \Piwik\Plugin\Controller
return $view->render();
}
- /**
- * Store the next date that the feedback reminder popup should be displayed to this user.
- */
- public function updateFeedbackReminderDate()
- {
- Piwik::checkUserIsNotAnonymous();
-
- $nextReminder = Common::getRequestVar('nextReminder');
-
- if ($nextReminder !== Feedback::NEVER_REMIND_ME_AGAIN) {
- $nextReminder = Date::now()->getStartOfDay()->addDay($nextReminder)->toString('Y-m-d');
- }
-
- $feedbackReminder = new FeedbackReminder();
- $feedbackReminder->setUserOption($nextReminder);
-
- Json::sendHeaderJSON();
- return json_encode(['Next reminder date: ' . $nextReminder]);
- }
-
- public function updateReferReminderDate()
- {
- Piwik::checkUserIsNotAnonymous();
-
- $nextReminder = Common::getRequestVar('nextReminder');
-
- if ($nextReminder !== Feedback::NEVER_REMIND_ME_AGAIN) {
- $nextReminder = Date::now()->getStartOfDay()->addDay($nextReminder)->toString('Y-m-d');
- }
-
- $referReminder = new ReferReminder();
- $referReminder->setUserOption($nextReminder);
-
- Json::sendHeaderJSON();
- return json_encode(['Next reminder date: ' . $nextReminder]);
- }
}
diff --git a/plugins/Feedback/Feedback.php b/plugins/Feedback/Feedback.php
index 8e6531b7af..55ccc67e4a 100644
--- a/plugins/Feedback/Feedback.php
+++ b/plugins/Feedback/Feedback.php
@@ -9,6 +9,9 @@
namespace Piwik\Plugins\Feedback;
use Piwik\Date;
+use Piwik\Plugins\UsersManager\API as APIUsersManager;
+use Piwik\Plugins\UsersManager\UsersManager;
+use Piwik\Site;
use Piwik\View;
use Piwik\Piwik;
use Piwik\Common;
@@ -39,22 +42,16 @@ class Feedback extends \Piwik\Plugin
{
$stylesheets[] = "plugins/Feedback/stylesheets/feedback.less";
$stylesheets[] = "plugins/Feedback/vue/src/RateFeature/RateFeature.less";
- $stylesheets[] = "plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.less";
- $stylesheets[] = "plugins/Feedback/angularjs/refer-banner/refer-banner.directive.less";
+ $stylesheets[] = "plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.less";
}
public function getJsFiles(&$jsFiles)
{
- $jsFiles[] = "plugins/Feedback/angularjs/feedback-popup/feedback-popup.controller.js";
- $jsFiles[] = "plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.js";
- $jsFiles[] = "plugins/Feedback/angularjs/refer-banner/refer-banner.directive.js";
- $jsFiles[] = "plugins/Feedback/angularjs/refer-banner/refer-banner.controller.js";
}
public function getClientSideTranslationKeys(&$translationKeys)
{
$translationKeys[] = 'Feedback_ThankYou';
- $translationKeys[] = 'Feedback_ThankYouForSpreading';
$translationKeys[] = 'Feedback_RateFeatureTitle';
$translationKeys[] = 'Feedback_RateFeatureThankYouTitle';
$translationKeys[] = 'Feedback_RateFeatureLeaveMessageLike';
@@ -65,97 +62,42 @@ class Feedback extends \Piwik\Plugin
$translationKeys[] = 'Feedback_PleaseLeaveExternalReviewForMatomo';
$translationKeys[] = 'Feedback_RemindMeLater';
$translationKeys[] = 'Feedback_NeverAskMeAgain';
- $translationKeys[] = 'Feedback_ReferMatomo';
- $translationKeys[] = 'Feedback_ReferBannerTitle';
- $translationKeys[] = 'Feedback_ReferBannerLonger';
- $translationKeys[] = 'Feedback_ReferBannerSocialShareText';
- $translationKeys[] = 'Feedback_ReferBannerEmailShareSubject';
- $translationKeys[] = 'Feedback_ReferBannerEmailShareBody';
$translationKeys[] = 'Feedback_WontShowAgain';
$translationKeys[] = 'General_Ok';
$translationKeys[] = 'General_Cancel';
+ $translationKeys[] = 'Feedback_Question0';
+ $translationKeys[] = 'Feedback_Question1';
+ $translationKeys[] = 'Feedback_Question2';
+ $translationKeys[] = 'Feedback_Question3';
+ $translationKeys[] = 'Feedback_Question4';
+ $translationKeys[] = 'Feedback_FeedbackTitle';
+ $translationKeys[] = 'Feedback_FeedbackSubtitle';
+ $translationKeys[] = 'Feedback_ThankYourForFeedback';
+ $translationKeys[] = 'Feedback_Policy';
+ $translationKeys[] = 'Feedback_ThankYourForFeedback';
+ $translationKeys[] = 'Feedback_ThankYou';
+ $translationKeys[] = 'Feedback_MessageBodyValidationError';
}
public function renderViewsAndAddToPage(&$pageHtml)
{
- $feedbackPopopView = $this->renderFeedbackPopup();
- $referBannerView = $this->renderReferBanner();
-
- $views = [$feedbackPopopView, $referBannerView];
- $implodedViews = implode('', $views);
-
- $endOfBody = strpos($pageHtml, '</body>');
- $pageHtml = substr_replace($pageHtml, $implodedViews, $endOfBody, 0);
- }
-
- public function renderFeedbackPopup()
- {
- $popupView = new View('@Feedback/feedbackPopup');
- $popupView->promptForFeedback = (int)$this->getShouldPromptForFeedback();
-
- return $popupView->render();
- }
-
- public function renderReferBanner()
- {
- $referBannerView = new View('@Feedback/referBanner');
- $referBannerView->showReferBanner = (int) $this->showReferBanner();
-
- return $referBannerView->render();
- }
-
- public function showReferBanner()
- {
- if ($this->getShouldPromptForFeedback()) {
- return false;
- }
-
- if (Piwik::isUserIsAnonymous()) {
- return false;
- }
-
+ //only show on superuser
if (!Piwik::hasUserSuperUserAccess()) {
- return false;
- }
-
- if ($this->isDisabledInTestMode()) {
- return false;
+ return $pageHtml;
}
+ $feedbackQuestionBanner = $this->renderFeedbackQuestion();
- $shouldShowReferBanner = true;
-
- /**
- * @internal
- */
- Piwik::postEvent('Feedback.showReferBanner', [&$shouldShowReferBanner]);
-
- if (!$shouldShowReferBanner) {
- return false;
- }
-
- $referReminder = new ReferReminder();
- $nextReminderDate = $referReminder->getUserOption();
-
- if ($nextReminderDate === false) {
- $nextReminder = Date::now()->getStartOfDay()->addDay(135)->toString('Y-m-d');
- $referReminder->setUserOption($nextReminder);
-
- return false;
- }
-
- if ($nextReminderDate === self::NEVER_REMIND_ME_AGAIN) {
- return false;
- }
+ $matches = preg_split('/(<body.*?>)/i', $pageHtml, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
+ $pageHtml = $matches[0] . $matches[1] . $feedbackQuestionBanner . $matches[2];
+ }
- $pluginManager = PluginManager::getInstance();
- if ($pluginManager->hasPremiumFeatures()) {
- return false;
- }
- $now = Date::now()->getTimestamp();
- $nextReminderDate = Date::factory($nextReminderDate);
+ public function renderFeedbackQuestion()
+ {
+ $feedbackQuestionBanner = new View('@Feedback/feedbackQuestionBanner');
+ $feedbackQuestionBanner->showQuestionBanner = (int)$this->getShouldPromptForFeedback();
- return $nextReminderDate->getTimestamp() <= $now;
+ return $feedbackQuestionBanner->render();
}
public function getShouldPromptForFeedback()
@@ -171,22 +113,35 @@ class Feedback extends \Piwik\Plugin
$feedbackReminder = new FeedbackReminder();
$nextReminderDate = $feedbackReminder->getUserOption();
+ $now = Date::now()->getTimestamp();
+ //user answered question
if ($nextReminderDate === self::NEVER_REMIND_ME_AGAIN) {
return false;
}
- if ($nextReminderDate === false) {
- $nextReminder = Date::now()->getStartOfDay()->addDay(90)->toString('Y-m-d');
+ // if is new user or old user field not exist
+ if ($nextReminderDate === false || $nextReminderDate <= 0) {
+
+ // if user is created more than 6 month ago, set reminder to today and show banner
+ $userCreatedDate = Piwik::getCurrentUserCreationData();
+ if (!empty($userCreatedDate) && Date::factory($userCreatedDate)->addMonth(6)->getTimestamp() < $now) {
+ $nextReminder = Date::now()->getStartOfDay()->subDay(1)->toString('Y-m-d');
+ $feedbackReminder->setUserOption($nextReminder);
+ return true;
+ }
+ //new user extend to 6 month, don't show banner
+ $nextReminder = Date::now()->getStartOfDay()->addMonth(6)->toString('Y-m-d');
$feedbackReminder->setUserOption($nextReminder);
-
return false;
}
- $now = Date::now()->getTimestamp();
$nextReminderDate = Date::factory($nextReminderDate);
+ if ($nextReminderDate->getTimestamp() > $now) {
+ return false;
+ }
+ return true;
- return $nextReminderDate->getTimestamp() <= $now;
}
// needs to be protected not private for testing purpose
diff --git a/plugins/Feedback/ReferReminder.php b/plugins/Feedback/ReferReminder.php
deleted file mode 100644
index b6cfa46c3b..0000000000
--- a/plugins/Feedback/ReferReminder.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-/**
- * Matomo - free/libre analytics platform
- *
- * @link https://matomo.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- *
- */
-namespace Piwik\Plugins\Feedback;
-
-use Piwik\Piwik;
-use Piwik\Option;
-
-class ReferReminder
-{
- public $userLogin;
- public $option;
-
- public function __construct()
- {
- $this->userLogin = Piwik::getCurrentUserLogin();
- $this->option = 'Feedback.nextReferReminder';
- }
-
- public function getUserOption()
- {
- return Option::get("{$this->option}.{$this->userLogin}");
- }
-
- public function setUserOption($value)
- {
- Option::set("{$this->option}.{$this->userLogin}", $value);
- }
-}
diff --git a/plugins/Feedback/angularjs/feedback-popup/feedback-popup.controller.js b/plugins/Feedback/angularjs/feedback-popup/feedback-popup.controller.js
deleted file mode 100644
index 02c669805f..0000000000
--- a/plugins/Feedback/angularjs/feedback-popup/feedback-popup.controller.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*!
- * Matomo - free/libre analytics platform
- *
- * @link http://matomo.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-(function () {
- angular.module('piwikApp').controller('FeedbackPopupController', FeedbackPopupController);
-
- FeedbackPopupController.$inject = ['$scope', '$timeout', 'piwikApi'];
-
- function FeedbackPopupController($scope, $timeout, piwikApi) {
-
- var saveNextReminder = function(nextReminder) {
- var ajaxHandler = new ajaxHelper();
- ajaxHandler.addParams({'module': 'Feedback', 'action': 'updateFeedbackReminderDate'}, 'GET');
- ajaxHandler.addParams({'nextReminder': nextReminder}, 'POST');
- ajaxHandler.send();
- };
-
- var remindMeLater = function() {
- saveNextReminder(90);
- };
-
- var dontShowAgain = function() {
- saveNextReminder(-1);
- };
-
- var init = function() {
- if ($scope.promptForFeedback === 1) {
- $timeout(function() {
- $scope.feedbackPopup.dialog = {};
- $scope.feedbackPopup.dialog.show = true;
- $scope.feedbackPopup.remindMeLater = remindMeLater;
- $scope.feedbackPopup.dontShowAgain = dontShowAgain;
- });
- }
- };
-
- init();
- }
-})(); \ No newline at end of file
diff --git a/plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.html b/plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.html
deleted file mode 100644
index ef48a83efe..0000000000
--- a/plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<div ng-controller="FeedbackPopupController">
- <div class="feedbackPopup ui-confirm"
- piwik-dialog="feedbackPopup.dialog.show"
- yes="feedbackPopup.remindMeLater()"
- no="feedbackPopup.dontShowAgain()"
- close=""
- >
-
- <div class="intro">
- <h2>{{'Feedback_ReviewMatomoTitle'|translate }}</h2>
- </div>
-
- <div ng-include="'plugins/Feedback/angularjs/feedback-popup/review-links.directive.html'"></div>
-
- <div class="footer">
- <input type="button" value="{{ 'Feedback_RemindMeLater'|translate }}" role="yes"/>
- <input type="button" value="{{ 'Feedback_NeverAskMeAgain'|translate }}" role="no"/>
- </div>
- </div>
-</div> \ No newline at end of file
diff --git a/plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.js b/plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.js
deleted file mode 100644
index 4614c88dc8..0000000000
--- a/plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/*!
- * Matomo - free/libre analytics platform
- *
- * @link http://matomo.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-
-/**
- * Usage:
- * <div piwik-feedback-popup>
- */
-(function () {
- angular.module('piwikApp').directive('piwikFeedbackPopup', piwikFeedbackPopup);
-
- piwikFeedbackPopup.$inject = ['piwik'];
-
- function piwikFeedbackPopup(piwik){
- var defaults = {
- };
-
- return {
- restrict: 'A',
- scope: {
- promptForFeedback: '<'
- },
- templateUrl: 'plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.html?cb=' + piwik.cacheBuster,
- controller: 'FeedbackPopupController',
- controllerAs: 'feedbackPopup',
- compile: function (element, attrs) {
- for (var index in defaults) {
- if (defaults.hasOwnProperty(index) && attrs[index] === undefined) {
- attrs[index] = defaults[index];
- }
- }
- }
- };
- }
-})(); \ No newline at end of file
diff --git a/plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.less b/plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.less
deleted file mode 100644
index 25aa00154c..0000000000
--- a/plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.less
+++ /dev/null
@@ -1,25 +0,0 @@
-.requestReview {
- .review-links {
- display: flex;
- }
-
- .review-link {
- width: 20%;
-
- div {
- width: 100%;
- }
-
- div.image {
- height: 80px;
- }
-
- div.link {
- font-size: 13px;
- }
-
- img {
- max-width: 60px;
- }
- }
-}
diff --git a/plugins/Feedback/angularjs/feedback-popup/review-links.directive.html b/plugins/Feedback/angularjs/feedback-popup/review-links.directive.html
deleted file mode 100644
index 5da2f819a9..0000000000
--- a/plugins/Feedback/angularjs/feedback-popup/review-links.directive.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<div class="requestReview">
- <p>{{ 'Feedback_PleaseLeaveExternalReviewForMatomo'|translate }}</p><br/><br/>
-
- <div class="review-links">
- <div class="review-link">
- <a href="https://www.capterra.com/p/182627/Matomo-Analytics/" target="_blank">
- <div class="image"><img loading="lazy" src="plugins/Feedback/images/capterra.svg"></div>
- <div class="link">Capterra</div>
- </a>
- </div>
-
- <div class="review-link">
- <a href="https://www.g2crowd.com/products/matomo-formerly-piwik/details" target="_blank">
- <div class="image"><img loading="lazy" src="plugins/Feedback/images/g2crowd.svg"></div>
- <div class="link">G2 Crowd</div>
- </a>
- </div>
-
- <div class="review-link">
- <a href="https://www.producthunt.com/posts/matomo-2" target="_blank">
- <div class="image"><img loading="lazy" src="plugins/Feedback/images/producthunt.svg"></div>
- <div class="link">Product Hunt</div>
- </a>
- </div>
-
- <div class="review-link">
- <a href="https://www.saasworthy.com/product/matomo" target="_blank">
- <div class="image"><img loading="lazy" src="plugins/Feedback/images/saasworthy.png"></div>
- <div class="link">SaaSworthy</div>
- </a>
- </div>
-
- <div class="review-link">
- <a href="https://www.trustradius.com/products/matomo/reviews" target="_blank">
- <div class="image"><img loading="lazy" src="plugins/Feedback/images/trustradius.svg"></div>
- <div class="link">TrustRadius</div>
- </a>
- </div>
- </div>
-</div>
diff --git a/plugins/Feedback/angularjs/refer-banner/refer-banner.controller.js b/plugins/Feedback/angularjs/refer-banner/refer-banner.controller.js
deleted file mode 100644
index 9babbe281e..0000000000
--- a/plugins/Feedback/angularjs/refer-banner/refer-banner.controller.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/*!
- * Matomo - free/libre analytics platform
- *
- * @link http://matomo.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-(function () {
- angular.module('piwikApp').controller('ReferBannerController', ReferBannerController);
-
- ReferBannerController.$inject = ['$scope', '$timeout'];
-
- function ReferBannerController($scope, $timeout) {
- var setNextReminder = function(nextReminder) {
- var ajaxHandler = new ajaxHelper();
- ajaxHandler.addParams({'module': 'Feedback', 'action': 'updateReferReminderDate'}, 'GET');
- ajaxHandler.addParams({'nextReminder': nextReminder}, 'POST');
- ajaxHandler.send();
- };
-
- var remindMeLater = function() {
- $scope.referBanner.show = false;
-
- setNextReminder(6 * 30);
- };
-
- var dontShowAgain = function() {
- $scope.referBanner.show = false;
-
- setNextReminder(-1);
- };
-
- var share = function() {
- var modal = M.Modal.getInstance($('.modal.open'));
-
- if (modal) {
- modal.close();
- }
-
- $scope.referBanner.showThanks = true;
- $scope.referBanner.show = false;
-
- setNextReminder(-1);
- }
-
- $scope.socialUrl = function (type) {
- var text = _pk_translate('Feedback_ReferBannerSocialShareText');
- var url = 'https://matomo.org/?pk_campaign=share&pk_kwd=onpremise';
-
- if (type === 'twitter') {
- var base = 'https://twitter.com/intent/tweet?';
-
- var params = { 'text': text, 'url': url};
- var paramString = '';
- for (var param in params) {
- paramString += param + '=' + encodeURIComponent(params[param]) + '&';
- }
-
- return base + paramString.slice(0, -1);
- }
-
- if (type === 'facebook') {
- var base = 'https://www.facebook.com/sharer.php?';
-
- var params = { 't': text, 'u': url};
- var paramString = '';
- for (var param in params) {
- paramString += param + '=' + encodeURIComponent(params[param]) + '&';
- }
-
- return base + paramString.slice(0, -1);
- }
-
- if (type === 'linkedin') {
- var base = 'https://www.linkedin.com/sharing/share-offsite/?';
-
- var params = { 'url': url };
- var paramString = '';
- for (var param in params) {
- paramString += param + '=' + encodeURIComponent(params[param]) + '&';
- }
-
- return base + paramString.slice(0, -1);
- }
-
- return '#';
- };
-
- $scope.referEmail = function () {
- var subject = _pk_translate('Feedback_ReferBannerEmailShareSubject');
- var body = _pk_translate('Feedback_ReferBannerEmailShareBody');
-
- return encodeURI('mailto:YOUR_FRIEND@EMAIL.ADDRESS?subject=' + subject + '&body=' + body);
- }
-
- var init = function() {
- $scope.referBanner.showThanks = false;
- $scope.referBanner.remindMeLater = remindMeLater;
- $scope.referBanner.dontShowAgain = dontShowAgain;
- $scope.referBanner.share = share;
-
- if ($scope.showReferBanner === 1) {
- $timeout(function() {
- $scope.referBanner.show = true;
- });
- }
- };
-
- init();
- }
-})();
diff --git a/plugins/Feedback/angularjs/refer-banner/refer-banner.directive.html b/plugins/Feedback/angularjs/refer-banner/refer-banner.directive.html
deleted file mode 100644
index 34bbd87d0b..0000000000
--- a/plugins/Feedback/angularjs/refer-banner/refer-banner.directive.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<div ng-controller="ReferBannerController">
- <div class="refer-banner ui-confirm"
- piwik-dialog="referBanner.show"
- yes="referBanner.remindMeLater()"
- no="referBanner.dontShowAgain()"
- close=""
- >
-
- <div class="intro">
- <h2>{{'Feedback_ReferBannerTitle'|translate }}</h2>
- </div>
-
- <div class="text-center">
- <p>{{'Feedback_ReferBannerLonger'|translate }}</p>
-
- <div class="flex items-center justify-around">
- <a ng-href="{{ socialUrl('twitter') }}" ng-click="referBanner.share()" class="share-button text-twitter-blue" target="_blank" rel="noreferrer noopener">
- <ng-include src="'plugins/Feedback/images/twitter_logo.svg'" />
- </a>
- <a ng-href="{{ socialUrl('facebook') }}" ng-click="referBanner.share()" class="share-button text-fb-blue" target="_blank" rel="noreferrer noopener">
- <ng-include src="'plugins/Feedback/images/facebook_logo.svg'" />
- </a>
- <a ng-href="{{ socialUrl('linkedin') }}" ng-click="referBanner.share()" class="share-button text-li-blue" target="_blank" rel="noreferrer noopener">
- <ng-include src="'plugins/Feedback/images/linkedin_logo.svg'" />
- </a>
- <a ng-show="{{ false }}" href="{{ socialUrl('mastodon') }}" ng-click="referBanner.share()" class="share-button" target="_blank" rel="noreferrer noopener">
- <ng-include src="'plugins/Feedback/images/mastodon_logo.svg'" />
- </a>
- </div>
- </div>
-
- <div class="footer">
- <input type="button" value="{{ 'Feedback_RemindMeLater'|translate }}" role="yes"/>
- <input type="button" value="{{ 'Feedback_NeverAskMeAgain'|translate }}" role="no"/>
- </div>
- </div>
-
- <div class="ui-confirm" piwik-dialog="referBanner.showThanks" yes="">
- <h2>{{ 'Feedback_ThankYouForSpreading'|translate }}</h2>
- <p style="text-align: center">{{ 'Feedback_WontShowAgain'|translate }}</p>
-
- <input type="button" value="{{ 'General_Ok'|translate }}" role="yes"/>
- </div>
-</div>
diff --git a/plugins/Feedback/angularjs/refer-banner/refer-banner.directive.js b/plugins/Feedback/angularjs/refer-banner/refer-banner.directive.js
deleted file mode 100644
index 4c14a49e3f..0000000000
--- a/plugins/Feedback/angularjs/refer-banner/refer-banner.directive.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*!
- * Matomo - free/libre analytics platform
- *
- * @link http://matomo.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-
-/**
- * Usage:
- * <div piwik-refer-banner>
- */
-(function () {
- angular.module('piwikApp').directive('piwikReferBanner', piwikReferBanner);
-
- piwikReferBanner.$inject = ['piwik'];
-
- function piwikReferBanner(piwik){
- return {
- restrict: 'A',
- scope: {
- showReferBanner: '<'
- },
- templateUrl: 'plugins/Feedback/angularjs/refer-banner/refer-banner.directive.html?cb=' + piwik.cacheBuster,
- controller: 'ReferBannerController',
- controllerAs: 'referBanner',
- };
- }
-})(); \ No newline at end of file
diff --git a/plugins/Feedback/angularjs/refer-banner/refer-banner.directive.less b/plugins/Feedback/angularjs/refer-banner/refer-banner.directive.less
deleted file mode 100644
index 543918a97e..0000000000
--- a/plugins/Feedback/angularjs/refer-banner/refer-banner.directive.less
+++ /dev/null
@@ -1,48 +0,0 @@
-.flex {
- display: flex;
-}
-
-.flex-grow {
- flex-grow: 1;
-}
-
-.flex-none {
- flex: none;
-}
-
-.items-center {
- align-items: center;
-}
-
-.justify-center {
- justify-content: center;
-}
-
-.justify-around {
- justify-content: space-around;
-}
-
-.text-center {
- text-align: center;
-}
-
-.h-full {
- height: 100%;
-}
-
-.text-twitter-blue {
- color: #00aced;
-}
-
-.text-fb-blue {
- color: #3b5998;
-}
-
-.text-li-blue {
- color: #007bb6;
-}
-
-.refer-banner .share-button {
- width:60px;
- margin-top:24px;
-}
diff --git a/plugins/Feedback/images/facebook_logo.svg b/plugins/Feedback/images/facebook_logo.svg
deleted file mode 100644
index 54a49626e0..0000000000
--- a/plugins/Feedback/images/facebook_logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg> \ No newline at end of file
diff --git a/plugins/Feedback/images/linkedin_logo.svg b/plugins/Feedback/images/linkedin_logo.svg
deleted file mode 100644
index 6a5826451d..0000000000
--- a/plugins/Feedback/images/linkedin_logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg> \ No newline at end of file
diff --git a/plugins/Feedback/images/mastodon_logo.svg b/plugins/Feedback/images/mastodon_logo.svg
deleted file mode 100644
index e19e492758..0000000000
--- a/plugins/Feedback/images/mastodon_logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M23.193 7.88c0-5.207-3.411-6.733-3.411-6.733C18.062.357 15.108.025 12.041 0h-.076c-3.069.025-6.02.357-7.74 1.147 0 0-3.412 1.526-3.412 6.732 0 1.193-.023 2.619.015 4.13.124 5.092.934 10.11 5.641 11.355 2.17.574 4.034.695 5.536.612 2.722-.15 4.25-.972 4.25-.972l-.09-1.975s-1.945.613-4.13.54c-2.165-.075-4.449-.234-4.799-2.892a5.5 5.5 0 0 1-.048-.745s2.125.52 4.818.643c1.646.075 3.19-.097 4.758-.283 3.007-.359 5.625-2.212 5.954-3.905.517-2.665.475-6.508.475-6.508zm-4.024 6.709h-2.497v-6.12c0-1.29-.543-1.944-1.628-1.944-1.2 0-1.802.776-1.802 2.313v3.349h-2.484v-3.35c0-1.537-.602-2.313-1.802-2.313-1.085 0-1.628.655-1.628 1.945v6.119H4.831V8.285c0-1.29.328-2.314.987-3.07.68-.759 1.57-1.147 2.674-1.147 1.278 0 2.246.491 2.886 1.474L12 6.585l.622-1.043c.64-.983 1.608-1.474 2.886-1.474 1.104 0 1.994.388 2.674 1.146.658.757.986 1.781.986 3.07v6.305z"/></svg> \ No newline at end of file
diff --git a/plugins/Feedback/images/twitter_logo.svg b/plugins/Feedback/images/twitter_logo.svg
deleted file mode 100644
index 49a98867fa..0000000000
--- a/plugins/Feedback/images/twitter_logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg> \ No newline at end of file
diff --git a/plugins/Feedback/lang/en.json b/plugins/Feedback/lang/en.json
index 887ab1555c..345be23916 100644
--- a/plugins/Feedback/lang/en.json
+++ b/plugins/Feedback/lang/en.json
@@ -14,7 +14,6 @@
"RateFeatureTitle": "Do you like the '%s' feature? Please rate and leave a comment",
"SendFeedback": "Send Feedback",
"ThankYou": "Thank you for helping us to make Matomo better!",
- "ThankYouForSpreading": "Thank you for spreading the word and creating a safer web",
"TopLinkTooltip": "Tell us what you think, or request Professional Support.",
"ViewAnswersToFAQ": "View answers to %1$sFrequently Asked Questions%2$s",
"FAQs": "FAQs",
@@ -43,12 +42,16 @@
"PurgeOldData": "I want to remove some old data",
"SearchHelpResources": "Search matomo.org help resources",
"PopularHelpTopics": "Popular help topics",
- "ReferMatomo": "Refer Matomo",
- "ReferBannerTitle": "Believe in Matomo?",
- "ReferBannerLonger": "Please help us spread the word about us so more people get control over their analytics data.",
- "ReferBannerEmailShareSubject": "Refer them to Matomo Analytics now to take back control!",
- "ReferBannerEmailShareBody": "I choose Matomo, an ethical alternative to Google Analytics that gives me 100%% data ownership and protects the data of my website visitors.\r\nI’m sharing this message in the hope that you too will take back the power from Google and get complete ownership of your own data.\r\n\r\nCheck out Matomo at https://matomo.org",
- "ReferBannerSocialShareText": "If you’re using Google Analytics, stay in control by switching to an ethical alternative like Matomo now!",
- "WontShowAgain": "We won't show this message again."
+ "WontShowAgain": "We won't show this message again.",
+ "Question0": "What are your biggest problems or pain points with Matomo and why?",
+ "Question1": "What is the one thing you’d like to see improved in Matomo and why?",
+ "Question2": "What is the feature you are missing the most in Matomo and why?",
+ "Question3": "What is your main goal for using Matomo?",
+ "Question4": "What is your main concern about Matomo?",
+ "FeedbackTitle": "Please help us improve Matomo",
+ "FeedbackSubtitle": "Here's your chance to ask for it! Please describe in as much details as you can. <br/> Your feedback will help us improve Matomo. %1$s",
+ "ThankYourForFeedback": "We really appreciate your feedback! %1$s We will be in touch in case we require more information about your feedback.",
+ "Policy": "Your message and your email address will be sent to us by submitting this form. The information will be only used to improve our products and services. Your data will be processed by us, our hosting provider, and our support ticket provider. For more information have a look at %1$sMatomo's Privacy Policy%2$s.",
+ "MessageBodyValidationError": "The message body is too short (minimum is 10 characters)."
}
} \ No newline at end of file
diff --git a/plugins/Feedback/templates/feedbackPopup.twig b/plugins/Feedback/templates/feedbackPopup.twig
deleted file mode 100644
index 7315d4ad12..0000000000
--- a/plugins/Feedback/templates/feedbackPopup.twig
+++ /dev/null
@@ -1 +0,0 @@
-<div piwik-feedback-popup prompt-for-feedback="{{ promptForFeedback }}"></div>
diff --git a/plugins/Feedback/templates/feedbackQuestionBanner.twig b/plugins/Feedback/templates/feedbackQuestionBanner.twig
new file mode 100644
index 0000000000..5daa2548ae
--- /dev/null
+++ b/plugins/Feedback/templates/feedbackQuestionBanner.twig
@@ -0,0 +1 @@
+<div piwik-feedback-question show-question-banner="{{ showQuestionBanner }}"></div> \ No newline at end of file
diff --git a/plugins/Feedback/templates/index.twig b/plugins/Feedback/templates/index.twig
index c14603f52e..73c149650f 100644
--- a/plugins/Feedback/templates/index.twig
+++ b/plugins/Feedback/templates/index.twig
@@ -94,10 +94,6 @@
)|raw }}</p>
</div>
- <div piwik-content-block content-title="{{'Feedback_ReviewMatomoTitle'|translate|e('html_attr') }}">
- <div ng-include="'plugins/Feedback/angularjs/feedback-popup/review-links.directive.html'"></div>
- </div>
-
<div class="footer">
<ul class="social">
<li>
diff --git a/plugins/Feedback/templates/referBanner.twig b/plugins/Feedback/templates/referBanner.twig
deleted file mode 100644
index 628d56c45c..0000000000
--- a/plugins/Feedback/templates/referBanner.twig
+++ /dev/null
@@ -1 +0,0 @@
-<div piwik-refer-banner show-refer-banner="{{ showReferBanner }}"></div>
diff --git a/plugins/Feedback/tests/Fixtures/FeedbackPopupFixture.php b/plugins/Feedback/tests/Fixtures/FeedbackQuestionBannerFixture.php
index 182582034c..9ea2e8a204 100644
--- a/plugins/Feedback/tests/Fixtures/FeedbackPopupFixture.php
+++ b/plugins/Feedback/tests/Fixtures/FeedbackQuestionBannerFixture.php
@@ -7,7 +7,7 @@ use Piwik\Date;
use Piwik\Option;
use Piwik\Tests\Fixtures\UITestFixture;
-class FeedbackPopupFixture extends UITestFixture
+class FeedbackQuestionBannerFixture extends UITestFixture
{
public function setUp(): void
{
diff --git a/plugins/Feedback/tests/Fixtures/ReferBannerFixture.php b/plugins/Feedback/tests/Fixtures/ReferBannerFixture.php
deleted file mode 100644
index 7e461bdb48..0000000000
--- a/plugins/Feedback/tests/Fixtures/ReferBannerFixture.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-
-namespace Piwik\Plugins\Feedback\tests\Fixtures;
-
-use Piwik\Date;
-use Piwik\Option;
-use Piwik\Tests\Fixtures\UITestFixture;
-
-class ReferBannerFixture extends UITestFixture
-{
- public function setUp(): void
- {
- parent::setUp();
- $yesterday = Date::yesterday();
- Option::set('Feedback.nextReferReminder.superUserLogin', $yesterday->toString('Y-m-d'));
- }
-
- public function tearDown(): void
- {
- parent::tearDown();
- Option::delete('Feedback.nextReferReminder.superUserLogin');
- }
-
-} \ No newline at end of file
diff --git a/plugins/Feedback/tests/Integration/ControllerTest.php b/plugins/Feedback/tests/Integration/ControllerTest.php
deleted file mode 100644
index a1699cf2bd..0000000000
--- a/plugins/Feedback/tests/Integration/ControllerTest.php
+++ /dev/null
@@ -1,116 +0,0 @@
-<?php
-/**
- * Matomo - free/libre analytics platform
- *
- * @link http://matomo.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-
-namespace Piwik\Plugins\Feedback\tests\Integration;
-
-use Piwik\Date;
-use Piwik\NoAccessException;
-use Piwik\Option;
-use Piwik\Plugins\Feedback\Controller;
-use Piwik\Plugins\UsersManager\Model;
-use Piwik\Tests\Framework\Mock\FakeAccess;
-use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
-
-class ControllerTest extends IntegrationTestCase
-{
- /** @var Controller */
- private $controller;
-
- /** @var Model */
- private $userModel;
-
- private $now;
-
- public function setUp(): void
- {
- parent::setUp();
- $this->controller = new Controller();
-
- $this->userModel = new Model();
- $this->userModel->addUser(
- 'user1',
- 'a98732d98732',
- 'user1@example.com',
- '2019-03-03'
- );
- FakeAccess::$identity = 'user1';
- FakeAccess::$superUser = false;
-
- $this->now = Date::$now;
- Date::$now = Date::factory('2019-05-31')->getTimestamp();
- }
-
- public function tearDown(): void
- {
- FakeAccess::$identity = 'user1';
- Option::deleteLike('Feedback.nextFeedbackReminder.%');
- $this->userModel->deleteUserOnly('user1');
- Date::$now = $this->now;
-
- parent::tearDown();
- }
-
- public function provideContainerConfig()
- {
- return array(
- 'Piwik\Access' => new FakeAccess()
- );
- }
-
- public function test_updateFeedbackReminder_addNinetyDays()
- {
- $_POST['nextReminder'] = '90';
- $this->controller->updateFeedbackReminderDate();
-
- $option = Option::get('Feedback.nextFeedbackReminder.user1');
- $this->assertEquals($option, '2019-08-29');
- }
-
- public function test_updateFeedbackReminder_neverAgain()
- {
- $_POST['nextReminder'] = '-1';
- $this->controller->updateFeedbackReminderDate();
-
- $option = Option::get('Feedback.nextFeedbackReminder.user1');
- $this->assertEquals($option, '-1');
- }
-
- public function test_updateFeedbackReminder_notLoggedIn()
- {
- $this->expectException(NoAccessException::class);
- FakeAccess::$identity = null;
- FakeAccess::$superUser = false;
- $this->controller->updateFeedbackReminderDate();
- }
-
- public function test_updateReferReminder_add180Days()
- {
- $_POST['nextReminder'] = '180';
- $this->controller->updateReferReminderDate();
-
- $option = Option::get('Feedback.nextReferReminder.user1');
- $this->assertEquals($option, '2019-11-27');
- }
-
- public function test_updateReferReminder_neverAgain()
- {
- $_POST['nextReminder'] = '-1';
- $this->controller->updateReferReminderDate();
-
- $option = Option::get('Feedback.nextReferReminder.user1');
- $this->assertEquals($option, '-1');
- }
-
- public function test_updateReferReminder_notLoggedIn()
- {
- $this->expectException(NoAccessException::class);
- FakeAccess::$identity = null;
- FakeAccess::$superUser = false;
- $this->controller->updateReferReminderDate();
- }
-}
diff --git a/plugins/Feedback/tests/Integration/FeedbackTest.php b/plugins/Feedback/tests/Integration/FeedbackTest.php
index f55d6e20f2..66fa6e7525 100644
--- a/plugins/Feedback/tests/Integration/FeedbackTest.php
+++ b/plugins/Feedback/tests/Integration/FeedbackTest.php
@@ -9,8 +9,10 @@
namespace Piwik\Plugins\Feedback\tests\Unit;
+use CpChart\Chart\Data;
use Piwik\Date;
use Piwik\Option;
+use Piwik\Piwik;
use Piwik\Plugins\Feedback\Feedback;
use Piwik\Plugins\UsersManager\Model;
use Piwik\Tests\Framework\Mock\FakeAccess;
@@ -40,9 +42,16 @@ class FeedbackTest extends IntegrationTestCase
'user1@example.com',
'2019-03-03'
);
+
+ $this->userModel->addUser(
+ 'user2',
+ 'a98732d98732',
+ 'user2@example.com',
+ Date('Y-m-d')
+ );
FakeAccess::$identity = 'user1';
FakeAccess::$superUser = false;
-
+ FakeAccess::$idSitesView = [1];
$this->now = Date::$now;
}
@@ -51,8 +60,12 @@ class FeedbackTest extends IntegrationTestCase
FakeAccess::$identity = 'user1';
Option::deleteLike('Feedback.nextFeedbackReminder.%');
$this->userModel->deleteUserOnly('user1');
- Date::$now = $this->now;
+ FakeAccess::$identity = 'user2';
+ Option::deleteLike('Feedback.nextFeedbackReminder.%');
+ $this->userModel->deleteUserOnly('user2');
+
+ Date::$now = $this->now;
parent::tearDown();
}
@@ -71,12 +84,6 @@ class FeedbackTest extends IntegrationTestCase
$this->assertFalse($this->feedback->getShouldPromptForFeedback());
}
- public function test_shouldPromptForFeedback_noFeedbackReminderOptionForUser()
- {
- Date::$now = Date::factory('2019-05-31')->getTimestamp(); // 89 days
-
- $this->assertFalse($this->feedback->getShouldPromptForFeedback());
- }
public function test_shouldPromptForFeedback_dontRemindUserAgain()
{
@@ -87,25 +94,27 @@ class FeedbackTest extends IntegrationTestCase
public function test_shouldPromptForFeedback_nextReminderDateInPast()
{
+ FakeAccess::$identity = 'user1';
Option::set('Feedback.nextFeedbackReminder.user1', '2019-05-31');
- Date::$now = Date::factory('2019-06-01')->getTimestamp();
-
$this->assertTrue($this->feedback->getShouldPromptForFeedback());
}
public function test_shouldPromptForFeedack_nextReminderDateToday()
{
- Option::set('Feedback.nextFeedbackReminder.user1', '2019-05-31');
- Date::$now = Date::factory('2019-05-31')->getTimestamp();
-
+ Option::set('Feedback.nextFeedbackReminder.user1', '2018-10-31');
$this->assertTrue($this->feedback->getShouldPromptForFeedback());
}
- public function test_shouldPromptForFeedack_nextReminderDateInFuture()
+ public function test_shouldPromptForFeedback_user_oldThanHalfYear()
{
- Option::set('Feedback.nextFeedbackReminder.user1', '2019-05-31');
- Date::$now = Date::factory('2019-05-30')->getTimestamp();
+ FakeAccess::$identity = 'user1';
+ Option::deleteLike('Feedback.nextFeedbackReminder.user1');
+ $this->assertFalse($this->feedback->getShouldPromptForFeedback());
+ }
+ public function test_shouldNotPromptForFeedback_user_LessThanHalfYear()
+ {
+ FakeAccess::$identity = 'user2';
$this->assertFalse($this->feedback->getShouldPromptForFeedback());
}
}
diff --git a/plugins/Feedback/tests/Integration/ReferBannerTest.php b/plugins/Feedback/tests/Integration/ReferBannerTest.php
deleted file mode 100644
index b57377ee68..0000000000
--- a/plugins/Feedback/tests/Integration/ReferBannerTest.php
+++ /dev/null
@@ -1,119 +0,0 @@
-<?php
-/**
- * Matomo - free/libre analytics platform
- *
- * @link http://matomo.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-
-namespace Piwik\Plugins\Feedback\tests\Integration;
-
-use Piwik\Date;
-use Piwik\Option;
-use Piwik\Plugins\Feedback\Feedback;
-use Piwik\Plugins\UsersManager\Model;
-use Piwik\Tests\Framework\Mock\FakeAccess;
-use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
-
-class ReferBannerTest extends IntegrationTestCase
-{
- /** @var Feedback */
- private $feedback;
-
- /** @var Model */
- private $userModel;
-
- public function setUp(): void
- {
- parent::setUp();
-
- $this->feedback = $this->createPartialMock(Feedback::class, ['isDisabledInTestMode']);
- $this->feedback->method('isDisabledInTestMode')->willReturn(false);
-
- $this->userModel = new Model();
- $this->userModel->addUser(
- 'user1',
- 'a98732d98732',
- 'user1@example.com',
- '2019-03-03',
- 'super'
- );
- FakeAccess::$identity = 'user1';
- FakeAccess::$superUser = false;
- }
-
- public function tearDown(): void
- {
- Option::deleteLike('Feedback.nextReferReminder.%');
- try {
- $this->userModel->deleteUserOnly('user1');
- } catch (\Exception $e) {
- // ignore possible errors triggered when the delete user event is posted
- }
-
- parent::tearDown();
- }
-
- public function provideContainerConfig()
- {
- return array(
- 'Piwik\Access' => new FakeAccess()
- );
- }
-
-
- public function test_shouldNotShowReferBannerTo_AnonymousUser()
- {
- FakeAccess::$identity = '';
-
- $this->assertFalse($this->feedback->showReferBanner());
- }
-
- public function test_shouldNotShowReferBannerTo_NotSuperUser()
- {
- FakeAccess::$identity = 'user1';
-
- $this->assertFalse($this->feedback->showReferBanner());
- }
-
- public function test_shouldNotShowReferBannerTo_SuperUser_First()
- {
- FakeAccess::$identity = 'super';
- FakeAccess::$superUser = true;
-
- $this->assertFalse($this->feedback->showReferBanner());
- }
-
- public function test_shouldNotShowReferBanner_ifNeverRemindOn()
- {
- FakeAccess::$identity = 'super';
- FakeAccess::$superUser = true;
- Option::set('Feedback.nextReferReminder.super', '-1');
-
- $this->assertFalse($this->feedback->showReferBanner());
- }
-
- public function test_shouldNotShowReferBanner_ifNextReminderDateInTheFuture()
- {
- FakeAccess::$identity = 'super';
- FakeAccess::$superUser = true;
-
- Date::$now = strtotime('2021-01-01');
- $futureDate = Date::factory('2021-02-01')->toString('Y-m-d');
- Option::set('Feedback.nextReferReminder.super', $futureDate);
-
- $this->assertFalse($this->feedback->showReferBanner());
- }
-
- public function test_shouldShowReferBanner_ifNextReminderDateInThePast()
- {
- FakeAccess::$identity = 'super';
- FakeAccess::$superUser = true;
-
- Date::$now = strtotime('2021-01-01');
- $pastDate = Date::factory('2020-01-01')->toString('Y-m-d');
- Option::set('Feedback.nextReferReminder.super', $pastDate);
-
- $this->assertTrue($this->feedback->showReferBanner());
- }
-}
diff --git a/plugins/Feedback/tests/UI/FeedbackPopup_spec.js b/plugins/Feedback/tests/UI/FeedbackPopup_spec.js
deleted file mode 100644
index cdfbbeb36e..0000000000
--- a/plugins/Feedback/tests/UI/FeedbackPopup_spec.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*!
- * Matomo - free/libre analytics platform
- *
- * UsersManager screenshot tests.
- *
- * @link https://matomo.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-
-describe("FeedbackPopup", function () {
- this.timeout(0);
- this.fixture = "Piwik\\Plugins\\Feedback\\tests\\Fixtures\\FeedbackPopupFixture";
-
- var url = "?module=CoreHome&action=index&idSite=1&period=day&date=2019-07-11&forceFeedbackTest=1";
-
- before(async function() {
- await page.webpage.setViewport({
- width: 1250,
- height: 768
- });
- });
-
- it('should display popup when next reminder date is in past', async function () {
- await page.goto(url);
- await page.waitForNetworkIdle();
-
- var modal = await page.waitForSelector('.modal.open', { visible: true });
- expect(await modal.screenshot()).to.matchImage('feedback_popup');
-
- // Click on the "Remind me in 90 days" button = the popup shouldn't appear for the next test
- var remindLaterBtn = await modal.$$('.modal-footer .btn-flat');
- await remindLaterBtn[0].click();
- await page.waitForNetworkIdle();
- });
-
- it('should not display popup when next reminder date is in future', async function () {
- await page.goto(url);
- await page.waitForNetworkIdle();
-
- // check dashboard is present
- await page.waitForSelector('#dashboardWidgetsArea');
-
- // check modal isn't opened
- await page.waitForFunction("$('.modal.open').length == 0");
- });
-}); \ No newline at end of file
diff --git a/plugins/Feedback/tests/UI/FeedbackQuestion_spec.js b/plugins/Feedback/tests/UI/FeedbackQuestion_spec.js
new file mode 100644
index 0000000000..70528468ff
--- /dev/null
+++ b/plugins/Feedback/tests/UI/FeedbackQuestion_spec.js
@@ -0,0 +1,52 @@
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * UsersManager screenshot tests.
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+describe('FeedbackQuestion', function () {
+ this.timeout(0);
+ this.fixture = 'Piwik\\Plugins\\Feedback\\tests\\Fixtures\\FeedbackQuestionBannerFixture';
+
+ var url = '?module=CoreHome&action=index&idSite=1&period=day&date=2019-07-11&forceFeedbackTest=1';
+
+ it('should display question banner', async function () {
+ await page.setCookie({
+ name: 'feedback-question',
+ value: '0',
+ expire: '3600',
+ 'url': 'http://localhost/tests/PHPUnit/proxy/' + url,
+ });
+ await page.goto(url);
+ await page.waitForNetworkIdle();
+
+ var banner = await page.waitForSelector('.bannerHeader', { visible: true });
+ expect(await banner.screenshot()).to.matchImage('feedback_banner');
+ });
+
+ it('should display popup when banner button is clicked', async function () {
+ await page.click('.bannerHeader .btn');
+ await page.waitForNetworkIdle();
+
+ var popup = await page.waitForSelector('.modal', { visible: true });
+ expect(await popup.screenshot()).to.matchImage('feedback_popup');
+ });
+
+ it('should show error when blank content submit', async function () {
+ await page.click('.modal .modal-footer a:nth-child(1)');
+ await page.waitForNetworkIdle();
+ var popup = await page.waitForSelector('.modal.open', { visible: true });
+ expect(await popup.screenshot()).to.matchImage('feedback_failed');
+ });
+
+ it('should show success when banner is submit', async function () {
+ await page.type('#message', 'test content, do not send emails');
+ await page.click('.modal .modal-footer a:nth-child(1)');
+ await page.waitForNetworkIdle();
+ var popup = await page.waitForSelector('.modal.open', { visible: true });
+ expect(await popup.screenshot()).to.matchImage('feedback_success');
+ });
+});
diff --git a/plugins/Feedback/tests/UI/ReferBanner_spec.js b/plugins/Feedback/tests/UI/ReferBanner_spec.js
deleted file mode 100644
index 84b8c1bb33..0000000000
--- a/plugins/Feedback/tests/UI/ReferBanner_spec.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/*!
- * Matomo - free/libre analytics platform
- *
- * UsersManager screenshot tests.
- *
- * @link https://matomo.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-
-describe("ReferBannerTest", function () {
- this.timeout(0);
- this.fixture = "Piwik\\Plugins\\Feedback\\tests\\Fixtures\\ReferBannerFixture";
-
- var url = "?module=CoreHome&action=index&idSite=1&period=day&date=2019-07-11&forceFeedbackTest=1";
-
- before(async function() {
- await page.webpage.setViewport({
- width: 1250,
- height: 768
- });
- });
-
- it('should display popup when next reminder date is in past', async function () {
- await page.goto(url);
- await page.waitForNetworkIdle();
-
- var banner = await page.waitForSelector('.refer-banner', { visible: true });
- expect(await banner.screenshot()).to.matchImage('feedback_popup');
- });
-});
diff --git a/plugins/Feedback/tests/UI/expected-screenshots/FeedbackForm_show.png b/plugins/Feedback/tests/UI/expected-screenshots/FeedbackForm_show.png
index 7ca34edd9d..a7315ae5cd 100644
--- a/plugins/Feedback/tests/UI/expected-screenshots/FeedbackForm_show.png
+++ b/plugins/Feedback/tests/UI/expected-screenshots/FeedbackForm_show.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:37bddab33dbd00a473c45f015a96bf420c6b3d9f21e0b4e668e0d569fb9d471f
-size 269098
+oid sha256:4b713af0c769a9175d73a73d15f5c58063a2b9135533f1943d97011ca923f93e
+size 244192
diff --git a/plugins/Feedback/tests/UI/expected-screenshots/FeedbackPopup_feedback_popup.png b/plugins/Feedback/tests/UI/expected-screenshots/FeedbackPopup_feedback_popup.png
deleted file mode 100644
index a6c7a12fe9..0000000000
--- a/plugins/Feedback/tests/UI/expected-screenshots/FeedbackPopup_feedback_popup.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:d5e4c0571a535a90244639b4d6f68c9679f53300dd0f1eedd3ac6024d3e0571a
-size 27936
diff --git a/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_banner.png b/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_banner.png
new file mode 100644
index 0000000000..eb4ea8dfbd
--- /dev/null
+++ b/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_banner.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:959b1e4ecf2ea17100c3029dc2d1829cec102bc5147ede612103d921e202f0c0
+size 11044
diff --git a/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_failed.png b/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_failed.png
new file mode 100644
index 0000000000..6f36784c47
--- /dev/null
+++ b/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_failed.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d721f1099ea0597eadfd29561e266e73e2b63b6436655a2d7f00f0757219e447
+size 48461
diff --git a/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_popup.png b/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_popup.png
new file mode 100644
index 0000000000..535df3821d
--- /dev/null
+++ b/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_popup.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:21932d52aa513e50bf7c2e5f9df26fb2e8f861fc16cac7e32e94989e19715018
+size 45154
diff --git a/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_success.png b/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_success.png
new file mode 100644
index 0000000000..cc29343ae3
--- /dev/null
+++ b/plugins/Feedback/tests/UI/expected-screenshots/FeedbackQuestion_feedback_success.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1977e1e89607e361282b66298b3f235b42f2de3f1f1b9f325c0c53875119f7f4
+size 16428
diff --git a/plugins/Feedback/tests/UI/expected-screenshots/ReferBannerTest_feedback_popup.png b/plugins/Feedback/tests/UI/expected-screenshots/ReferBannerTest_feedback_popup.png
deleted file mode 100644
index bc9ade9144..0000000000
--- a/plugins/Feedback/tests/UI/expected-screenshots/ReferBannerTest_feedback_popup.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:001fa5fc54e4f316dfac5aab1b1802f9620e671dcb83e85279a4843afdfaef67
-size 14794
diff --git a/plugins/Feedback/vue/dist/Feedback.umd.js b/plugins/Feedback/vue/dist/Feedback.umd.js
index d50ae72ce5..fca5e1f1d8 100644
--- a/plugins/Feedback/vue/dist/Feedback.umd.js
+++ b/plugins/Feedback/vue/dist/Feedback.umd.js
@@ -118,8 +118,8 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__8bbf__;
__webpack_require__.r(__webpack_exports__);
// EXPORTS
-__webpack_require__.d(__webpack_exports__, "ReviewLinks", function() { return /* reexport */ ReviewLinks; });
__webpack_require__.d(__webpack_exports__, "RateFeature", function() { return /* reexport */ RateFeature; });
+__webpack_require__.d(__webpack_exports__, "FeedbackQuestion", function() { return /* reexport */ FeedbackQuestion; });
// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/setPublicPath.js
// This file is imported into lib/wc client bundles.
@@ -143,7 +143,7 @@ var external_CoreHome_ = __webpack_require__("19dc");
// EXTERNAL MODULE: external {"commonjs":"vue","commonjs2":"vue","root":"Vue"}
var external_commonjs_vue_commonjs2_vue_root_Vue_ = __webpack_require__("8bbf");
-// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-babel/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/@vue/cli-plugin-babel/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/templateLoader.js??ref--6!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/Feedback/vue/src/RateFeature/RateFeature.vue?vue&type=template&id=65bd066a
+// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-babel/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/@vue/cli-plugin-babel/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/templateLoader.js??ref--6!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/Feedback/vue/src/RateFeature/RateFeature.vue?vue&type=template&id=10cf2a3c
var _hoisted_1 = ["title"];
var _hoisted_2 = {
@@ -173,8 +173,6 @@ var _hoisted_11 = ["value"];
function render(_ctx, _cache, $props, $setup, $data, $options) {
var _component_MatomoDialog = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("MatomoDialog");
- var _component_ReviewLinks = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("ReviewLinks");
-
return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", {
title: _ctx.translate('Feedback_RateFeatureTitle', _ctx.$sanitize(_ctx.title)),
class: "ratefeature"
@@ -235,7 +233,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
})
}, {
default: Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withCtx"])(function () {
- return [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_9, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("h2", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('Feedback_ThankYou', _ctx.title)), 1), _ctx.like ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", _hoisted_10, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_ReviewLinks)])) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("input", {
+ return [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_9, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("h2", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('Feedback_ThankYou', _ctx.title)), 1), _ctx.like ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", _hoisted_10)) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("input", {
type: "button",
value: _ctx.translate('General_Ok'),
role: "yes"
@@ -244,44 +242,17 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
_: 1
}, 8, ["modelValue"])], 8, _hoisted_1);
}
-// CONCATENATED MODULE: ./plugins/Feedback/vue/src/RateFeature/RateFeature.vue?vue&type=template&id=65bd066a
-
-// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-babel/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/@vue/cli-plugin-babel/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/templateLoader.js??ref--6!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/Feedback/vue/src/ReviewLinks/ReviewLinks.vue?vue&type=template&id=4471fc41
-
-var ReviewLinksvue_type_template_id_4471fc41_hoisted_1 = {
- class: "requestReview"
-};
-
-var ReviewLinksvue_type_template_id_4471fc41_hoisted_2 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createStaticVNode"])("<br><br><div class=\"review-links\"><div class=\"review-link\"><a href=\"https://www.capterra.com/p/182627/Matomo-Analytics/\" target=\"_blank\"><div class=\"image\"><img loading=\"lazy\" src=\"plugins/Feedback/images/capterra.svg\"></div><div class=\"link\">Capterra</div></a></div><div class=\"review-link\"><a href=\"https://www.g2crowd.com/products/matomo-formerly-piwik/details\" target=\"_blank\"><div class=\"image\"><img loading=\"lazy\" src=\"plugins/Feedback/images/g2crowd.svg\"></div><div class=\"link\">G2 Crowd</div></a></div><div class=\"review-link\"><a href=\"https://www.producthunt.com/posts/matomo-2\" target=\"_blank\"><div class=\"image\"><img loading=\"lazy\" src=\"plugins/Feedback/images/producthunt.svg\"></div><div class=\"link\">Product Hunt</div></a></div><div class=\"review-link\"><a href=\"https://www.saasworthy.com/product/matomo\" target=\"_blank\"><div class=\"image\"><img loading=\"lazy\" src=\"plugins/Feedback/images/saasworthy.png\"></div><div class=\"link\">SaaSworthy</div></a></div><div class=\"review-link\"><a href=\"https://www.trustradius.com/products/matomo/reviews\" target=\"_blank\"><div class=\"image\"><img loading=\"lazy\" src=\"plugins/Feedback/images/trustradius.svg\"></div><div class=\"link\">TrustRadius</div></a></div></div>", 3);
-
-function ReviewLinksvue_type_template_id_4471fc41_render(_ctx, _cache, $props, $setup, $data, $options) {
- return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", ReviewLinksvue_type_template_id_4471fc41_hoisted_1, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("p", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('Feedback_PleaseLeaveExternalReviewForMatomo')), 1), ReviewLinksvue_type_template_id_4471fc41_hoisted_2]);
-}
-// CONCATENATED MODULE: ./plugins/Feedback/vue/src/ReviewLinks/ReviewLinks.vue?vue&type=template&id=4471fc41
-
-// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-typescript/node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/@vue/cli-plugin-typescript/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-plugin-typescript/node_modules/ts-loader??ref--14-3!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/Feedback/vue/src/ReviewLinks/ReviewLinks.vue?vue&type=script&lang=ts
+// CONCATENATED MODULE: ./plugins/Feedback/vue/src/RateFeature/RateFeature.vue?vue&type=template&id=10cf2a3c
-/* harmony default export */ var ReviewLinksvue_type_script_lang_ts = (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["defineComponent"])({}));
-// CONCATENATED MODULE: ./plugins/Feedback/vue/src/ReviewLinks/ReviewLinks.vue?vue&type=script&lang=ts
-
-// CONCATENATED MODULE: ./plugins/Feedback/vue/src/ReviewLinks/ReviewLinks.vue
-
-
-
-ReviewLinksvue_type_script_lang_ts.render = ReviewLinksvue_type_template_id_4471fc41_render
-
-/* harmony default export */ var ReviewLinks = (ReviewLinksvue_type_script_lang_ts);
// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-typescript/node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/@vue/cli-plugin-typescript/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-plugin-typescript/node_modules/ts-loader??ref--14-3!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/Feedback/vue/src/RateFeature/RateFeature.vue?vue&type=script&lang=ts
-
/* harmony default export */ var RateFeaturevue_type_script_lang_ts = (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["defineComponent"])({
props: {
title: String
},
components: {
- MatomoDialog: external_CoreHome_["MatomoDialog"],
- ReviewLinks: ReviewLinks
+ MatomoDialog: external_CoreHome_["MatomoDialog"]
},
data: function data() {
return {
@@ -337,6 +308,242 @@ RateFeaturevue_type_script_lang_ts.render = render
},
directiveName: 'piwikRateFeature'
}));
+// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-babel/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/@vue/cli-plugin-babel/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/templateLoader.js??ref--6!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.vue?vue&type=template&id=2d5e9885
+
+var FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_1 = {
+ key: 0,
+ class: "bannerHeader"
+};
+
+var FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_2 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("i", {
+ class: "icon-heart red-text"
+}, null, -1);
+
+var FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_3 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("i", {
+ class: "icon-close white-text"
+}, null, -1);
+
+var FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_4 = [FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_3];
+var FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_5 = {
+ class: "ratefeature"
+};
+var FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_6 = {
+ class: "ui-confirm ratefeatureDialog"
+};
+var FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_7 = ["innerHTML"];
+
+var FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_8 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("br", null, null, -1);
+
+var FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_9 = {
+ class: "messageContainer"
+};
+var FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_10 = {
+ key: 0,
+ class: "error-text"
+};
+
+var FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_11 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("br", null, null, -1);
+
+var _hoisted_12 = ["innerHTML"];
+var _hoisted_13 = ["value"];
+var _hoisted_14 = ["value"];
+var _hoisted_15 = {
+ class: "ui-confirm ratefeatureDialog"
+};
+var _hoisted_16 = ["innerHTML"];
+var _hoisted_17 = ["value"];
+function FeedbackQuestionvue_type_template_id_2d5e9885_render(_ctx, _cache, $props, $setup, $data, $options) {
+ var _component_MatomoDialog = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("MatomoDialog");
+
+ return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", null, [!_ctx.isHidden ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_1, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("span", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createTextVNode"])(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate("Feedback_FeedbackTitle")) + " ", 1), FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_2]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("a", {
+ onClick: _cache[0] || (_cache[0] = function () {
+ return _ctx.showQuestion && _ctx.showQuestion.apply(_ctx, arguments);
+ }),
+ class: "btn"
+ }, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate("Feedback_Question".concat(_ctx.question))), 1), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("a", {
+ class: "close-btn",
+ onClick: _cache[1] || (_cache[1] = function () {
+ return _ctx.disableReminder && _ctx.disableReminder.apply(_ctx, arguments);
+ })
+ }, FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_4)])) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_5, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_MatomoDialog, {
+ modelValue: _ctx.showFeedbackForm,
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = function ($event) {
+ return _ctx.showFeedbackForm = $event;
+ }),
+ onValidation: _cache[4] || (_cache[4] = function ($event) {
+ return _ctx.sendFeedback();
+ })
+ }, {
+ default: Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withCtx"])(function () {
+ return [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_6, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("h2", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate("Feedback_Question".concat(_ctx.question))), 1), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("p", {
+ innerHTML: _ctx.translate('Feedback_FeedbackSubtitle', "<i class='icon-heart red-text'></i>")
+ }, null, 8, FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_7), FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_8, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_9, [_ctx.errorMessage ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_10, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.errorMessage), 1)) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withDirectives"])(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("textarea", {
+ id: "message",
+ class: Object(external_commonjs_vue_commonjs2_vue_root_Vue_["normalizeClass"])({
+ 'has-error': _ctx.errorMessage
+ }),
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = function ($event) {
+ return _ctx.feedbackMessage = $event;
+ })
+ }, null, 2), [[external_commonjs_vue_commonjs2_vue_root_Vue_["vModelText"], _ctx.feedbackMessage]])]), FeedbackQuestionvue_type_template_id_2d5e9885_hoisted_11, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("p", {
+ innerHTML: _ctx.translate('Feedback_Policy', "<a rel='nofollow' href='https://matomo.org/privacy-policy/' target='_blank'>", '</a>')
+ }, null, 8, _hoisted_12), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("input", {
+ type: "button",
+ role: "validation",
+ value: _ctx.translate('Feedback_SendFeedback')
+ }, null, 8, _hoisted_13), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("input", {
+ type: "button",
+ role: "cancel",
+ value: _ctx.translate('General_Cancel')
+ }, null, 8, _hoisted_14)])];
+ }),
+ _: 1
+ }, 8, ["modelValue"]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_MatomoDialog, {
+ modelValue: _ctx.feedbackDone,
+ "onUpdate:modelValue": _cache[5] || (_cache[5] = function ($event) {
+ return _ctx.feedbackDone = $event;
+ })
+ }, {
+ default: Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withCtx"])(function () {
+ return [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_15, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("h2", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate("Feedback_ThankYou")), 1), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("p", {
+ innerHTML: _ctx.translate('Feedback_ThankYourForFeedback', "<i class='icon-heart red-text'></i>")
+ }, null, 8, _hoisted_16), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("input", {
+ type: "button",
+ role: "cancel",
+ value: _ctx.translate('General_Close')
+ }, null, 8, _hoisted_17)])];
+ }),
+ _: 1
+ }, 8, ["modelValue"])])]);
+}
+// CONCATENATED MODULE: ./plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.vue?vue&type=template&id=2d5e9885
+
+// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-typescript/node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/@vue/cli-plugin-typescript/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-plugin-typescript/node_modules/ts-loader??ref--14-3!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.vue?vue&type=script&lang=ts
+
+
+var _window = window,
+ $ = _window.$;
+var cookieName = 'feedback-question';
+/* harmony default export */ var FeedbackQuestionvue_type_script_lang_ts = (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["defineComponent"])({
+ props: {
+ showQuestionBanner: String
+ },
+ components: {
+ MatomoDialog: external_CoreHome_["MatomoDialog"]
+ },
+ computed: {
+ isHidden: function isHidden() {
+ if (this.showQuestionBanner === '0') {
+ return true;
+ }
+
+ return !!this.hide;
+ }
+ },
+ data: function data() {
+ return {
+ questionText: '',
+ question: 0,
+ hide: null,
+ feedbackDone: false,
+ expanded: false,
+ showFeedbackForm: false,
+ feedbackMessage: null,
+ errorMessage: null
+ };
+ },
+ watch: {
+ showFeedbackForm: function showFeedbackForm(val) {
+ // eslint-disable-next-line no-underscore-dangle
+ this.questionText = Object(external_CoreHome_["translate"])("Feedback_Question".concat(this.question));
+
+ if (val) {
+ setInterval(function () {
+ $('#message').focus();
+ }, 500);
+ }
+ }
+ },
+ created: function created() {
+ if (this.showQuestionBanner !== '0') {
+ this.initQuestion();
+ }
+ },
+ methods: {
+ initQuestion: function initQuestion() {
+ if (!Object(external_CoreHome_["getCookie"])(cookieName)) {
+ this.question = this.getRandomIntBetween(0, 4);
+ } else {
+ // eslint-disable-next-line radix
+ this.question = parseInt(Object(external_CoreHome_["getCookie"])(cookieName));
+ }
+
+ var nextQuestion = (this.question + 1) % 4;
+ var sevenDays = 7 * 60 * 60 * 24 * 1000;
+ Object(external_CoreHome_["setCookie"])(cookieName, nextQuestion, sevenDays);
+ },
+ getRandomIntBetween: function getRandomIntBetween(min, max) {
+ // eslint-disable-next-line no-param-reassign
+ min = Math.ceil(min); // eslint-disable-next-line no-param-reassign
+
+ max = Math.floor(max);
+ return Math.floor(Math.random() * (max - min + 1) + min);
+ },
+ showQuestion: function showQuestion() {
+ this.showFeedbackForm = true;
+ this.errorMessage = null;
+ },
+ disableReminder: function disableReminder() {
+ external_CoreHome_["AjaxHelper"].fetch({
+ method: 'Feedback.updateFeedbackReminderDate'
+ });
+ this.hide = true;
+ },
+ sendFeedback: async function sendFeedback() {
+ this.errorMessage = null;
+ var res = await external_CoreHome_["AjaxHelper"].fetch({
+ method: 'Feedback.sendFeedbackForSurvey',
+ question: this.questionText,
+ message: this.feedbackMessage
+ });
+
+ if (res.value === 'success') {
+ $('.modal').modal('close');
+ this.feedbackDone = true;
+ this.hide = true;
+ } else {
+ this.errorMessage = res.value;
+ }
+ }
+ }
+}));
+// CONCATENATED MODULE: ./plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.vue?vue&type=script&lang=ts
+
+// CONCATENATED MODULE: ./plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.vue
+
+
+
+FeedbackQuestionvue_type_script_lang_ts.render = FeedbackQuestionvue_type_template_id_2d5e9885_render
+
+/* harmony default export */ var FeedbackQuestion = (FeedbackQuestionvue_type_script_lang_ts);
+// CONCATENATED MODULE: ./plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.adapter.ts
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+
+/* harmony default export */ var FeedbackQuestion_adapter = (Object(external_CoreHome_["createAngularJsAdapter"])({
+ component: FeedbackQuestion,
+ scope: {
+ showQuestionBanner: {
+ angularJsBind: '@'
+ }
+ },
+ directiveName: 'piwikFeedbackQuestion'
+}));
// CONCATENATED MODULE: ./plugins/Feedback/vue/src/index.ts
/*!
* Matomo - free/libre analytics platform
@@ -347,6 +554,7 @@ RateFeaturevue_type_script_lang_ts.render = render
+
// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/entry-lib-no-default.js
diff --git a/plugins/Feedback/vue/dist/Feedback.umd.min.js b/plugins/Feedback/vue/dist/Feedback.umd.min.js
index 805ddb155a..690932aefa 100644
--- a/plugins/Feedback/vue/dist/Feedback.umd.min.js
+++ b/plugins/Feedback/vue/dist/Feedback.umd.min.js
@@ -1,8 +1,14 @@
-(function(e,t){"object"===typeof exports&&"object"===typeof module?module.exports=t(require("CoreHome"),require("vue")):"function"===typeof define&&define.amd?define(["CoreHome"],t):"object"===typeof exports?exports["Feedback"]=t(require("CoreHome"),require("vue")):e["Feedback"]=t(e["CoreHome"],e["Vue"])})("undefined"!==typeof self?self:this,(function(e,t){return function(e){var t={};function a(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,a),r.l=!0,r.exports}return a.m=e,a.c=t,a.d=function(e,t,n){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},a.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(a.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)a.d(n,r,function(t){return e[t]}.bind(null,r));return n},a.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="plugins/Feedback/vue/dist/",a(a.s="fae3")}({"19dc":function(t,a){t.exports=e},"8bbf":function(e,a){e.exports=t},fae3:function(e,t,a){"use strict";if(a.r(t),a.d(t,"ReviewLinks",(function(){return h})),a.d(t,"RateFeature",(function(){return V})),"undefined"!==typeof window){var n=window.document.currentScript,r=n&&n.src.match(/(.+\/)[^/]+\.js(\?.*)?$/);r&&(a.p=r[1])}var i=a("19dc"),o=a("8bbf"),c=["title"],l={class:"ui-confirm ratefeatureDialog"},s={key:0},d={key:1},u=Object(o["createElementVNode"])("br",null,null,-1),b={class:"messageContainer"},m=["title","value"],p=["value"],v={class:"ui-confirm ratefeatureDialog"},f={key:0},k=["value"];function g(e,t,a,n,r,i){var g=Object(o["resolveComponent"])("MatomoDialog"),j=Object(o["resolveComponent"])("ReviewLinks");return Object(o["openBlock"])(),Object(o["createElementBlock"])("div",{title:e.translate("Feedback_RateFeatureTitle",e.$sanitize(e.title)),class:"ratefeature"},[Object(o["createElementVNode"])("div",{class:"iconContainer",onMouseenter:t[2]||(t[2]=function(t){return e.expanded=!0}),onMouseleave:t[3]||(t[3]=function(t){return e.expanded=!1})},[Object(o["createElementVNode"])("img",{onClick:t[0]||(t[0]=function(t){e.likeFeature(),e.showFeedbackForm=!0}),class:"like-icon",src:"plugins/Feedback/vue/src/RateFeature/thumbs-up.png"}),Object(o["withDirectives"])(Object(o["createElementVNode"])("img",{onClick:t[1]||(t[1]=function(t){e.dislikeFeature(),e.showFeedbackForm=!0}),class:"dislike-icon",src:"plugins/Feedback/vue/src/RateFeature/thumbs-down.png"},null,512),[[o["vShow"],e.expanded]])],32),Object(o["createVNode"])(g,{modelValue:e.showFeedbackForm,"onUpdate:modelValue":t[5]||(t[5]=function(t){return e.showFeedbackForm=t}),onYes:t[6]||(t[6]=function(t){return e.sendFeedback()})},{default:Object(o["withCtx"])((function(){return[Object(o["createElementVNode"])("div",l,[Object(o["createElementVNode"])("h2",null,Object(o["toDisplayString"])(e.translate("Feedback_RateFeatureThankYouTitle",e.title)),1),e.like?(Object(o["openBlock"])(),Object(o["createElementBlock"])("p",s,Object(o["toDisplayString"])(e.translate("Feedback_RateFeatureLeaveMessageLike")),1)):Object(o["createCommentVNode"])("",!0),e.like?Object(o["createCommentVNode"])("",!0):(Object(o["openBlock"])(),Object(o["createElementBlock"])("p",d,Object(o["toDisplayString"])(e.translate("Feedback_RateFeatureLeaveMessageDislike")),1)),u,Object(o["createElementVNode"])("div",b,[Object(o["withDirectives"])(Object(o["createElementVNode"])("textarea",{"onUpdate:modelValue":t[4]||(t[4]=function(t){return e.feedbackMessage=t})},null,512),[[o["vModelText"],e.feedbackMessage]])]),Object(o["createElementVNode"])("input",{type:"button",title:e.translate("Feedback_RateFeatureSendFeedbackInformation"),value:e.translate("Feedback_SendFeedback"),role:"yes"},null,8,m),Object(o["createElementVNode"])("input",{type:"button",role:"cancel",value:e.translate("General_Cancel")},null,8,p)])]})),_:1},8,["modelValue"]),Object(o["createVNode"])(g,{modelValue:e.ratingDone,"onUpdate:modelValue":t[7]||(t[7]=function(t){return e.ratingDone=t})},{default:Object(o["withCtx"])((function(){return[Object(o["createElementVNode"])("div",v,[Object(o["createElementVNode"])("h2",null,Object(o["toDisplayString"])(e.translate("Feedback_ThankYou",e.title)),1),e.like?(Object(o["openBlock"])(),Object(o["createElementBlock"])("div",f,[Object(o["createVNode"])(j)])):Object(o["createCommentVNode"])("",!0),Object(o["createElementVNode"])("input",{type:"button",value:e.translate("General_Ok"),role:"yes"},null,8,k)])]})),_:1},8,["modelValue"])],8,c)}var j={class:"requestReview"},O=Object(o["createStaticVNode"])('<br><br><div class="review-links"><div class="review-link"><a href="https://www.capterra.com/p/182627/Matomo-Analytics/" target="_blank"><div class="image"><img loading="lazy" src="plugins/Feedback/images/capterra.svg"></div><div class="link">Capterra</div></a></div><div class="review-link"><a href="https://www.g2crowd.com/products/matomo-formerly-piwik/details" target="_blank"><div class="image"><img loading="lazy" src="plugins/Feedback/images/g2crowd.svg"></div><div class="link">G2 Crowd</div></a></div><div class="review-link"><a href="https://www.producthunt.com/posts/matomo-2" target="_blank"><div class="image"><img loading="lazy" src="plugins/Feedback/images/producthunt.svg"></div><div class="link">Product Hunt</div></a></div><div class="review-link"><a href="https://www.saasworthy.com/product/matomo" target="_blank"><div class="image"><img loading="lazy" src="plugins/Feedback/images/saasworthy.png"></div><div class="link">SaaSworthy</div></a></div><div class="review-link"><a href="https://www.trustradius.com/products/matomo/reviews" target="_blank"><div class="image"><img loading="lazy" src="plugins/Feedback/images/trustradius.svg"></div><div class="link">TrustRadius</div></a></div></div>',3);function w(e,t,a,n,r,i){return Object(o["openBlock"])(),Object(o["createElementBlock"])("div",j,[Object(o["createElementVNode"])("p",null,Object(o["toDisplayString"])(e.translate("Feedback_PleaseLeaveExternalReviewForMatomo")),1),O])}var F=Object(o["defineComponent"])({});F.render=w;var h=F,y=Object(o["defineComponent"])({props:{title:String},components:{MatomoDialog:i["MatomoDialog"],ReviewLinks:h},data:function(){return{like:!1,ratingDone:!1,expanded:!1,showFeedbackForm:!1,feedbackMessage:""}},methods:{dislikeFeature:function(){this.like=!1},likeFeature:function(){this.like=!0},sendFeedback:function(){i["AjaxHelper"].fetch({method:"Feedback.sendFeedbackForFeature",featureName:this.title,like:this.like?"1":"0",message:this.feedbackMessage}),this.ratingDone=!0}}});y.render=g;var V=y;
+(function(e,t){"object"===typeof exports&&"object"===typeof module?module.exports=t(require("CoreHome"),require("vue")):"function"===typeof define&&define.amd?define(["CoreHome"],t):"object"===typeof exports?exports["Feedback"]=t(require("CoreHome"),require("vue")):e["Feedback"]=t(e["CoreHome"],e["Vue"])})("undefined"!==typeof self?self:this,(function(e,t){return function(e){var t={};function n(a){if(t[a])return t[a].exports;var o=t[a]={i:a,l:!1,exports:{}};return e[a].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(n.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(a,o,function(t){return e[t]}.bind(null,o));return a},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="plugins/Feedback/vue/dist/",n(n.s="fae3")}({"19dc":function(t,n){t.exports=e},"8bbf":function(e,n){e.exports=t},fae3:function(e,t,n){"use strict";if(n.r(t),n.d(t,"RateFeature",(function(){return F})),n.d(t,"FeedbackQuestion",(function(){return U})),"undefined"!==typeof window){var a=window.document.currentScript,o=a&&a.src.match(/(.+\/)[^/]+\.js(\?.*)?$/);o&&(n.p=o[1])}var r=n("19dc"),c=n("8bbf"),l=["title"],i={class:"ui-confirm ratefeatureDialog"},s={key:0},u={key:1},d=Object(c["createElementVNode"])("br",null,null,-1),b={class:"messageContainer"},m=["title","value"],f=["value"],k={class:"ui-confirm ratefeatureDialog"},p={key:0},j=["value"];function O(e,t,n,a,o,r){var O=Object(c["resolveComponent"])("MatomoDialog");return Object(c["openBlock"])(),Object(c["createElementBlock"])("div",{title:e.translate("Feedback_RateFeatureTitle",e.$sanitize(e.title)),class:"ratefeature"},[Object(c["createElementVNode"])("div",{class:"iconContainer",onMouseenter:t[2]||(t[2]=function(t){return e.expanded=!0}),onMouseleave:t[3]||(t[3]=function(t){return e.expanded=!1})},[Object(c["createElementVNode"])("img",{onClick:t[0]||(t[0]=function(t){e.likeFeature(),e.showFeedbackForm=!0}),class:"like-icon",src:"plugins/Feedback/vue/src/RateFeature/thumbs-up.png"}),Object(c["withDirectives"])(Object(c["createElementVNode"])("img",{onClick:t[1]||(t[1]=function(t){e.dislikeFeature(),e.showFeedbackForm=!0}),class:"dislike-icon",src:"plugins/Feedback/vue/src/RateFeature/thumbs-down.png"},null,512),[[c["vShow"],e.expanded]])],32),Object(c["createVNode"])(O,{modelValue:e.showFeedbackForm,"onUpdate:modelValue":t[5]||(t[5]=function(t){return e.showFeedbackForm=t}),onYes:t[6]||(t[6]=function(t){return e.sendFeedback()})},{default:Object(c["withCtx"])((function(){return[Object(c["createElementVNode"])("div",i,[Object(c["createElementVNode"])("h2",null,Object(c["toDisplayString"])(e.translate("Feedback_RateFeatureThankYouTitle",e.title)),1),e.like?(Object(c["openBlock"])(),Object(c["createElementBlock"])("p",s,Object(c["toDisplayString"])(e.translate("Feedback_RateFeatureLeaveMessageLike")),1)):Object(c["createCommentVNode"])("",!0),e.like?Object(c["createCommentVNode"])("",!0):(Object(c["openBlock"])(),Object(c["createElementBlock"])("p",u,Object(c["toDisplayString"])(e.translate("Feedback_RateFeatureLeaveMessageDislike")),1)),d,Object(c["createElementVNode"])("div",b,[Object(c["withDirectives"])(Object(c["createElementVNode"])("textarea",{"onUpdate:modelValue":t[4]||(t[4]=function(t){return e.feedbackMessage=t})},null,512),[[c["vModelText"],e.feedbackMessage]])]),Object(c["createElementVNode"])("input",{type:"button",title:e.translate("Feedback_RateFeatureSendFeedbackInformation"),value:e.translate("Feedback_SendFeedback"),role:"yes"},null,8,m),Object(c["createElementVNode"])("input",{type:"button",role:"cancel",value:e.translate("General_Cancel")},null,8,f)])]})),_:1},8,["modelValue"]),Object(c["createVNode"])(O,{modelValue:e.ratingDone,"onUpdate:modelValue":t[7]||(t[7]=function(t){return e.ratingDone=t})},{default:Object(c["withCtx"])((function(){return[Object(c["createElementVNode"])("div",k,[Object(c["createElementVNode"])("h2",null,Object(c["toDisplayString"])(e.translate("Feedback_ThankYou",e.title)),1),e.like?(Object(c["openBlock"])(),Object(c["createElementBlock"])("div",p)):Object(c["createCommentVNode"])("",!0),Object(c["createElementVNode"])("input",{type:"button",value:e.translate("General_Ok"),role:"yes"},null,8,j)])]})),_:1},8,["modelValue"])],8,l)}var h=Object(c["defineComponent"])({props:{title:String},components:{MatomoDialog:r["MatomoDialog"]},data:function(){return{like:!1,ratingDone:!1,expanded:!1,showFeedbackForm:!1,feedbackMessage:""}},methods:{dislikeFeature:function(){this.like=!1},likeFeature:function(){this.like=!0},sendFeedback:function(){r["AjaxHelper"].fetch({method:"Feedback.sendFeedbackForFeature",featureName:this.title,like:this.like?"1":"0",message:this.feedbackMessage}),this.ratingDone=!0}}});h.render=O;var F=h,g=(Object(r["createAngularJsAdapter"])({component:F,scope:{title:{angularJsBind:"@"}},directiveName:"piwikRateFeature"}),{key:0,class:"bannerHeader"}),v=Object(c["createElementVNode"])("i",{class:"icon-heart red-text"},null,-1),V=Object(c["createElementVNode"])("i",{class:"icon-close white-text"},null,-1),y=[V],N={class:"ratefeature"},w={class:"ui-confirm ratefeatureDialog"},M=["innerHTML"],E=Object(c["createElementVNode"])("br",null,null,-1),x={class:"messageContainer"},D={key:0,class:"error-text"},C=Object(c["createElementVNode"])("br",null,null,-1),_=["innerHTML"],S=["value"],B=["value"],T={class:"ui-confirm ratefeatureDialog"},q=["innerHTML"],H=["value"];
/*!
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */Object(i["createAngularJsAdapter"])({component:V,scope:{title:{angularJsBind:"@"}},directiveName:"piwikRateFeature"})}})}));
+ */function R(e,t,n,a,o,r){var l=Object(c["resolveComponent"])("MatomoDialog");return Object(c["openBlock"])(),Object(c["createElementBlock"])("div",null,[e.isHidden?Object(c["createCommentVNode"])("",!0):(Object(c["openBlock"])(),Object(c["createElementBlock"])("div",g,[Object(c["createElementVNode"])("span",null,[Object(c["createTextVNode"])(Object(c["toDisplayString"])(e.translate("Feedback_FeedbackTitle"))+" ",1),v]),Object(c["createElementVNode"])("a",{onClick:t[0]||(t[0]=function(){return e.showQuestion&&e.showQuestion.apply(e,arguments)}),class:"btn"},Object(c["toDisplayString"])(e.translate("Feedback_Question".concat(e.question))),1),Object(c["createElementVNode"])("a",{class:"close-btn",onClick:t[1]||(t[1]=function(){return e.disableReminder&&e.disableReminder.apply(e,arguments)})},y)])),Object(c["createElementVNode"])("div",N,[Object(c["createVNode"])(l,{modelValue:e.showFeedbackForm,"onUpdate:modelValue":t[3]||(t[3]=function(t){return e.showFeedbackForm=t}),onValidation:t[4]||(t[4]=function(t){return e.sendFeedback()})},{default:Object(c["withCtx"])((function(){return[Object(c["createElementVNode"])("div",w,[Object(c["createElementVNode"])("h2",null,Object(c["toDisplayString"])(e.translate("Feedback_Question".concat(e.question))),1),Object(c["createElementVNode"])("p",{innerHTML:e.translate("Feedback_FeedbackSubtitle","<i class='icon-heart red-text'></i>")},null,8,M),E,Object(c["createElementVNode"])("div",x,[e.errorMessage?(Object(c["openBlock"])(),Object(c["createElementBlock"])("div",D,Object(c["toDisplayString"])(e.errorMessage),1)):Object(c["createCommentVNode"])("",!0),Object(c["withDirectives"])(Object(c["createElementVNode"])("textarea",{id:"message",class:Object(c["normalizeClass"])({"has-error":e.errorMessage}),"onUpdate:modelValue":t[2]||(t[2]=function(t){return e.feedbackMessage=t})},null,2),[[c["vModelText"],e.feedbackMessage]])]),C,Object(c["createElementVNode"])("p",{innerHTML:e.translate("Feedback_Policy","<a rel='nofollow' href='https://matomo.org/privacy-policy/' target='_blank'>","</a>")},null,8,_),Object(c["createElementVNode"])("input",{type:"button",role:"validation",value:e.translate("Feedback_SendFeedback")},null,8,S),Object(c["createElementVNode"])("input",{type:"button",role:"cancel",value:e.translate("General_Cancel")},null,8,B)])]})),_:1},8,["modelValue"]),Object(c["createVNode"])(l,{modelValue:e.feedbackDone,"onUpdate:modelValue":t[5]||(t[5]=function(t){return e.feedbackDone=t})},{default:Object(c["withCtx"])((function(){return[Object(c["createElementVNode"])("div",T,[Object(c["createElementVNode"])("h2",null,Object(c["toDisplayString"])(e.translate("Feedback_ThankYou")),1),Object(c["createElementVNode"])("p",{innerHTML:e.translate("Feedback_ThankYourForFeedback","<i class='icon-heart red-text'></i>")},null,8,q),Object(c["createElementVNode"])("input",{type:"button",role:"cancel",value:e.translate("General_Close")},null,8,H)])]})),_:1},8,["modelValue"])])])}var Q=window,L=Q.$,A="feedback-question",P=Object(c["defineComponent"])({props:{showQuestionBanner:String},components:{MatomoDialog:r["MatomoDialog"]},computed:{isHidden:function(){return"0"===this.showQuestionBanner||!!this.hide}},data:function(){return{questionText:"",question:0,hide:null,feedbackDone:!1,expanded:!1,showFeedbackForm:!1,feedbackMessage:null,errorMessage:null}},watch:{showFeedbackForm:function(e){this.questionText=Object(r["translate"])("Feedback_Question".concat(this.question)),e&&setInterval((function(){L("#message").focus()}),500)}},created:function(){"0"!==this.showQuestionBanner&&this.initQuestion()},methods:{initQuestion:function(){Object(r["getCookie"])(A)?this.question=parseInt(Object(r["getCookie"])(A)):this.question=this.getRandomIntBetween(0,4);var e=(this.question+1)%4,t=6048e5;Object(r["setCookie"])(A,e,t)},getRandomIntBetween:function(e,t){return e=Math.ceil(e),t=Math.floor(t),Math.floor(Math.random()*(t-e+1)+e)},showQuestion:function(){this.showFeedbackForm=!0,this.errorMessage=null},disableReminder:function(){r["AjaxHelper"].fetch({method:"Feedback.updateFeedbackReminderDate"}),this.hide=!0},sendFeedback:async function(){this.errorMessage=null;var e=await r["AjaxHelper"].fetch({method:"Feedback.sendFeedbackForSurvey",question:this.questionText,message:this.feedbackMessage});"success"===e.value?(L(".modal").modal("close"),this.feedbackDone=!0,this.hide=!0):this.errorMessage=e.value}}});P.render=R;var U=P;
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */Object(r["createAngularJsAdapter"])({component:U,scope:{showQuestionBanner:{angularJsBind:"@"}},directiveName:"piwikFeedbackQuestion"})}})}));
//# sourceMappingURL=Feedback.umd.min.js.map \ No newline at end of file
diff --git a/plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.adapter.ts b/plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.adapter.ts
new file mode 100644
index 0000000000..8206972ef7
--- /dev/null
+++ b/plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.adapter.ts
@@ -0,0 +1,19 @@
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+import { createAngularJsAdapter } from 'CoreHome';
+import RateFeature from './FeedbackQuestion.vue';
+
+export default createAngularJsAdapter({
+ component: RateFeature,
+ scope: {
+ showQuestionBanner: {
+ angularJsBind: '@',
+ },
+ },
+ directiveName: 'piwikFeedbackQuestion',
+});
diff --git a/plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.less b/plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.less
new file mode 100644
index 0000000000..1d65d14b05
--- /dev/null
+++ b/plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.less
@@ -0,0 +1,34 @@
+.bannerHeader {
+ min-height: 48px;
+ background-color: #263238;
+ text-align: center;
+ color: #fff;
+
+ span {
+ vertical-align: sub;
+ font-size: 14px;
+ }
+
+ a {
+ margin-left: 16px;
+ margin-top: 6px;
+ }
+
+ .close-btn {
+ float: right;
+ margin-right: 20px;
+ font-size: 1.2em;
+ margin-top: 12px;
+ }
+}
+
+.modal {
+ .has-error {
+ border: 1px red solid;
+ }
+
+ .error-text {
+ float: left;
+ color: red;
+ }
+} \ No newline at end of file
diff --git a/plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.vue b/plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.vue
new file mode 100644
index 0000000000..52fa9cd9fa
--- /dev/null
+++ b/plugins/Feedback/vue/src/FeedbackQuestion/FeedbackQuestion.vue
@@ -0,0 +1,169 @@
+<!--
+ Matomo - free/libre analytics platform
+ @link https://matomo.org
+ @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+-->
+
+<template>
+ <div>
+ <div v-if="!isHidden" class="bannerHeader">
+ <span>{{ translate(`Feedback_FeedbackTitle`) }} <i class="icon-heart red-text"></i></span>
+ <a @click="showQuestion" class="btn">
+ {{ translate(`Feedback_Question${question}`) }}
+ </a>
+ <a class="close-btn" @click="disableReminder">
+ <i class="icon-close white-text"></i></a>
+ </div>
+ <div class="ratefeature">
+ <MatomoDialog
+ v-model="showFeedbackForm"
+ @validation="sendFeedback()"
+ >
+ <div
+ class="ui-confirm ratefeatureDialog"
+ >
+ <h2>{{ translate(`Feedback_Question${question}`) }}</h2>
+ <p
+ v-html="translate('Feedback_FeedbackSubtitle',
+ `<i class='icon-heart red-text'></i>`)"></p>
+ <br/>
+ <div class="messageContainer">
+ <div class="error-text" v-if="errorMessage">{{ errorMessage }}</div>
+ <textarea id="message" :class="{'has-error':errorMessage}" v-model="feedbackMessage"/>
+ </div>
+ <br/>
+ <p
+ v-html="translate('Feedback_Policy',`<a rel='nofollow' href='https://matomo.org/privacy-policy/' target='_blank'>`,'</a>')"></p>
+ <input
+ type="button"
+ role="validation"
+ :value="translate('Feedback_SendFeedback')"
+ />
+ <input
+ type="button"
+ role="cancel"
+ :value="translate('General_Cancel')"
+ />
+ </div>
+ </MatomoDialog>
+ <MatomoDialog v-model="feedbackDone">
+ <div
+ class="ui-confirm ratefeatureDialog"
+ >
+ <h2>{{ translate(`Feedback_ThankYou`) }}</h2>
+ <p v-html="translate('Feedback_ThankYourForFeedback',
+ `<i class='icon-heart red-text'></i>`)">
+ </p>
+ <input
+ type="button"
+ role="cancel"
+ :value="translate('General_Close')"
+ />
+ </div>
+ </MatomoDialog>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import {
+ MatomoDialog, AjaxHelper, setCookie, getCookie, translate,
+} from 'CoreHome';
+
+const { $ } = window;
+
+const cookieName = 'feedback-question';
+export default defineComponent({
+
+ props: {
+ showQuestionBanner: String,
+ },
+ components: {
+ MatomoDialog,
+ },
+ computed: {
+ isHidden() {
+ if (this.showQuestionBanner === '0') {
+ return true;
+ }
+ return !!this.hide;
+ },
+ },
+ data() {
+ return {
+ questionText: '',
+ question: 0,
+ hide: null,
+ feedbackDone: false,
+ expanded: false,
+ showFeedbackForm: false,
+ feedbackMessage: null,
+ errorMessage: null,
+ };
+ },
+ watch: {
+ showFeedbackForm(val) {
+ // eslint-disable-next-line no-underscore-dangle
+ this.questionText = translate(`Feedback_Question${this.question}`);
+ if (val) {
+ setInterval(() => {
+ $('#message').focus();
+ }, 500);
+ }
+ },
+ },
+ created() {
+ if (this.showQuestionBanner !== '0') {
+ this.initQuestion();
+ }
+ },
+ methods: {
+ initQuestion() {
+ if (!getCookie(cookieName)) {
+ this.question = this.getRandomIntBetween(0, 4);
+ } else {
+ // eslint-disable-next-line radix
+ this.question = parseInt(getCookie(cookieName));
+ }
+
+ const nextQuestion = (this.question + 1) % 4;
+ const sevenDays = 7 * 60 * 60 * 24 * 1000;
+ setCookie(cookieName, nextQuestion, sevenDays);
+ },
+ getRandomIntBetween(min, max) {
+ // eslint-disable-next-line no-param-reassign
+ min = Math.ceil(min);
+ // eslint-disable-next-line no-param-reassign
+ max = Math.floor(max);
+ return Math.floor(Math.random() * (max - min + 1) + min);
+ },
+ showQuestion() {
+ this.showFeedbackForm = true;
+ this.errorMessage = null;
+ },
+ disableReminder() {
+ AjaxHelper.fetch({
+ method: 'Feedback.updateFeedbackReminderDate',
+ });
+ this.hide = true;
+ },
+ async sendFeedback() {
+ this.errorMessage = null;
+ const res = await AjaxHelper.fetch({
+ method: 'Feedback.sendFeedbackForSurvey',
+ question: this.questionText,
+ message: this.feedbackMessage,
+ });
+
+ if (res.value === 'success') {
+ $('.modal').modal('close');
+ this.feedbackDone = true;
+ this.hide = true;
+ } else {
+ this.errorMessage = res.value;
+ }
+ },
+ },
+});
+</script>
diff --git a/plugins/Feedback/vue/src/RateFeature/RateFeature.vue b/plugins/Feedback/vue/src/RateFeature/RateFeature.vue
index 324142273f..ba90382e55 100644
--- a/plugins/Feedback/vue/src/RateFeature/RateFeature.vue
+++ b/plugins/Feedback/vue/src/RateFeature/RateFeature.vue
@@ -63,7 +63,6 @@
<div
v-if="like"
>
- <ReviewLinks />
</div>
<input
type="button"
@@ -78,7 +77,6 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { MatomoDialog, AjaxHelper } from 'CoreHome';
-import ReviewLinks from '../ReviewLinks/ReviewLinks.vue';
export default defineComponent({
props: {
@@ -86,7 +84,6 @@ export default defineComponent({
},
components: {
MatomoDialog,
- ReviewLinks,
},
data() {
return {
diff --git a/plugins/Feedback/vue/src/ReviewLinks/ReviewLinks.vue b/plugins/Feedback/vue/src/ReviewLinks/ReviewLinks.vue
deleted file mode 100644
index fa65f8569f..0000000000
--- a/plugins/Feedback/vue/src/ReviewLinks/ReviewLinks.vue
+++ /dev/null
@@ -1,90 +0,0 @@
-<!--
- Matomo - free/libre analytics platform
-
- @link https://matomo.org
- @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
--->
-
-<template>
- <div class="requestReview">
- <p>{{ translate('Feedback_PleaseLeaveExternalReviewForMatomo') }}</p><br><br>
- <div class="review-links">
- <div class="review-link">
- <a
- href="https://www.capterra.com/p/182627/Matomo-Analytics/"
- target="_blank"
- >
- <div class="image">
- <img
- loading="lazy"
- src="plugins/Feedback/images/capterra.svg"
- />
- </div>
- <div class="link">Capterra</div>
- </a>
- </div>
- <div class="review-link">
- <a
- href="https://www.g2crowd.com/products/matomo-formerly-piwik/details"
- target="_blank"
- >
- <div class="image">
- <img
- loading="lazy"
- src="plugins/Feedback/images/g2crowd.svg"
- />
- </div>
- <div class="link">G2 Crowd</div>
- </a>
- </div>
- <div class="review-link">
- <a
- href="https://www.producthunt.com/posts/matomo-2"
- target="_blank"
- >
- <div class="image">
- <img
- loading="lazy"
- src="plugins/Feedback/images/producthunt.svg"
- />
- </div>
- <div class="link">Product Hunt</div>
- </a>
- </div>
- <div class="review-link">
- <a
- href="https://www.saasworthy.com/product/matomo"
- target="_blank"
- >
- <div class="image">
- <img
- loading="lazy"
- src="plugins/Feedback/images/saasworthy.png"
- />
- </div>
- <div class="link">SaaSworthy</div>
- </a>
- </div>
- <div class="review-link">
- <a
- href="https://www.trustradius.com/products/matomo/reviews"
- target="_blank"
- >
- <div class="image">
- <img
- loading="lazy"
- src="plugins/Feedback/images/trustradius.svg"
- />
- </div>
- <div class="link">TrustRadius</div>
- </a>
- </div>
- </div>
- </div>
-</template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-
-export default defineComponent({});
-</script>
diff --git a/plugins/Feedback/vue/src/index.ts b/plugins/Feedback/vue/src/index.ts
index 5f37c3b890..d4018200f8 100644
--- a/plugins/Feedback/vue/src/index.ts
+++ b/plugins/Feedback/vue/src/index.ts
@@ -6,6 +6,7 @@
*/
import './RateFeature/RateFeature.adapter';
+import './FeedbackQuestion/FeedbackQuestion.adapter';
-export { default as ReviewLinks } from './ReviewLinks/ReviewLinks.vue';
export { default as RateFeature } from './RateFeature/RateFeature.vue';
+export { default as FeedbackQuestion } from './FeedbackQuestion/FeedbackQuestion.vue';