From 1dd8569ba0279843b9e7b96f5712d34605530fbe Mon Sep 17 00:00:00 2001 From: dizzy Date: Mon, 7 Feb 2022 07:49:41 -0800 Subject: [Vue] migrate capabilities edit component (#18566) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 string concat * 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 * do not submit form * check for api errors in promise chain in ajaxhelper.ts * force a digest after a location change * use proper abortcontroller method instead of promise hack, have to add new polyfill + try to fix random test failure * some UI test fixes * fix some report export issues * several save button fixes + make replace approximation in createAngularJsAdapter better * fix sparkline * apply after manual click triggering in savebutton * css fixes and piwik-content-table was never applied by angularjs in installtion * rebuild vue * add names to divs so they can still be queried as they were in angularjs * rebuild vue * rebuild vue * now that format_metrics checkbox works, need to check it * small delay before processing first popover * fix dropdown class/directive name * fix overlay test * remove unintended changes * remove unintended changes * migrate archiving controller * do not do a passthrough transpile of vue typescript, and fix many typescript errors in existing code * more typescript fixes * even more fixes * workarounds to fix recursive typing issues * get corehome to build w/ full typescript build and output type definitions to local dir * get outputted typings to be used when compiling other plugins and fix typescript issues in CorePluginsAdmin * readd corehome umd * fix typescript errors in ExampleVue plugin * fix feedback typescript errors * rebuild * migrate branding controller and get to build * fix issues and get to work * rebuild * fix notification scroll * migrate smtp settings controller in coreadminhome * get to work * migrate js tracking code generator and get to build * migrate image tracking code generator and get to build * get to work in UI * get UI tests to pass locally * forgot to add files + rebuild vue * update screenshots * Show a summary of new features (#18065) * Added "What is new" notification display, populated by a new event * Removed test example event hook * Added support for applying a link attribute to menu items, fixes layout issue for mobile with html menu items * Updated UI test screenshots * Revert accidental edit * Hide the "What's new" icon if there are no new features to show * Changed to use changes.json, track user last viewed, added ui test * Fix UserManager unit tests broken by new ts_changes_viewed user field * Moved getChanges to separate helper class, added unit test, added user view access check * Updated to add new changes table and populate only on plugin update/install * Added missing fixture class, updated UI screenshots * Updated matomo font to add ringing bell and new releases icons * Fix for integration test * Reworked class structure, removed unnecessary angular directive, merged templates, other tidy ups * built vue files * built vue files * Added null user check, missing table exception handling, show plugin name in change title, better handling of missing change fields * Added sample changes file, moved UserChanges db code to changes model, added return type hints, better db error code handling, various other improvements * Revert accidental UI screenshot commit * Fix for incorrect link name parameter in sample changes, switched back to using $db->query for INSERT IGNORE * Integration test fix, UI screenshot updates * Test fix * Added link styling, show CoreHome changes without plugin prefix in title * Update UI test screenshot * Added styles to the popover, added event for filtering changes * Test fix * UI test screenshot updates Co-authored-by: sgiehl Co-authored-by: bx80 * Update test translation (#18531) update a test failed XML * updates all submodules (#18541) Co-authored-by: diosmosis * Translations update from Hosted Weblate (#18529) * Translated using Weblate (Greek) Currently translated at 100.0% (162 of 162 strings) Translation: Matomo/Plugin CoreAdminHome Translate-URL: https://hosted.weblate.org/projects/matomo/plugin-coreadminhome/el/ [ci skip] Co-authored-by: Hosted Weblate Co-authored-by: Vasilis Lourdas * Translated using Weblate (Chinese (Simplified)) Currently translated at 83.9% (136 of 162 strings) Translation: Matomo/Plugin CoreAdminHome Translate-URL: https://hosted.weblate.org/projects/matomo/plugin-coreadminhome/zh_Hans/ [ci skip] Translated using Weblate (Chinese (Simplified)) Currently translated at 99.6% (620 of 622 strings) Translation: Matomo/Matomo Base Translate-URL: https://hosted.weblate.org/projects/matomo/matomo-base/zh_Hans/ [ci skip] Co-authored-by: Hosted Weblate Co-authored-by: 刘韬 * Update translation files Updated by "Squash Git commits" hook in Weblate. Translation: Matomo/Plugin CoreAdminHome Translate-URL: https://hosted.weblate.org/projects/matomo/plugin-coreadminhome/ [ci skip] Co-authored-by: Vasilis Lourdas Co-authored-by: 刘韬 * [Vue] migrate report export directive and popover (#18440) * 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 * create sites selector model adapter * fix siteselector vue bug, initial site is only set if there is just one site available * rebuild vue * migrate plugin settings directive * remove TODO * migrate plugin filter directive * migrate two more plugins directives * migrate save button * fix a bunch of bugs * fix another widget bug * allow change event name between angularjs and vue * rebuild vue * migrate plugin form directive * get to work * migrate select-on-focus directive and start migrating report-export directive * finish migrating report export directive & popover component + create reusable function to create vue app and add globals to it * rebuild vue * remove angularjs files and move less contents to vue dir * 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 string concat * 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 * do not submit form * check for api errors in promise chain in ajaxhelper.ts * force a digest after a location change * use proper abortcontroller method instead of promise hack, have to add new polyfill + try to fix random test failure * some UI test fixes * fix some report export issues * several save button fixes + make replace approximation in createAngularJsAdapter better * apply after manual click triggering in savebutton * add names to divs so they can still be queried as they were in angularjs * rebuild vue * now that format_metrics checkbox works, need to check it * fix unintended changes * updated expected screenshots * update two more * go back to previous format_metrics behavior in popover Co-authored-by: Justin Velluppillai Co-authored-by: justinvelluppillai Co-authored-by: Matthieu Aubry * [Vue] remove support in vue for FormField.allSettings (#18542) * deprecate support in vue for FormField.allSettings since deep watching the property doesnt quite work * built vue files * update screenshots * update screenshot * Show a summary of new features (#18065) * Added "What is new" notification display, populated by a new event * Removed test example event hook * Added support for applying a link attribute to menu items, fixes layout issue for mobile with html menu items * Updated UI test screenshots * Revert accidental edit * Hide the "What's new" icon if there are no new features to show * Changed to use changes.json, track user last viewed, added ui test * Fix UserManager unit tests broken by new ts_changes_viewed user field * Moved getChanges to separate helper class, added unit test, added user view access check * Updated to add new changes table and populate only on plugin update/install * Added missing fixture class, updated UI screenshots * Updated matomo font to add ringing bell and new releases icons * Fix for integration test * Reworked class structure, removed unnecessary angular directive, merged templates, other tidy ups * built vue files * built vue files * Added null user check, missing table exception handling, show plugin name in change title, better handling of missing change fields * Added sample changes file, moved UserChanges db code to changes model, added return type hints, better db error code handling, various other improvements * Revert accidental UI screenshot commit * Fix for incorrect link name parameter in sample changes, switched back to using $db->query for INSERT IGNORE * Integration test fix, UI screenshot updates * Test fix * Added link styling, show CoreHome changes without plugin prefix in title * Update UI test screenshot * Added styles to the popover, added event for filtering changes * Test fix * UI test screenshot updates Co-authored-by: sgiehl Co-authored-by: bx80 * Update test translation (#18531) update a test failed XML * updates all submodules (#18541) Co-authored-by: diosmosis * Translations update from Hosted Weblate (#18529) * Translated using Weblate (Greek) Currently translated at 100.0% (162 of 162 strings) Translation: Matomo/Plugin CoreAdminHome Translate-URL: https://hosted.weblate.org/projects/matomo/plugin-coreadminhome/el/ [ci skip] Co-authored-by: Hosted Weblate Co-authored-by: Vasilis Lourdas * Translated using Weblate (Chinese (Simplified)) Currently translated at 83.9% (136 of 162 strings) Translation: Matomo/Plugin CoreAdminHome Translate-URL: https://hosted.weblate.org/projects/matomo/plugin-coreadminhome/zh_Hans/ [ci skip] Translated using Weblate (Chinese (Simplified)) Currently translated at 99.6% (620 of 622 strings) Translation: Matomo/Matomo Base Translate-URL: https://hosted.weblate.org/projects/matomo/matomo-base/zh_Hans/ [ci skip] Co-authored-by: Hosted Weblate Co-authored-by: 刘韬 * Update translation files Updated by "Squash Git commits" hook in Weblate. Translation: Matomo/Plugin CoreAdminHome Translate-URL: https://hosted.weblate.org/projects/matomo/plugin-coreadminhome/ [ci skip] Co-authored-by: Vasilis Lourdas Co-authored-by: 刘韬 * [Vue] migrate report export directive and popover (#18440) * 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 * create sites selector model adapter * fix siteselector vue bug, initial site is only set if there is just one site available * rebuild vue * migrate plugin settings directive * remove TODO * migrate plugin filter directive * migrate two more plugins directives * migrate save button * fix a bunch of bugs * fix another widget bug * allow change event name between angularjs and vue * rebuild vue * migrate plugin form directive * get to work * migrate select-on-focus directive and start migrating report-export directive * finish migrating report export directive & popover component + create reusable function to create vue app and add globals to it * rebuild vue * remove angularjs files and move less contents to vue dir * 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 string concat * 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 * do not submit form * check for api errors in promise chain in ajaxhelper.ts * force a digest after a location change * use proper abortcontroller method instead of promise hack, have to add new polyfill + try to fix random test failure * some UI test fixes * fix some report export issues * several save button fixes + make replace approximation in createAngularJsAdapter better * apply after manual click triggering in savebutton * add names to divs so they can still be queried as they were in angularjs * rebuild vue * now that format_metrics checkbox works, need to check it * fix unintended changes * updated expected screenshots * update two more * go back to previous format_metrics behavior in popover Co-authored-by: Justin Velluppillai Co-authored-by: justinvelluppillai Co-authored-by: Matthieu Aubry * [Vue] remove support in vue for FormField.allSettings (#18542) * deprecate support in vue for FormField.allSettings since deep watching the property doesnt quite work * built vue files * update screenshots * update screenshot * fix tests * rebuild * rebuild * order plugins by dependencies in vue:build and fix warning in corehome build * built vue files * built vue files * remove unused imports * built vue files * remove multilinefield component, fieldtextareaarray does the same thing * edit-trigger is not used anywhere * migrate sitetypes model to store * do not load nonexistant files * remove reference nonexistant files * start converting sitefields component * more work on sitefields component * undo submodule change * rebuild * get sitesmanager to build * get SiteFields component to work in UI * datepicker does not format times * export other stores * fix some typing issues and rebuild * start on site management conversion * add more comma delimited props to list + remove controller JS * rebuild * convert sites manager controller to sitesmanagement component * remove TODOs * finish migrating sitesmanager * remove some TODO * get to build * fixes from testing * rebuild * rebuild and fix issue w/ globalsettings hash detection * migrate capabilities-edit component. * some fixes and get to build * get to work * built vue files * more fixes * update file * fix bug and rebuild * fix bug and rebuild * fix issue * fix issues and rebuild * fix ui test * fix UI test failure * fixing some issues * complete fixes * fix some more issues * fix ui test failures * another fix * several more fixes * fix delete dialog * more fixes * fix styling issue * more fixes * fix another ui test + update other UI tests * fixing edisiteid handling * update screenshots * fix UI tests somre more * fix random failure * in groupedsetting handle templateFile property for angularjs BC * rebuild vue * fix view tracking code link * Update screenshot. * update screenshot Co-authored-by: Ben Burgess <88810029+bx80@users.noreply.github.com> Co-authored-by: sgiehl Co-authored-by: bx80 Co-authored-by: Peter Zhang Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Weblate (bot) Co-authored-by: Vasilis Lourdas Co-authored-by: 刘韬 Co-authored-by: Justin Velluppillai Co-authored-by: justinvelluppillai Co-authored-by: Matthieu Aubry --- plugins/UsersManager/UsersManager.php | 4 +- .../capabilities-edit.component.html | 48 -- .../capabilities-edit.component.js | 214 -------- .../capabilities-edit.component.less | 76 --- .../capability-edit/capability-edit.component.html | 3 - .../capability-edit/capability-edit.component.less | 3 - .../permissions-metadata.service.js | 35 -- plugins/UsersManager/tests/UI/UsersManager_spec.js | 1 + .../UsersManager_permissions_all_sites_access.png | 4 +- ...sersManager_permissions_bulk_access_set_all.png | 4 +- ...sManager_permissions_capability_single_site.png | 4 +- .../UsersManager_permissions_next.png | 4 +- .../UsersManager_permissions_remove_single.png | 4 +- .../UsersManager_permissions_select_multiple.png | 4 +- ...UsersManager_permissions_single_site_access.png | 4 +- plugins/UsersManager/vue/dist/UsersManager.umd.js | 596 +++++++++++++++++++++ .../UsersManager/vue/dist/UsersManager.umd.min.js | 14 + plugins/UsersManager/vue/dist/umd.metadata.json | 6 + .../CapabilitiesEdit/CapabilitiesEdit.adapter.ts | 50 ++ .../vue/src/CapabilitiesEdit/CapabilitiesEdit.less | 76 +++ .../vue/src/CapabilitiesEdit/CapabilitiesEdit.vue | 311 +++++++++++ .../CapabilitiesStore/CapabilitiesStore.adapter.ts | 23 + .../vue/src/CapabilitiesStore/CapabilitiesStore.ts | 57 ++ .../vue/src/CapabilitiesStore/Capability.ts | 17 + plugins/UsersManager/vue/src/index.ts | 10 + 25 files changed, 1176 insertions(+), 396 deletions(-) delete mode 100644 plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.html delete mode 100644 plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.js delete mode 100644 plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.less delete mode 100644 plugins/UsersManager/angularjs/capability-edit/capability-edit.component.html delete mode 100644 plugins/UsersManager/angularjs/capability-edit/capability-edit.component.less delete mode 100644 plugins/UsersManager/angularjs/permissions-metadata/permissions-metadata.service.js create mode 100644 plugins/UsersManager/vue/dist/UsersManager.umd.js create mode 100644 plugins/UsersManager/vue/dist/UsersManager.umd.min.js create mode 100644 plugins/UsersManager/vue/dist/umd.metadata.json create mode 100644 plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.adapter.ts create mode 100644 plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.less create mode 100644 plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.vue create mode 100644 plugins/UsersManager/vue/src/CapabilitiesStore/CapabilitiesStore.adapter.ts create mode 100644 plugins/UsersManager/vue/src/CapabilitiesStore/CapabilitiesStore.ts create mode 100644 plugins/UsersManager/vue/src/CapabilitiesStore/Capability.ts create mode 100644 plugins/UsersManager/vue/src/index.ts diff --git a/plugins/UsersManager/UsersManager.php b/plugins/UsersManager/UsersManager.php index e5620260ef..d45083b1f2 100644 --- a/plugins/UsersManager/UsersManager.php +++ b/plugins/UsersManager/UsersManager.php @@ -134,8 +134,6 @@ class UsersManager extends \Piwik\Plugin $jsFiles[] = "plugins/UsersManager/angularjs/user-permissions-edit/user-permissions-edit.component.js"; $jsFiles[] = "plugins/UsersManager/angularjs/personal-settings/personal-settings.controller.js"; $jsFiles[] = "plugins/UsersManager/angularjs/personal-settings/anonymous-settings.controller.js"; - $jsFiles[] = "plugins/UsersManager/angularjs/permissions-metadata/permissions-metadata.service.js"; - $jsFiles[] = "plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.js"; } /** @@ -149,7 +147,7 @@ class UsersManager extends \Piwik\Plugin $stylesheets[] = "plugins/UsersManager/angularjs/paged-users-list/paged-users-list.component.less"; $stylesheets[] = "plugins/UsersManager/angularjs/user-edit-form/user-edit-form.component.less"; $stylesheets[] = "plugins/UsersManager/angularjs/user-permissions-edit/user-permissions-edit.component.less"; - $stylesheets[] = "plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.less"; + $stylesheets[] = "plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.less"; } /** diff --git a/plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.html b/plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.html deleted file mode 100644 index 4eee7fe20e..0000000000 --- a/plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.html +++ /dev/null @@ -1,48 +0,0 @@ -
-
- - {{ capability.category }}: {{ capability.name }} - - -
- -
-
- - -
diff --git a/plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.js b/plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.js deleted file mode 100644 index 6efe3129a0..0000000000 --- a/plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.js +++ /dev/null @@ -1,214 +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: - * - */ -(function () { - angular.module('piwikApp').component('piwikCapabilitiesEdit', { - templateUrl: 'plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.html?cb=' + piwik.cacheBuster, - bindings: { - idsite: '<', - siteName: '<', - userLogin: '<', - userRole: '<', - capabilities: '<', - onCapabilitiesChange: '&', - }, - controller: CapabilitiesEditController - }); - - CapabilitiesEditController.$inject = ['piwikApi', 'permissionsMetadataService', 'piwik', '$element']; - - function CapabilitiesEditController(piwikApi, permissionsMetadataService, piwik, $element) { - var vm = this; - - vm.isBusy = false; - vm.availableCapabilities = []; - vm.availableCapabilitiesGrouped = []; - vm.capabilitiesSet = {}; - - // intermediate state - vm.isAddingCapability = false; - vm.capabilityToAddOrRemoveId = null; - vm.capabilityToAddOrRemove = null; - - vm.$onInit = $onInit; - vm.$onChanges = $onChanges; - vm.onToggleCapability = onToggleCapability; - vm.toggleCapability = toggleCapability; - vm.isIncludedInRole = isIncludedInRole; - - function $onInit() { - fetchAvailableCapabilities(); - - if (typeof vm.capabilities === 'undefined') { - fetchCapabilities(); - } - } - - function $onChanges() { - setCapabilitiesSet(); - } - - function isIncludedInRole(capability) { - return capability.includedInRoles.indexOf(vm.userRole) !== -1; - } - - function fetchAvailableCapabilities() { - permissionsMetadataService.getAllCapabilities() - .then(function (capabilities) { - vm.availableCapabilities = capabilities; - setCapabilitiesSet(); - setAvailableCapabilitiesDropdown(); - }); - } - - function fetchCapabilities() { - vm.isBusy = true; - piwikApi.fetch({ - method: 'UsersManager.getUsersPlusRole', - limit: '1', - filter_search: vm.userLogin, - }).then(function (user) { - if (!user || !user.capabilities) { - return []; - } - - return user.capabilities; - }).then(function (capabilities) { - vm.capabilities = capabilities; - setCapabilitiesSet(); - setAvailableCapabilitiesDropdown(); - })['finally'](function () { - vm.isBusy = false; - }); - } - - function setCapabilitiesSet() { - vm.capabilitiesSet = {}; - (vm.capabilities || []).forEach(function (capability) { - vm.capabilitiesSet[capability] = true; - }); - (vm.availableCapabilities || []).forEach(function (capability) { - if (vm.isIncludedInRole(capability)) { - vm.capabilitiesSet[capability.id] = true; - } - }); - } - - function setAvailableCapabilitiesDropdown() { - var availableCapabilitiesGrouped = []; - vm.availableCapabilities.forEach(function (capability) { - if (vm.capabilitiesSet[capability.id]) { - return; - } - - availableCapabilitiesGrouped.push({ - group: capability.category, - key: capability.id, - value: capability.name, - tooltip: capability.description, - }); - }); - vm.availableCapabilitiesGrouped = availableCapabilitiesGrouped; - vm.availableCapabilitiesGrouped.sort(function (lhs, rhs) { - if (lhs.group === rhs.group) { - if (lhs.value === rhs.value) { - return 0; - } - return lhs.value < rhs.value ? -1 : 1; - } - return lhs.group < rhs.group ? -1 : 1; - }); - } - - function onToggleCapability(isAdd) { - vm.isAddingCapability = isAdd; - - vm.capabilityToAddOrRemove = null; - vm.availableCapabilities.forEach(function (capability) { - if (capability.id === vm.capabilityToAddOrRemoveId) { - vm.capabilityToAddOrRemove = capability; - } - }); - - $element.find('.confirmCapabilityToggle').modal({ - dismissible: false, - yes: function () { - }, - }).modal('open'); - } - - function toggleCapability() { - if (vm.isAddingCapability) { - addCapability(vm.capabilityToAddOrRemove); - } else { - removeCapability(vm.capabilityToAddOrRemove); - } - } - - function addCapability(capability) { - vm.isBusy = true; - piwikApi.post({ - method: 'UsersManager.addCapabilities', - }, { - userLogin: vm.userLogin, - capabilities: capability.id, - idSites: vm.idsite - }).then(function () { - vm.onCapabilitiesChange.call({ - capabilities: getCapabilitiesList(), - }); - - setCapabilitiesSet(); - setAvailableCapabilitiesDropdown(); - })['finally'](function () { - vm.isBusy = false; - vm.capabilityToAddOrRemove = null; - vm.capabilityToAddOrRemoveId = null; - }); - } - - function removeCapability(capability) { - vm.isBusy = true; - piwikApi.post({ - method: 'UsersManager.removeCapabilities', - }, { - userLogin: vm.userLogin, - capabilities: capability.id, - idSites: vm.idsite - }).then(function () { - vm.onCapabilitiesChange.call({ - capabilities: getCapabilitiesList(), - }); - - setCapabilitiesSet(); - setAvailableCapabilitiesDropdown(); - })['finally'](function () { - vm.isBusy = false; - vm.capabilityToAddOrRemove = null; - vm.capabilityToAddOrRemoveId = null; - }); - } - - function getCapabilitiesList() { - var result = []; - vm.availableCapabilities.forEach(function (capability) { - if (vm.isIncludedInRole(capability)) { - return; - } - - if (vm.capabilitiesSet[capability.id]) { - result.push(capability.id); - } - }); - return result; - } - } -})(); diff --git a/plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.less b/plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.less deleted file mode 100644 index 8a0305bfcd..0000000000 --- a/plugins/UsersManager/angularjs/capabilities-edit/capabilities-edit.component.less +++ /dev/null @@ -1,76 +0,0 @@ -.capabilitiesEdit { - display: inline-block; - margin-bottom: -8px; - - > div.chip { - margin-right: 8px; - display: inline-block; - margin-bottom: 8px; - - span.capability-name { - padding-right: .4rem; - } - - > span.icon-close { - font-size: .6rem; - float: right; - margin-top: 1.4em; - cursor: pointer; - } - } - - .addCapability { - display: inline-block; - margin-bottom: 8px; - vertical-align: bottom; - - .input-field { - margin-top: 0; - .caret { - right: -25px; - top: 16px; - z-index: 9; - cursor: pointer; - } - .select-dropdown { - margin-top: 8px; - margin-bottom: 0; - border: 0; - background: #e4e4e4; - display: inline-block; - height: 32px; - font-size: 13px; - font-weight: 500; - color: rgba(0,0,0,0.6); - line-height: 32px; - border-radius: 3em; - padding-left: 12px; - padding-right: 30px; - } - } - - .select-wrapper { - transform: scale(.89) translate(-.6rem); - margin-top: -0.55rem; - max-width: 160px; - - input { - margin-bottom: 0; - height: 2rem; - line-height: 2rem; - } - } - } - - &.busy { - opacity: 0.5; - } - - .confirmCapabilityToggle { - .modal-no { - margin-left: 1em; - margin-right: 1em; - margin-top: 1em; - } - } -} \ No newline at end of file diff --git a/plugins/UsersManager/angularjs/capability-edit/capability-edit.component.html b/plugins/UsersManager/angularjs/capability-edit/capability-edit.component.html deleted file mode 100644 index e20609a83b..0000000000 --- a/plugins/UsersManager/angularjs/capability-edit/capability-edit.component.html +++ /dev/null @@ -1,3 +0,0 @@ -
- {{ capabilityEdit.myProperty }} -
\ No newline at end of file diff --git a/plugins/UsersManager/angularjs/capability-edit/capability-edit.component.less b/plugins/UsersManager/angularjs/capability-edit/capability-edit.component.less deleted file mode 100644 index a59690b170..0000000000 --- a/plugins/UsersManager/angularjs/capability-edit/capability-edit.component.less +++ /dev/null @@ -1,3 +0,0 @@ -.capabilityEdit { - // ... -} \ No newline at end of file diff --git a/plugins/UsersManager/angularjs/permissions-metadata/permissions-metadata.service.js b/plugins/UsersManager/angularjs/permissions-metadata/permissions-metadata.service.js deleted file mode 100644 index 1728041412..0000000000 --- a/plugins/UsersManager/angularjs/permissions-metadata/permissions-metadata.service.js +++ /dev/null @@ -1,35 +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: - * - */ -(function () { - angular.module('piwikApp').factory('permissionsMetadataService', PermissionsMetadataService); - - PermissionsMetadataService.$inject = ['piwikApi', '$q']; - - function PermissionsMetadataService(piwikApi, $q) { - var allCapabilities; - - return { - getAllCapabilities: function () { - if (allCapabilities) { - return $q.when(allCapabilities); - } - - return piwikApi.fetch({ - method: 'UsersManager.getAvailableCapabilities', - }).then(function (capabilities) { - allCapabilities = capabilities; - return allCapabilities; - }); - }, - }; - } -})(); diff --git a/plugins/UsersManager/tests/UI/UsersManager_spec.js b/plugins/UsersManager/tests/UI/UsersManager_spec.js index e53e654cd3..475bba3d8c 100644 --- a/plugins/UsersManager/tests/UI/UsersManager_spec.js +++ b/plugins/UsersManager/tests/UI/UsersManager_spec.js @@ -332,6 +332,7 @@ describe("UsersManager", function () { it('should select all displayed rows when the select all checkbox is clicked', async function () { await page.click('.userPermissionsEdit th.select-cell input + span'); await page.waitForTimeout(250); // for checkbox animations + await page.mouse.move(-10, -10); expect(await page.screenshotSelector('.usersManager')).to.matchImage({ imageName: 'permissions_select_all', diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_all_sites_access.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_all_sites_access.png index ca5768d6ef..3ce1307b10 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_all_sites_access.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_all_sites_access.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d508ef919076c7de2aca6ef361ca5d8c508d340b1bc6d2a3e60e3ca6314bb34e -size 102083 +oid sha256:1187cff49198d1ec7784bcf8ef9c57813b4325c0e6778117dd32b30d777c4594 +size 100480 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_bulk_access_set_all.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_bulk_access_set_all.png index 19208deb3b..f6531a6194 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_bulk_access_set_all.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_bulk_access_set_all.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:990108c86e38681e565ccd517fb02369ad98f43a80e7892fe33a940781176596 -size 80978 +oid sha256:aaffd292e9b45fe77a6985984a20507d4ac198078074139c4b83eeab1fc0b2b7 +size 80848 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_capability_single_site.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_capability_single_site.png index 50f12fb58a..9365527f47 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_capability_single_site.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_capability_single_site.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9484fcaf803922946c6cdbddfcfce0908fed6e77619655022d2454ed595f3f4d -size 92451 +oid sha256:7245e5f4269836c8e2cde0c44de8ddb12423eb63f2e36d1ddb72c2926225ea5d +size 92457 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_next.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_next.png index b655bd93ca..f22b6b6284 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_next.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_next.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:846991e7dfd320e07e82212bc46bd7bef663289c17863a81f6881aef5df58698 -size 92113 +oid sha256:2ec58a4d3d51a8b13bad20f858453cba578e68b5a946ecede4d2b0174a76d83f +size 92466 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_remove_single.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_remove_single.png index efeb7da210..367f2c5b10 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_remove_single.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_remove_single.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5b1ac3c0fba9928c19cb39b56cc13ce064f9a8359e2fe91ee887269efd7b64e1 -size 90338 +oid sha256:86efc969c58f87ddfe9df3451d585cfe3710d851354e71f4d45b52225b03c320 +size 90565 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_select_multiple.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_select_multiple.png index 0436cb04b7..69215c0e74 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_select_multiple.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_select_multiple.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4b68f0989997324e8575cfaa9ad1ba67bdc62aad3673626a1af495f74749bcba -size 92270 +oid sha256:bb5d14dcd6075e80cdbf488ad9e03dc6a830dbfb8b31b3f0a172c9396697c82b +size 92579 diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_single_site_access.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_single_site_access.png index 52d4c428fb..ab419ee5f9 100644 --- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_single_site_access.png +++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_single_site_access.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c69e778f61c9697067eea1cf4da7293161b3e19fd5d20d8523a7cb87cc36a0e2 -size 89089 +oid sha256:cec452b68a9801e37be4050f2454d5656844c5ccdd31af643d1e0583dbf8df08 +size 89100 diff --git a/plugins/UsersManager/vue/dist/UsersManager.umd.js b/plugins/UsersManager/vue/dist/UsersManager.umd.js new file mode 100644 index 0000000000..ae145d094b --- /dev/null +++ b/plugins/UsersManager/vue/dist/UsersManager.umd.js @@ -0,0 +1,596 @@ +(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["UsersManager"] = factory(require("CoreHome"), require("vue"), require("CorePluginsAdmin")); + else + root["UsersManager"] = 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/UsersManager/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__, "CapabilitiesEdit", function() { return /* reexport */ CapabilitiesEdit; }); + +// 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 "CoreHome" +var external_CoreHome_ = __webpack_require__("19dc"); + +// EXTERNAL MODULE: external {"commonjs":"vue","commonjs2":"vue","root":"Vue"} +var external_commonjs_vue_commonjs2_vue_root_Vue_ = __webpack_require__("8bbf"); + +// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-babel/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/@vue/cli-plugin-babel/node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/templateLoader.js??ref--6!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.vue?vue&type=template&id=259d8ccf + +var _hoisted_1 = ["title"]; +var _hoisted_2 = ["onClick"]; +var _hoisted_3 = { + key: 0, + class: "addCapability" +}; +var _hoisted_4 = { + class: "ui-confirm confirmCapabilityToggle modal", + ref: "confirmCapabilityToggleModal" +}; +var _hoisted_5 = { + class: "modal-content" +}; +var _hoisted_6 = ["innerHTML"]; +var _hoisted_7 = ["innerHTML"]; +var _hoisted_8 = { + class: "modal-footer" +}; +function render(_ctx, _cache, $props, $setup, $data, $options) { + var _component_Field = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["resolveComponent"])("Field"); + + return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", { + class: Object(external_commonjs_vue_commonjs2_vue_root_Vue_["normalizeClass"])(["capabilitiesEdit", { + busy: _ctx.isBusy + }]) + }, [(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.actualCapabilities, function (capability) { + return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", { + key: capability.id, + class: "chip" + }, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("span", { + class: "capability-name", + title: "".concat(capability.description, " ").concat(_ctx.isIncludedInRole(capability) ? "

".concat(_ctx.translate('UsersManager_IncludedInUsersRole')) : '') + }, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(capability.category) + ": " + Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(capability.name), 9, _hoisted_1), !_ctx.isIncludedInRole(capability) ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("span", { + key: 0, + class: "icon-close", + onClick: function onClick($event) { + _ctx.capabilityToRemoveId = capability.id; + + _ctx.onToggleCapability(false); + } + }, null, 8, _hoisted_2)) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true)]); + }), 128)), _ctx.availableCapabilitiesGrouped.length ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("div", _hoisted_3, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createVNode"])(_component_Field, { + "model-value": _ctx.capabilityToAddId, + "onUpdate:modelValue": _cache[0] || (_cache[0] = function ($event) { + _ctx.capabilityToAddId = $event; + + _ctx.onToggleCapability(true); + }), + disabled: _ctx.isBusy, + uicontrol: "expandable-select", + name: "add_capability", + "full-width": true, + options: _ctx.availableCapabilitiesGrouped + }, null, 8, ["model-value", "disabled", "options"])])) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_4, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_5, [_ctx.isAddingCapability ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("h2", { + key: 0, + innerHTML: _ctx.$sanitize(_ctx.confirmAddCapabilityToggleContent) + }, null, 8, _hoisted_6)) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true), !_ctx.isAddingCapability ? (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["openBlock"])(), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementBlock"])("h2", { + key: 1, + innerHTML: _ctx.$sanitize(_ctx.confirmCapabilityToggleContent) + }, null, 8, _hoisted_7)) : Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createCommentVNode"])("", true)]), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("div", _hoisted_8, [Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("a", { + href: "", + class: "modal-action modal-close btn", + onClick: _cache[1] || (_cache[1] = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withModifiers"])(function ($event) { + return _ctx.toggleCapability(); + }, ["prevent"])) + }, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('General_Yes')), 1), Object(external_commonjs_vue_commonjs2_vue_root_Vue_["createElementVNode"])("a", { + href: "", + class: "modal-action modal-close modal-no", + onClick: _cache[2] || (_cache[2] = Object(external_commonjs_vue_commonjs2_vue_root_Vue_["withModifiers"])(function ($event) { + _ctx.capabilityToAddOrRemove = null; + _ctx.capabilityToAddId = null; + _ctx.capabilityToRemoveId = null; + }, ["prevent"])) + }, Object(external_commonjs_vue_commonjs2_vue_root_Vue_["toDisplayString"])(_ctx.translate('General_No')), 1)])], 512)], 2); +} +// CONCATENATED MODULE: ./plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.vue?vue&type=template&id=259d8ccf + +// EXTERNAL MODULE: external "CorePluginsAdmin" +var external_CorePluginsAdmin_ = __webpack_require__("a5a2"); + +// CONCATENATED MODULE: ./plugins/UsersManager/vue/src/CapabilitiesStore/CapabilitiesStore.ts +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +/*! + * Matomo - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + + + +var CapabilitiesStore_CapabilitiesStore = /*#__PURE__*/function () { + function CapabilitiesStore() { + var _this = this; + + _classCallCheck(this, CapabilitiesStore); + + _defineProperty(this, "privateState", Object(external_commonjs_vue_commonjs2_vue_root_Vue_["reactive"])({ + isLoading: false, + capabilities: [] + })); + + _defineProperty(this, "state", Object(external_commonjs_vue_commonjs2_vue_root_Vue_["computed"])(function () { + return Object(external_commonjs_vue_commonjs2_vue_root_Vue_["readonly"])(_this.privateState); + })); + + _defineProperty(this, "capabilities", Object(external_commonjs_vue_commonjs2_vue_root_Vue_["computed"])(function () { + return _this.state.value.capabilities; + })); + + _defineProperty(this, "isLoading", Object(external_commonjs_vue_commonjs2_vue_root_Vue_["computed"])(function () { + return _this.state.value.isLoading; + })); + + _defineProperty(this, "fetchPromise", void 0); + + this.fetchCapabilities(); + } + + _createClass(CapabilitiesStore, [{ + key: "fetchCapabilities", + value: function fetchCapabilities() { + var _this2 = this; + + if (!this.fetchPromise) { + this.privateState.isLoading = true; + this.fetchPromise = external_CoreHome_["AjaxHelper"].fetch({ + method: 'UsersManager.getAvailableCapabilities' + }).then(function (capabilities) { + _this2.privateState.capabilities = capabilities; + return _this2.capabilities.value; + }).finally(function () { + _this2.privateState.isLoading = false; + }); + } + + return this.fetchPromise; + } + }]); + + return CapabilitiesStore; +}(); + +/* harmony default export */ var src_CapabilitiesStore_CapabilitiesStore = (Object(external_CoreHome_["lazyInitSingleton"])(CapabilitiesStore_CapabilitiesStore)); +// CONCATENATED MODULE: ./node_modules/@vue/cli-plugin-typescript/node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/@vue/cli-plugin-typescript/node_modules/ts-loader??ref--14-2!./node_modules/@vue/cli-service/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist??ref--0-1!./plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.vue?vue&type=script&lang=ts + + + + +var _window = window, + $ = _window.$; +/* harmony default export */ var CapabilitiesEditvue_type_script_lang_ts = (Object(external_commonjs_vue_commonjs2_vue_root_Vue_["defineComponent"])({ + props: { + idsite: [String, Number], + siteName: { + type: String, + required: true + }, + userLogin: { + type: String, + required: true + }, + userRole: { + type: String, + required: true + }, + capabilities: Array + }, + components: { + Field: external_CorePluginsAdmin_["Field"] + }, + data: function data() { + return { + theCapabilities: this.capabilities || [], + isBusy: false, + isAddingCapability: false, + capabilityToAddId: null, + capabilityToRemoveId: null, + capabilityToAddOrRemove: null + }; + }, + emits: ['change'], + watch: { + capabilities: function capabilities(newValue) { + if (newValue) { + this.theCapabilities = newValue; + } + } + }, + created: function created() { + var _this = this; + + if (!this.capabilities) { + this.isBusy = true; + external_CoreHome_["AjaxHelper"].fetch({ + method: 'UsersManager.getUsersPlusRole', + limit: '1', + filter_search: this.userLogin + }).then(function (user) { + if (!user || !user.capabilities) { + return []; + } + + return user.capabilities; + }).then(function (capabilities) { + _this.theCapabilities = capabilities; + }).finally(function () { + _this.isBusy = false; + }); + } else { + this.theCapabilities = this.capabilities; + } + }, + methods: { + onToggleCapability: function onToggleCapability(isAdd) { + var _this2 = this; + + this.isAddingCapability = isAdd; + var capabilityToAddOrRemoveId = isAdd ? this.capabilityToAddId : this.capabilityToRemoveId; + this.capabilityToAddOrRemove = null; + this.availableCapabilities.forEach(function (capability) { + if (capability.id === capabilityToAddOrRemoveId) { + _this2.capabilityToAddOrRemove = capability; + } + }); + + if (this.$refs.confirmCapabilityToggleModal) { + $(this.$refs.confirmCapabilityToggleModal).modal({ + dismissible: false, + yes: function yes() { + return null; + } + }).modal('open'); + } + }, + toggleCapability: function toggleCapability() { + if (this.isAddingCapability) { + this.addCapability(this.capabilityToAddOrRemove); + } else { + this.removeCapability(this.capabilityToAddOrRemove); + } + }, + isIncludedInRole: function isIncludedInRole(capability) { + return (capability.includedInRoles || []).indexOf(this.userRole) !== -1; + }, + getCapabilitiesList: function getCapabilitiesList() { + var _this3 = this; + + var result = []; + this.availableCapabilities.forEach(function (capability) { + if (_this3.isIncludedInRole(capability)) { + return; + } + + if (_this3.capabilitiesSet[capability.id]) { + result.push(capability.id); + } + }); + return result; + }, + addCapability: function addCapability(capability) { + var _this4 = this; + + this.isBusy = true; + external_CoreHome_["AjaxHelper"].post({ + method: 'UsersManager.addCapabilities' + }, { + userLogin: this.userLogin, + capabilities: capability.id, + idSites: this.idsite + }).then(function () { + _this4.$emit('change', _this4.getCapabilitiesList()); + }).finally(function () { + _this4.isBusy = false; + _this4.capabilityToAddOrRemove = null; + _this4.capabilityToAddId = null; + _this4.capabilityToRemoveId = null; + }); + }, + removeCapability: function removeCapability(capability) { + var _this5 = this; + + this.isBusy = true; + external_CoreHome_["AjaxHelper"].post({ + method: 'UsersManager.removeCapabilities' + }, { + userLogin: this.userLogin, + capabilities: capability.id, + idSites: this.idsite + }).then(function () { + _this5.$emit('change', _this5.getCapabilitiesList()); + }).finally(function () { + _this5.isBusy = false; + _this5.capabilityToAddOrRemove = null; + _this5.capabilityToAddId = null; + _this5.capabilityToRemoveId = null; + }); + } + }, + computed: { + availableCapabilities: function availableCapabilities() { + return src_CapabilitiesStore_CapabilitiesStore.capabilities.value; + }, + confirmAddCapabilityToggleContent: function confirmAddCapabilityToggleContent() { + return Object(external_CoreHome_["translate"])('UsersManager_AreYouSureAddCapability', "".concat(this.userLogin, ""), "".concat(this.capabilityToAddOrRemove ? this.capabilityToAddOrRemove.name : '', ""), "".concat(this.siteNameText, "")); + }, + confirmCapabilityToggleContent: function confirmCapabilityToggleContent() { + return Object(external_CoreHome_["translate"])('UsersManager_AreYouSureRemoveCapability', "".concat(this.capabilityToAddOrRemove ? this.capabilityToAddOrRemove.name : '', ""), "".concat(this.userLogin, ""), "".concat(this.siteNameText, "")); + }, + siteNameText: function siteNameText() { + return external_CoreHome_["Matomo"].helper.htmlEntities(this.siteName); + }, + availableCapabilitiesGrouped: function availableCapabilitiesGrouped() { + var _this6 = this; + + var availableCapabilitiesGrouped = this.availableCapabilities.filter(function (c) { + return !_this6.capabilitiesSet[c.id]; + }).map(function (c) { + return { + group: c.category, + key: c.id, + value: c.name, + tooltip: c.description + }; + }); + availableCapabilitiesGrouped.sort(function (lhs, rhs) { + if (lhs.group === rhs.group) { + if (lhs.value === rhs.value) { + return 0; + } + + return lhs.value < rhs.value ? -1 : 1; + } + + return lhs.group < rhs.group ? -1 : 1; + }); + return availableCapabilitiesGrouped; + }, + capabilitiesSet: function capabilitiesSet() { + var _this7 = this; + + var capabilitiesSet = {}; + var capabilities = this.theCapabilities; + (capabilities || []).forEach(function (capability) { + capabilitiesSet[capability] = true; + }); + (this.availableCapabilities || []).forEach(function (capability) { + if (_this7.isIncludedInRole(capability)) { + capabilitiesSet[capability.id] = true; + } + }); + return capabilitiesSet; + }, + actualCapabilities: function actualCapabilities() { + var capabilitiesSet = this.capabilitiesSet; + return this.availableCapabilities.filter(function (c) { + return !!capabilitiesSet[c.id]; + }); + } + } +})); +// CONCATENATED MODULE: ./plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.vue?vue&type=script&lang=ts + +// CONCATENATED MODULE: ./plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.vue + + + +CapabilitiesEditvue_type_script_lang_ts.render = render + +/* harmony default export */ var CapabilitiesEdit = (CapabilitiesEditvue_type_script_lang_ts); +// CONCATENATED MODULE: ./plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.adapter.ts +/*! + * Matomo - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + + +/* harmony default export */ var CapabilitiesEdit_adapter = (Object(external_CoreHome_["createAngularJsAdapter"])({ + component: CapabilitiesEdit, + scope: { + idsite: { + angularJsBind: '<' + }, + siteName: { + angularJsBind: '<' + }, + userLogin: { + angularJsBind: '<' + }, + userRole: { + angularJsBind: '<' + }, + capabilities: { + angularJsBind: '<' + }, + onCapabilitiesChange: { + angularJsBind: '&', + vue: 'change' + } + }, + directiveName: 'piwikCapabilitiesEdit', + restrict: 'E', + $inject: ['$timeout'], + events: { + change: function change(caps, vm, scope, element, attrs, controller, $timeout) { + $timeout(function () { + if (scope.onCapabilitiesChange) { + scope.onCapabilitiesChange.call({ + capabilities: caps + }); + } + }); + } + } +})); +// CONCATENATED MODULE: ./plugins/UsersManager/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=UsersManager.umd.js.map \ No newline at end of file diff --git a/plugins/UsersManager/vue/dist/UsersManager.umd.min.js b/plugins/UsersManager/vue/dist/UsersManager.umd.min.js new file mode 100644 index 0000000000..2a1f272e0c --- /dev/null +++ b/plugins/UsersManager/vue/dist/UsersManager.umd.min.js @@ -0,0 +1,14 @@ +(function(e,i){"object"===typeof exports&&"object"===typeof module?module.exports=i(require("CoreHome"),require("vue"),require("CorePluginsAdmin")):"function"===typeof define&&define.amd?define(["CoreHome",,"CorePluginsAdmin"],i):"object"===typeof exports?exports["UsersManager"]=i(require("CoreHome"),require("vue"),require("CorePluginsAdmin")):e["UsersManager"]=i(e["CoreHome"],e["Vue"],e["CorePluginsAdmin"])})("undefined"!==typeof self?self:this,(function(e,i,t){return function(e){var i={};function t(a){if(i[a])return i[a].exports;var n=i[a]={i:a,l:!1,exports:{}};return e[a].call(n.exports,n,n.exports,t),n.l=!0,n.exports}return t.m=e,t.c=i,t.d=function(e,i,a){t.o(e,i)||Object.defineProperty(e,i,{enumerable:!0,get:a})},t.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,i){if(1&i&&(e=t(e)),8&i)return e;if(4&i&&"object"===typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(t.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&i&&"string"!=typeof e)for(var n in e)t.d(a,n,function(i){return e[i]}.bind(null,n));return a},t.n=function(e){var i=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(i,"a",i),i},t.o=function(e,i){return Object.prototype.hasOwnProperty.call(e,i)},t.p="plugins/UsersManager/vue/dist/",t(t.s="fae3")}({"19dc":function(i,t){i.exports=e},"8bbf":function(e,t){e.exports=i},a5a2:function(e,i){e.exports=t},fae3:function(e,i,t){"use strict";if(t.r(i),t.d(i,"CapabilitiesEdit",(function(){return B})),"undefined"!==typeof window){var a=window.document.currentScript,n=a&&a.src.match(/(.+\/)[^/]+\.js(\?.*)?$/);n&&(t.p=n[1])}var o=t("19dc"),l=t("8bbf"),r=["title"],s=["onClick"],c={key:0,class:"addCapability"},u={class:"ui-confirm confirmCapabilityToggle modal",ref:"confirmCapabilityToggleModal"},d={class:"modal-content"},p=["innerHTML"],b=["innerHTML"],f={class:"modal-footer"};function m(e,i,t,a,n,o){var m=Object(l["resolveComponent"])("Field");return Object(l["openBlock"])(),Object(l["createElementBlock"])("div",{class:Object(l["normalizeClass"])(["capabilitiesEdit",{busy:e.isBusy}])},[(Object(l["openBlock"])(!0),Object(l["createElementBlock"])(l["Fragment"],null,Object(l["renderList"])(e.actualCapabilities,(function(i){return Object(l["openBlock"])(),Object(l["createElementBlock"])("div",{key:i.id,class:"chip"},[Object(l["createElementVNode"])("span",{class:"capability-name",title:"".concat(i.description," ").concat(e.isIncludedInRole(i)?"

".concat(e.translate("UsersManager_IncludedInUsersRole")):"")},Object(l["toDisplayString"])(i.category)+": "+Object(l["toDisplayString"])(i.name),9,r),e.isIncludedInRole(i)?Object(l["createCommentVNode"])("",!0):(Object(l["openBlock"])(),Object(l["createElementBlock"])("span",{key:0,class:"icon-close",onClick:function(t){e.capabilityToRemoveId=i.id,e.onToggleCapability(!1)}},null,8,s))])})),128)),e.availableCapabilitiesGrouped.length?(Object(l["openBlock"])(),Object(l["createElementBlock"])("div",c,[Object(l["createVNode"])(m,{"model-value":e.capabilityToAddId,"onUpdate:modelValue":i[0]||(i[0]=function(i){e.capabilityToAddId=i,e.onToggleCapability(!0)}),disabled:e.isBusy,uicontrol:"expandable-select",name:"add_capability","full-width":!0,options:e.availableCapabilitiesGrouped},null,8,["model-value","disabled","options"])])):Object(l["createCommentVNode"])("",!0),Object(l["createElementVNode"])("div",u,[Object(l["createElementVNode"])("div",d,[e.isAddingCapability?(Object(l["openBlock"])(),Object(l["createElementBlock"])("h2",{key:0,innerHTML:e.$sanitize(e.confirmAddCapabilityToggleContent)},null,8,p)):Object(l["createCommentVNode"])("",!0),e.isAddingCapability?Object(l["createCommentVNode"])("",!0):(Object(l["openBlock"])(),Object(l["createElementBlock"])("h2",{key:1,innerHTML:e.$sanitize(e.confirmCapabilityToggleContent)},null,8,b))]),Object(l["createElementVNode"])("div",f,[Object(l["createElementVNode"])("a",{href:"",class:"modal-action modal-close btn",onClick:i[1]||(i[1]=Object(l["withModifiers"])((function(i){return e.toggleCapability()}),["prevent"]))},Object(l["toDisplayString"])(e.translate("General_Yes")),1),Object(l["createElementVNode"])("a",{href:"",class:"modal-action modal-close modal-no",onClick:i[2]||(i[2]=Object(l["withModifiers"])((function(i){e.capabilityToAddOrRemove=null,e.capabilityToAddId=null,e.capabilityToRemoveId=null}),["prevent"]))},Object(l["toDisplayString"])(e.translate("General_No")),1)])],512)],2)}var g=t("a5a2");function h(e,i){if(!(e instanceof i))throw new TypeError("Cannot call a class as a function")}function y(e,i){for(var t=0;t".concat(this.userLogin,""),"".concat(this.capabilityToAddOrRemove?this.capabilityToAddOrRemove.name:"",""),"".concat(this.siteNameText,""))},confirmCapabilityToggleContent:function(){return Object(o["translate"])("UsersManager_AreYouSureRemoveCapability","".concat(this.capabilityToAddOrRemove?this.capabilityToAddOrRemove.name:"",""),"".concat(this.userLogin,""),"".concat(this.siteNameText,""))},siteNameText:function(){return o["Matomo"].helper.htmlEntities(this.siteName)},availableCapabilitiesGrouped:function(){var e=this,i=this.availableCapabilities.filter((function(i){return!e.capabilitiesSet[i.id]})).map((function(e){return{group:e.category,key:e.id,value:e.name,tooltip:e.description}}));return i.sort((function(e,i){return e.group===i.group?e.value===i.value?0:e.value({ + component: CapabilitiesEdit, + scope: { + idsite: { + angularJsBind: '<', + }, + siteName: { + angularJsBind: '<', + }, + userLogin: { + angularJsBind: '<', + }, + userRole: { + angularJsBind: '<', + }, + capabilities: { + angularJsBind: '<', + }, + onCapabilitiesChange: { + angularJsBind: '&', + vue: 'change', + }, + }, + directiveName: 'piwikCapabilitiesEdit', + restrict: 'E', + $inject: ['$timeout'], + events: { + change(caps: Capability[], vm, scope, element, attrs, controller, $timeout) { + $timeout(() => { + if (scope.onCapabilitiesChange) { + scope.onCapabilitiesChange.call({ + capabilities: caps, + }); + } + }); + }, + }, +}); diff --git a/plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.less b/plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.less new file mode 100644 index 0000000000..3d4cf06b95 --- /dev/null +++ b/plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.less @@ -0,0 +1,76 @@ +.capabilitiesEdit { + display: inline-block; + margin-bottom: -8px; + + div.chip { + margin-right: 8px; + display: inline-block; + margin-bottom: 8px; + + span.capability-name { + padding-right: .4rem; + } + + span.icon-close { + font-size: .6rem; + float: right; + margin-top: 1.4em; + cursor: pointer; + } + } + + .addCapability { + display: inline-block; + margin-bottom: 8px; + vertical-align: bottom; + + .input-field { + margin-top: 0; + .caret { + right: -25px; + top: 16px; + z-index: 9; + cursor: pointer; + } + .select-dropdown { + margin-top: 8px; + margin-bottom: 0; + border: 0; + background: #e4e4e4; + display: inline-block; + height: 32px; + font-size: 13px; + font-weight: 500; + color: rgba(0,0,0,0.6); + line-height: 32px; + border-radius: 3em; + padding-left: 12px; + padding-right: 30px; + } + } + + .select-wrapper { + transform: scale(.89) translate(-.6rem); + margin-top: -0.55rem; + max-width: 160px; + + input { + margin-bottom: 0; + height: 2rem; + line-height: 2rem; + } + } + } + + &.busy { + opacity: 0.5; + } + + .confirmCapabilityToggle { + .modal-no { + margin-left: 1em; + margin-right: 1em; + margin-top: 1em; + } + } +} \ No newline at end of file diff --git a/plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.vue b/plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.vue new file mode 100644 index 0000000000..e1c226b56e --- /dev/null +++ b/plugins/UsersManager/vue/src/CapabilitiesEdit/CapabilitiesEdit.vue @@ -0,0 +1,311 @@ + + + + + diff --git a/plugins/UsersManager/vue/src/CapabilitiesStore/CapabilitiesStore.adapter.ts b/plugins/UsersManager/vue/src/CapabilitiesStore/CapabilitiesStore.adapter.ts new file mode 100644 index 0000000000..dc3f08419f --- /dev/null +++ b/plugins/UsersManager/vue/src/CapabilitiesStore/CapabilitiesStore.adapter.ts @@ -0,0 +1,23 @@ +/*! + * Matomo - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +import { DeepReadonly } from 'vue'; +import Capability from './Capability'; +import CapabilitiesStore from "./CapabilitiesStore"; + +function permissionsMetadataServiceAdapter() { + return { + getAllCapabilities(): Promise> { + return CapabilitiesStore.fetchCapabilities(); + }, + }; +} + +window.angular.module('piwikApp.service').factory( + 'permissionsMetadataService', + permissionsMetadataServiceAdapter, +); diff --git a/plugins/UsersManager/vue/src/CapabilitiesStore/CapabilitiesStore.ts b/plugins/UsersManager/vue/src/CapabilitiesStore/CapabilitiesStore.ts new file mode 100644 index 0000000000..36b3c8113f --- /dev/null +++ b/plugins/UsersManager/vue/src/CapabilitiesStore/CapabilitiesStore.ts @@ -0,0 +1,57 @@ +/*! + * Matomo - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +import { + reactive, + readonly, + computed, + DeepReadonly, +} from 'vue'; +import { AjaxHelper, lazyInitSingleton } from 'CoreHome'; +import Capability from './Capability'; + +interface CapabilitiesStoreState { + isLoading: boolean; + capabilities: Capability[]; +} + +class CapabilitiesStore { + private privateState = reactive({ + isLoading: false, + capabilities: [], + }); + + private readonly state = computed(() => readonly(this.privateState)); + + readonly capabilities = computed(() => this.state.value.capabilities); + + readonly isLoading = computed(() => this.state.value.isLoading); + + private fetchPromise?: Promise>; + + constructor() { + this.fetchCapabilities(); + } + + public fetchCapabilities(): Promise> { + if (!this.fetchPromise) { + this.privateState.isLoading = true; + this.fetchPromise = AjaxHelper.fetch({ + method: 'UsersManager.getAvailableCapabilities', + }).then((capabilities) => { + this.privateState.capabilities = capabilities; + return this.capabilities.value; + }).finally(() => { + this.privateState.isLoading = false; + }); + } + + return this.fetchPromise!; + } +} + +export default lazyInitSingleton(CapabilitiesStore) as CapabilitiesStore; diff --git a/plugins/UsersManager/vue/src/CapabilitiesStore/Capability.ts b/plugins/UsersManager/vue/src/CapabilitiesStore/Capability.ts new file mode 100644 index 0000000000..0f099b8a32 --- /dev/null +++ b/plugins/UsersManager/vue/src/CapabilitiesStore/Capability.ts @@ -0,0 +1,17 @@ +/*! + * Matomo - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +interface Capability { + id: string; + name: string; + description: string; + helpUrl: string; + includedInRoles: string[]; + category: string; +} + +export default Capability; diff --git a/plugins/UsersManager/vue/src/index.ts b/plugins/UsersManager/vue/src/index.ts new file mode 100644 index 0000000000..7411497560 --- /dev/null +++ b/plugins/UsersManager/vue/src/index.ts @@ -0,0 +1,10 @@ +/*! + * Matomo - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +import './CapabilitiesEdit/CapabilitiesEdit.adapter'; + +export { default as CapabilitiesEdit } from './CapabilitiesEdit/CapabilitiesEdit.vue'; +export { default as Capability } from './CapabilitiesStore/Capability'; -- cgit v1.2.3