diff options
author | dizzy <diosmosis@users.noreply.github.com> | 2022-04-06 17:43:42 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-06 17:43:42 +0300 |
commit | 6ab9923d6324c3d98765881e525d7ecf8ba9d831 (patch) | |
tree | 7304f857cb6b11ee31dc447e62b7e5458a4284a6 /plugins/UserCountry | |
parent | 698c83bb1e411b18c6ea7c4d1df8668f9f432855 (diff) |
[Vue] migrate location-provider-selection directive to vue component (#19026)
* migrate location-provider-selection directive to vue component
* test manually
* fix UI tests
* fix paragraph markup
Co-authored-by: sgiehl <stefan@matomo.org>
Diffstat (limited to 'plugins/UserCountry')
11 files changed, 760 insertions, 200 deletions
diff --git a/plugins/UserCountry/LocationProvider/DefaultProvider.php b/plugins/UserCountry/LocationProvider/DefaultProvider.php index e5f311fed6..4c426eef6b 100644 --- a/plugins/UserCountry/LocationProvider/DefaultProvider.php +++ b/plugins/UserCountry/LocationProvider/DefaultProvider.php @@ -111,10 +111,10 @@ class DefaultProvider extends LocationProvider */ public function getInfo() { - $desc = Piwik::translate('UserCountry_DefaultLocationProviderDesc1') . ' ' + $desc = '<p>' . Piwik::translate('UserCountry_DefaultLocationProviderDesc1') . ' ' . Piwik::translate('UserCountry_DefaultLocationProviderDesc2', array('<strong>', '', '', '</strong>')) - . '<p><a href="https://matomo.org/faq/how-to/#faq_163" rel="noreferrer noopener" target="_blank">' + . '</p><p><a href="https://matomo.org/faq/how-to/#faq_163" rel="noreferrer noopener" target="_blank">' . Piwik::translate('UserCountry_HowToInstallGeoIPDatabases') . '</a></p>'; return array('id' => self::ID, 'title' => self::TITLE, 'description' => $desc, 'order' => 1); diff --git a/plugins/UserCountry/UserCountry.php b/plugins/UserCountry/UserCountry.php index 4fea13b899..a91b2e95d8 100644 --- a/plugins/UserCountry/UserCountry.php +++ b/plugins/UserCountry/UserCountry.php @@ -24,6 +24,7 @@ class UserCountry extends \Piwik\Plugin public function registerEvents() { return array( + 'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys', 'AssetManager.getStylesheetFiles' => 'getStylesheetFiles', 'AssetManager.getJavaScriptFiles' => 'getJsFiles', 'Tracker.setTrackerCacheGeneral' => 'setTrackerCacheGeneral', @@ -31,6 +32,19 @@ class UserCountry extends \Piwik\Plugin ); } + public function getClientSideTranslationKeys(&$translations) + { + $translations[] = 'General_InfoFor'; + $translations[] = 'General_NotInstalled'; + $translations[] = 'General_Installed'; + $translations[] = 'General_Broken'; + $translations[] = 'UserCountry_CurrentLocationIntro'; + $translations[] = 'General_Refresh'; + $translations[] = 'UserCountry_CannotLocalizeLocalIP'; + $translations[] = 'UserCountry_NoProviders'; + $translations[] = 'General_Disabled'; + } + public function addReportToInsightsOverview(&$reports) { $reports['UserCountry_getCountry'] = array(); @@ -48,8 +62,6 @@ class UserCountry extends \Piwik\Plugin public function getJsFiles(&$jsFiles) { - $jsFiles[] = "plugins/UserCountry/angularjs/location-provider-selection/location-provider-selection.controller.js"; - $jsFiles[] = "plugins/UserCountry/angularjs/location-provider-selection/location-provider-selection.directive.js"; } /** diff --git a/plugins/UserCountry/angularjs/location-provider-selection/location-provider-selection.controller.js b/plugins/UserCountry/angularjs/location-provider-selection/location-provider-selection.controller.js deleted file mode 100644 index a415e15686..0000000000 --- a/plugins/UserCountry/angularjs/location-provider-selection/location-provider-selection.controller.js +++ /dev/null @@ -1,72 +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('LocationProviderSelectionController', LocationProviderSelectionController); - - LocationProviderSelectionController.$inject = ['piwikApi']; - - function LocationProviderSelectionController(piwikApi) { - var self = this; - - this.isLoading = false; - this.updateLoading = {}; - - // handle 'refresh location' link click - this.refreshProviderInfo = function (providerId) { - - this.updateLoading[providerId] = true; - - // this should not be in a controller... ideally we fetch this data always from client side and do not - // prefill it server side - var $locationNode = $('.provider' + providerId + ' .location'); - $locationNode.css('visibility', 'hidden'); - - piwikApi.fetch({ - module: 'UserCountry', - action: 'getLocationUsingProvider', - id: providerId, - format: 'html' - }).then(function (response) { - self.updateLoading[providerId] = false; - $locationNode.html('<strong>' + response + '</strong>').css('visibility', 'visible'); - }, function () { - self.updateLoading[providerId] = false; - }); - }; - - this.save = function () { - if (!this.selectedProvider) { - return; - } - - this.isLoading = true; - - var parent = $(this).closest('p'), - loading = $('.loadingPiwik', parent), - ajaxSuccess = $('.success', parent); - - piwikApi.withTokenInUrl(); - piwikApi.fetch({ - method: 'UserCountry.setLocationProvider', - providerId: this.selectedProvider - }).then(function () { - self.isLoading = false; - var UI = require('piwik/UI'); - var notification = new UI.Notification(); - notification.show(_pk_translate('General_Done'), { - context: 'success', - noclear: true, - type: 'toast', - id: 'userCountryLocationProvider' - }); - notification.scrollToNotification(); - }, function () { - self.isLoading = false; - }); - }; - } -})();
\ No newline at end of file diff --git a/plugins/UserCountry/angularjs/location-provider-selection/location-provider-selection.directive.js b/plugins/UserCountry/angularjs/location-provider-selection/location-provider-selection.directive.js deleted file mode 100644 index e5bc4efb5b..0000000000 --- a/plugins/UserCountry/angularjs/location-provider-selection/location-provider-selection.directive.js +++ /dev/null @@ -1,33 +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-location-provider-selection> - */ -(function () { - angular.module('piwikApp').directive('piwikLocationProviderSelection', piwikLocationProviderSelection); - - piwikLocationProviderSelection.$inject = ['piwik']; - - function piwikLocationProviderSelection(piwik){ - - return { - restrict: 'A', - transclude: true, - controller: 'LocationProviderSelectionController', - controllerAs: 'locationSelector', - template: '<div ng-transclude></div>', - compile: function (element, attrs) { - - return function (scope, element, attrs, controller) { - controller.selectedProvider = attrs.piwikLocationProviderSelection; - }; - } - }; - } -})();
\ No newline at end of file diff --git a/plugins/UserCountry/stylesheets/userCountry.less b/plugins/UserCountry/stylesheets/userCountry.less index 515513bf8d..1fb2dce597 100644 --- a/plugins/UserCountry/stylesheets/userCountry.less +++ b/plugins/UserCountry/stylesheets/userCountry.less @@ -44,4 +44,10 @@ span.is-broken { [name="geoip-isp-db"] .alert { margin-bottom: 0; +} + +.locationProviderSelection { + .loadingPiwik { + padding: 1px; + } }
\ No newline at end of file diff --git a/plugins/UserCountry/templates/adminIndex.twig b/plugins/UserCountry/templates/adminIndex.twig index 20cc6deede..658bcc0b27 100644 --- a/plugins/UserCountry/templates/adminIndex.twig +++ b/plugins/UserCountry/templates/adminIndex.twig @@ -12,97 +12,16 @@ <p>{{ 'UserCountry_GeolocationPageDesc'|translate }}</p> </div> <div piwik-content-block content-title="{{ 'UserCountry_LocationProvider'|translate|e('html_attr') }}"> -<div piwik-location-provider-selection="{{ currentProviderId|e('html_attr') }}"> - - {% if not isThereWorkingProvider %} - {{ setUpGuides|raw }} - {% endif %} - - <div class="row"> - <div class="col s12 push-m9 m3">{{ 'General_InfoFor'|translate(thisIP) }}</div> - </div> - - {% for id,provider in locationProviders|filter(provider => provider.isVisible) %} - <div class="row form-group provider{{ id|e('html_attr') }}"> - <div class="col s12 m4 l2"> - <p> - <label> - <input class="location-provider" - name="location-provider" - value="{{ id }}" - type="radio" - ng-model="locationSelector.selectedProvider" - id="provider_input_{{ id }}" {% if provider.status != 1 %}disabled="disabled"{% endif %}/> - - <span>{{ provider.title|translate }}</span> - </label> - </p> - <p class="loc-provider-status"> - {% if provider.status == 0 %} - <span class="is-not-installed">{{ 'General_NotInstalled'|translate}}</span> - {% elseif provider.status == 1 %} - <span class="is-installed">{{ 'General_Installed'|translate }}</span> - {% elseif provider.status == 2 %} - <span class="is-broken">{{ 'General_Broken'|translate }}</span> - {% endif %} - </p> - </div> - <div class="col s12 m4 l6"> - <p>{{ provider.description|translate|raw }}</p> - {% if provider.status != 1 and provider.install_docs is defined %} - <p>{{ provider.install_docs|raw }}</p> - {% endif %} - </div> - <div class="col s12 m4 l4"> - {% if provider.status == 1 %} - <div class="form-help"> - {% if thisIP != '127.0.0.1' %} - {{ 'UserCountry_CurrentLocationIntro'|translate }}: - <div> - <br/> - <div style="position: absolute;" - piwik-activity-indicator - loading='locationSelector.updateLoading[{{ id|json_encode }}]'></div> - <span class="location"><strong>{{ provider.location|raw }}</strong></span> - </div> - <div class="text-right"> - <a href="javascript:;" - ng-click='locationSelector.refreshProviderInfo({{ id|json_encode }})'>{{ 'General_Refresh'|translate }}</a> - </div> - {% else %} - {{ 'UserCountry_CannotLocalizeLocalIP'|translate(thisIP) }} - {% endif %} - </div> - {% endif %} - {% if provider.statusMessage is defined and provider.statusMessage %} - <div class="form-help"> - {% if provider.status == 2 %}<strong>{{ 'General_Error'|translate }}:</strong> {% endif %}{{ provider.statusMessage|raw }} - </div> - {% endif %} - {% if provider.extra_message is defined and provider.extra_message %} - <div class="form-help"> - {{ provider.extra_message|raw }} - </div> - {% endif %} - </div> - </div> - {% endfor %} - - - {% if locationProviders|filter(provider => ( - provider.id != constant("Piwik\\Plugins\\UserCountry\\LocationProvider\\DefaultProvider::ID") and - provider.id != constant("Piwik\\Plugins\\UserCountry\\LocationProvider\\DisabledProvider::ID") - ))|length == 0 %} - <div piwik-notification - noclear="true" - context="warning"> - {{ 'UserCountry_NoProviders'|translate('<a rel="noreferrer noopener" href="https://db-ip.com/?refid=mtm">','</a>')|raw }} - </div> - {% endif %} - - <div piwik-save-button onconfirm="locationSelector.save()" saving="locationSelector.isLoading"></div> - -</div> +<div + vue-entry="UserCountry.LocationProviderSelection" + current-provider-id="{{ currentProviderId|json_encode|e('html_attr') }}" + is-there-working-provider="{{ isThereWorkingProvider|default(null)|json_encode|e('html_attr') }}" + set-up-guides="{{ setUpGuides|default(null)|json_encode|e('html_attr') }}" + this-ip="{{ thisIP|default(null)|json_encode|e('html_attr') }}" + location-providers="{{ locationProviders|default(null)|json_encode|e('html_attr') }}" + default-provider-id="{{ constant("Piwik\\Plugins\\UserCountry\\LocationProvider\\DefaultProvider::ID")|default(null)|json_encode|e('html_attr') }}" + disabled-provider-id="{{ constant("Piwik\\Plugins\\UserCountry\\LocationProvider\\DisabledProvider::ID")|default(null)|json_encode|e('html_attr') }}" +></div> </div> {{ configurations|raw }} diff --git a/plugins/UserCountry/vue/dist/UserCountry.umd.js b/plugins/UserCountry/vue/dist/UserCountry.umd.js new file mode 100644 index 0000000000..a6e7f01ed1 --- /dev/null +++ b/plugins/UserCountry/vue/dist/UserCountry.umd.js @@ -0,0 +1,456 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("CoreHome"), require("vue"), require("CorePluginsAdmin")); + else if(typeof define === 'function' && define.amd) + define(["CoreHome", , "CorePluginsAdmin"], factory); + else if(typeof exports === 'object') + exports["UserCountry"] = factory(require("CoreHome"), require("vue"), require("CorePluginsAdmin")); + else + root["UserCountry"] = factory(root["CoreHome"], root["Vue"], root["CorePluginsAdmin"]); +})((typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__19dc__, __WEBPACK_EXTERNAL_MODULE__8bbf__, __WEBPACK_EXTERNAL_MODULE_a5a2__) { +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/UserCountry/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__; + +/***/ }), + +/***/ "a5a2": +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_a5a2__; + +/***/ }), + +/***/ "fae3": +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +// ESM COMPAT FLAG +__webpack_require__.r(__webpack_exports__); + +// EXPORTS +__webpack_require__.d(__webpack_exports__, "LocationProviderSelection", function() { return /* reexport */ LocationProviderSelection; }); + +// 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); + +// 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/UserCountry/vue/src/LocationProviderSelection/LocationProviderSelection.vue?vue&type=template&id=2fa21635 + +var _hoisted_1 = { + class: "locationProviderSelection" +}; +var _hoisted_2 = ["innerHTML"]; +var _hoisted_3 = { + class: "row" +}; +var _hoisted_4 = { + class: "col s12 push-m9 m3" +}; +var _hoisted_5 = { + class: "col s12 m4 l2" +}; +var _hoisted_6 = ["id", "disabled", "checked", "onChange"]; +var _hoisted_7 = { + class: "loc-provider-status" +}; +var _hoisted_8 = { + key: 0, + class: "is-not-installed" +}; +var _hoisted_9 = { + key: 1, + class: "is-installed" +}; +var _hoisted_10 = { + key: 2, + class: "is-broken" +}; +var _hoisted_11 = { + class: "col s12 m4 l6" +}; +var _hoisted_12 = ["innerHTML"]; +var _hoisted_13 = ["innerHTML"]; +var _hoisted_14 = { + class: "col s12 m4 l4" +}; +var _hoisted_15 = { + key: 0, + class: "form-help" +}; +var _hoisted_16 = { + key: 0 +}; + +var _hoisted_17 = /*#__PURE__*/Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("br", null, null, -1); + +var _hoisted_18 = { + style: { + "position": "absolute" + } +}; +var _hoisted_19 = ["innerHTML"]; +var _hoisted_20 = { + class: "text-right" +}; +var _hoisted_21 = ["onClick"]; +var _hoisted_22 = { + key: 1 +}; +var _hoisted_23 = { + key: 1, + class: "form-help" +}; +var _hoisted_24 = { + key: 0 +}; +var _hoisted_25 = ["innerHTML"]; +var _hoisted_26 = ["innerHTML"]; +var _hoisted_27 = { + key: 1 +}; +var _hoisted_28 = ["innerHTML"]; +function render(_ctx, _cache, $props, $setup, $data, $options) { + var _component_ActivityIndicator = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("ActivityIndicator"); + + var _component_Notification = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("Notification"); + + var _component_SaveButton = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("SaveButton"); + + return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", _hoisted_1, [!_ctx.isThereWorkingProvider ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", { + key: 0, + innerHTML: _ctx.$sanitize(_ctx.setUpGuides || '') + }, null, 8, _hoisted_2)) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_3, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_4, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('General_InfoFor', _ctx.thisIp)), 1)]), (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.visibleLocationProviders, function (provider, id) { + return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", { + key: id, + class: Object(external_commonjs_vue_commonjs2_vue_root_Vue_["normalizeClass"])("row form-group provider".concat(id)) + }, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_5, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("p", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("label", null, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("input", { + class: "location-provider", + name: "location-provider", + type: "radio", + id: "provider_input_".concat(id), + disabled: provider.status !== 1, + checked: _ctx.selectedProvider === id, + onChange: function onChange($event) { + return _ctx.selectedProvider = id; + } + }, null, 40, _hoisted_6), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("span", null, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translateOrDefault(provider.title)), 1)])]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("p", _hoisted_7, [provider.status === 0 ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("span", _hoisted_8, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('General_NotInstalled')), 1)) : provider.status === 1 ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("span", _hoisted_9, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('General_Installed')), 1)) : provider.status === 2 ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("span", _hoisted_10, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('General_Broken')), 1)) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true)])]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_11, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("p", { + innerHTML: _ctx.$sanitize(_ctx.translateOrDefault(provider.description)) + }, null, 8, _hoisted_12), provider.status !== 1 && provider.install_docs ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("p", { + key: 0, + innerHTML: _ctx.$sanitize(provider.install_docs) + }, null, 8, _hoisted_13)) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true)]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_14, [provider.status === 1 ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", _hoisted_15, [_ctx.thisIp !== '127.0.0.1' ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", _hoisted_16, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createTextVNode"])(Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('UserCountry_CurrentLocationIntro')) + ": ", 1), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", null, [_hoisted_17, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_18, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_ActivityIndicator, { + loading: _ctx.updateLoading[id] + }, null, 8, ["loading"])]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("span", { + class: "location", + style: Object(external_commonjs_vue_commonjs2_vue_root_Vue_["normalizeStyle"])({ + visibility: _ctx.providerLocations[id] ? 'visible' : 'hidden' + }) + }, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("strong", { + innerHTML: _ctx.$sanitize(_ctx.providerLocations[id] || ' ') + }, null, 8, _hoisted_19)], 4)]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_20, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("a", { + onClick: Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withModifiers"])(function ($event) { + return _ctx.refreshProviderInfo(id); + }, ["prevent"]) + }, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('General_Refresh')), 9, _hoisted_21)])])) : (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", _hoisted_22, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('UserCountry_CannotLocalizeLocalIP', _ctx.thisIp)), 1))])) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), provider.statusMessage ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", _hoisted_23, [provider.status === 2 ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("strong", _hoisted_24, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('General_Error')) + ":", 1)) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("span", { + innerHTML: _ctx.$sanitize(provider.statusMessage) + }, null, 8, _hoisted_25)])) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), provider.extra_message ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", { + key: 2, + class: "form-help", + innerHTML: _ctx.$sanitize(provider.extra_message) + }, null, 8, _hoisted_26)) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true)])], 2); + }), 128)), !Object.keys(_ctx.locationProvidersNotDefaultOrDisabled).length ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", _hoisted_27, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Notification, { + noclear: true, + context: "warning" + }, { + default: Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withCtx"])(function () { + return [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("span", { + innerHTML: _ctx.$sanitize(_ctx.noProvidersText) + }, null, 8, _hoisted_28)]; + }), + _: 1 + })])) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_SaveButton, { + onConfirm: _cache[0] || (_cache[0] = function ($event) { + return _ctx.save(); + }), + saving: _ctx.isLoading + }, null, 8, ["saving"])]); +} +// CONCATENATED MODULE: ./plugins/UserCountry/vue/src/LocationProviderSelection/LocationProviderSelection.vue?vue&type=template&id=2fa21635 + +// EXTERNAL MODULE: external "CoreHome" +var external_CoreHome_ = __webpack_require__("19dc"); + +// EXTERNAL MODULE: external "CorePluginsAdmin" +var external_CorePluginsAdmin_ = __webpack_require__("a5a2"); + +// 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/UserCountry/vue/src/LocationProviderSelection/LocationProviderSelection.vue?vue&type=script&lang=ts +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } + +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } + +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + +function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } + +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } + + + + +/* harmony default export */ var LocationProviderSelectionvue_type_script_lang_ts = (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["defineComponent"])({ + props: { + currentProviderId: { + type: String, + required: true + }, + isThereWorkingProvider: Boolean, + setUpGuides: String, + thisIp: { + type: String, + required: true + }, + locationProviders: { + type: Object, + required: true + }, + defaultProviderId: { + type: String, + required: true + }, + disabledProviderId: { + type: String, + required: true + } + }, + components: { + ActivityIndicator: external_CoreHome_["ActivityIndicator"], + Notification: external_CoreHome_["Notification"], + SaveButton: external_CorePluginsAdmin_["SaveButton"] + }, + data: function data() { + return { + isLoading: false, + updateLoading: {}, + selectedProvider: this.currentProviderId, + providerLocations: Object.fromEntries(Object.entries(this.locationProviders).map(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + k = _ref2[0], + p = _ref2[1]; + + return [k, p.location]; + })) + }; + }, + methods: { + refreshProviderInfo: function refreshProviderInfo(providerId) { + var _this = this; + + // this should not be in a controller... ideally we fetch this data always from client side + // and do not prefill it server side + this.updateLoading[providerId] = true; + delete this.providerLocations[providerId]; + external_CoreHome_["AjaxHelper"].fetch({ + module: 'UserCountry', + action: 'getLocationUsingProvider', + id: providerId, + format: 'html' + }, { + format: 'html' + }).then(function (response) { + _this.providerLocations[providerId] = response; + }).finally(function () { + _this.updateLoading[providerId] = false; + }); + }, + save: function save() { + var _this2 = this; + + if (!this.selectedProvider) { + return; + } + + this.isLoading = true; + external_CoreHome_["AjaxHelper"].fetch({ + method: 'UserCountry.setLocationProvider', + providerId: this.selectedProvider + }, { + withTokenInUrl: true + }).then(function () { + var notificationInstanceId = external_CoreHome_["NotificationsStore"].show({ + message: Object(external_CoreHome_["translate"])('General_Done'), + context: 'success', + noclear: true, + type: 'toast', + id: 'userCountryLocationProvider' + }); + external_CoreHome_["NotificationsStore"].scrollToNotification(notificationInstanceId); + }).finally(function () { + _this2.isLoading = false; + }); + } + }, + computed: { + visibleLocationProviders: function visibleLocationProviders() { + return Object.fromEntries(Object.entries(this.locationProviders).filter(function (_ref3) { + var _ref4 = _slicedToArray(_ref3, 2), + p = _ref4[1]; + + return p.isVisible; + })); + }, + locationProvidersNotDefaultOrDisabled: function locationProvidersNotDefaultOrDisabled() { + var _this3 = this; + + return Object.fromEntries(Object.entries(this.locationProviders).filter(function (_ref5) { + var _ref6 = _slicedToArray(_ref5, 2), + p = _ref6[1]; + + return p.id !== _this3.defaultProviderId && p.id !== _this3.disabledProviderId; + })); + }, + noProvidersText: function noProvidersText() { + return Object(external_CoreHome_["translate"])('UserCountry_NoProviders', '<a rel="noreferrer noopener" href="https://db-ip.com/?refid=mtm" target="_blank">', '</a>'); + } + } +})); +// CONCATENATED MODULE: ./plugins/UserCountry/vue/src/LocationProviderSelection/LocationProviderSelection.vue?vue&type=script&lang=ts + +// CONCATENATED MODULE: ./plugins/UserCountry/vue/src/LocationProviderSelection/LocationProviderSelection.vue + + + +LocationProviderSelectionvue_type_script_lang_ts.render = render + +/* harmony default export */ var LocationProviderSelection = (LocationProviderSelectionvue_type_script_lang_ts); +// CONCATENATED MODULE: ./plugins/UserCountry/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=UserCountry.umd.js.map
\ No newline at end of file diff --git a/plugins/UserCountry/vue/dist/UserCountry.umd.min.js b/plugins/UserCountry/vue/dist/UserCountry.umd.min.js new file mode 100644 index 0000000000..850c46d8f2 --- /dev/null +++ b/plugins/UserCountry/vue/dist/UserCountry.umd.min.js @@ -0,0 +1,8 @@ +(function(e,t){"object"===typeof exports&&"object"===typeof module?module.exports=t(require("CoreHome"),require("vue"),require("CorePluginsAdmin")):"function"===typeof define&&define.amd?define(["CoreHome",,"CorePluginsAdmin"],t):"object"===typeof exports?exports["UserCountry"]=t(require("CoreHome"),require("vue"),require("CorePluginsAdmin")):e["UserCountry"]=t(e["CoreHome"],e["Vue"],e["CorePluginsAdmin"])})("undefined"!==typeof self?self:this,(function(e,t,r){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="plugins/UserCountry/vue/dist/",r(r.s="fae3")}({"19dc":function(t,r){t.exports=e},"8bbf":function(e,r){e.exports=t},a5a2:function(e,t){e.exports=r},fae3:function(e,t,r){"use strict";if(r.r(t),r.d(t,"LocationProviderSelection",(function(){return $})),"undefined"!==typeof window){var n=window.document.currentScript,o=n&&n.src.match(/(.+\/)[^/]+\.js(\?.*)?$/);o&&(r.p=o[1])}var i=r("8bbf"),c={class:"locationProviderSelection"},a=["innerHTML"],l={class:"row"},s={class:"col s12 push-m9 m3"},d={class:"col s12 m4 l2"},u=["id","disabled","checked","onChange"],b={class:"loc-provider-status"},f={key:0,class:"is-not-installed"},p={key:1,class:"is-installed"},m={key:2,class:"is-broken"},v={class:"col s12 m4 l6"},j=["innerHTML"],O=["innerHTML"],y={class:"col s12 m4 l4"},g={key:0,class:"form-help"},h={key:0},k=Object(i["createElementVNode"])("br",null,null,-1),N={style:{position:"absolute"}},P=["innerHTML"],E={class:"text-right"},C=["onClick"],L={key:1},B={key:1,class:"form-help"},V={key:0},S=["innerHTML"],I=["innerHTML"],x={key:1},T=["innerHTML"];function _(e,t,r,n,o,_){var M=Object(i["resolveComponent"])("ActivityIndicator"),H=Object(i["resolveComponent"])("Notification"),w=Object(i["resolveComponent"])("SaveButton");return Object(i["openBlock"])(),Object(i["createElementBlock"])("div",c,[e.isThereWorkingProvider?Object(i["createCommentVNode"])("",!0):(Object(i["openBlock"])(),Object(i["createElementBlock"])("div",{key:0,innerHTML:e.$sanitize(e.setUpGuides||"")},null,8,a)),Object(i["createElementVNode"])("div",l,[Object(i["createElementVNode"])("div",s,Object(i["toDisplayString"])(e.translate("General_InfoFor",e.thisIp)),1)]),(Object(i["openBlock"])(!0),Object(i["createElementBlock"])(i["Fragment"],null,Object(i["renderList"])(e.visibleLocationProviders,(function(t,r){return Object(i["openBlock"])(),Object(i["createElementBlock"])("div",{key:r,class:Object(i["normalizeClass"])("row form-group provider".concat(r))},[Object(i["createElementVNode"])("div",d,[Object(i["createElementVNode"])("p",null,[Object(i["createElementVNode"])("label",null,[Object(i["createElementVNode"])("input",{class:"location-provider",name:"location-provider",type:"radio",id:"provider_input_".concat(r),disabled:1!==t.status,checked:e.selectedProvider===r,onChange:function(t){return e.selectedProvider=r}},null,40,u),Object(i["createElementVNode"])("span",null,Object(i["toDisplayString"])(e.translateOrDefault(t.title)),1)])]),Object(i["createElementVNode"])("p",b,[0===t.status?(Object(i["openBlock"])(),Object(i["createElementBlock"])("span",f,Object(i["toDisplayString"])(e.translate("General_NotInstalled")),1)):1===t.status?(Object(i["openBlock"])(),Object(i["createElementBlock"])("span",p,Object(i["toDisplayString"])(e.translate("General_Installed")),1)):2===t.status?(Object(i["openBlock"])(),Object(i["createElementBlock"])("span",m,Object(i["toDisplayString"])(e.translate("General_Broken")),1)):Object(i["createCommentVNode"])("",!0)])]),Object(i["createElementVNode"])("div",v,[Object(i["createElementVNode"])("p",{innerHTML:e.$sanitize(e.translateOrDefault(t.description))},null,8,j),1!==t.status&&t.install_docs?(Object(i["openBlock"])(),Object(i["createElementBlock"])("p",{key:0,innerHTML:e.$sanitize(t.install_docs)},null,8,O)):Object(i["createCommentVNode"])("",!0)]),Object(i["createElementVNode"])("div",y,[1===t.status?(Object(i["openBlock"])(),Object(i["createElementBlock"])("div",g,["127.0.0.1"!==e.thisIp?(Object(i["openBlock"])(),Object(i["createElementBlock"])("div",h,[Object(i["createTextVNode"])(Object(i["toDisplayString"])(e.translate("UserCountry_CurrentLocationIntro"))+": ",1),Object(i["createElementVNode"])("div",null,[k,Object(i["createElementVNode"])("div",N,[Object(i["createVNode"])(M,{loading:e.updateLoading[r]},null,8,["loading"])]),Object(i["createElementVNode"])("span",{class:"location",style:Object(i["normalizeStyle"])({visibility:e.providerLocations[r]?"visible":"hidden"})},[Object(i["createElementVNode"])("strong",{innerHTML:e.$sanitize(e.providerLocations[r]||" ")},null,8,P)],4)]),Object(i["createElementVNode"])("div",E,[Object(i["createElementVNode"])("a",{onClick:Object(i["withModifiers"])((function(t){return e.refreshProviderInfo(r)}),["prevent"])},Object(i["toDisplayString"])(e.translate("General_Refresh")),9,C)])])):(Object(i["openBlock"])(),Object(i["createElementBlock"])("div",L,Object(i["toDisplayString"])(e.translate("UserCountry_CannotLocalizeLocalIP",e.thisIp)),1))])):Object(i["createCommentVNode"])("",!0),t.statusMessage?(Object(i["openBlock"])(),Object(i["createElementBlock"])("div",B,[2===t.status?(Object(i["openBlock"])(),Object(i["createElementBlock"])("strong",V,Object(i["toDisplayString"])(e.translate("General_Error"))+":",1)):Object(i["createCommentVNode"])("",!0),Object(i["createElementVNode"])("span",{innerHTML:e.$sanitize(t.statusMessage)},null,8,S)])):Object(i["createCommentVNode"])("",!0),t.extra_message?(Object(i["openBlock"])(),Object(i["createElementBlock"])("div",{key:2,class:"form-help",innerHTML:e.$sanitize(t.extra_message)},null,8,I)):Object(i["createCommentVNode"])("",!0)])],2)})),128)),Object.keys(e.locationProvidersNotDefaultOrDisabled).length?Object(i["createCommentVNode"])("",!0):(Object(i["openBlock"])(),Object(i["createElementBlock"])("div",x,[Object(i["createVNode"])(H,{noclear:!0,context:"warning"},{default:Object(i["withCtx"])((function(){return[Object(i["createElementVNode"])("span",{innerHTML:e.$sanitize(e.noProvidersText)},null,8,T)]})),_:1})])),Object(i["createVNode"])(w,{onConfirm:t[0]||(t[0]=function(t){return e.save()}),saving:e.isLoading},null,8,["saving"])])}var M=r("19dc"),H=r("a5a2");function w(e,t){return z(e)||q(e,t)||A(e,t)||D()}function D(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function A(e,t){if(e){if("string"===typeof e)return U(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?U(e,t):void 0}}function U(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function q(e,t){var r=null==e?null:"undefined"!==typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i=[],c=!0,a=!1;try{for(r=r.call(e);!(c=(n=r.next()).done);c=!0)if(i.push(n.value),t&&i.length===t)break}catch(l){a=!0,o=l}finally{try{c||null==r["return"]||r["return"]()}finally{if(a)throw o}}return i}}function z(e){if(Array.isArray(e))return e}var G=Object(i["defineComponent"])({props:{currentProviderId:{type:String,required:!0},isThereWorkingProvider:Boolean,setUpGuides:String,thisIp:{type:String,required:!0},locationProviders:{type:Object,required:!0},defaultProviderId:{type:String,required:!0},disabledProviderId:{type:String,required:!0}},components:{ActivityIndicator:M["ActivityIndicator"],Notification:M["Notification"],SaveButton:H["SaveButton"]},data:function(){return{isLoading:!1,updateLoading:{},selectedProvider:this.currentProviderId,providerLocations:Object.fromEntries(Object.entries(this.locationProviders).map((function(e){var t=w(e,2),r=t[0],n=t[1];return[r,n.location]})))}},methods:{refreshProviderInfo:function(e){var t=this;this.updateLoading[e]=!0,delete this.providerLocations[e],M["AjaxHelper"].fetch({module:"UserCountry",action:"getLocationUsingProvider",id:e,format:"html"},{format:"html"}).then((function(r){t.providerLocations[e]=r})).finally((function(){t.updateLoading[e]=!1}))},save:function(){var e=this;this.selectedProvider&&(this.isLoading=!0,M["AjaxHelper"].fetch({method:"UserCountry.setLocationProvider",providerId:this.selectedProvider},{withTokenInUrl:!0}).then((function(){var e=M["NotificationsStore"].show({message:Object(M["translate"])("General_Done"),context:"success",noclear:!0,type:"toast",id:"userCountryLocationProvider"});M["NotificationsStore"].scrollToNotification(e)})).finally((function(){e.isLoading=!1})))}},computed:{visibleLocationProviders:function(){return Object.fromEntries(Object.entries(this.locationProviders).filter((function(e){var t=w(e,2),r=t[1];return r.isVisible})))},locationProvidersNotDefaultOrDisabled:function(){var e=this;return Object.fromEntries(Object.entries(this.locationProviders).filter((function(t){var r=w(t,2),n=r[1];return n.id!==e.defaultProviderId&&n.id!==e.disabledProviderId})))},noProvidersText:function(){return Object(M["translate"])("UserCountry_NoProviders",'<a rel="noreferrer noopener" href="https://db-ip.com/?refid=mtm" target="_blank">',"</a>")}}});G.render=_;var $=G; +/*! + * Matomo - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */}})})); +//# sourceMappingURL=UserCountry.umd.min.js.map
\ No newline at end of file diff --git a/plugins/UserCountry/vue/dist/umd.metadata.json b/plugins/UserCountry/vue/dist/umd.metadata.json new file mode 100644 index 0000000000..dce4477a3c --- /dev/null +++ b/plugins/UserCountry/vue/dist/umd.metadata.json @@ -0,0 +1,6 @@ +{ + "dependsOn": [ + "CoreHome", + "CorePluginsAdmin" + ] +}
\ No newline at end of file diff --git a/plugins/UserCountry/vue/src/LocationProviderSelection/LocationProviderSelection.vue b/plugins/UserCountry/vue/src/LocationProviderSelection/LocationProviderSelection.vue new file mode 100644 index 0000000000..8563a75749 --- /dev/null +++ b/plugins/UserCountry/vue/src/LocationProviderSelection/LocationProviderSelection.vue @@ -0,0 +1,250 @@ +<!-- + 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="locationProviderSelection"> + <div v-if="!isThereWorkingProvider" v-html="$sanitize(setUpGuides || '')"></div> + <div class="row"> + <div class="col s12 push-m9 m3">{{ translate('General_InfoFor', thisIp) }}</div> + </div> + <div + v-for="(provider, id) in visibleLocationProviders" + :key="id" + :class="`row form-group provider${id}`" + > + <div class="col s12 m4 l2"> + <p> + <label> + <input + class="location-provider" + name="location-provider" + type="radio" + :id="`provider_input_${id}`" + :disabled="provider.status !== 1" + :checked="selectedProvider === id" + @change="selectedProvider = id" + /> + <span>{{ translateOrDefault(provider.title) }}</span> + </label> + </p> + <p class="loc-provider-status"> + <span v-if="provider.status === 0 " class="is-not-installed"> + {{ translate('General_NotInstalled') }} + </span> + <span v-else-if="provider.status === 1" class="is-installed"> + {{ translate('General_Installed') }} + </span> + <span v-else-if="provider.status === 2" class="is-broken"> + {{ translate('General_Broken') }} + </span> + </p> + </div> + <div class="col s12 m4 l6"> + <p v-html="$sanitize(translateOrDefault(provider.description))"></p> + <p + v-if="provider.status !== 1 && provider.install_docs" + v-html="$sanitize(provider.install_docs)" + ></p> + </div> + <div class="col s12 m4 l4"> + <div class="form-help" v-if="provider.status === 1"> + <div v-if="thisIp !== '127.0.0.1'"> + {{ translate('UserCountry_CurrentLocationIntro') }}: + <div> + <br /> + <div style="position: absolute;"> + <ActivityIndicator + :loading="updateLoading[id]" + /> + </div> + <span + class="location" + :style="{ visibility: providerLocations[id] ? 'visible' : 'hidden'}" + > + <strong v-html="$sanitize(providerLocations[id] || ' ')"/> + </span> + </div> + <div class="text-right"> + <a + @click.prevent="refreshProviderInfo(id)" + >{{ translate('General_Refresh') }}</a> + </div> + </div> + <div v-else> + {{ translate('UserCountry_CannotLocalizeLocalIP', thisIp) }} + </div> + </div> + <div class="form-help" v-if="provider.statusMessage"> + <strong v-if="provider.status === 2">{{ translate('General_Error') }}:</strong> + <span v-html="$sanitize(provider.statusMessage)"/> + </div> + <div + class="form-help" + v-if="provider.extra_message" + v-html="$sanitize(provider.extra_message)" + > + </div> + </div> + </div> + <div v-if="!Object.keys(locationProvidersNotDefaultOrDisabled).length"> + <Notification + :noclear="true" + context="warning" + > + <span v-html="$sanitize(noProvidersText)"></span> + </Notification> + </div> + <SaveButton + @confirm="save()" + :saving="isLoading" + /> + </div> +</template> + +<script lang="ts"> +import { defineComponent } from 'vue'; +import { + translate, + AjaxHelper, + NotificationsStore, + ActivityIndicator, + Notification, +} from 'CoreHome'; +import { SaveButton } from 'CorePluginsAdmin'; + +interface ProviderInfo { + id: string; + isVisible: boolean; + description: string; + status: number; + install_docs?: string; + extra_message?: string; + location?: string; +} + +interface LocationProviderSelectionState { + isLoading: boolean; + updateLoading: Record<string, boolean>; + selectedProvider: string; + statusMessage?: string; + providerLocations: Record<string, string>; +} + +export default defineComponent({ + props: { + currentProviderId: { + type: String, + required: true, + }, + isThereWorkingProvider: Boolean, + setUpGuides: String, + thisIp: { + type: String, + required: true, + }, + locationProviders: { + type: Object, + required: true, + }, + defaultProviderId: { + type: String, + required: true, + }, + disabledProviderId: { + type: String, + required: true, + }, + }, + components: { + ActivityIndicator, + Notification, + SaveButton, + }, + data(): LocationProviderSelectionState { + return { + isLoading: false, + updateLoading: {}, + selectedProvider: this.currentProviderId, + providerLocations: Object.fromEntries( + Object.entries(this.locationProviders).map(([k, p]) => [k, p.location]), + ), + }; + }, + methods: { + refreshProviderInfo(providerId: string) { + // this should not be in a controller... ideally we fetch this data always from client side + // and do not prefill it server side + this.updateLoading[providerId] = true; + + delete this.providerLocations[providerId]; + + AjaxHelper.fetch<string>( + { + module: 'UserCountry', + action: 'getLocationUsingProvider', + id: providerId, + format: 'html', + }, + { + format: 'html', + }, + ).then((response) => { + this.providerLocations[providerId] = response; + }).finally(() => { + this.updateLoading[providerId] = false; + }); + }, + save() { + if (!this.selectedProvider) { + return; + } + + this.isLoading = true; + AjaxHelper.fetch( + { + method: 'UserCountry.setLocationProvider', + providerId: this.selectedProvider, + }, + { + withTokenInUrl: true, + }, + ).then(() => { + const notificationInstanceId = NotificationsStore.show({ + message: translate('General_Done'), + context: 'success', + noclear: true, + type: 'toast', + id: 'userCountryLocationProvider', + }); + NotificationsStore.scrollToNotification(notificationInstanceId); + }).finally(() => { + this.isLoading = false; + }); + }, + }, + computed: { + visibleLocationProviders() { + return Object.fromEntries( + Object.entries(this.locationProviders as ProviderInfo[]).filter(([, p]) => p.isVisible), + ); + }, + locationProvidersNotDefaultOrDisabled() { + return Object.fromEntries( + Object.entries(this.locationProviders as ProviderInfo[]).filter( + ([, p]) => p.id !== this.defaultProviderId && p.id !== this.disabledProviderId, + ), + ); + }, + noProvidersText() { + return translate( + 'UserCountry_NoProviders', + '<a rel="noreferrer noopener" href="https://db-ip.com/?refid=mtm" target="_blank">', + '</a>', + ); + }, + }, +}); +</script> diff --git a/plugins/UserCountry/vue/src/index.ts b/plugins/UserCountry/vue/src/index.ts new file mode 100644 index 0000000000..9f5cffa51d --- /dev/null +++ b/plugins/UserCountry/vue/src/index.ts @@ -0,0 +1,8 @@ +/*! + * Matomo - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +export { default as LocationProviderSelection } from './LocationProviderSelection/LocationProviderSelection.vue'; |