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:
authordizzy <diosmosis@users.noreply.github.com>2022-03-17 04:21:09 +0300
committerGitHub <noreply@github.com>2022-03-17 04:21:09 +0300
commit39d5fbab4aaf6c4728ba4b42ed818bb4652f4f68 (patch)
tree60eac15e9c1b2dbf6441ebda308f24f2f9ed011e
parentf3c9ee7652cad18ce815d60fdc564bcdd076c10b (diff)
[Vue] migrate LanguagesManager to vue (#18931)
* migrate translation search directive to vue * Allow specifying usable components in vue-entry and use in LanguagesManager configuration.twig * migrate language selector, fix prop type in personalsettings.vue, and get selector to work in installation * built vue files
-rw-r--r--core/AssetManager/UIAssetFetcher/PluginUmdAssetFetcher.php34
-rw-r--r--plugins/LanguagesManager/LanguagesManager.php12
-rw-r--r--plugins/LanguagesManager/angularjs/languageselector/languageselector.directive.js36
-rw-r--r--plugins/LanguagesManager/angularjs/translationsearch/translationsearch.controller.js68
-rw-r--r--plugins/LanguagesManager/angularjs/translationsearch/translationsearch.directive.html44
-rw-r--r--plugins/LanguagesManager/angularjs/translationsearch/translationsearch.directive.js31
-rw-r--r--plugins/LanguagesManager/templates/searchTranslation.twig9
-rw-r--r--plugins/LanguagesManager/vue/dist/LanguagesManager.umd.js401
-rw-r--r--plugins/LanguagesManager/vue/dist/LanguagesManager.umd.min.js20
-rw-r--r--plugins/LanguagesManager/vue/dist/umd.metadata.json5
-rw-r--r--plugins/LanguagesManager/vue/src/LanguageSelector/LanguageSelector.adapter.ts31
-rw-r--r--plugins/LanguagesManager/vue/src/LanguageSelector/LanguageSelector.ts36
-rw-r--r--plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.adapter.ts14
-rw-r--r--plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.vue183
-rw-r--r--plugins/LanguagesManager/vue/src/index.ts12
-rw-r--r--plugins/Morpheus/javascripts/piwikHelper.js26
-rw-r--r--plugins/UsersManager/vue/dist/UsersManager.umd.js38
-rw-r--r--plugins/UsersManager/vue/dist/UsersManager.umd.min.js2
-rw-r--r--plugins/UsersManager/vue/src/PersonalSettings/PersonalSettings.vue4
19 files changed, 780 insertions, 226 deletions
diff --git a/core/AssetManager/UIAssetFetcher/PluginUmdAssetFetcher.php b/core/AssetManager/UIAssetFetcher/PluginUmdAssetFetcher.php
index 6834d2923f..f86f7f5102 100644
--- a/core/AssetManager/UIAssetFetcher/PluginUmdAssetFetcher.php
+++ b/core/AssetManager/UIAssetFetcher/PluginUmdAssetFetcher.php
@@ -176,21 +176,31 @@ class PluginUmdAssetFetcher extends UIAssetFetcher
$plugins = self::orderPluginsByPluginDependencies($plugins, false);
foreach ($plugins as $plugin) {
- $pluginDir = self::getRelativePluginDirectory($plugin);
+ $fileLocation = self::getUmdFileToUseForPlugin($plugin);
+ if ($fileLocation) {
+ $this->fileLocations[] = $fileLocation;
+ }
+ }
+ }
- $devUmd = "$pluginDir/vue/dist/$plugin.development.umd.js";
- $minifiedUmd = "$pluginDir/vue/dist/$plugin.umd.min.js";
- $umdSrcFolder = "$pluginDir/vue/src";
-
- // in case there are dist files but no src files, which can happen during development
- if (is_dir(PIWIK_INCLUDE_PATH . '/' . $umdSrcFolder)) {
- if (Development::isEnabled() && is_file(PIWIK_INCLUDE_PATH . '/' . $devUmd)) {
- $this->fileLocations[] = $devUmd;
- } else if (is_file(PIWIK_INCLUDE_PATH . '/' . $minifiedUmd)) {
- $this->fileLocations[] = $minifiedUmd;
- }
+ public static function getUmdFileToUseForPlugin($plugin)
+ {
+ $pluginDir = self::getRelativePluginDirectory($plugin);
+
+ $devUmd = "$pluginDir/vue/dist/$plugin.development.umd.js";
+ $minifiedUmd = "$pluginDir/vue/dist/$plugin.umd.min.js";
+ $umdSrcFolder = "$pluginDir/vue/src";
+
+ // in case there are dist files but no src files, which can happen during development
+ if (is_dir(PIWIK_INCLUDE_PATH . '/' . $umdSrcFolder)) {
+ if (Development::isEnabled() && is_file(PIWIK_INCLUDE_PATH . '/' . $devUmd)) {
+ return $devUmd;
+ } else if (is_file(PIWIK_INCLUDE_PATH . '/' . $minifiedUmd)) {
+ return $minifiedUmd;
}
}
+
+ return null;
}
public static function orderPluginsByPluginDependencies($plugins, $keepUnresolved = true)
diff --git a/plugins/LanguagesManager/LanguagesManager.php b/plugins/LanguagesManager/LanguagesManager.php
index 988a0a9c70..a52a613035 100644
--- a/plugins/LanguagesManager/LanguagesManager.php
+++ b/plugins/LanguagesManager/LanguagesManager.php
@@ -11,6 +11,7 @@ namespace Piwik\Plugins\LanguagesManager;
use Exception;
use Piwik\API\Request;
+use Piwik\AssetManager\UIAssetFetcher\PluginUmdAssetFetcher;
use Piwik\Common;
use Piwik\Config;
use Piwik\Container\StaticContainer;
@@ -35,7 +36,6 @@ class LanguagesManager extends \Piwik\Plugin
public function registerEvents()
{
return array(
- 'AssetManager.getJavaScriptFiles' => 'getJsFiles',
'Config.NoConfigurationFile' => 'initLanguage',
'Request.dispatchCoreAndPluginUpdatesScreen' => 'initLanguage',
'Request.dispatch' => 'initLanguage',
@@ -57,13 +57,6 @@ class LanguagesManager extends \Piwik\Plugin
$allTablesInstalled[] = Common::prefixTable('user_language');
}
- public function getJsFiles(&$jsFiles)
- {
- $jsFiles[] = "plugins/LanguagesManager/angularjs/languageselector/languageselector.directive.js";
- $jsFiles[] = "plugins/LanguagesManager/angularjs/translationsearch/translationsearch.controller.js";
- $jsFiles[] = "plugins/LanguagesManager/angularjs/translationsearch/translationsearch.directive.js";
- }
-
/**
* Adds the languages drop-down list to topbars other than the main one rendered
* in CoreHome/templates/top_bar.twig. The 'other' topbars are on the Installation
@@ -73,7 +66,8 @@ class LanguagesManager extends \Piwik\Plugin
{
// piwik object & scripts aren't loaded in 'other' topbars
$str .= "<script type='text/javascript'>if (!window.piwik) window.piwik={};</script>";
- $str .= "<script type='text/javascript' src='plugins/LanguagesManager/angularjs/languageselector/languageselector.directive.js'></script>";
+ $file = PluginUmdAssetFetcher::getUmdFileToUseForPlugin('LanguagesManager');
+ $str .= "<script type='text/javascript' src='$file' defer></script>";
$str .= $this->getLanguagesSelector();
}
diff --git a/plugins/LanguagesManager/angularjs/languageselector/languageselector.directive.js b/plugins/LanguagesManager/angularjs/languageselector/languageselector.directive.js
deleted file mode 100644
index 3eddb08839..0000000000
--- a/plugins/LanguagesManager/angularjs/languageselector/languageselector.directive.js
+++ /dev/null
@@ -1,36 +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
- */
-
-/**
- * Usage:
- * <div class="languageSelection">
- * </div>
- */
-(function () {
- angular.module('piwikApp').directive('languageSelection', languageSelection);
-
- function languageSelection() {
-
- return {
- restrict: 'C',
- link: function(scope, element, attr, ctrl) {
-
- function postLanguageChange () {
- var value = $(this).attr('value');
- if (value) {
- element.find('#language').val(value).parents('form').submit();
- }
- }
-
- element.on('click', 'a[value]', postLanguageChange);
- scope.$on('$destroy', function() {
- element.off('click', 'a[value]', postLanguageChange);
- });
- }
- };
- }
-})(); \ No newline at end of file
diff --git a/plugins/LanguagesManager/angularjs/translationsearch/translationsearch.controller.js b/plugins/LanguagesManager/angularjs/translationsearch/translationsearch.controller.js
deleted file mode 100644
index 8c6ed08564..0000000000
--- a/plugins/LanguagesManager/angularjs/translationsearch/translationsearch.controller.js
+++ /dev/null
@@ -1,68 +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
- */
-(function () {
- angular.module('piwikApp').controller('TranslationSearchController', TranslationSearchController);
-
- TranslationSearchController.$inject = ['piwikApi'];
-
- function TranslationSearchController(piwikApi) {
-
- function fetchTranslations(languageCode) {
- piwikApi.fetch({
- method: 'LanguagesManager.getTranslationsForLanguage',
- filter_limit: -1,
- languageCode: languageCode
- }).then(function (response) {
- if (response) {
- if (languageCode === 'en') {
- vm.existingTranslations = response;
- } else {
- vm.compareTranslations = {};
- angular.forEach(response, function (translation) {
- vm.compareTranslations[translation.label] = translation.value;
- });
- }
- }
- });
- }
-
- function fetchLanguages() {
- piwikApi.fetch({
- method: 'LanguagesManager.getAvailableLanguagesInfo',
- filter_limit: -1
- }).then(function (languages) {
- vm.languages = [{key: '', value: 'None'}];
- if (languages) {
- angular.forEach(languages, function (language) {
- if (language.code === 'en') {
- return;
- }
- vm.languages.push({key: language.code, value: language.name});
- });
- }
- });
- }
-
- var vm = this;
- vm.compareTranslations = null;
- vm.existingTranslations = [];
- vm.languages = [];
- vm.compareLanguage = '';
-
- this.doCompareLanguage = function () {
- if (vm.compareLanguage) {
- vm.compareTranslations = null;
- fetchTranslations(vm.compareLanguage);
- }
- };
-
- fetchTranslations('en');
-
- fetchLanguages();
-
- }
-})(); \ No newline at end of file
diff --git a/plugins/LanguagesManager/angularjs/translationsearch/translationsearch.directive.html b/plugins/LanguagesManager/angularjs/translationsearch/translationsearch.directive.html
deleted file mode 100644
index e56b0d15ea..0000000000
--- a/plugins/LanguagesManager/angularjs/translationsearch/translationsearch.directive.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<div>
-
- <p>
- This page helps you to find existing translations that you can reuse in your Plugin.
- If you want to know more about translations have a look at our <a href="https://developer.matomo.org/guides/internationalization" rel="noreferrer noopener" target="_blank">Internationalization guide</a>.
- Enter a search term to find translations and their corresponding keys:
- </p>
-
- <div piwik-field uicontrol="text" name="alias"
- inline-help="Search for English translation. Max 1000 results will be shown."
- ng-model="translationSearch.searchTerm"
- placeholder="Search for English translation">
- </div>
-
- <div piwik-field uicontrol="select" name="translationSearch.compareLanguage"
- inline-help="Optionally select a language to compare the English language with."
- ng-model="translationSearch.compareLanguage"
- ng-change="translationSearch.doCompareLanguage()"
- options='translationSearch.languages'>
- </div>
-
- <br />
- <br />
-
- <table piwik-content-table
- ng-show="translationSearch.searchTerm"
- style="word-break: break-all;">
- <thead>
- <tr>
- <th style="width:250px;">Key</th>
- <th>English translation</th>
- <th ng-show="translationSearch.compareLanguage && translationSearch.compareTranslations">Compare translation</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="translation in translationSearch.existingTranslations | filter:translationSearch.searchTerm | limitTo: 1000">
- <td>{{ translation.label }}</td>
- <td>{{ translation.value }}</td>
- <td ng-show="translationSearch.compareLanguage && translationSearch.compareTranslations">{{ translationSearch.compareTranslations[translation.label] }}</td>
- </tr>
- </tbody>
- </table>
-
-</div>
diff --git a/plugins/LanguagesManager/angularjs/translationsearch/translationsearch.directive.js b/plugins/LanguagesManager/angularjs/translationsearch/translationsearch.directive.js
deleted file mode 100644
index 96d9a247ce..0000000000
--- a/plugins/LanguagesManager/angularjs/translationsearch/translationsearch.directive.js
+++ /dev/null
@@ -1,31 +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
- */
-
-/**
- * Usage:
- *
- * <div piwik-translation-search></div>
- *
- * Will show a text box which allows the user to search for translation keys and actual translations. Currently,
- * only english is supported.
- */
-(function () {
- angular.module('piwikApp').directive('piwikTranslationSearch', piwikTranslationSearch);
-
- piwikTranslationSearch.$inject = ['piwik'];
-
- function piwikTranslationSearch(piwik){
-
- return {
- restrict: 'A',
- scope: {},
- templateUrl: 'plugins/LanguagesManager/angularjs/translationsearch/translationsearch.directive.html?cb=' + piwik.cacheBuster,
- controller: 'TranslationSearchController',
- controllerAs: 'translationSearch'
- };
- }
-})(); \ No newline at end of file
diff --git a/plugins/LanguagesManager/templates/searchTranslation.twig b/plugins/LanguagesManager/templates/searchTranslation.twig
index d2b040f1b9..c8ed0140db 100644
--- a/plugins/LanguagesManager/templates/searchTranslation.twig
+++ b/plugins/LanguagesManager/templates/searchTranslation.twig
@@ -4,8 +4,13 @@
{% block content %}
- <div piwik-content-block content-title="{{ title|e('html_attr') }}" feature="true">
- <div piwik-translation-search></div>
+ <div
+ vue-entry="CoreHome.ContentBlock"
+ vue-components="LanguagesManager.TranslationSearch"
+ content-title="{{ title|json_encode|e('html_attr') }}"
+ feature="{{ 'true'|json_encode }}"
+ >
+ <translation-search />
</div>
{% endblock %}
diff --git a/plugins/LanguagesManager/vue/dist/LanguagesManager.umd.js b/plugins/LanguagesManager/vue/dist/LanguagesManager.umd.js
new file mode 100644
index 0000000000..0273a089d1
--- /dev/null
+++ b/plugins/LanguagesManager/vue/dist/LanguagesManager.umd.js
@@ -0,0 +1,401 @@
+(function webpackUniversalModuleDefinition(root, factory) {
+ if(typeof exports === 'object' && typeof module === 'object')
+ module.exports = factory(require("CoreHome"), require("vue"));
+ else if(typeof define === 'function' && define.amd)
+ define(["CoreHome", ], factory);
+ else if(typeof exports === 'object')
+ exports["LanguagesManager"] = factory(require("CoreHome"), require("vue"));
+ else
+ root["LanguagesManager"] = factory(root["CoreHome"], root["Vue"]);
+})((typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__19dc__, __WEBPACK_EXTERNAL_MODULE__8bbf__) {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId]) {
+/******/ return installedModules[moduleId].exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ i: moduleId,
+/******/ l: false,
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ // Flag the module as loaded
+/******/ module.l = true;
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/******/
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = modules;
+/******/
+/******/ // expose the module cache
+/******/ __webpack_require__.c = installedModules;
+/******/
+/******/ // define getter function for harmony exports
+/******/ __webpack_require__.d = function(exports, name, getter) {
+/******/ if(!__webpack_require__.o(exports, name)) {
+/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ }
+/******/ };
+/******/
+/******/ // define __esModule on exports
+/******/ __webpack_require__.r = function(exports) {
+/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ }
+/******/ Object.defineProperty(exports, '__esModule', { value: true });
+/******/ };
+/******/
+/******/ // create a fake namespace object
+/******/ // mode & 1: value is a module id, require it
+/******/ // mode & 2: merge all properties of value into the ns
+/******/ // mode & 4: return value when already ns object
+/******/ // mode & 8|1: behave like require
+/******/ __webpack_require__.t = function(value, mode) {
+/******/ if(mode & 1) value = __webpack_require__(value);
+/******/ if(mode & 8) return value;
+/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ var ns = Object.create(null);
+/******/ __webpack_require__.r(ns);
+/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ return ns;
+/******/ };
+/******/
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function getDefault() { return module['default']; } :
+/******/ function getModuleExports() { return module; };
+/******/ __webpack_require__.d(getter, 'a', getter);
+/******/ return getter;
+/******/ };
+/******/
+/******/ // Object.prototype.hasOwnProperty.call
+/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ // __webpack_public_path__
+/******/ __webpack_require__.p = "plugins/LanguagesManager/vue/dist/";
+/******/
+/******/
+/******/ // Load entry module and return exports
+/******/ return __webpack_require__(__webpack_require__.s = "fae3");
+/******/ })
+/************************************************************************/
+/******/ ({
+
+/***/ "19dc":
+/***/ (function(module, exports) {
+
+module.exports = __WEBPACK_EXTERNAL_MODULE__19dc__;
+
+/***/ }),
+
+/***/ "8bbf":
+/***/ (function(module, exports) {
+
+module.exports = __WEBPACK_EXTERNAL_MODULE__8bbf__;
+
+/***/ }),
+
+/***/ "fae3":
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+// ESM COMPAT FLAG
+__webpack_require__.r(__webpack_exports__);
+
+// EXPORTS
+__webpack_require__.d(__webpack_exports__, "TranslationSearch", function() { return /* reexport */ TranslationSearch; });
+__webpack_require__.d(__webpack_exports__, "LanguageSelector", function() { return /* reexport */ LanguageSelector; });
+
+// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/setPublicPath.js
+// This file is imported into lib/wc client bundles.
+
+if (typeof window !== 'undefined') {
+ var currentScript = window.document.currentScript
+ if (false) { var getCurrentScript; }
+
+ var src = currentScript && currentScript.src.match(/(.+\/)[^/]+\.js(\?.*)?$/)
+ if (src) {
+ __webpack_require__.p = src[1] // eslint-disable-line
+ }
+}
+
+// Indicate to webpack that this file can be concatenated
+/* harmony default export */ var setPublicPath = (null);
+
+// CONCATENATED MODULE: ./plugins/LanguagesManager/vue/src/LanguageSelector/LanguageSelector.ts
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+var _window = window,
+ $ = _window.$;
+
+function postLanguageChange(element, event) {
+ var value = $(event.target).attr('value');
+
+ if (value) {
+ $(element).find('#language').val(value).parents('form').submit();
+ }
+}
+
+/* harmony default export */ var LanguageSelector = ({
+ mounted: function mounted(el, binding) {
+ binding.value.onClick = postLanguageChange.bind(null, el);
+ $(el).on('click', 'a[value]', binding.value.onClick);
+ },
+ unmounted: function unmounted(el, binding) {
+ $(el).off('click', 'a[value]', binding.value.onClick);
+ }
+});
+// CONCATENATED MODULE: ./plugins/LanguagesManager/vue/src/LanguageSelector/LanguageSelector.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
+ */
+
+
+function languageSelection() {
+ return {
+ restrict: 'C',
+ link: function languageSelectionLink(scope, element) {
+ var binding = {
+ instance: null,
+ value: {},
+ oldValue: null,
+ modifiers: {},
+ dir: {}
+ };
+ LanguageSelector.mounted(element[0], binding);
+ element.on('$destroy', function () {
+ LanguageSelector.unmounted(element[0], binding);
+ });
+ }
+ };
+}
+
+window.angular.module('piwikApp').directive('languageSelection', languageSelection);
+// EXTERNAL MODULE: external "CoreHome"
+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/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.vue?vue&type=template&id=3d477584
+
+
+var _hoisted_1 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("p", null, [/*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createTextVNode"])(" This page helps you to find existing translations that you can reuse in your Plugin. If you want to know more about translations have a look at our "), /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("a", {
+ href: "https://developer.matomo.org/guides/internationalization",
+ rel: "noreferrer noopener",
+ target: "_blank"
+}, "Internationalization guide"), /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createTextVNode"])(". Enter a search term to find translations and their corresponding keys: ")], -1);
+
+var _hoisted_2 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("br", null, null, -1);
+
+var _hoisted_3 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("br", null, null, -1);
+
+var _hoisted_4 = {
+ style: {
+ "word-break": "break-all"
+ }
+};
+
+var _hoisted_5 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("th", {
+ style: {
+ "width": "250px"
+ }
+}, "Key", -1);
+
+var _hoisted_6 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("th", null, "English translation", -1);
+
+var _hoisted_7 = {
+ key: 0
+};
+function render(_ctx, _cache, $props, $setup, $data, $options) {
+ var _component_Field = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("Field");
+
+ var _directive_content_table = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveDirective"])("content-table");
+
+ return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", null, [_hoisted_1, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Field, {
+ uicontrol: "text",
+ name: "alias",
+ "inline-help": "Search for English translation. Max 1000 results will be shown.",
+ placeholder: "Search for English translation",
+ modelValue: _ctx.searchTerm,
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = function ($event) {
+ return _ctx.searchTerm = $event;
+ })
+ }, null, 8, ["modelValue"])]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Field, {
+ uicontrol: "select",
+ name: "translationSearch.compareLanguage",
+ "inline-help": "Optionally select a language to compare the English language with.",
+ "model-value": _ctx.compareLanguage,
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = function ($event) {
+ _ctx.compareLanguage = $event;
+
+ _ctx.doCompareLanguage();
+ }),
+ options: _ctx.languages
+ }, null, 8, ["model-value", "options"])]), _hoisted_2, _hoisted_3, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withDirectives"])(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("table", _hoisted_4, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("thead", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("tr", null, [_hoisted_5, _hoisted_6, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withDirectives"])(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("th", null, "Compare translation", 512), [[external_commonjs_vue_commonjs2_vue_root_Vue_["vShow"], _ctx.compareLanguage && _ctx.compareTranslations]])])]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("tbody", null, [(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])(external_commonjs_vue_commonjs2_vue_root_Vue_["Fragment"], null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["renderList"])(_ctx.filteredTranslations, function (translation) {
+ return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("tr", {
+ key: translation.label
+ }, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("td", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(translation.label), 1), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("td", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(translation.value), 1), _ctx.compareLanguage && _ctx.compareTranslations ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("td", _hoisted_7, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.compareTranslations[translation.label]), 1)) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true)]);
+ }), 128))])], 512), [[external_commonjs_vue_commonjs2_vue_root_Vue_["vShow"], _ctx.searchTerm], [_directive_content_table]])]);
+}
+// CONCATENATED MODULE: ./plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.vue?vue&type=template&id=3d477584
+
+// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-typescript/node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/@vue/cli-plugin-typescript/node_modules/ts-loader??ref--14-2!./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/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.vue?vue&type=script&lang=ts
+
+ // loading a component this way since during Installation we don't want to load CorePluginsAdmin
+// just for the language selector directive
+
+var Field = Object(external_CoreHome_["useExternalPluginComponent"])('CorePluginsAdmin', 'Field');
+/* harmony default export */ var TranslationSearchvue_type_script_lang_ts = (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["defineComponent"])({
+ components: {
+ Field: Field
+ },
+ directives: {
+ ContentTable: external_CoreHome_["ContentTable"]
+ },
+ data: function data() {
+ return {
+ compareTranslations: null,
+ existingTranslations: [],
+ languages: [],
+ compareLanguage: '',
+ searchTerm: ''
+ };
+ },
+ created: function created() {
+ this.fetchTranslations('en');
+ this.fetchLanguages();
+ },
+ methods: {
+ fetchTranslations: function fetchTranslations(languageCode) {
+ var _this = this;
+
+ external_CoreHome_["AjaxHelper"].fetch({
+ method: 'LanguagesManager.getTranslationsForLanguage',
+ filter_limit: -1,
+ languageCode: languageCode
+ }).then(function (response) {
+ if (!response) {
+ return;
+ }
+
+ if (languageCode === 'en') {
+ _this.existingTranslations = response;
+ } else {
+ _this.compareTranslations = {};
+ response.forEach(function (translation) {
+ _this.compareTranslations[translation.label] = translation.value;
+ });
+ }
+ });
+ },
+ fetchLanguages: function fetchLanguages() {
+ var _this2 = this;
+
+ external_CoreHome_["AjaxHelper"].fetch({
+ method: 'LanguagesManager.getAvailableLanguagesInfo',
+ filter_limit: -1
+ }).then(function (languages) {
+ _this2.languages = [{
+ key: '',
+ value: 'None'
+ }];
+
+ if (languages) {
+ languages.forEach(function (language) {
+ if (language.code === 'en') {
+ return;
+ }
+
+ _this2.languages.push({
+ key: language.code,
+ value: language.name
+ });
+ });
+ }
+ });
+ },
+ doCompareLanguage: function doCompareLanguage() {
+ if (this.compareLanguage) {
+ this.compareTranslations = null;
+ this.fetchTranslations(this.compareLanguage);
+ }
+ }
+ },
+ computed: {
+ filteredTranslations: function filteredTranslations() {
+ var _this3 = this;
+
+ var filtered = this.existingTranslations.filter(function (t) {
+ return t.label.includes(_this3.searchTerm) || t.value.includes(_this3.searchTerm);
+ });
+ filtered = filtered.slice(0, 1000);
+ return filtered;
+ }
+ }
+}));
+// CONCATENATED MODULE: ./plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.vue?vue&type=script&lang=ts
+
+// CONCATENATED MODULE: ./plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.vue
+
+
+
+TranslationSearchvue_type_script_lang_ts.render = render
+
+/* harmony default export */ var TranslationSearch = (TranslationSearchvue_type_script_lang_ts);
+// CONCATENATED MODULE: ./plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.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 TranslationSearch_adapter = (Object(external_CoreHome_["createAngularJsAdapter"])({
+ component: TranslationSearch,
+ directiveName: 'piwikTranslationSearch'
+}));
+// CONCATENATED MODULE: ./plugins/LanguagesManager/vue/src/index.ts
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+
+
+
+// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/entry-lib-no-default.js
+
+
+
+
+/***/ })
+
+/******/ });
+});
+//# sourceMappingURL=LanguagesManager.umd.js.map \ No newline at end of file
diff --git a/plugins/LanguagesManager/vue/dist/LanguagesManager.umd.min.js b/plugins/LanguagesManager/vue/dist/LanguagesManager.umd.min.js
new file mode 100644
index 0000000000..e07348f412
--- /dev/null
+++ b/plugins/LanguagesManager/vue/dist/LanguagesManager.umd.min.js
@@ -0,0 +1,20 @@
+(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["LanguagesManager"]=t(require("CoreHome"),require("vue")):e["LanguagesManager"]=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/LanguagesManager/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,"TranslationSearch",(function(){return T})),n.d(t,"LanguageSelector",(function(){return c})),"undefined"!==typeof window){var a=window.document.currentScript,o=a&&a.src.match(/(.+\/)[^/]+\.js(\?.*)?$/);o&&(n.p=o[1])}var r=window,l=r.$;
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */function i(e,t){var n=l(t.target).attr("value");n&&l(e).find("#language").val(n).parents("form").submit()}var c={mounted:function(e,t){t.value.onClick=i.bind(null,e),l(e).on("click","a[value]",t.value.onClick)},unmounted:function(e,t){l(e).off("click","a[value]",t.value.onClick)}};
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */function u(){return{restrict:"C",link:function(e,t){var n={instance:null,value:{},oldValue:null,modifiers:{},dir:{}};c.mounted(t[0],n),t.on("$destroy",(function(){c.unmounted(t[0],n)}))}}}window.angular.module("piwikApp").directive("languageSelection",u);var s=n("19dc"),d=n("8bbf"),f=Object(d["createElementVNode"])("p",null,[Object(d["createTextVNode"])(" This page helps you to find existing translations that you can reuse in your Plugin. If you want to know more about translations have a look at our "),Object(d["createElementVNode"])("a",{href:"https://developer.matomo.org/guides/internationalization",rel:"noreferrer noopener",target:"_blank"},"Internationalization guide"),Object(d["createTextVNode"])(". Enter a search term to find translations and their corresponding keys: ")],-1),g=Object(d["createElementVNode"])("br",null,null,-1),m=Object(d["createElementVNode"])("br",null,null,-1),p={style:{"word-break":"break-all"}},b=Object(d["createElementVNode"])("th",{style:{width:"250px"}},"Key",-1),h=Object(d["createElementVNode"])("th",null,"English translation",-1),v={key:0};function j(e,t,n,a,o,r){var l=Object(d["resolveComponent"])("Field"),i=Object(d["resolveDirective"])("content-table");return Object(d["openBlock"])(),Object(d["createElementBlock"])("div",null,[f,Object(d["createElementVNode"])("div",null,[Object(d["createVNode"])(l,{uicontrol:"text",name:"alias","inline-help":"Search for English translation. Max 1000 results will be shown.",placeholder:"Search for English translation",modelValue:e.searchTerm,"onUpdate:modelValue":t[0]||(t[0]=function(t){return e.searchTerm=t})},null,8,["modelValue"])]),Object(d["createElementVNode"])("div",null,[Object(d["createVNode"])(l,{uicontrol:"select",name:"translationSearch.compareLanguage","inline-help":"Optionally select a language to compare the English language with.","model-value":e.compareLanguage,"onUpdate:modelValue":t[1]||(t[1]=function(t){e.compareLanguage=t,e.doCompareLanguage()}),options:e.languages},null,8,["model-value","options"])]),g,m,Object(d["withDirectives"])(Object(d["createElementVNode"])("table",p,[Object(d["createElementVNode"])("thead",null,[Object(d["createElementVNode"])("tr",null,[b,h,Object(d["withDirectives"])(Object(d["createElementVNode"])("th",null,"Compare translation",512),[[d["vShow"],e.compareLanguage&&e.compareTranslations]])])]),Object(d["createElementVNode"])("tbody",null,[(Object(d["openBlock"])(!0),Object(d["createElementBlock"])(d["Fragment"],null,Object(d["renderList"])(e.filteredTranslations,(function(t){return Object(d["openBlock"])(),Object(d["createElementBlock"])("tr",{key:t.label},[Object(d["createElementVNode"])("td",null,Object(d["toDisplayString"])(t.label),1),Object(d["createElementVNode"])("td",null,Object(d["toDisplayString"])(t.value),1),e.compareLanguage&&e.compareTranslations?(Object(d["openBlock"])(),Object(d["createElementBlock"])("td",v,Object(d["toDisplayString"])(e.compareTranslations[t.label]),1)):Object(d["createCommentVNode"])("",!0)])})),128))])],512),[[d["vShow"],e.searchTerm],[i]])])}var O=Object(s["useExternalPluginComponent"])("CorePluginsAdmin","Field"),y=Object(d["defineComponent"])({components:{Field:O},directives:{ContentTable:s["ContentTable"]},data:function(){return{compareTranslations:null,existingTranslations:[],languages:[],compareLanguage:"",searchTerm:""}},created:function(){this.fetchTranslations("en"),this.fetchLanguages()},methods:{fetchTranslations:function(e){var t=this;s["AjaxHelper"].fetch({method:"LanguagesManager.getTranslationsForLanguage",filter_limit:-1,languageCode:e}).then((function(n){n&&("en"===e?t.existingTranslations=n:(t.compareTranslations={},n.forEach((function(e){t.compareTranslations[e.label]=e.value}))))}))},fetchLanguages:function(){var e=this;s["AjaxHelper"].fetch({method:"LanguagesManager.getAvailableLanguagesInfo",filter_limit:-1}).then((function(t){e.languages=[{key:"",value:"None"}],t&&t.forEach((function(t){"en"!==t.code&&e.languages.push({key:t.code,value:t.name})}))}))},doCompareLanguage:function(){this.compareLanguage&&(this.compareTranslations=null,this.fetchTranslations(this.compareLanguage))}},computed:{filteredTranslations:function(){var e=this,t=this.existingTranslations.filter((function(t){return t.label.includes(e.searchTerm)||t.value.includes(e.searchTerm)}));return t=t.slice(0,1e3),t}}});y.render=j;var T=y;
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */Object(s["createAngularJsAdapter"])({component:T,directiveName:"piwikTranslationSearch"})}})}));
+//# sourceMappingURL=LanguagesManager.umd.min.js.map \ No newline at end of file
diff --git a/plugins/LanguagesManager/vue/dist/umd.metadata.json b/plugins/LanguagesManager/vue/dist/umd.metadata.json
new file mode 100644
index 0000000000..9ecfcc0456
--- /dev/null
+++ b/plugins/LanguagesManager/vue/dist/umd.metadata.json
@@ -0,0 +1,5 @@
+{
+ "dependsOn": [
+ "CoreHome"
+ ]
+} \ No newline at end of file
diff --git a/plugins/LanguagesManager/vue/src/LanguageSelector/LanguageSelector.adapter.ts b/plugins/LanguagesManager/vue/src/LanguageSelector/LanguageSelector.adapter.ts
new file mode 100644
index 0000000000..bd8076421f
--- /dev/null
+++ b/plugins/LanguagesManager/vue/src/LanguageSelector/LanguageSelector.adapter.ts
@@ -0,0 +1,31 @@
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+import { IScope } from 'angular';
+import LanguageSelector from './LanguageSelector';
+
+function languageSelection() {
+ return {
+ restrict: 'C',
+ link: function languageSelectionLink(scope: IScope, element: JQuery) {
+ const binding = {
+ instance: null,
+ value: {},
+ oldValue: null,
+ modifiers: {},
+ dir: {},
+ };
+
+ LanguageSelector.mounted(element[0], binding);
+ element.on('$destroy', () => {
+ LanguageSelector.unmounted(element[0], binding);
+ });
+ },
+ };
+}
+
+window.angular.module('piwikApp').directive('languageSelection', languageSelection);
diff --git a/plugins/LanguagesManager/vue/src/LanguageSelector/LanguageSelector.ts b/plugins/LanguagesManager/vue/src/LanguageSelector/LanguageSelector.ts
new file mode 100644
index 0000000000..e2f622998b
--- /dev/null
+++ b/plugins/LanguagesManager/vue/src/LanguageSelector/LanguageSelector.ts
@@ -0,0 +1,36 @@
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+import { DirectiveBinding } from 'vue';
+import ClickEvent = JQuery.ClickEvent;
+
+const { $ } = window;
+
+interface LanguageSelectorBinding {
+ onClick?: (event: ClickEvent) => void;
+}
+
+function postLanguageChange(element: HTMLElement, event: ClickEvent) {
+ const value = $(event.target).attr('value');
+ if (value) {
+ $(element)
+ .find('#language')
+ .val(value)
+ .parents('form')
+ .submit();
+ }
+}
+
+export default {
+ mounted(el: HTMLElement, binding: DirectiveBinding<LanguageSelectorBinding>): void {
+ binding.value.onClick = postLanguageChange.bind(null, el);
+ $(el).on('click', 'a[value]', binding.value.onClick!);
+ },
+ unmounted(el: HTMLElement, binding: DirectiveBinding<LanguageSelectorBinding>): void {
+ $(el).off('click', 'a[value]', binding.value.onClick!);
+ },
+};
diff --git a/plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.adapter.ts b/plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.adapter.ts
new file mode 100644
index 0000000000..c32abdf102
--- /dev/null
+++ b/plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.adapter.ts
@@ -0,0 +1,14 @@
+/*!
+ * 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 TranslationSearch from './TranslationSearch.vue';
+
+export default createAngularJsAdapter({
+ component: TranslationSearch,
+ directiveName: 'piwikTranslationSearch',
+});
diff --git a/plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.vue b/plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.vue
new file mode 100644
index 0000000000..c84c02df02
--- /dev/null
+++ b/plugins/LanguagesManager/vue/src/TranslationSearch/TranslationSearch.vue
@@ -0,0 +1,183 @@
+<!--
+ 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>
+ <p>
+ This page helps you to find existing translations that you can reuse in your Plugin.
+ If you want to know more about translations have a look at our
+ <a
+ href="https://developer.matomo.org/guides/internationalization"
+ rel="noreferrer noopener"
+ target="_blank"
+ >Internationalization guide</a>.
+ Enter a search term to find translations and their corresponding keys:
+ </p>
+ <div>
+ <Field
+ uicontrol="text"
+ name="alias"
+ inline-help="Search for English translation. Max 1000 results will be shown."
+ placeholder="Search for English translation"
+ v-model="searchTerm"
+ >
+ </Field>
+ </div>
+ <div>
+ <Field
+ uicontrol="select"
+ name="translationSearch.compareLanguage"
+ inline-help="Optionally select a language to compare the English language with."
+ :model-value="compareLanguage"
+ @update:model-value="compareLanguage = $event; doCompareLanguage()"
+ :options="languages"
+ >
+ </Field>
+ </div>
+ <br />
+ <br />
+ <table
+ style="word-break: break-all;"
+ v-show="searchTerm"
+ v-content-table
+ >
+ <thead>
+ <tr>
+ <th style="width:250px;">Key</th>
+ <th>English translation</th>
+ <th v-show="compareLanguage && compareTranslations">Compare translation</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="translation in filteredTranslations"
+ :key="translation.label"
+ >
+ <td>{{ translation.label }}</td>
+ <td>{{ translation.value }}</td>
+ <td v-if="compareLanguage && compareTranslations">
+ {{ compareTranslations[translation.label] }}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import { AjaxHelper, ContentTable, useExternalPluginComponent } from 'CoreHome';
+
+interface Option {
+ key: string;
+ value: string;
+}
+
+interface Translation {
+ label: string;
+ value: string;
+}
+
+interface Language {
+ code: string;
+ name: string;
+}
+
+interface TranslationSearchState {
+ compareTranslations: Record<string, string>|null;
+ existingTranslations: Translation[];
+ languages: Option[];
+ compareLanguage: string;
+ searchTerm: string;
+}
+
+// loading a component this way since during Installation we don't want to load CorePluginsAdmin
+// just for the language selector directive
+const Field = useExternalPluginComponent('CorePluginsAdmin', 'Field');
+
+export default defineComponent({
+ components: {
+ Field,
+ },
+ directives: {
+ ContentTable,
+ },
+ data(): TranslationSearchState {
+ return {
+ compareTranslations: null,
+ existingTranslations: [],
+ languages: [],
+ compareLanguage: '',
+ searchTerm: '',
+ };
+ },
+ created() {
+ this.fetchTranslations('en');
+ this.fetchLanguages();
+ },
+ methods: {
+ fetchTranslations(languageCode: string) {
+ AjaxHelper.fetch<Translation[]>({
+ method: 'LanguagesManager.getTranslationsForLanguage',
+ filter_limit: -1,
+ languageCode,
+ }).then((response) => {
+ if (!response) {
+ return;
+ }
+
+ if (languageCode === 'en') {
+ this.existingTranslations = response;
+ } else {
+ this.compareTranslations = {};
+ response.forEach((translation) => {
+ this.compareTranslations![translation.label] = translation.value;
+ });
+ }
+ });
+ },
+ fetchLanguages() {
+ AjaxHelper.fetch<Language[]>({
+ method: 'LanguagesManager.getAvailableLanguagesInfo',
+ filter_limit: -1,
+ }).then((languages) => {
+ this.languages = [{
+ key: '',
+ value: 'None',
+ }];
+
+ if (languages) {
+ languages.forEach((language) => {
+ if (language.code === 'en') {
+ return;
+ }
+
+ this.languages.push({
+ key: language.code,
+ value: language.name,
+ });
+ });
+ }
+ });
+ },
+ doCompareLanguage() {
+ if (this.compareLanguage) {
+ this.compareTranslations = null;
+ this.fetchTranslations(this.compareLanguage);
+ }
+ },
+ },
+ computed: {
+ filteredTranslations(): Translation[] {
+ let filtered = this.existingTranslations.filter(
+ (t) => t.label.includes(this.searchTerm) || t.value.includes(this.searchTerm),
+ );
+ filtered = filtered.slice(0, 1000);
+ return filtered;
+ },
+ },
+});
+</script>
diff --git a/plugins/LanguagesManager/vue/src/index.ts b/plugins/LanguagesManager/vue/src/index.ts
new file mode 100644
index 0000000000..d31cd92ab9
--- /dev/null
+++ b/plugins/LanguagesManager/vue/src/index.ts
@@ -0,0 +1,12 @@
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+import './LanguageSelector/LanguageSelector.adapter';
+import './TranslationSearch/TranslationSearch.adapter';
+
+export { default as TranslationSearch } from './TranslationSearch/TranslationSearch.vue';
+export { default as LanguageSelector } from './LanguageSelector/LanguageSelector.ts';
diff --git a/plugins/Morpheus/javascripts/piwikHelper.js b/plugins/Morpheus/javascripts/piwikHelper.js
index 2c232ea666..4a544e22f4 100644
--- a/plugins/Morpheus/javascripts/piwikHelper.js
+++ b/plugins/Morpheus/javascripts/piwikHelper.js
@@ -155,18 +155,27 @@ window.piwikHelper = {
// initial call for 'body' later in this file
compileVueEntryComponents: function (selector) {
function toCamelCase(arg) {
- return arg.substring(0, 1) + arg.substring(1)
- .replace(/-[a-z]/g, function (s) { return s.substring(1).toUpperCase(); });
+ return arg[0] + arg.substring(1)
+ .replace(/-[a-z]/g, function (s) { return s[1].toUpperCase(); });
+ }
+
+ function toKebabCase(arg) {
+ return arg[0].toLowerCase() + arg.substring(1)
+ .replace(/[A-Z]/g, function (s) { return '-' + s[0].toLowerCase(); });
}
$('[vue-entry]', selector).add($(selector).filter('[vue-entry]')).each(function () {
var entry = $(this).attr('vue-entry');
+ var componentsToRegister = $(this).attr('vue-components').split(/\s+/).filter(function (s) {
+ return !!s.length;
+ });
var parts = entry.split('.');
if (parts.length !== 2) {
throw new Error('Expects vue-entry to have format Plugin.Component, where Component is exported Vue component. Got: ' + entry);
}
+ var useExternalPluginComponent = CoreHome.useExternalPluginComponent;
var createVueApp = CoreHome.createVueApp;
var plugin = window[parts[0]];
if (!plugin) {
@@ -210,6 +219,19 @@ window.piwikHelper = {
}
});
app.component('root', component);
+
+ componentsToRegister.forEach(function (componentRef) {
+ var parts = componentRef.split('.');
+ var pluginName = parts[0];
+ var componentName = parts[1];
+
+ var component = useExternalPluginComponent(pluginName, componentName);
+
+ // the component is made available via kebab case, since casing is lost in HTML,
+ // and tag names will appear all lower case when vue processes them
+ app.component(toKebabCase(componentName), component);
+ });
+
app.mount(this);
this.addEventListener('matomoVueDestroy', function () {
diff --git a/plugins/UsersManager/vue/dist/UsersManager.umd.js b/plugins/UsersManager/vue/dist/UsersManager.umd.js
index d39e14ac58..a79c88744d 100644
--- a/plugins/UsersManager/vue/dist/UsersManager.umd.js
+++ b/plugins/UsersManager/vue/dist/UsersManager.umd.js
@@ -3592,38 +3592,38 @@ NewsletterSettingsvue_type_script_lang_ts.render = NewsletterSettingsvue_type_te
scope: {},
directiveName: 'matomoNewsletterSettings'
}));
-// 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/UsersManager/vue/src/PersonalSettings/PersonalSettings.vue?vue&type=template&id=d46d01d4
+// 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/UsersManager/vue/src/PersonalSettings/PersonalSettings.vue?vue&type=template&id=94ecac48
-var PersonalSettingsvue_type_template_id_d46d01d4_hoisted_1 = {
+var PersonalSettingsvue_type_template_id_94ecac48_hoisted_1 = {
id: "userSettingsTable"
};
-var PersonalSettingsvue_type_template_id_d46d01d4_hoisted_2 = {
+var PersonalSettingsvue_type_template_id_94ecac48_hoisted_2 = {
key: 0
};
-var PersonalSettingsvue_type_template_id_d46d01d4_hoisted_3 = {
+var PersonalSettingsvue_type_template_id_94ecac48_hoisted_3 = {
id: "languageHelp",
class: "inline-help-node"
};
-var PersonalSettingsvue_type_template_id_d46d01d4_hoisted_4 = {
+var PersonalSettingsvue_type_template_id_94ecac48_hoisted_4 = {
target: "_blank",
rel: "noreferrer noopener",
href: "https://matomo.org/translations/"
};
-var PersonalSettingsvue_type_template_id_d46d01d4_hoisted_5 = {
+var PersonalSettingsvue_type_template_id_94ecac48_hoisted_5 = {
class: "sites_autocomplete"
};
-var PersonalSettingsvue_type_template_id_d46d01d4_hoisted_6 = {
+var PersonalSettingsvue_type_template_id_94ecac48_hoisted_6 = {
class: "modal",
id: "confirmChangesWithPassword",
ref: "confirmChangesWithPasswordModal"
};
-var PersonalSettingsvue_type_template_id_d46d01d4_hoisted_7 = {
+var PersonalSettingsvue_type_template_id_94ecac48_hoisted_7 = {
class: "modal-content"
};
-var PersonalSettingsvue_type_template_id_d46d01d4_hoisted_8 = {
+var PersonalSettingsvue_type_template_id_94ecac48_hoisted_8 = {
class: "modal-footer"
};
-function PersonalSettingsvue_type_template_id_d46d01d4_render(_ctx, _cache, $props, $setup, $data, $options) {
+function PersonalSettingsvue_type_template_id_94ecac48_render(_ctx, _cache, $props, $setup, $data, $options) {
var _component_Field = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("Field");
var _component_SiteSelector = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("SiteSelector");
@@ -3639,7 +3639,7 @@ function PersonalSettingsvue_type_template_id_d46d01d4_render(_ctx, _cache, $pro
feature: 'true'
}, {
default: Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withCtx"])(function () {
- return [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withDirectives"])(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("form", PersonalSettingsvue_type_template_id_d46d01d4_hoisted_1, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Field, {
+ return [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withDirectives"])(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("form", PersonalSettingsvue_type_template_id_94ecac48_hoisted_1, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Field, {
uicontrol: "text",
name: "username",
title: _ctx.translate('General_Username'),
@@ -3649,7 +3649,7 @@ function PersonalSettingsvue_type_template_id_d46d01d4_render(_ctx, _cache, $pro
return _ctx.username = $event;
}),
"inline-help": _ctx.translate('UsersManager_YourUsernameCannotBeChanged')
- }, null, 8, ["title", "modelValue", "inline-help"])]), _ctx.isUsersAdminEnabled ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", PersonalSettingsvue_type_template_id_d46d01d4_hoisted_2, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Field, {
+ }, null, 8, ["title", "modelValue", "inline-help"])]), _ctx.isUsersAdminEnabled ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", PersonalSettingsvue_type_template_id_94ecac48_hoisted_2, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Field, {
uicontrol: "text",
name: "email",
"model-value": _ctx.email,
@@ -3659,7 +3659,7 @@ function PersonalSettingsvue_type_template_id_d46d01d4_render(_ctx, _cache, $pro
}),
maxlength: 100,
title: _ctx.translate('UsersManager_Email')
- }, null, 8, ["model-value", "title"])])) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", PersonalSettingsvue_type_template_id_d46d01d4_hoisted_3, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("a", PersonalSettingsvue_type_template_id_d46d01d4_hoisted_4, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('LanguagesManager_AboutPiwikTranslations')), 1)]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Field, {
+ }, null, 8, ["model-value", "title"])])) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", PersonalSettingsvue_type_template_id_94ecac48_hoisted_3, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("a", PersonalSettingsvue_type_template_id_94ecac48_hoisted_4, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('LanguagesManager_AboutPiwikTranslations')), 1)]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Field, {
uicontrol: "select",
name: "language",
modelValue: _ctx.language,
@@ -3688,7 +3688,7 @@ function PersonalSettingsvue_type_template_id_d46d01d4_render(_ctx, _cache, $pro
introduction: _ctx.translate('UsersManager_ReportToLoadByDefault'),
title: _ctx.translate('General_AllWebsitesDashboard'),
options: _ctx.defaultReportOptions
- }, null, 8, ["modelValue", "introduction", "title", "options"])]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", PersonalSettingsvue_type_template_id_d46d01d4_hoisted_5, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_SiteSelector, {
+ }, null, 8, ["modelValue", "introduction", "title", "options"])]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", PersonalSettingsvue_type_template_id_94ecac48_hoisted_5, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_SiteSelector, {
modelValue: _ctx.site,
"onUpdate:modelValue": _cache[5] || (_cache[5] = function ($event) {
return _ctx.site = $event;
@@ -3712,7 +3712,7 @@ function PersonalSettingsvue_type_template_id_d46d01d4_render(_ctx, _cache, $pro
return _ctx.save();
}),
saving: _ctx.loading
- }, null, 8, ["saving"]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", PersonalSettingsvue_type_template_id_d46d01d4_hoisted_6, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", PersonalSettingsvue_type_template_id_d46d01d4_hoisted_7, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("h2", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('UsersManager_ConfirmWithPassword')), 1), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Field, {
+ }, null, 8, ["saving"]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", PersonalSettingsvue_type_template_id_94ecac48_hoisted_6, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", PersonalSettingsvue_type_template_id_94ecac48_hoisted_7, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("h2", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('UsersManager_ConfirmWithPassword')), 1), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Field, {
uicontrol: "password",
name: "currentPassword",
autocomplete: false,
@@ -3722,7 +3722,7 @@ function PersonalSettingsvue_type_template_id_d46d01d4_render(_ctx, _cache, $pro
}),
"full-width": true,
title: _ctx.translate('UsersManager_YourCurrentPassword')
- }, null, 8, ["modelValue", "title"])])]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", PersonalSettingsvue_type_template_id_d46d01d4_hoisted_8, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("a", {
+ }, null, 8, ["modelValue", "title"])])]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", PersonalSettingsvue_type_template_id_94ecac48_hoisted_8, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("a", {
href: "",
class: "modal-action btn",
onClick: _cache[9] || (_cache[9] = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withModifiers"])(function ($event) {
@@ -3742,7 +3742,7 @@ function PersonalSettingsvue_type_template_id_d46d01d4_render(_ctx, _cache, $pro
_: 1
}, 8, ["content-title"]);
}
-// CONCATENATED MODULE: ./plugins/UsersManager/vue/src/PersonalSettings/PersonalSettings.vue?vue&type=template&id=d46d01d4
+// CONCATENATED MODULE: ./plugins/UsersManager/vue/src/PersonalSettings/PersonalSettings.vue?vue&type=template&id=94ecac48
// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-typescript/node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/@vue/cli-plugin-typescript/node_modules/ts-loader??ref--14-2!./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/UsersManager/vue/src/PersonalSettings/PersonalSettings.vue?vue&type=script&lang=ts
@@ -3785,7 +3785,7 @@ var PersonalSettingsvue_type_script_lang_ts_window = window,
required: true
},
defaultReport: {
- type: String,
+ type: [String, Number],
required: true
},
defaultReportOptions: {
@@ -3900,7 +3900,7 @@ var PersonalSettingsvue_type_script_lang_ts_window = window,
-PersonalSettingsvue_type_script_lang_ts.render = PersonalSettingsvue_type_template_id_d46d01d4_render
+PersonalSettingsvue_type_script_lang_ts.render = PersonalSettingsvue_type_template_id_94ecac48_render
/* harmony default export */ var PersonalSettings = (PersonalSettingsvue_type_script_lang_ts);
// CONCATENATED MODULE: ./plugins/UsersManager/vue/src/PersonalSettings/PersonalSettings.adapter.ts
diff --git a/plugins/UsersManager/vue/dist/UsersManager.umd.min.js b/plugins/UsersManager/vue/dist/UsersManager.umd.min.js
index ca332199e1..370dfc72c5 100644
--- a/plugins/UsersManager/vue/dist/UsersManager.umd.min.js
+++ b/plugins/UsersManager/vue/dist/UsersManager.umd.min.js
@@ -46,7 +46,7 @@
*
* @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */function ks(e,t,n,s,r,i){var o=Object(a["resolveComponent"])("Field"),l=Object(a["resolveComponent"])("SiteSelector"),c=Object(a["resolveComponent"])("SaveButton"),d=Object(a["resolveComponent"])("ContentBlock"),u=Object(a["resolveDirective"])("form");return Object(a["openBlock"])(),Object(a["createBlock"])(d,{"content-title":e.title,feature:"true"},{default:Object(a["withCtx"])((function(){return[Object(a["withDirectives"])(Object(a["createElementVNode"])("form",vs,[Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"text",name:"username",title:e.translate("General_Username"),disabled:!0,modelValue:e.username,"onUpdate:modelValue":t[0]||(t[0]=function(t){return e.username=t}),"inline-help":e.translate("UsersManager_YourUsernameCannotBeChanged")},null,8,["title","modelValue","inline-help"])]),e.isUsersAdminEnabled?(Object(a["openBlock"])(),Object(a["createElementBlock"])("div",Cs,[Object(a["createVNode"])(o,{uicontrol:"text",name:"email","model-value":e.email,"onUpdate:modelValue":t[1]||(t[1]=function(t){e.email=t,e.doesRequirePasswordConfirmation=!0}),maxlength:100,title:e.translate("UsersManager_Email")},null,8,["model-value","title"])])):Object(a["createCommentVNode"])("",!0),Object(a["createElementVNode"])("div",Ss,[Object(a["createElementVNode"])("a",Ns,Object(a["toDisplayString"])(e.translate("LanguagesManager_AboutPiwikTranslations")),1)]),Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"select",name:"language",modelValue:e.language,"onUpdate:modelValue":t[2]||(t[2]=function(t){return e.language=t}),title:e.translate("General_Language"),options:e.languageOptions,"inline-help":"#languageHelp"},null,8,["modelValue","title","options"])]),Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"select",name:"timeformat",modelValue:e.timeformat,"onUpdate:modelValue":t[3]||(t[3]=function(t){return e.timeformat=t}),title:e.translate("General_TimeFormat"),options:e.timeFormats},null,8,["modelValue","title","options"])]),Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"radio",name:"defaultReport",modelValue:e.theDefaultReport,"onUpdate:modelValue":t[4]||(t[4]=function(t){return e.theDefaultReport=t}),introduction:e.translate("UsersManager_ReportToLoadByDefault"),title:e.translate("General_AllWebsitesDashboard"),options:e.defaultReportOptions},null,8,["modelValue","introduction","title","options"])]),Object(a["createElementVNode"])("div",Us,[Object(a["createVNode"])(l,{modelValue:e.site,"onUpdate:modelValue":t[5]||(t[5]=function(t){return e.site=t}),"show-selected-site":!0,"switch-site-on-select":!1,"show-all-sites-item":!1,showselectedsite:!0,id:"defaultReportSiteSelector"},null,8,["modelValue"])]),Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"radio",name:"defaultDate",modelValue:e.theDefaultDate,"onUpdate:modelValue":t[6]||(t[6]=function(t){return e.theDefaultDate=t}),introduction:e.translate("UsersManager_ReportDateToLoadByDefault"),options:e.availableDefaultDates},null,8,["modelValue","introduction","options"])]),Object(a["createVNode"])(c,{onConfirm:t[7]||(t[7]=function(t){return e.save()}),saving:e.loading},null,8,["saving"]),Object(a["createElementVNode"])("div",ys,[Object(a["createElementVNode"])("div",Vs,[Object(a["createElementVNode"])("h2",null,Object(a["toDisplayString"])(e.translate("UsersManager_ConfirmWithPassword")),1),Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"password",name:"currentPassword",autocomplete:!1,modelValue:e.passwordCurrent,"onUpdate:modelValue":t[8]||(t[8]=function(t){return e.passwordCurrent=t}),"full-width":!0,title:e.translate("UsersManager_YourCurrentPassword")},null,8,["modelValue","title"])])]),Object(a["createElementVNode"])("div",Es,[Object(a["createElementVNode"])("a",{href:"",class:"modal-action btn",onClick:t[9]||(t[9]=Object(a["withModifiers"])((function(t){return e.save()}),["prevent"])),style:{"margin-right":"3.5px"}},Object(a["toDisplayString"])(e.translate("General_Ok")),1),Object(a["createElementVNode"])("a",{href:"",class:"modal-action modal-close modal-no",onClick:t[10]||(t[10]=Object(a["withModifiers"])((function(t){return e.passwordCurrent=""}),["prevent"]))},Object(a["toDisplayString"])(e.translate("General_Cancel")),1)])],512)],512),[[u]])]})),_:1},8,["content-title"])}var As=window,ws=As.$,Ts=Object(a["defineComponent"])({props:{isUsersAdminEnabled:{type:Boolean,required:!0},title:{type:String,required:!0},userLogin:{type:String,required:!0},userEmail:{type:String,required:!0},currentLanguageCode:{type:String,required:!0},languageOptions:{type:Object,required:!0},currentTimeformat:{type:Number,required:!0},timeFormats:{type:Object,required:!0},defaultReport:{type:String,required:!0},defaultReportOptions:{type:Object,required:!0},defaultReportIdSite:{type:[String,Number],required:!0},defaultReportSiteName:{type:String,required:!0},defaultDate:{type:String,required:!0},availableDefaultDates:{type:Object,required:!0}},components:{ContentBlock:i["ContentBlock"],SaveButton:h["SaveButton"],Field:h["Field"],SiteSelector:i["SiteSelector"]},directives:{Form:h["Form"]},data:function(){return{doesRequirePasswordConfirmation:!1,username:this.userLogin,email:this.userEmail,language:this.currentLanguageCode,timeformat:this.currentTimeformat,theDefaultReport:this.defaultReport,site:{id:this.defaultReportIdSite,name:i["Matomo"].helper.htmlDecode(this.defaultReportSiteName)},theDefaultDate:this.defaultDate,loading:!1,passwordCurrent:""}},methods:{save:function(){var e=this;if(!this.doesRequirePasswordConfirmation||this.passwordCurrent){var t=M.Modal.getInstance(this.$refs.confirmChangesWithPasswordModal);t&&t.close();var n={email:this.email,defaultReport:"MultiSites"===this.theDefaultReport?this.theDefaultReport:this.site.id,defaultDate:this.theDefaultDate,language:this.language,timeformat:this.timeformat};this.passwordCurrent&&(n.passwordConfirmation=this.passwordCurrent),this.loading=!0,i["AjaxHelper"].post({module:"UsersManager",action:"recordUserSettings",format:"json"},n,{withTokenInUrl:!0}).then((function(){var t=i["NotificationsStore"].show({message:Object(i["translate"])("CoreAdminHome_SettingsSaveSuccess"),id:"PersonalSettingsSuccess",context:"success",type:"transient"});i["NotificationsStore"].scrollToNotification(t),e.doesRequirePasswordConfirmation=!1,e.passwordCurrent="",e.loading=!1})).catch((function(){e.loading=!1,e.passwordCurrent=""}))}else ws(this.$refs.confirmChangesWithPasswordModal).modal({dismissible:!1,ready:function(){ws(".modal.open #currentPassword").focus()}}).modal("open")}}});Ts.render=ks;var Ms=Ts;
+ */function ks(e,t,n,s,r,i){var o=Object(a["resolveComponent"])("Field"),l=Object(a["resolveComponent"])("SiteSelector"),c=Object(a["resolveComponent"])("SaveButton"),d=Object(a["resolveComponent"])("ContentBlock"),u=Object(a["resolveDirective"])("form");return Object(a["openBlock"])(),Object(a["createBlock"])(d,{"content-title":e.title,feature:"true"},{default:Object(a["withCtx"])((function(){return[Object(a["withDirectives"])(Object(a["createElementVNode"])("form",vs,[Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"text",name:"username",title:e.translate("General_Username"),disabled:!0,modelValue:e.username,"onUpdate:modelValue":t[0]||(t[0]=function(t){return e.username=t}),"inline-help":e.translate("UsersManager_YourUsernameCannotBeChanged")},null,8,["title","modelValue","inline-help"])]),e.isUsersAdminEnabled?(Object(a["openBlock"])(),Object(a["createElementBlock"])("div",Cs,[Object(a["createVNode"])(o,{uicontrol:"text",name:"email","model-value":e.email,"onUpdate:modelValue":t[1]||(t[1]=function(t){e.email=t,e.doesRequirePasswordConfirmation=!0}),maxlength:100,title:e.translate("UsersManager_Email")},null,8,["model-value","title"])])):Object(a["createCommentVNode"])("",!0),Object(a["createElementVNode"])("div",Ss,[Object(a["createElementVNode"])("a",Ns,Object(a["toDisplayString"])(e.translate("LanguagesManager_AboutPiwikTranslations")),1)]),Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"select",name:"language",modelValue:e.language,"onUpdate:modelValue":t[2]||(t[2]=function(t){return e.language=t}),title:e.translate("General_Language"),options:e.languageOptions,"inline-help":"#languageHelp"},null,8,["modelValue","title","options"])]),Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"select",name:"timeformat",modelValue:e.timeformat,"onUpdate:modelValue":t[3]||(t[3]=function(t){return e.timeformat=t}),title:e.translate("General_TimeFormat"),options:e.timeFormats},null,8,["modelValue","title","options"])]),Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"radio",name:"defaultReport",modelValue:e.theDefaultReport,"onUpdate:modelValue":t[4]||(t[4]=function(t){return e.theDefaultReport=t}),introduction:e.translate("UsersManager_ReportToLoadByDefault"),title:e.translate("General_AllWebsitesDashboard"),options:e.defaultReportOptions},null,8,["modelValue","introduction","title","options"])]),Object(a["createElementVNode"])("div",Us,[Object(a["createVNode"])(l,{modelValue:e.site,"onUpdate:modelValue":t[5]||(t[5]=function(t){return e.site=t}),"show-selected-site":!0,"switch-site-on-select":!1,"show-all-sites-item":!1,showselectedsite:!0,id:"defaultReportSiteSelector"},null,8,["modelValue"])]),Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"radio",name:"defaultDate",modelValue:e.theDefaultDate,"onUpdate:modelValue":t[6]||(t[6]=function(t){return e.theDefaultDate=t}),introduction:e.translate("UsersManager_ReportDateToLoadByDefault"),options:e.availableDefaultDates},null,8,["modelValue","introduction","options"])]),Object(a["createVNode"])(c,{onConfirm:t[7]||(t[7]=function(t){return e.save()}),saving:e.loading},null,8,["saving"]),Object(a["createElementVNode"])("div",ys,[Object(a["createElementVNode"])("div",Vs,[Object(a["createElementVNode"])("h2",null,Object(a["toDisplayString"])(e.translate("UsersManager_ConfirmWithPassword")),1),Object(a["createElementVNode"])("div",null,[Object(a["createVNode"])(o,{uicontrol:"password",name:"currentPassword",autocomplete:!1,modelValue:e.passwordCurrent,"onUpdate:modelValue":t[8]||(t[8]=function(t){return e.passwordCurrent=t}),"full-width":!0,title:e.translate("UsersManager_YourCurrentPassword")},null,8,["modelValue","title"])])]),Object(a["createElementVNode"])("div",Es,[Object(a["createElementVNode"])("a",{href:"",class:"modal-action btn",onClick:t[9]||(t[9]=Object(a["withModifiers"])((function(t){return e.save()}),["prevent"])),style:{"margin-right":"3.5px"}},Object(a["toDisplayString"])(e.translate("General_Ok")),1),Object(a["createElementVNode"])("a",{href:"",class:"modal-action modal-close modal-no",onClick:t[10]||(t[10]=Object(a["withModifiers"])((function(t){return e.passwordCurrent=""}),["prevent"]))},Object(a["toDisplayString"])(e.translate("General_Cancel")),1)])],512)],512),[[u]])]})),_:1},8,["content-title"])}var As=window,ws=As.$,Ts=Object(a["defineComponent"])({props:{isUsersAdminEnabled:{type:Boolean,required:!0},title:{type:String,required:!0},userLogin:{type:String,required:!0},userEmail:{type:String,required:!0},currentLanguageCode:{type:String,required:!0},languageOptions:{type:Object,required:!0},currentTimeformat:{type:Number,required:!0},timeFormats:{type:Object,required:!0},defaultReport:{type:[String,Number],required:!0},defaultReportOptions:{type:Object,required:!0},defaultReportIdSite:{type:[String,Number],required:!0},defaultReportSiteName:{type:String,required:!0},defaultDate:{type:String,required:!0},availableDefaultDates:{type:Object,required:!0}},components:{ContentBlock:i["ContentBlock"],SaveButton:h["SaveButton"],Field:h["Field"],SiteSelector:i["SiteSelector"]},directives:{Form:h["Form"]},data:function(){return{doesRequirePasswordConfirmation:!1,username:this.userLogin,email:this.userEmail,language:this.currentLanguageCode,timeformat:this.currentTimeformat,theDefaultReport:this.defaultReport,site:{id:this.defaultReportIdSite,name:i["Matomo"].helper.htmlDecode(this.defaultReportSiteName)},theDefaultDate:this.defaultDate,loading:!1,passwordCurrent:""}},methods:{save:function(){var e=this;if(!this.doesRequirePasswordConfirmation||this.passwordCurrent){var t=M.Modal.getInstance(this.$refs.confirmChangesWithPasswordModal);t&&t.close();var n={email:this.email,defaultReport:"MultiSites"===this.theDefaultReport?this.theDefaultReport:this.site.id,defaultDate:this.theDefaultDate,language:this.language,timeformat:this.timeformat};this.passwordCurrent&&(n.passwordConfirmation=this.passwordCurrent),this.loading=!0,i["AjaxHelper"].post({module:"UsersManager",action:"recordUserSettings",format:"json"},n,{withTokenInUrl:!0}).then((function(){var t=i["NotificationsStore"].show({message:Object(i["translate"])("CoreAdminHome_SettingsSaveSuccess"),id:"PersonalSettingsSuccess",context:"success",type:"transient"});i["NotificationsStore"].scrollToNotification(t),e.doesRequirePasswordConfirmation=!1,e.passwordCurrent="",e.loading=!1})).catch((function(){e.loading=!1,e.passwordCurrent=""}))}else ws(this.$refs.confirmChangesWithPasswordModal).modal({dismissible:!1,ready:function(){ws(".modal.open #currentPassword").focus()}}).modal("open")}}});Ts.render=ks;var Ms=Ts;
/*!
* Matomo - free/libre analytics platform
*
diff --git a/plugins/UsersManager/vue/src/PersonalSettings/PersonalSettings.vue b/plugins/UsersManager/vue/src/PersonalSettings/PersonalSettings.vue
index 927368a371..1780e05675 100644
--- a/plugins/UsersManager/vue/src/PersonalSettings/PersonalSettings.vue
+++ b/plugins/UsersManager/vue/src/PersonalSettings/PersonalSettings.vue
@@ -147,7 +147,7 @@ interface PersonalSettingsState {
email: string;
language: string;
timeformat: number;
- theDefaultReport: string;
+ theDefaultReport: string|number;
site: SiteRef;
theDefaultDate: string;
loading: boolean;
@@ -191,7 +191,7 @@ export default defineComponent({
required: true,
},
defaultReport: {
- type: String,
+ type: [String, Number],
required: true,
},
defaultReportOptions: {