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:
Diffstat (limited to 'plugins/Feedback/vue/src')
-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
6 files changed, 224 insertions, 94 deletions
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';