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>2021-11-19 17:18:57 +0300
committerGitHub <noreply@github.com>2021-11-19 17:18:57 +0300
commit5ae81f880dbbd7ab3fc0d223d7a9b4409ae548eb (patch)
treea6f43d9984f62ac579acf970334aae13346b817d /plugins/CoreHome/angularjs/quick-access
parent45d8528596500769ae2587b780cb43b5f7f303dd (diff)
[Vue] migrate siteselector directive and quick-access directive (#18292)
* migrating RateFeature and ReviewLinks + adding AjaxHelper.fetch utility method (all untested) * get ratefeature component to work, modify matomodialog component to use v-model, add event parameters to createAngularAdapter, allow translate to use variadic args or one string array + rebuild * remove ratefeature angularjs files * rebuild + make vue mapping property optional in createANgularJsAdapter * migrate enrichedheadline and get to work * fix test * fix translate * fix another translate issue & migrate contentblock directive * fix anchor links, not including the "/" causes angularjs to fail (also on 4.x-dev) * update expected screenshots * fix ui test * fix some test failures * fix nested transclude issue * remove content block files * fix icon spacing that occurs due to angularjs inserting empty comments in between nodes while vue 3 does not * update some screenshots * update screenshot (actually fixes an alignment issue) * update screenshot * first pass at converting comparisons service/component * get new code to build and load without error in the UI * debugging * getting basic functionaltiy to work * Update _dataTable.twig * fix UI test failure + URL encoding/angularjs issue causing back button to not work * fix order of operations issue * built vue files * using ref in setup() is not needed to access this.$refs * Convert comparisons service angularjs tests to comparison store typescript tests. * migrate piwik-date-picker directive * migrate date range picker component (changed invalid date in input handling to just reset back to the previous date since it was easier in vue to do that) * migrate period-date-picker component (using composition api more when easier for migration) * convert piwik-expand-onclick directive to vue directive * migrate expand on hover directive to vue directive * fix variable reference * build * Add materialize-css @types and migrate piwik-dropdown-menu. * migrate focus-anywhere-but-here directive to vue directive * migrate focus-if directive * migrate menudropdown directive * forgot to remove old files * built vue files * first pass at migrating notification directive, notification service and parts of UI.Notification to Vue * rewrite URL handling to use computed properties in a URL store + do the same for other dependent data in the comparison store to allow vues to subscribe to the properties for changes to global state * fix some tests * some more fixes * more fixes + disallow modifications to MatomoUrl state * get angularjs unit tests to pass + fix a couple more issues * another fix * fix bad merge * self review + fixes * remove old fix as it may not be needed anymore * empty string is not a valid date + do not report invalid date exception just rethrow * update screenshots and try to fix random failure * use jquery $destroy event instead of scope one since the scope one is broadcasted * rangeChange event must be triggered once on mount * initialize startDateText/endDateText correctly * use jquery $destroy event instead of angularjs one * built vue files * fix menudropdown.directive.js reference * load vue in installation/updater & correctly make focusanywherebuthere stateful * correctly implement stateful directives for ExpandOnClick/ExpandOnHover * less tweak (angularjs comment removal) * fix submenu check * quick type fix * load vue in installation workflow * add broadcast.js to Installation workflow + do not fail in pk_translate if no translations are loaded * update expected screenshots (spacing of arrow changed because of angularjs comment no longer being there) * start moving Notification class code to notifications store * fix prop type * fix html escaping * built vue files * get toast and other transitions to work + fix broken toast * move all of notification.js to NotificationStore * wait for angular to be initialized to post events to avoid loading race condition * get scroll to notification to work + get initialization of notification groups to work * correct unmount + remove notifications service file * fix some test failures * re add accidentally removed (?) file * remove no longer needed file * Add CoreHome UMD in CoreUpdater/Installation. * self review * fix type + add default value * remove file from JS list * fix test * fix UI tests * set correct type in users manager notification and allow scope values to be transformed in createAngularAdapter * start migrating siteselector * small addition * migrate rest of site selector code + make some breaking changes to function signatures in createAngularJsAdapter * disable webpack asset size hints/warnings + get siteselector code to build * fixing some bugs * fix some more issues (allow specifing require in createAngularJsAdapter and make AjaxHelper promises abortable) * get npm test to pass * a couple more fixes * remove existing files * convert quick-access directive and use shared code/state with site selector * remove site selector model * fix more issues and get UI tests to pass for quickaccess * remove debugging code / todo * fix initial value * add back a $timeout() * fixing tests, the post blur scope.$apply()s are apparently required for angularjs to function properly * fixing more UI test failures * rebuild * fix vue build * why were these deleted? * remove debug code * fix css class issue + update expected screenshots * rebuild CoreHome * revert styling change * built vue files * get focus-if to work and remove debugging return; * rebuilt vue * should not need to specify type there * built CoreHome * built vue files * apply review feedback * get auto clearing behavior to work in site selector * fix a couple more bugs * rebuild vue * escape htmle entities in site name * tweak Co-authored-by: sgiehl <stefan@matomo.org>
Diffstat (limited to 'plugins/CoreHome/angularjs/quick-access')
-rw-r--r--plugins/CoreHome/angularjs/quick-access/quick-access.controller.js90
-rw-r--r--plugins/CoreHome/angularjs/quick-access/quick-access.directive.html48
-rw-r--r--plugins/CoreHome/angularjs/quick-access/quick-access.directive.js287
-rw-r--r--plugins/CoreHome/angularjs/quick-access/quick-access.directive.less65
4 files changed, 0 insertions, 490 deletions
diff --git a/plugins/CoreHome/angularjs/quick-access/quick-access.controller.js b/plugins/CoreHome/angularjs/quick-access/quick-access.controller.js
deleted file mode 100644
index f9f28c923c..0000000000
--- a/plugins/CoreHome/angularjs/quick-access/quick-access.controller.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/*!
- * Matomo - free/libre analytics platform
- *
- * @link https://matomo.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- */
-(function () {
- angular.module('piwikApp').controller('QuickAccessController', QuickAccessController);
-
- QuickAccessController.$inject = ['$scope', '$filter', 'siteSelectorModel'];
-
- function QuickAccessController($scope, $filter, siteSelectorModel){
-
- this.menuItems = [];
- this.numMenuItems = 0;
- this.sitesModel = siteSelectorModel;
-
- this.onKeypress = function (event) {
- var areSearchResultsDisplayed = $scope.search && $scope.search.term && $scope.view && $scope.view.searchActive;
- var isTabKey = 9 == event.which;
- var isEscKey = 27 == event.which;
-
- if (38 == event.which) {
- $scope.highlightPreviousItem();
- event.preventDefault();
- } else if (40 == event.which) {
- $scope.highlightNextItem();
- event.preventDefault();
- } else if (13 == event.which) {
- $scope.clickQuickAccessMenuItem();
- } else if (isTabKey && areSearchResultsDisplayed) {
- $scope.deactivateSearch();
- } else if (isEscKey && areSearchResultsDisplayed) {
- $scope.deactivateSearch();
- }
- };
-
- this.searchMenu = function (searchTerm) {
- searchTerm = searchTerm.toLowerCase();
-
- var index = -1;
- var menuItemsIndex = {};
- var menuItems = [];
-
- var moveToCategory = function (i, submenuItem) {
- submenuItem = angular.copy(submenuItem); // force rerender of element to prevent weird side effects
- submenuItem.menuIndex = ++index; // needed for proper highlighting with arrow keys
-
- var category = submenuItem.category;
- if (!(category in menuItemsIndex)) {
- menuItems.push({title: category, items: []});
- menuItemsIndex[category] = menuItems.length - 1;
- }
-
- var indexOfCategory = menuItemsIndex[category];
- menuItems[indexOfCategory].items.push(submenuItem);
- };
-
- $scope.resetSearchIndex();
-
- if ($scope.hasSitesSelector) {
- this.sitesModel.searchSite(searchTerm);
- }
-
- var topMenuItems = $filter('filter')($scope.getTopMenuItems(), searchTerm);
- var leftMenuItems = $filter('filter')($scope.getLeftMenuItems(), searchTerm);
- var segmentItems = $filter('filter')($scope.getSegmentItems(), searchTerm);
-
- $.each(topMenuItems, moveToCategory);
- $.each(leftMenuItems, moveToCategory);
- $.each(segmentItems, moveToCategory);
-
- this.numMenuItems = topMenuItems.length + leftMenuItems.length + segmentItems.length;
- this.menuItems = menuItems;
- };
-
- this.selectSite = function (idsite) {
- this.sitesModel.loadSite(idsite);
- };
-
- this.selectMenuItem = function (index) {
- $scope.selectMenuItem(index);
- };
-
- if (typeof initTopControls !== 'undefined' && initTopControls) {
- initTopControls();
- }
-
- }
-})();
diff --git a/plugins/CoreHome/angularjs/quick-access/quick-access.directive.html b/plugins/CoreHome/angularjs/quick-access/quick-access.directive.html
deleted file mode 100644
index c28c8f1d1f..0000000000
--- a/plugins/CoreHome/angularjs/quick-access/quick-access.directive.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<div class="quick-access piwikSelector"
- ng-class="{active: view.searchActive, expanded: view.searchActive}"
- piwik-focus-anywhere-but-here="view.searchActive = false;">
- <span class="icon-search" ng-hide="search.term || view.searchActive"
- ng-mouseenter="view.searchActive=true"></span>
- <input class="s"
- title="{{ quickAccessTitle }}"
- ng-keydown="quickAccess.onKeypress($event)"
- ng-change="view.searchActive=true;quickAccess.searchMenu(search.term)"
- ng-focus="view.searchActive=true"
- ng-model="search.term" piwik-focus-if="view.searchActive"
- type="text" tabindex="2"/>
- <div class="dropdown" ng-show="search.term && view.searchActive">
- <ul ng-hide="(quickAccess.numMenuItems > 0) || (quickAccess.sitesModel.sites | length)">
- <li class="no-result">{{ 'General_SearchNoResults' | translate }}</li>
- </ul>
- <ul ng-repeat="subcategory in quickAccess.menuItems">
- <li class="quick-access-category"
- ng-click="search.term = subcategory.title;quickAccess.searchMenu(search.term)">{{ subcategory.title }}</li>
- <li class="result"
- ng-class="{selected: submenuEntry.menuIndex == search.index}"
- ng-mouseenter="search.index=submenuEntry.menuIndex"
- ng-click="quickAccess.selectMenuItem(submenuEntry.index)"
- ng-repeat="submenuEntry in subcategory.items"><a>{{ submenuEntry.name | trim }}</a></li>
- </ul>
- <ul class="quickAccessMatomoSearch">
- <li class="quick-access-category websiteCategory"
- ng-show="hasSitesSelector && ((quickAccess.sitesModel.sites | length) || quickAccess.sitesModel.isLoading)"
- >{{ 'SitesManager_Sites' | translate }}</li>
- <li class="no-result"
- ng-show="hasSitesSelector && quickAccess.sitesModel.isLoading">{{ 'MultiSites_LoadingWebsites' | translate }}</li>
- <li class="result"
- ng-show="hasSitesSelector && !quickAccess.sitesModel.isLoading"
- ng-mouseenter="search.index=(quickAccess.numMenuItems + $index)"
- ng-class="{selected: (quickAccess.numMenuItems + $index) == search.index}"
- ng-click="quickAccess.selectSite(site.idsite)"
- ng-repeat="site in quickAccess.sitesModel.sites"><a ng-bind="site.name"></a></li>
- </ul>
- <ul>
- <li class="quick-access-category helpCategory">{{ 'General_HelpResources' | translate }}</li>
- <li ng-class="{selected: search.index == 'help'}"
- class="quick-access-help"
- ng-mouseenter="search.index='help'">
- <a ng-href="https://matomo.org?s={{ urlEncode(search.term) }}" target="_blank">{{'CoreHome_SearchOnMatomo' | translate:(search.term)}}</a>
- </li>
- </ul>
- </div>
-</div>
diff --git a/plugins/CoreHome/angularjs/quick-access/quick-access.directive.js b/plugins/CoreHome/angularjs/quick-access/quick-access.directive.js
deleted file mode 100644
index 7417261c8e..0000000000
--- a/plugins/CoreHome/angularjs/quick-access/quick-access.directive.js
+++ /dev/null
@@ -1,287 +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-dialog="showDialog">...</div>
- * Will show dialog once showDialog evaluates to true.
- *
- * Will execute the "executeMyFunction" function in the current scope once the yes button is pressed.
- */
-(function () {
- angular.module('piwikApp').directive('piwikQuickAccess', QuickAccessDirective);
-
- QuickAccessDirective.$inject = ['$rootElement', '$timeout', 'piwik', '$filter'];
-
- function QuickAccessDirective ($rootElement, $timeout, piwik, $filter) {
-
- return {
- restrict: 'A',
- replace: true,
- scope: {},
- templateUrl: 'plugins/CoreHome/angularjs/quick-access/quick-access.directive.html?cb=' + piwik.cacheBuster,
- controller: 'QuickAccessController',
- controllerAs: 'quickAccess',
- link: function (scope, element, attrs) {
-
- var menuIndex = -1; // the menu index is used to identify which element to click
- var topMenuItems = []; // cache for top menu items
- var leftMenuItems = []; // cache for left menu items
- var segmentItems = []; // cache for segment items
- var hasSegmentSelector = angular.element('.segmentEditorPanel').length;
- scope.hasSitesSelector = angular.element('.top_controls [piwik-siteselector]').length;
-
-
- var translate = $filter('translate');
- var searchAreasTitle = '';
- var searchAreas = [translate('CoreHome_MenuEntries')];
-
- if (hasSegmentSelector) {
- searchAreas.push(translate('CoreHome_Segments'));
- }
-
- if (scope.hasSitesSelector) {
- searchAreas.push(translate('SitesManager_Sites'));
- }
-
- while (searchAreas.length) {
- searchAreasTitle += searchAreas.shift();
- if (searchAreas.length >= 2) {
- searchAreasTitle += ', ';
- } else if (searchAreas.length === 1) {
- searchAreasTitle += ' ' + translate('General_And') + ' ';
- }
- }
-
- scope.quickAccessTitle = translate('CoreHome_QuickAccessTitle', searchAreasTitle);
-
- function trim(str) {
- if (str) {
- return str.replace(/^\s+|\s+$/g,'');
- }
- return str;
- }
-
- scope.getTopMenuItems = function()
- {
- if (topMenuItems && topMenuItems.length) {
- return topMenuItems;
- }
-
- var category = _pk_translate('CoreHome_Menu');
-
- $rootElement.find('nav .sidenav li > a').each(function (index, element) {
- var $element = $(element);
-
- var text = trim($element.text());
-
- if (!text) {
- text = trim($element.attr('title')); // possibly a icon, use title instead
- }
-
- if (text) {
- topMenuItems.push({name: text, index: ++menuIndex, category: category});
- $element.attr('quick_access', menuIndex);
- }
- });
-
- return topMenuItems;
- };
-
- scope.getLeftMenuItems = function ()
- {
- if (leftMenuItems && leftMenuItems.length) {
- return leftMenuItems;
- }
-
- $rootElement.find('#secondNavBar .menuTab').each(function (index, element) {
- var $element = angular.element(element);
- var category = trim($element.find('> .item').text());
-
- if (category && -1 !== category.lastIndexOf("\n")) {
- // remove "\n\nMenu"
- category = trim(category.substr(0, category.lastIndexOf("\n")));
- }
-
- $element.find('li .item').each(function (i, element) {
- var $element = angular.element(element);
- var text = trim($element.text());
- if (text) {
- leftMenuItems.push({name: text, category: category, index: ++menuIndex});
- $element.attr('quick_access', menuIndex);
- }
- });
-
- });
-
- return leftMenuItems;
- };
-
- scope.getSegmentItems = function()
- {
- if (!hasSegmentSelector) {
- return [];
- }
-
- if (segmentItems && segmentItems.length) {
- return segmentItems;
- }
-
- var category = _pk_translate('CoreHome_Segments');
-
- $rootElement.find('.segmentList [data-idsegment]').each(function (index, element) {
- var $element = angular.element(element);
- var text = trim($element.find('.segname').text());
-
- if (text) {
- segmentItems.push({name: text, category: category, index: ++menuIndex});
- $element.attr('quick_access', menuIndex);
- }
- });
-
- return segmentItems;
- };
-
- scope.activateSearch = function()
- {
- scope.$eval('view.searchActive = true');
- $timeout(function () {
- scope.$apply();
- }, 0);
- };
-
- scope.deactivateSearch = function()
- {
- scope.$eval('search.term = ""');
- scope.$eval('view.searchActive = false');
- element.find('input').blur();
- $timeout(function () {
- scope.$apply();
- }, 0);
- };
-
- function isElementInViewport(element) {
-
- var rect = element.getBoundingClientRect();
-
- return (
- rect.top >= 0 &&
- rect.left >= 0 &&
- rect.bottom <= $(window).height() &&
- rect.right <= $(window).width()
- );
- }
-
- function getCurrentlySelectedElement(index)
- {
- var results = element.find('li.result');
- if (results && results.length && results[scope.search.index]) {
- return $(results[scope.search.index]);
- }
- }
-
- function makeSureSelectedItemIsInViewport() {
- var element = getCurrentlySelectedElement();
-
- if (element && element[0] && !isElementInViewport(element[0])) {
- scrollFirstElementIntoView(element);
- }
- }
-
- function scrollFirstElementIntoView(element)
- {
- if (element && element[0] && element[0].scrollIntoView) {
- // make sure search is visible
- element[0].scrollIntoView();
- }
- }
-
- scope.highlightPreviousItem = function()
- {
- if (0 >= (scope.search.index - 1)) {
- scope.search.index = 0;
- } else {
- scope.search.index--;
- }
- makeSureSelectedItemIsInViewport();
- };
-
- scope.resetSearchIndex = function () {
- scope.search.index = 0;
- makeSureSelectedItemIsInViewport();
- };
-
- scope.highlightNextItem = function()
- {
- var numTotal = element.find('li.result').length;
-
- if (numTotal <= (scope.search.index + 1)) {
- scope.search.index = numTotal - 1;
- } else {
- scope.search.index++;
- }
-
- makeSureSelectedItemIsInViewport();
- };
-
- scope.clickQuickAccessMenuItem = function()
- {
- var selectedMenuElement = getCurrentlySelectedElement();
- if (selectedMenuElement) {
- $timeout(function () {
- selectedMenuElement.click();
- }, 20);
- }
- };
-
- scope.selectMenuItem = function(index)
- {
- var target = $rootElement.find('[quick_access=' + index + ']');
-
- if (target && target.length && target[0]) {
- scope.deactivateSearch();
-
- var actualTarget = target[0];
-
- var href = $(actualTarget).attr('href');
-
- if (href && href.length > 10 && actualTarget && actualTarget.click) {
- try {
- actualTarget.click();
- } catch (e) {
- $(actualTarget).click();
- }
- } else {
- $(actualTarget).click();
- }
- }
- };
-
- scope.urlEncode = function(term)
- {
- return encodeURIComponent(term);
- };
-
- piwikHelper.registerShortcut('f', _pk_translate('CoreHome_ShortcutSearch'), function(event) {
- if (event.altKey) {
- return;
- }
- if (event.preventDefault) {
- event.preventDefault();
- } else {
- event.returnValue = false; // IE
- }
-
- scrollFirstElementIntoView(element);
-
- scope.activateSearch();
- });
-
- }
- };
- }
-})();
diff --git a/plugins/CoreHome/angularjs/quick-access/quick-access.directive.less b/plugins/CoreHome/angularjs/quick-access/quick-access.directive.less
deleted file mode 100644
index 3bad77b9ba..0000000000
--- a/plugins/CoreHome/angularjs/quick-access/quick-access.directive.less
+++ /dev/null
@@ -1,65 +0,0 @@
-.quick-access {
- position: relative;
-
- &:hover,
- &.expanded,
- &.active {
- input {
- background-color: @theme-color-background-contrast !important;
- }
- }
- li {
- font-size: 11px;
- }
-
- li a {
- padding: 10px 19px;
- display: inline-block;
- text-decoration: none;
- word-break: break-all;
- }
-
- .icon-search {
- position: absolute;
- font-size: 14px;
- top: 10px;
- left: 10px;
-
- }
- input {
- width:100%;
- height: 100%;
- box-shadow: 0 0 !important;
- border-radius: 0 !important;
- background-color: @theme-color-background-base !important;
- font-size: 11px;
- &:focus {
- outline: none;
- }
- }
- .selected {
- background-color: @theme-color-background-tinyContrast !important;
- }
- .quick-access-category {
- text-align: left !important;
- font-size: 11px;
- padding: 5px 5px 5px 10px;
- cursor: pointer;
- }
- .result {
- cursor: pointer;
- }
- .quick-access-category:hover {
- background: none !important;
- }
- .no-result {
- padding: 10px 19px;
- cursor: default;
- }
- .websiteCategory {
- cursor: default;
- }
- li.quick-access-help a {
- word-break: break-word;
- }
-} \ No newline at end of file