From 8fb83ba71dfa1de1eabd0f4abd651c9d6b4b4710 Mon Sep 17 00:00:00 2001 From: dizzy Date: Wed, 15 Dec 2021 07:30:51 -0800 Subject: [Vue] migrate reporting page directive (#18430) * build again * refactor some code and fix an issue with checkbox array field handling in angularjs * more fixes * another fix * even more fixes * remove more todo * hopefully the last changes * update vue files * update submodule * revert debugging change + fix issue * built vue files * fix another select issue * rebuild vue files * fix broken refactor * update two screenshots * add some more timeouts and update screenshots * initial conversion, loading w/o error * tweaks * get period selector work in UI * fix site selector model binding * rebuild vue * fix viewDate not being kept in sync * rebuild CoreHome * [Vue] fix modal notification placement (#18377) * Use separate div in modals to display notifications otherwise Vue will erase modal content when initializing NotificationGroup component. * built vue files * two fixes * couple UI test fixes * rebuild vue * update files * sidenav start * make getRef a utility method * tweak * add return type * finish converting side-nav directive * starting on reporting menu conversion * remove unused properties * convert reporting pages service * migrate report metadata store * remove angularjs files * migrating reporting pages store * make store adapters more immutable * get service adapters to work * fix a UI test * another html fix * migrate most of reporting menu directive and model * Use themed font family for input forms to override materialize.css styling * rebuild vue * add a missing div * ui test fixes * update styling * get to build * get to load in the UI w/o error * clone result of functions * fix compile issue * migrate widget loader and get to load in UI * rebuild vue * migrate widgetcontainer * migrate widget bydimension container * migrate widget + add tooltips directive * quick fix * Updating version to 4.6.0 * loading in page * update expected screenshot * add wait just in case travis is slow * fix ordering bug * add another wait * rebuild vue * css tweak * fix some bugs and tests * undo screenshot changes * Menus test passing locally * [Vue] date picker viewDate property is not kept up to date (#18385) * viewDate ref is not kept up to date * rebuild corehome * reporting menu subcategory items are meant to be normal links * update some screenshots * use innerText instead of text() since angularjs maintains newlines in HTML that vue does not add * trigger angularjs digest after ajaxhelper request * rebuild vue * update screenshots, fix bug in link generation in reporting menu and allow syncing multiple screenshot regexes at a time * undo box-shadow change for UI tests * fix more issues & update more tests * update some screenshots * fix some tests * rebuild CoreHome * quick fix * built vue files * fix angularjs issue * add comment * update umd files * 4.6.1-rc1 * 4.6.1 * fix field array title * apply some pr feedback * apply more pr feedback * another fix * tweak * fix ng-change not executed before ng-model * fix another set of issues * fix another issue * rebuild vue * better ng-change/ng-model fix * update some screenshots * rebuild vue * remove some TODOs * initiate initial ng-change ONLY for site selectors where this behavior applies * emit/broadcast on correct scope in wrapper * rebuild vue * fix some issues * couple more fixes * fix another title issue * rebuild vue * do not report on ajax errors in notifications if not logged in * migrate reporting page and model * rebuild vue * fix a bunch of bugs * fix another widget bug * built vue files * fix function signature * fix vue warning * fix ajax request race condition * rebuild vue * add new notification type "help" so the help notification is not cleared when clearing transient notifications * fix some bugs and tests * update screenshot * update screenshot & fix a test * allow using unminified jquery ui + fix bug in last fix * fix error when enrichedheadline is used in modal * add polyfill min.js * remove two todos * fix widget url logic * update some screenshots and fix sanitization/escape issue * update screenshots * rebuild vue * fix url location updating regression in MatomoUrl.updateLocation use * submodule * update screenshots and fix possible error in json parse * built vue files * Merge branch 'vue-period-selector-regression' into vue-reporting-menu * rebuild vue * use correct variable * rebuild vue * fix widget url logic * segment parameter can be undefined now for some reason * fix ngmodel binding in siteselector adapter (for last time hopefully) * the original site selector only set the first site to the first site in the initial sites query if there was only one site in the entire matomo instance * fix sitesmanager ui test failure * fix usersettings test failure * rebuild vue * more siteselector tweaks. * build CoreHome * more siteselector tweaks. * another siteselector issue * update screenshots * update screenshot and try to fix random failure * fix some issues in widget.vue when containerid is specified * fix couple tests * fix several test failures * fix test failure * extra change * fix last change and random failure * styling fix * fix last fix * real fix this time * fix stray request * proper fix * update build files * try to fix random failure * update screenshots * post loadPage event after url changes so URL changes are propagated properly to widgets, take columns param into account when re-rendering a page * revert invalid UI file changes * fix two regressions in period selector comparison launching/detection (#18497) * forward compareSegments in when applying period selector change + check if comparing periods in period selector * built vue files * fix piwik-widget selector in dataTable.js * extra scope apply after hash change so angularjs notices, change css class to use kebab case, check for field using css class as well in Widget.vue * rebuild vue * built vue files * try to fix random failure * fix order of JS in karma tests * remove empty props * use promise chaining * check if undefined since returned value can be response or undefined Co-authored-by: Justin Velluppillai Co-authored-by: justinvelluppillai Co-authored-by: Matthieu Aubry Co-authored-by: sgiehl --- .../reporting-page/reportingpage-model.js | 173 --------------- .../reporting-page/reportingpage.controller.js | 245 --------------------- .../reporting-page/reportingpage.directive.html | 17 -- .../reporting-page/reportingpage.directive.js | 31 --- .../reporting-page/reportingpage.directive.less | 24 -- 5 files changed, 490 deletions(-) delete mode 100644 plugins/CoreHome/angularjs/reporting-page/reportingpage-model.js delete mode 100644 plugins/CoreHome/angularjs/reporting-page/reportingpage.controller.js delete mode 100644 plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.html delete mode 100644 plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.js delete mode 100644 plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.less (limited to 'plugins/CoreHome/angularjs') diff --git a/plugins/CoreHome/angularjs/reporting-page/reportingpage-model.js b/plugins/CoreHome/angularjs/reporting-page/reportingpage-model.js deleted file mode 100644 index e91b5053a7..0000000000 --- a/plugins/CoreHome/angularjs/reporting-page/reportingpage-model.js +++ /dev/null @@ -1,173 +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').factory('reportingPageModel', reportingPageModelService); - - reportingPageModelService.$inject = ['$filter', 'reportingPagesModel', 'reportMetadataModel']; - - function reportingPageModelService ($filter, reportingPagesModel, reportMetadataModel) { - // those sites are going to be displayed - var model = { - fetchPage: fetchPage, - resetPage: resetPage, - widgets: [], - page: null, - }; - - return model; - - function resetPage() - { - model.page = null; - model.widgets = []; - } - - function sortWidgets(widgets) - { - return $filter('orderBy')(widgets, 'order'); - } - - function shouldBeRenderedWithFullWidth(widget) - { - // rather controller logic - if ((widget.isContainer && widget.layout && widget.layout === 'ByDimension') - || widget.viewDataTable === 'bydimension') { - return true; - } - - if ('undefined' !== typeof widget.isWide && widget.isWide) { - return true; - } - - return widget.viewDataTable && (widget.viewDataTable === 'tableAllColumns' || widget.viewDataTable === 'sparklines' || widget.viewDataTable === 'graphEvolution'); - } - - function buildPage(page) - { - if (!page) { - return; - } - - var widgets = []; - var reportsToIgnore = []; - - angular.forEach(page.widgets, function (widget) { - - if (isIgnoredReport(reportsToIgnore, widget)) { - return; - } - - reportsToIgnore = reportsToIgnore.concat(getRelatedReports(widget)); - - widgets.push(widget); - }); - - widgets = sortWidgets(widgets); - - var groupedWidgets = []; - - if (widgets.length === 1) { - // if there is only one widget, we always display it full width - groupedWidgets = widgets; - } else { - for (var i = 0; i < widgets.length; i++) { - var widget = widgets[i]; - - if (shouldBeRenderedWithFullWidth(widget) || (widgets[i+1] && shouldBeRenderedWithFullWidth(widgets[i+1]))) { - widget.widgets = sortWidgets(widget.widgets); - - groupedWidgets.push(widget); - } else { - - var counter = 0; - var left = [widget]; - var right = []; - - while (widgets[i+1] && !shouldBeRenderedWithFullWidth(widgets[i+1])) { - i++; - counter++; - if (counter % 2 === 0) { - left.push(widgets[i]); - } else { - right.push(widgets[i]); - } - } - - groupedWidgets.push({group: true, left: left, right: right}); - } - } - } - - var copyWidgets = angular.copy(groupedWidgets); - copyWidgets = markWidgetsInFirstRowOfPage(copyWidgets); - - // angular.copy forces the page to re-render. Otherwise it won't reload some pages - model.widgets = copyWidgets; - } - - function markWidgetsInFirstRowOfPage(widgets) - { - if (widgets && widgets[0]) { - if (widgets[0].group) { - markWidgetsInFirstRowOfPage(widgets[0].left); - markWidgetsInFirstRowOfPage(widgets[0].right); - } else { - widgets[0].isFirstInPage = true; - } - } - - return widgets; - } - - function getRelatedReports(widget) - { - if (widget.isReport) { - var report = reportMetadataModel.findReport(widget.module, widget.action); - - if (report && report.relatedReports) { - return report.relatedReports; - } - } - - return []; - } - - function isIgnoredReport(reportsToIgnore, widget) - { - var found = false; - - if (widget.isReport) { - angular.forEach(reportsToIgnore, function (report) { - if (report.module === widget.module && - report.action === widget.action) { - found = true; - } - }); - } - - return found; - } - - function fetchPage(category, subcategory) - { - resetPage(); - - var pagesPromise = reportingPagesModel.getAllPages(); - var reportsPromise = reportMetadataModel.fetchReportMetadata(); - - return pagesPromise.then(function () { - model.page = reportingPagesModel.findPage(category, subcategory); - - reportsPromise.then(function () { - buildPage(model.page); - }); - - return model.page; - }); - } - } -})(); diff --git a/plugins/CoreHome/angularjs/reporting-page/reportingpage.controller.js b/plugins/CoreHome/angularjs/reporting-page/reportingpage.controller.js deleted file mode 100644 index 4fac133741..0000000000 --- a/plugins/CoreHome/angularjs/reporting-page/reportingpage.controller.js +++ /dev/null @@ -1,245 +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('ReportingPageController', ReportingPageController); - - ReportingPageController.$inject = ['$scope', 'piwik', '$rootScope', '$location', 'reportingPageModel', 'reportingPagesModel', 'notifications', 'piwikUrl', 'piwikPeriods', 'piwikApi']; - - function ReportingPageController($scope, piwik, $rootScope, $location, pageModel, pagesModel, notifications, piwikUrl, $piwikPeriods, piwikApi) { - pageModel.resetPage(); - $scope.pageModel = pageModel; - - var currentCategory = null; - var currentSubcategory = null; - var currentPeriod = null; - var currentDate = null; - var currentSegment = null; - - var currentCompareDates = null; - var currentComparePeriods = null; - var currentCompareSegments = null; - - var hasRawData = false; - var hasNoVisits = false; - var dateLastChecked = null; - - var UI = require('piwik/UI'); - var notification = new UI.Notification(); - - function renderInitialPage() - { - var $search = $location.search(); - currentPeriod = piwikUrl.getSearchParam('period'); - currentDate = piwikUrl.getSearchParam('date'); - currentSegment = $search.segment; - currentCompareSegments = piwikUrl.getSearchParam('compareSegments'); - currentCompareDates = piwikUrl.getSearchParam('compareDates'); - currentComparePeriods = piwikUrl.getSearchParam('comparePeriods'); - $scope.renderPage($search.category, $search.subcategory); - } - - function showOnlyRawDataNotification() { - var attributes = {}; - attributes.id = 'onlyRawData'; - attributes.animate = false; - attributes.context = 'info'; - var url = broadcast.buildReportingUrl('category=General_Visitors&subcategory=Live_VisitorLog') - var message = _pk_translate('CoreHome_PeriodHasOnlyRawData', ['', '']); - notification.show(message, attributes); - } - - function hideOnlyRawDataNoticifation() { - notification.remove('onlyRawData'); - } - - function showOnlyRawDataMessageIfRequired() { - if (hasRawData && hasNoVisits) { - showOnlyRawDataNotification(); - } - - var $search = $location.search(); - - if ($search.segment) { - hideOnlyRawDataNoticifation(); - return; - } - - var subcategoryExceptions = [ - 'Live_VisitorLog', - 'General_RealTime', - 'UserCountryMap_RealTimeMap', - 'MediaAnalytics_TypeAudienceLog', - 'MediaAnalytics_TypeRealTime', - 'FormAnalytics_TypeRealTime', - 'Goals_AddNewGoal', - ]; - - var categoryExceptions = [ - 'HeatmapSessionRecording_Heatmaps', - 'HeatmapSessionRecording_SessionRecordings', - 'Marketplace_Marketplace', - ]; - - if (subcategoryExceptions.indexOf($search.subcategory) !== -1 || categoryExceptions.indexOf($search.category) !== -1 || $search.subcategory.toLowerCase().indexOf('manage') !== -1) { - hideOnlyRawDataNoticifation(); - return; - } - - var minuteInMilliseconds = 60000; - if (dateLastChecked && (new Date().getTime() - dateLastChecked) < minuteInMilliseconds) { - return; - } - - piwikApi.fetch({ method: 'VisitsSummary.getVisits' }).then(function (json) { - dateLastChecked = new Date().getTime(); - - if (json.value > 0) { - hasNoVisits = false; - hideOnlyRawDataNoticifation(); - return; - } - - hasNoVisits = true; - - if (hasRawData) { - showOnlyRawDataNotification(); - return; - } - - piwikApi.fetch({ method: 'Live.getLastVisitsDetails', filter_limit: 1, doNotFetchActions: 1 }).then(function (json) { - if (json.length == 0) { - hasRawData = false; - hideOnlyRawDataNoticifation(); - return; - } - - hasRawData = true; - showOnlyRawDataNotification(); - }); - }); - } - - $scope.renderPage = function (category, subcategory) { - if (!category || !subcategory) { - pageModel.resetPage(); - $scope.loading = false; - return; - } - - try { - $piwikPeriods.parse(currentPeriod, currentDate); - } catch (e) { - var attributes = {}; - attributes.id = 'invalidDate'; - attributes.animate = false; - attributes.context = 'error'; - notification.show(_pk_translate('CoreHome_DateInvalid'), attributes); - - pageModel.resetPage(); - $scope.loading = false; - return; - } - - notification.remove('invalidDate'); - - $rootScope.$emit('piwikPageChange', {}); - - currentCategory = category; - currentSubcategory = subcategory; - - notifications.clearTransientNotifications(); - - if ($piwikPeriods.parse(currentPeriod, currentDate).containsToday()) { - showOnlyRawDataMessageIfRequired(); - } - - if (category === 'Dashboard_Dashboard' && $.isNumeric(subcategory) && $('[piwik-dashboard]').length) { - // hack to make loading of dashboards faster since all the information is already there in the - // piwik-dashboard widget, we can let the piwik-dashboard widget render the page. We need to find - // a proper solution for this. A workaround for now could be an event or something to let other - // components render a specific page. - $scope.loading = true; - var element = $('[piwik-dashboard]'); - var scope = angular.element(element).scope(); - scope.fetchDashboard(parseInt(subcategory, 10)).then(function () { - $scope.loading = false; - }, function () { - $scope.loading = false; - }); - return; - } - - pageModel.fetchPage(category, subcategory).then(function () { - if (!pageModel.page) { - var page = pagesModel.findPageInCategory(category); - if (page && page.subcategory) { - var $search = $location.search(); - $search.subcategory = page.subcategory.id; - $location.search($search); - return; - } - } - - $scope.hasNoPage = !pageModel.page; - $scope.loading = false; - }); - }; - - $scope.loading = true; // we only set loading on initial load - - renderInitialPage(); - - $rootScope.$on('$locationChangeSuccess', function () { - var $search = $location.search(); - - // should be handled by $route - var category = $search.category; - var subcategory = $search.subcategory; - var period = piwikUrl.getSearchParam('period'); - var date = piwikUrl.getSearchParam('date'); - var segment = $search.segment; - - // $location does not handle array parameters properly - var compareSegments = piwikUrl.getSearchParam('compareSegments'); - var compareDates = piwikUrl.getSearchParam('compareDates'); - var comparePeriods = piwikUrl.getSearchParam('comparePeriods'); - - if (category === currentCategory - && subcategory === currentSubcategory - && period === currentPeriod - && date === currentDate - && segment === currentSegment - && JSON.stringify(compareDates) === JSON.stringify(currentCompareDates) - && JSON.stringify(comparePeriods) === JSON.stringify(currentComparePeriods) - && JSON.stringify(compareSegments) === JSON.stringify(currentCompareSegments) - ) { - // this page is already loaded - return; - } - - if (date !== currentDate || period !== currentPeriod) { - hideOnlyRawDataNoticifation(); - dateLastChecked = null; - hasRawData = false; - hasNoVisits = false; - } - - currentPeriod = period; - currentDate = date; - currentSegment = segment; - currentCompareDates = compareDates; - currentComparePeriods = comparePeriods; - currentCompareSegments = compareSegments; - - $scope.renderPage(category, subcategory); - }); - - $rootScope.$on('loadPage', function (event, category, subcategory) { - $scope.renderPage(category, subcategory); - }); - } -})(); diff --git a/plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.html b/plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.html deleted file mode 100644 index 4abf3a27e2..0000000000 --- a/plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.html +++ /dev/null @@ -1,17 +0,0 @@ -
- -
- -
{{ 'CoreHome_NoSuchPage'|translate }}
- -
-
- -
-
-
-
-
-
-
-
diff --git a/plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.js b/plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.js deleted file mode 100644 index 375bd071db..0000000000 --- a/plugins/CoreHome/angularjs/reporting-page/reportingpage.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 - */ - -/** - * Shows a piwik reporting page. - * - * The content to be displayed is automatically loaded via API based on the current URL. The URL parameters - * 'category' and 'subcategory' need to be present in the URL in order to see something in the reporting page. - * - * Example: - *
- */ -(function () { - angular.module('piwikApp').directive('piwikReportingPage', piwikReportingPage); - - piwikReportingPage.$inject = ['piwik']; - - function piwikReportingPage(piwik){ - - return { - restrict: 'A', - scope: {}, - templateUrl: 'plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.html?cb=' + piwik.cacheBuster, - controller: 'ReportingPageController' - }; - } -})(); \ No newline at end of file diff --git a/plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.less b/plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.less deleted file mode 100644 index 1d9fde17b9..0000000000 --- a/plugins/CoreHome/angularjs/reporting-page/reportingpage.directive.less +++ /dev/null @@ -1,24 +0,0 @@ -.reporting-page { - > .row { - margin-bottom: 0; - } - - .fullWidgetColumn { - padding-left: 0; - padding-right: 0; - } - - .leftWidgetColumn { - padding-left: 0; - } - - .rightWidgetColumn { - padding-right: 0; - } - - .isFirstWidgetInPage { - .card { - margin-top: 0; - } - } -} \ No newline at end of file -- cgit v1.2.3