From 4bb7aae4675164eda6df1527e40d5cea1d0a4b01 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Wed, 10 Feb 2021 12:12:27 -0300 Subject: [PATCH 01/94] Begins implementation of new reports page #483 --- src/views/class-tainacan-admin.php | 42 ++++++++ src/views/reports/js/reports-main.js | 31 ++++++ src/views/reports/js/reports-router.js | 29 ++++++ src/views/reports/js/wp-i18n-plugin.js | 29 ++++++ src/views/reports/pages/reports-list.vue | 20 ++++ src/views/reports/reports.vue | 118 +++++++++++++++++++++++ src/views/reports/tainacan-reports.scss | 3 + webpack.common.js | 1 + 8 files changed, 273 insertions(+) create mode 100644 src/views/reports/js/reports-main.js create mode 100644 src/views/reports/js/reports-router.js create mode 100644 src/views/reports/js/wp-i18n-plugin.js create mode 100644 src/views/reports/pages/reports-list.vue create mode 100644 src/views/reports/reports.vue create mode 100644 src/views/reports/tainacan-reports.scss diff --git a/src/views/class-tainacan-admin.php b/src/views/class-tainacan-admin.php index e8467eb7c..65afcc8ca 100644 --- a/src/views/class-tainacan-admin.php +++ b/src/views/class-tainacan-admin.php @@ -58,6 +58,15 @@ class Admin { array( &$this, 'roles_page' ) ); + $reports_page_suffix = add_submenu_page( + $this->menu_slug, + __('Reports', 'tainacan'), + __('Reports', 'tainacan'), + 'read', + 'tainacan_reports', + array( &$this, 'reports_page' ) + ); + add_submenu_page( $this->menu_slug, __('Item Submission', 'tainacan'), @@ -69,6 +78,7 @@ class Admin { add_action( 'load-' . $page_suffix, array( &$this, 'load_admin_page' ) ); add_action( 'load-' . $roles_page_suffix, array( &$this, 'load_roles_page' ) ); + add_action( 'load-' . $reports_page_suffix, array( &$this, 'load_reports_page' ) ); } function load_admin_page() { @@ -82,6 +92,11 @@ class Admin { add_action( 'admin_enqueue_scripts', array( &$this, 'add_roles_js' ), 90 ); } + function load_reports_page() { + add_action( 'admin_enqueue_scripts', array( &$this, 'add_reports_css' ), 90 ); + add_action( 'admin_enqueue_scripts', array( &$this, 'add_reports_js' ), 90 ); + } + function login_styles_reset( $style ) { if ( strpos( $style, 'wp-admin-css' ) !== false ) { $style = null; @@ -130,6 +145,33 @@ class Admin { echo "
"; } + function add_reports_css() { + global $TAINACAN_BASE_URL; + + wp_enqueue_style( 'tainacan-reports-page', $TAINACAN_BASE_URL . '/assets/css/tainacan-reports.css', [], TAINACAN_VERSION ); + } + + function add_reports_js() { + + global $TAINACAN_BASE_URL; + + wp_enqueue_script( 'tainacan-reports', $TAINACAN_BASE_URL . '/assets/js/reports.js', ['underscore', 'wp-i18n'], TAINACAN_VERSION, true ); + wp_set_script_translations('tainacan-reports', 'tainacan'); + + $settings = $this->get_admin_js_localization_params(); + wp_localize_script( 'tainacan-reports', 'tainacan_plugin', $settings ); + wp_enqueue_script('underscore'); + wp_enqueue_script('wp-i18n'); + + do_action('tainacan-enqueue-reports-scripts'); + } + + function reports_page() { + global $TAINACAN_BASE_URL; + // TODO move it to a separate file and start the Vue project + echo "
"; + } + function add_admin_css() { global $TAINACAN_BASE_URL; diff --git a/src/views/reports/js/reports-main.js b/src/views/reports/js/reports-main.js new file mode 100644 index 000000000..bc6f626b9 --- /dev/null +++ b/src/views/reports/js/reports-main.js @@ -0,0 +1,31 @@ +import Vue from 'vue'; +import store from '../../admin/js/store/store'; +import router from './reports-router'; +import VTooltip from 'v-tooltip'; +import { Snackbar, Modal } from 'buefy'; + +// Vue Dev Tools! +Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development'; + +import { I18NPlugin } from './wp-i18n-plugin'; + +import ReportsPage from '../reports.vue'; + +Vue.use(I18NPlugin); +Vue.use(VTooltip); +Vue.use(Snackbar); +Vue.use(Modal); + +// Changing title of pages +router.beforeEach((to, from, next) => { + document.title = to.meta.title; + if (next() != undefined) + next(); +}); + +new Vue({ + el: '#tainacan-reports-app', + store, + router, + render: h => h(ReportsPage) +}); \ No newline at end of file diff --git a/src/views/reports/js/reports-router.js b/src/views/reports/js/reports-router.js new file mode 100644 index 000000000..5de88c64d --- /dev/null +++ b/src/views/reports/js/reports-router.js @@ -0,0 +1,29 @@ +import Vue from 'vue'; +import VueRouter from 'vue-router' +import qs from 'qs'; + +import ReportsList from '../pages/reports-list.vue'; + +const { __ } = wp.i18n; + +Vue.use(VueRouter); + +const routes = [ + { path: '/', redirect:'/reports' }, + { path: '/reports', name: 'ReportsList', component: ReportsList, meta: { title: __('Tainacan Reports') } }, + + { path: '*', redirect: '/'} +]; + +export default new VueRouter ({ + routes, + // set custom query resolver + parseQuery(query) { + return qs.parse(query); + }, + stringifyQuery(query) { + let result = qs.stringify(query); + + return result ? ('?' + result) : ''; + } +}); \ No newline at end of file diff --git a/src/views/reports/js/wp-i18n-plugin.js b/src/views/reports/js/wp-i18n-plugin.js new file mode 100644 index 000000000..e6e6c79cc --- /dev/null +++ b/src/views/reports/js/wp-i18n-plugin.js @@ -0,0 +1,29 @@ + +const { __, _x, _n, _nx } = wp.i18n; + +/** + I18N PLUGIN - Allows access to Wordpress translation functions. + __( '__', 'my-domain' ); + _x( '_x', '_x_context', 'my-domain' ); + _n( '_n_single', '_n_plural', number, 'my-domain' ); + _nx( '_nx_single', '_nx_plural', number, '_nx_context', 'my-domain' ); +**/ +export const I18NPlugin = {}; +I18NPlugin.install = function (Vue, options = {}) { + + Vue.prototype.$i18n = { + get(key) { + return __(key, 'tainacan'); + }, + getWithContext(key, keyContext) { + return _x(key, keyContext, 'tainacan'); + }, + getWithNumber(keySingle, keyPlural, number) { + return _n(keySingle, keyPlural, number, 'tainacan'); + }, + getWithNumberAndContext(keySingle, keyPlural, number, keyContext) { + return _nx(keySingle, keyPlural, number, keyContext, 'tainacan'); + }, + } + +}; \ No newline at end of file diff --git a/src/views/reports/pages/reports-list.vue b/src/views/reports/pages/reports-list.vue new file mode 100644 index 000000000..9e6518bce --- /dev/null +++ b/src/views/reports/pages/reports-list.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/src/views/reports/reports.vue b/src/views/reports/reports.vue new file mode 100644 index 000000000..3ea847b47 --- /dev/null +++ b/src/views/reports/reports.vue @@ -0,0 +1,118 @@ + + + + + \ No newline at end of file diff --git a/src/views/reports/tainacan-reports.scss b/src/views/reports/tainacan-reports.scss new file mode 100644 index 000000000..b1d22df4b --- /dev/null +++ b/src/views/reports/tainacan-reports.scss @@ -0,0 +1,3 @@ +#tainacan-reports-app { + +} \ No newline at end of file diff --git a/webpack.common.js b/webpack.common.js index d9f4c3091..cb9b14217 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -6,6 +6,7 @@ module.exports = { theme_search: './src/views/theme-search/js/theme-main.js', item_submission: './src/views/item-submission/js/item-submission-main.js', roles: './src/views/roles/js/roles-main.js', + reports: './src/views/reports/js/reports-main.js', block_terms_list: './src/views/gutenberg-blocks/tainacan-terms/terms-list/index.js', From cf4f42d5b1f973066ee183a42f1ea36c9890beb0 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Wed, 10 Feb 2021 15:40:00 -0300 Subject: [PATCH 02/94] Install apexcharts and tests some graphs. --- package-lock.json | 82 +++++++ package.json | 4 +- src/views/reports/components/chart-block.vue | 18 ++ src/views/reports/js/reports-main.js | 7 + src/views/reports/pages/reports-list.vue | 231 ++++++++++++++++++- src/views/reports/reports.vue | 98 +------- src/views/reports/scss/reports-basics.sass | 13 ++ 7 files changed, 353 insertions(+), 100 deletions(-) create mode 100644 src/views/reports/components/chart-block.vue create mode 100644 src/views/reports/scss/reports-basics.sass diff --git a/package-lock.json b/package-lock.json index 75b370569..6efb55564 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1665,6 +1665,19 @@ } } }, + "apexcharts": { + "version": "3.24.0", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.24.0.tgz", + "integrity": "sha512-iT6czJCIVrmAtrcO90MZTQCvC+xi6R6Acf0jNH/d40FVTtCfcqECuKIh5iAMyOTtgUb7+fQ8rbadH2bm1kbL9Q==", + "requires": { + "svg.draggable.js": "^2.2.2", + "svg.easing.js": "^2.0.0", + "svg.filter.js": "^2.0.2", + "svg.pathmorphing.js": "^0.1.3", + "svg.resize.js": "^1.4.3", + "svg.select.js": "^3.0.1" + } + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -9983,6 +9996,70 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" }, + "svg.draggable.js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz", + "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==", + "requires": { + "svg.js": "^2.0.1" + } + }, + "svg.easing.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz", + "integrity": "sha1-iqmUawqOJ4V6XEChDrpAkeVpHxI=", + "requires": { + "svg.js": ">=2.3.x" + } + }, + "svg.filter.js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz", + "integrity": "sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM=", + "requires": { + "svg.js": "^2.2.5" + } + }, + "svg.js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz", + "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" + }, + "svg.pathmorphing.js": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz", + "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==", + "requires": { + "svg.js": "^2.4.0" + } + }, + "svg.resize.js": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz", + "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==", + "requires": { + "svg.js": "^2.6.5", + "svg.select.js": "^2.1.2" + }, + "dependencies": { + "svg.select.js": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz", + "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==", + "requires": { + "svg.js": "^2.2.5" + } + } + } + }, + "svg.select.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz", + "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==", + "requires": { + "svg.js": "^2.6.5" + } + }, "swiper": { "version": "5.4.5", "resolved": "https://registry.npmjs.org/swiper/-/swiper-5.4.5.tgz", @@ -10699,6 +10776,11 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz", "integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==" }, + "vue-apexcharts": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vue-apexcharts/-/vue-apexcharts-1.6.0.tgz", + "integrity": "sha512-sT6tuVTLBwfH3TA7azecDNS/W70bmz14ZJI7aE7QIqcG9I6OywyH7x3hcOeY1v1DxttI8Svc5RuYj4Dd+A5F4g==" + }, "vue-awesome-swiper": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/vue-awesome-swiper/-/vue-awesome-swiper-4.1.1.tgz", diff --git a/package.json b/package.json index 0227f7253..c77aa34c9 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,9 @@ "build-prod": "cross-env NODE_ENV=production webpack --config webpack.prod.js --display-error-details --progress --hide-modules" }, "dependencies": { - "blurhash": "^1.1.3", + "apexcharts": "^3.24.0", "axios": "^0.21.1", + "blurhash": "^1.1.3", "buefy": "^0.9.4", "bulma": "^0.9.1", "css-vars-ponyfill": "^2.3.1", @@ -23,6 +24,7 @@ "t": "^0.5.1", "v-tooltip": "^2.0.3", "vue": "^2.6.11", + "vue-apexcharts": "^1.6.0", "vue-awesome-swiper": "^4.1.1", "vue-blurhash": "^0.1.4", "vue-masonry-css": "^1.0.3", diff --git a/src/views/reports/components/chart-block.vue b/src/views/reports/components/chart-block.vue new file mode 100644 index 000000000..7f8121996 --- /dev/null +++ b/src/views/reports/components/chart-block.vue @@ -0,0 +1,18 @@ + + + \ No newline at end of file diff --git a/src/views/reports/js/reports-main.js b/src/views/reports/js/reports-main.js index bc6f626b9..857994c9e 100644 --- a/src/views/reports/js/reports-main.js +++ b/src/views/reports/js/reports-main.js @@ -3,6 +3,7 @@ import store from '../../admin/js/store/store'; import router from './reports-router'; import VTooltip from 'v-tooltip'; import { Snackbar, Modal } from 'buefy'; +import VueApexCharts from 'vue-apexcharts'; // Vue Dev Tools! Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development'; @@ -10,12 +11,18 @@ Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'develo import { I18NPlugin } from './wp-i18n-plugin'; import ReportsPage from '../reports.vue'; +import ChartBlock from '../components/chart-block.vue'; + +Vue.use(VueApexCharts) Vue.use(I18NPlugin); Vue.use(VTooltip); Vue.use(Snackbar); Vue.use(Modal); +Vue.component('chart-block', ChartBlock); +Vue.component('apexchart', VueApexCharts); + // Changing title of pages router.beforeEach((to, from, next) => { document.title = to.meta.title; diff --git a/src/views/reports/pages/reports-list.vue b/src/views/reports/pages/reports-list.vue index 9e6518bce..346744db7 100644 --- a/src/views/reports/pages/reports-list.vue +++ b/src/views/reports/pages/reports-list.vue @@ -1,17 +1,238 @@ - diff --git a/src/views/reports/reports.vue b/src/views/reports/reports.vue index 3ea847b47..f2039babb 100644 --- a/src/views/reports/reports.vue +++ b/src/views/reports/reports.vue @@ -13,106 +13,16 @@ \ No newline at end of file diff --git a/src/views/reports/scss/reports-basics.sass b/src/views/reports/scss/reports-basics.sass new file mode 100644 index 000000000..475489744 --- /dev/null +++ b/src/views/reports/scss/reports-basics.sass @@ -0,0 +1,13 @@ +@import "../../../../node_modules/bulma/sass/utilities/_all.sass" +@import "../../../../node_modules/bulma/sass/helpers/_all.sass" +@import "../../../../node_modules/bulma/sass/form/_all.sass" +@import "../../../../node_modules/bulma/sass/grid/_all.sass" +@import "../../../../node_modules/bulma/sass/components/pagination.sass" +@import "../../../../node_modules/bulma/sass/components/card.sass" +@import "../../../../node_modules/bulma/sass/elements/icon.sass" +@import "../../../../node_modules/bulma/sass/elements/tag.sass" +@import "../../../../node_modules/bulma/sass/elements/notification.sass" +@import "../../../../node_modules/bulma/sass/components/tabs.sass" +@import "../../../../node_modules/bulma/sass/elements/button.sass" +@import "../../../../node_modules/bulma/sass/components/dropdown.sass" +@import "../../../../node_modules/bulma/sass/components/modal.sass" \ No newline at end of file From 586861088aa83b9905fd3ceb4b218f5276e2c71c Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Wed, 10 Feb 2021 16:59:56 -0300 Subject: [PATCH 03/94] Taiancan color scheme for the charts. #483. --- src/views/reports/js/reports-main.js | 18 ++++++++++++++++++ src/views/reports/reports.vue | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/src/views/reports/js/reports-main.js b/src/views/reports/js/reports-main.js index 857994c9e..bf4986bca 100644 --- a/src/views/reports/js/reports-main.js +++ b/src/views/reports/js/reports-main.js @@ -15,6 +15,24 @@ import ChartBlock from '../components/chart-block.vue'; Vue.use(VueApexCharts) +// Apex.theme = { +// monochrome: { +// enabled: true, +// color: '#298596', +// shadeTo: 'light', +// shadeIntensity: 0.65 +// } +// } +Apex.colors = [ + '#298596', // Tainacan Turquoise + '#01295c', // Tainacan Blue + '#25a189', // Tainacan Green + '#e69810', // Tainacan Yellow + '#a23939', // Tainacan Red + '#592570', // Tainacan Purple + '#ed4f63' // Tainacan Pink +]; + Vue.use(I18NPlugin); Vue.use(VTooltip); Vue.use(Snackbar); diff --git a/src/views/reports/reports.vue b/src/views/reports/reports.vue index f2039babb..a20c2c0c7 100644 --- a/src/views/reports/reports.vue +++ b/src/views/reports/reports.vue @@ -24,5 +24,9 @@ a:hover { cursor: pointer; } + + .wp-heading-inline { + margin-bottom: 2rem; + } } \ No newline at end of file From 72ffb786a4e230e82cf4e59160aa7274024771b6 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Thu, 11 Feb 2021 11:45:23 -0300 Subject: [PATCH 04/94] Adds number type box as sample. Loads collections on mounted to begins fetching data #483. --- src/views/class-tainacan-admin.php | 1 + src/views/reports/components/chart-block.vue | 10 +- src/views/reports/js/reports-main.js | 10 +- src/views/reports/js/wp-i18n-plugin.js | 29 - src/views/reports/pages/reports-list.vue | 543 ++++++++++++------- src/views/reports/reports.vue | 9 +- src/views/reports/scss/reports-basics.sass | 1 + 7 files changed, 354 insertions(+), 249 deletions(-) delete mode 100644 src/views/reports/js/wp-i18n-plugin.js diff --git a/src/views/class-tainacan-admin.php b/src/views/class-tainacan-admin.php index 65afcc8ca..a984f3d1d 100644 --- a/src/views/class-tainacan-admin.php +++ b/src/views/class-tainacan-admin.php @@ -148,6 +148,7 @@ class Admin { function add_reports_css() { global $TAINACAN_BASE_URL; + wp_enqueue_style( 'tainacan-fonts', $TAINACAN_BASE_URL . '/assets/css/tainacanicons.css', [], TAINACAN_VERSION ); wp_enqueue_style( 'tainacan-reports-page', $TAINACAN_BASE_URL . '/assets/css/tainacan-reports.css', [], TAINACAN_VERSION ); } diff --git a/src/views/reports/components/chart-block.vue b/src/views/reports/components/chart-block.vue index 7f8121996..0633725e6 100644 --- a/src/views/reports/components/chart-block.vue +++ b/src/views/reports/components/chart-block.vue @@ -1,10 +1,8 @@ diff --git a/src/views/reports/reports.vue b/src/views/reports/reports.vue index a20c2c0c7..acd284cd6 100644 --- a/src/views/reports/reports.vue +++ b/src/views/reports/reports.vue @@ -7,13 +7,16 @@ \ No newline at end of file diff --git a/src/views/reports/js/reports-main.js b/src/views/reports/js/reports-main.js index 0977417a3..aed2bd100 100644 --- a/src/views/reports/js/reports-main.js +++ b/src/views/reports/js/reports-main.js @@ -15,6 +15,7 @@ Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'develo import ReportsPage from '../reports.vue'; import ChartBlock from '../components/chart-block.vue'; +import NumberBlock from '../components/number-block.vue'; Vue.use(VueApexCharts) @@ -45,6 +46,7 @@ Vue.use(Snackbar); Vue.use(Modal); Vue.component('chart-block', ChartBlock); +Vue.component('number-block', NumberBlock); Vue.component('apexchart', VueApexCharts); // Changing title of pages diff --git a/src/views/reports/pages/reports-list.vue b/src/views/reports/pages/reports-list.vue index 902024128..edefd660f 100644 --- a/src/views/reports/pages/reports-list.vue +++ b/src/views/reports/pages/reports-list.vue @@ -4,7 +4,8 @@ -
-
-

24

-

- - - -  {{ $i18n.get('collections') }} -

-
    -
  • - - - - - -
  • -
+
+
+
-
-

2344

-

- - - -  {{ $i18n.get('items') }} -

-
    -
  • - - - - - -
  • -
+
+
-
-

8

-

- - - -  {{ $i18n.get('taxonomies') }} -

-
    -
  • - - - - - -
  • -
+
+
-
+
-
+
-
+
this.isLoadingCollections = false) @@ -351,16 +301,3 @@ export default { } - From 4b6f67077f9283a77fddc9ba565fdf1ec39c42c3 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Mon, 15 Feb 2021 09:19:47 -0300 Subject: [PATCH 06/94] Creates fake reports storage to save demo graphs. --- compile-sass.sh | 26 +- src/assets/css/tainacan-reports.css | 3 + src/assets/css/tainacan-reports.css.map | 7 + .../admin/js/store/modules/report/actions.js | 21 + .../admin/js/store/modules/report/getters.js | 3 + .../admin/js/store/modules/report/index.js | 669 ++++++++++++++++++ .../js/store/modules/report/mutations.js | 3 + src/views/admin/js/store/store.js | 4 +- src/views/reports/pages/reports-list.vue | 267 ++----- 9 files changed, 768 insertions(+), 235 deletions(-) create mode 100644 src/assets/css/tainacan-reports.css create mode 100644 src/assets/css/tainacan-reports.css.map create mode 100644 src/views/admin/js/store/modules/report/actions.js create mode 100644 src/views/admin/js/store/modules/report/getters.js create mode 100644 src/views/admin/js/store/modules/report/index.js create mode 100644 src/views/admin/js/store/modules/report/mutations.js diff --git a/compile-sass.sh b/compile-sass.sh index cdfdc2787..2be3f3bfe 100644 --- a/compile-sass.sh +++ b/compile-sass.sh @@ -13,31 +13,33 @@ sass -E 'UTF-8' --cache-location .tmp/sass-cache-1 src/views/admin/scss/tainacan sass -E 'UTF-8' --cache-location .tmp/sass-cache-2 src/views/roles/tainacan-roles.scss:src/assets/css/tainacan-roles.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-3 src/views/gutenberg-blocks/tainacan-collections/collections-list/collections-list.scss:src/assets/css/tainacan-gutenberg-block-collections-list.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-3 src/views/roles/tainacan-roles.scss:src/assets/css/tainacan-reports.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-4 src/views/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list.scss:src/assets/css/tainacan-gutenberg-block-carousel-collections-list.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-4 src/views/gutenberg-blocks/tainacan-collections/collections-list/collections-list.scss:src/assets/css/tainacan-gutenberg-block-collections-list.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-5 src/views/gutenberg-blocks/tainacan-items/items-list/items-list.scss:src/assets/css/tainacan-gutenberg-block-items-list.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-5 src/views/gutenberg-blocks/tainacan-collections/carousel-collections-list/carousel-collections-list.scss:src/assets/css/tainacan-gutenberg-block-carousel-collections-list.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-6 src/views/gutenberg-blocks/tainacan-items/dynamic-items-list/dynamic-items-list.scss:src/assets/css/tainacan-gutenberg-block-dynamic-items-list.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-6 src/views/gutenberg-blocks/tainacan-items/items-list/items-list.scss:src/assets/css/tainacan-gutenberg-block-items-list.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-7 src/views/gutenberg-blocks/tainacan-items/search-bar/search-bar.scss:src/assets/css/tainacan-gutenberg-block-search-bar.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-7 src/views/gutenberg-blocks/tainacan-items/dynamic-items-list/dynamic-items-list.scss:src/assets/css/tainacan-gutenberg-block-dynamic-items-list.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-8 src/views/gutenberg-blocks/tainacan-items/carousel-items-list/carousel-items-list.scss:src/assets/css/tainacan-gutenberg-block-carousel-items-list.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-8 src/views/gutenberg-blocks/tainacan-items/search-bar/search-bar.scss:src/assets/css/tainacan-gutenberg-block-search-bar.css sass -E 'UTF-8' --cache-location .tmp/sass-cache-9 src/views/gutenberg-blocks/tainacan-items/carousel-items-list/carousel-items-list.scss:src/assets/css/tainacan-gutenberg-block-carousel-items-list.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-10 src/views/gutenberg-blocks/tainacan-terms/terms-list/terms-list.scss:src/assets/css/tainacan-gutenberg-block-terms-list.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-10 src/views/gutenberg-blocks/tainacan-items/carousel-items-list/carousel-items-list.scss:src/assets/css/tainacan-gutenberg-block-carousel-items-list.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-11 src/views/gutenberg-blocks/tainacan-facets/facets-list/facets-list.scss:src/assets/css/tainacan-gutenberg-block-facets-list.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-11 src/views/gutenberg-blocks/tainacan-terms/terms-list/terms-list.scss:src/assets/css/tainacan-gutenberg-block-terms-list.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-12 src/views/gutenberg-blocks/tainacan-terms/carousel-terms-list/carousel-terms-list.scss:src/assets/css/tainacan-gutenberg-block-carousel-terms-list.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-12 src/views/gutenberg-blocks/tainacan-facets/facets-list/facets-list.scss:src/assets/css/tainacan-gutenberg-block-facets-list.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-13 src/views/gutenberg-blocks/tainacan-facets/faceted-search/faceted-search.scss:src/assets/css/tainacan-gutenberg-block-faceted-search.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-13 src/views/gutenberg-blocks/tainacan-terms/carousel-terms-list/carousel-terms-list.scss:src/assets/css/tainacan-gutenberg-block-carousel-terms-list.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-14 src/views/gutenberg-blocks/tainacan-items/item-submission-form/item-submission-form.scss:src/assets/css/tainacan-gutenberg-block-item-submission-form.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-14 src/views/gutenberg-blocks/tainacan-facets/faceted-search/faceted-search.scss:src/assets/css/tainacan-gutenberg-block-faceted-search.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-15 src/views/gutenberg-blocks/gutenberg-blocks-style.scss:src/assets/css/tainacan-gutenberg-block-common-styles.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-15 src/views/gutenberg-blocks/tainacan-items/item-submission-form/item-submission-form.scss:src/assets/css/tainacan-gutenberg-block-item-submission-form.css + +sass -E 'UTF-8' --cache-location .tmp/sass-cache-16 src/views/gutenberg-blocks/gutenberg-blocks-style.scss:src/assets/css/tainacan-gutenberg-block-common-styles.css echo "Compilação do Sass Concluído!" exit 0 diff --git a/src/assets/css/tainacan-reports.css b/src/assets/css/tainacan-reports.css new file mode 100644 index 000000000..75c999f5f --- /dev/null +++ b/src/assets/css/tainacan-reports.css @@ -0,0 +1,3 @@ + + +/*# sourceMappingURL=tainacan-reports.css.map */ diff --git a/src/assets/css/tainacan-reports.css.map b/src/assets/css/tainacan-reports.css.map new file mode 100644 index 000000000..4b34ef731 --- /dev/null +++ b/src/assets/css/tainacan-reports.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "", +"sources": [], +"names": [], +"file": "tainacan-reports.css" +} diff --git a/src/views/admin/js/store/modules/report/actions.js b/src/views/admin/js/store/modules/report/actions.js new file mode 100644 index 000000000..1d471fc89 --- /dev/null +++ b/src/views/admin/js/store/modules/report/actions.js @@ -0,0 +1,21 @@ +import axios from '../../../axios'; + +export const fetchReports = ({ commit }, {} ) => { + + let endpoint = `/reports`; + + return new Promise((resolve, reject) => { + axios.tainacan.get(endpoint) + .then(res => { + let reports = res.data; + + commit('setReports', reports); + + resolve({ + reports: reports, + total: res.headers['x-wp-total'] + }); + }) + .catch(error => reject(error)); + }); +}; diff --git a/src/views/admin/js/store/modules/report/getters.js b/src/views/admin/js/store/modules/report/getters.js new file mode 100644 index 000000000..cefe6d749 --- /dev/null +++ b/src/views/admin/js/store/modules/report/getters.js @@ -0,0 +1,3 @@ +export const getReports = state => { + return state.reports; +}; \ No newline at end of file diff --git a/src/views/admin/js/store/modules/report/index.js b/src/views/admin/js/store/modules/report/index.js new file mode 100644 index 000000000..711c11e58 --- /dev/null +++ b/src/views/admin/js/store/modules/report/index.js @@ -0,0 +1,669 @@ +import * as actions from './actions'; +import * as getters from './getters'; +import * as mutations from './mutations'; + +const state = { + reports: [ + { + chartSeries: [44, 55, 13, 43, 22], + chartOptions: { + chart: { + width: 200, + type: 'pie', + }, + legend: { + position: 'bottom' + }, + labels: ['Team A', 'Team B', 'Team C', 'Team D', 'Team E'], + title: { + text: 'Pie chart' + }, + responsive: [{ + breakpoint: 1216, + options: { + chart: { + width: 380 + }, + legend: { + position: 'left' + } + } + }] + }, + }, + { + chartSeries: [ + { + name: 'Marine Sprite', + data: [44, 55, 41, 37, 22] + }, { + name: 'Striking Calf', + data: [53, 32, 33, 52, 13] + }, { + name: 'Tank Picture', + data: [12, 17, 11, 9, 15] + }, { + name: 'Bucket Slope', + data: [9, 7, 5, 8, 6] + } + ], + chartOptions: { + chart: { + type: 'bar', + height: 350, + stacked: true, + stackType: '100%' + }, + plotOptions: { + bar: { + horizontal: true, + }, + }, + stroke: { + width: 1, + colors: ['#fff'] + }, + title: { + text: '100% Stacked Bar' + }, + xaxis: { + categories: [2008, 2009, 2010, 2011, 2012], + }, + tooltip: { + y: { + formatter: function (val) { + return val + "K" + } + } + }, + fill: { + opacity: 1 + }, + legend: { + position: 'top', + horizontalAlign: 'left', + offsetX: 40 + } + }, + }, + { + chartSeries: [ + { + data: [ + { + x: 'New Delhi', + y: 218 + }, + { + x: 'Kolkata', + y: 149 + }, + { + x: 'Mumbai', + y: 184 + }, + { + x: 'Ahmedabad', + y: 55 + }, + { + x: 'Bangaluru', + y: 84 + }, + { + x: 'Pune', + y: 31 + }, + { + x: 'Chennai', + y: 70 + }, + { + x: 'Jaipur', + y: 30 + }, + { + x: 'Surat', + y: 44 + }, + { + x: 'Hyderabad', + y: 68 + }, + { + x: 'Lucknow', + y: 28 + }, + { + x: 'Indore', + y: 19 + }, + { + x: 'Kanpur', + y: 29 + } + ] + } + ], + chartOptions: { + legend: { + show: false + }, + chart: { + height: 350, + type: 'treemap' + }, + title: { + text: 'Basic Treemap' + } + }, + }, + { + chartSeries: [ + { + name: 'Net Profit', + data: [44, 55, 57, 56, 61, 58, 63, 60, 66] + }, { + name: 'Revenue', + data: [76, 85, 101, 98, 87, 105, 91, 114, 94] + }, { + name: 'Free Cash Flow', + data: [35, 41, 36, 26, 45, 48, 52, 53, 41] + } + ], + chartOptions: { + chart: { + type: 'bar', + height: 350 + }, + plotOptions: { + bar: { + horizontal: false, + columnWidth: '55%', + endingShape: 'rounded' + }, + }, + dataLabels: { + enabled: false + }, + stroke: { + show: true, + width: 2, + colors: ['transparent'] + }, + xaxis: { + categories: ['Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct'], + }, + yaxis: { + title: { + text: '$ (thousands)' + } + }, + title: { + text: 'Vertical columns' + }, + fill: { + opacity: 1 + }, + tooltip: { + y: { + formatter: function (val) { + return "$ " + val + " thousands" + } + } + } + } + }, + { + chartSeries: [ + { + data: [ + [1327359600000,30.95], + [1327446000000,31.34], + [1327532400000,31.18], + [1327618800000,31.05], + [1327878000000,31.00], + [1327964400000,30.95], + [1328050800000,31.24], + [1328137200000,31.29], + [1328223600000,31.85], + [1328482800000,31.86], + [1328569200000,32.28], + [1328655600000,32.10], + [1328742000000,32.65], + [1328828400000,32.21], + [1329087600000,32.35], + [1329174000000,32.44], + [1329260400000,32.46], + [1329346800000,32.86], + [1329433200000,32.75], + [1329778800000,32.54], + [1329865200000,32.33], + [1329951600000,32.97], + [1330038000000,33.41], + [1330297200000,33.27], + [1330383600000,33.27], + [1330470000000,32.89], + [1330556400000,33.10], + [1330642800000,33.73], + [1330902000000,33.22], + [1330988400000,31.99], + [1331074800000,32.41], + [1331161200000,33.05], + [1331247600000,33.64], + [1331506800000,33.56], + [1331593200000,34.22], + [1331679600000,33.77], + [1331766000000,34.17], + [1331852400000,33.82], + [1332111600000,34.51], + [1332198000000,33.16], + [1332284400000,33.56], + [1332370800000,33.71], + [1332457200000,33.81], + [1332712800000,34.40], + [1332799200000,34.63], + [1332885600000,34.46], + [1332972000000,34.48], + [1333058400000,34.31], + [1333317600000,34.70], + [1333404000000,34.31], + [1333490400000,33.46], + [1333576800000,33.59], + [1333922400000,33.22], + [1334008800000,32.61], + [1334095200000,33.01], + [1334181600000,33.55], + [1334268000000,33.18], + [1334527200000,32.84], + [1334613600000,33.84], + [1334700000000,33.39], + [1334786400000,32.91], + [1334872800000,33.06], + [1335132000000,32.62], + [1335218400000,32.40], + [1335304800000,33.13], + [1335391200000,33.26], + [1335477600000,33.58], + [1335736800000,33.55], + [1335823200000,33.77], + [1335909600000,33.76], + [1335996000000,33.32], + [1336082400000,32.61], + [1336341600000,32.52], + [1336428000000,32.67], + [1336514400000,32.52], + [1336600800000,31.92], + [1336687200000,32.20], + [1336946400000,32.23], + [1337032800000,32.33], + [1337119200000,32.36], + [1337205600000,32.01], + [1337292000000,31.31], + [1337551200000,32.01], + [1337637600000,32.01], + [1337724000000,32.18], + [1337810400000,31.54], + [1337896800000,31.60], + [1338242400000,32.05], + [1338328800000,31.29], + [1338415200000,31.05], + [1338501600000,29.82], + [1338760800000,30.31], + [1338847200000,30.70], + [1338933600000,31.69], + [1339020000000,31.32], + [1339106400000,31.65], + [1339365600000,31.13], + [1339452000000,31.77], + [1339538400000,31.79], + [1339624800000,31.67], + [1339711200000,32.39], + [1339970400000,32.63], + [1340056800000,32.89], + [1340143200000,31.99], + [1340229600000,31.23], + [1340316000000,31.57], + [1340575200000,30.84], + [1340661600000,31.07], + [1340748000000,31.41], + [1340834400000,31.17], + [1340920800000,32.37], + [1341180000000,32.19], + [1341266400000,32.51], + [1341439200000,32.53], + [1341525600000,31.37], + [1341784800000,30.43], + [1341871200000,30.44], + [1341957600000,30.20], + [1342044000000,30.14], + [1342130400000,30.65], + [1342389600000,30.40], + [1342476000000,30.65], + [1342562400000,31.43], + [1342648800000,31.89], + [1342735200000,31.38], + [1342994400000,30.64], + [1343080800000,30.02], + [1343167200000,30.33], + [1343253600000,30.95], + [1343340000000,31.89], + [1343599200000,31.01], + [1343685600000,30.88], + [1343772000000,30.69], + [1343858400000,30.58], + [1343944800000,32.02], + [1344204000000,32.14], + [1344290400000,32.37], + [1344376800000,32.51], + [1344463200000,32.65], + [1344549600000,32.64], + [1344808800000,32.27], + [1344895200000,32.10], + [1344981600000,32.91], + [1345068000000,33.65], + [1345154400000,33.80], + [1345413600000,33.92], + [1345500000000,33.75], + [1345586400000,33.84], + [1345672800000,33.50], + [1345759200000,32.26], + [1346018400000,32.32], + [1346104800000,32.06], + [1346191200000,31.96], + [1346277600000,31.46], + [1346364000000,31.27], + [1346709600000,31.43], + [1346796000000,32.26], + [1346882400000,32.79], + [1346968800000,32.46], + [1347228000000,32.13], + [1347314400000,32.43], + [1347400800000,32.42], + [1347487200000,32.81], + [1347573600000,33.34], + [1347832800000,33.41], + [1347919200000,32.57], + [1348005600000,33.12], + [1348092000000,34.53], + [1348178400000,33.83], + [1348437600000,33.41], + [1348524000000,32.90], + [1348610400000,32.53], + [1348696800000,32.80], + [1348783200000,32.44], + [1349042400000,32.62], + [1349128800000,32.57], + [1349215200000,32.60], + [1349301600000,32.68], + [1349388000000,32.47], + [1349647200000,32.23], + [1349733600000,31.68], + [1349820000000,31.51], + [1349906400000,31.78], + [1349992800000,31.94], + [1350252000000,32.33], + [1350338400000,33.24], + [1350424800000,33.44], + [1350511200000,33.48], + [1350597600000,33.24], + [1350856800000,33.49], + [1350943200000,33.31], + [1351029600000,33.36], + [1351116000000,33.40], + [1351202400000,34.01], + [1351638000000,34.02], + [1351724400000,34.36], + [1351810800000,34.39], + [1352070000000,34.24], + [1352156400000,34.39], + [1352242800000,33.47], + [1352329200000,32.98], + [1352415600000,32.90], + [1352674800000,32.70], + [1352761200000,32.54], + [1352847600000,32.23], + [1352934000000,32.64], + [1353020400000,32.65], + [1353279600000,32.92], + [1353366000000,32.64], + [1353452400000,32.84], + [1353625200000,33.40], + [1353884400000,33.30], + [1353970800000,33.18], + [1354057200000,33.88], + [1354143600000,34.09], + [1354230000000,34.61], + [1354489200000,34.70], + [1354575600000,35.30], + [1354662000000,35.40], + [1354748400000,35.14], + [1354834800000,35.48], + [1355094000000,35.75], + [1355180400000,35.54], + [1355266800000,35.96], + [1355353200000,35.53], + [1355439600000,37.56], + [1355698800000,37.42], + [1355785200000,37.49], + [1355871600000,38.09], + [1355958000000,37.87], + [1356044400000,37.71], + [1356303600000,37.53], + [1356476400000,37.55], + [1356562800000,37.30], + [1356649200000,36.90], + [1356908400000,37.68], + [1357081200000,38.34], + [1357167600000,37.75], + [1357254000000,38.13], + [1357513200000,37.94], + [1357599600000,38.14], + [1357686000000,38.66], + [1357772400000,38.62], + [1357858800000,38.09], + [1358118000000,38.16], + [1358204400000,38.15], + [1358290800000,37.88], + [1358377200000,37.73], + [1358463600000,37.98], + [1358809200000,37.95], + [1358895600000,38.25], + [1358982000000,38.10], + [1359068400000,38.32], + [1359327600000,38.24], + [1359414000000,38.52], + [1359500400000,37.94], + [1359586800000,37.83], + [1359673200000,38.34], + [1359932400000,38.10], + [1360018800000,38.51], + [1360105200000,38.40], + [1360191600000,38.07], + [1360278000000,39.12], + [1360537200000,38.64], + [1360623600000,38.89], + [1360710000000,38.81], + [1360796400000,38.61], + [1360882800000,38.63], + [1361228400000,38.99], + [1361314800000,38.77], + [1361401200000,38.34], + [1361487600000,38.55], + [1361746800000,38.11], + [1361833200000,38.59], + [1361919600000,39.60], + ] + } + ], + chartOptions: { + chart: { + id: 'area-datetime', + type: 'area', + height: 350, + zoom: { + autoScaleYaxis: true + } + }, + annotations: { + yaxis: [{ + y: 30, + borderColor: '#999', + label: { + show: true, + text: 'Support', + style: { + color: "#fff", + background: '#00E396' + } + } + }], + xaxis: [{ + x: new Date('14 Nov 2012').getTime(), + borderColor: '#999', + yAxisIndex: 0, + label: { + show: true, + text: 'Rally', + style: { + color: "#fff", + background: '#775DD0' + } + } + }] + }, + dataLabels: { + enabled: false + }, + markers: { + size: 0, + style: 'hollow', + }, + xaxis: { + type: 'datetime', + min: new Date('01 Mar 2012').getTime(), + tickAmount: 6, + }, + tooltip: { + x: { + format: 'dd MMM yyyy' + } + }, + fill: { + type: 'gradient', + gradient: { + shadeIntensity: 1, + opacityFrom: 0.7, + opacityTo: 0.9, + stops: [0, 100] + } + }, + }, + }, + { + chartSeries: + [ + { + name: 'Metric1', + data: generateData(20, { + min: 0, + max: 90 + }) + }, + { + name: 'Metric2', + data: generateData(20, { + min: 0, + max: 90 + }) + }, + { + name: 'Metric3', + data: generateData(20, { + min: 0, + max: 90 + }) + }, + { + name: 'Metric4', + data: generateData(20, { + min: 0, + max: 90 + }) + }, + { + name: 'Metric5', + data: generateData(20, { + min: 0, + max: 90 + }) + }, + { + name: 'Metric6', + data: generateData(20, { + min: 0, + max: 90 + }) + }, + { + name: 'Metric7', + data: generateData(20, { + min: 0, + max: 90 + }) + }, + { + name: 'Metric8', + data: generateData(20, { + min: 0, + max: 90 + }) + }, + { + name: 'Metric9', + data: generateData(20, { + min: 0, + max: 90 + }) + } + ], + chartOptions: { + chart: { + height: 350, + type: 'heatmap', + }, + dataLabels: { + enabled: false + }, + colors: ["#298596"], + xaxis: { + type: 'category', + }, + title: { + text: 'HeatMap Chart (Single color)' + }, + }, + } + ] +}; +function generateData (count, yrange) { + var i = 0; + var series = []; + while (i < count) { + var x = (i + 1).toString(); + var y = Math.floor(Math.random() * (yrange.max - yrange.min + 1)) + yrange.min; + series.push({ + x: x, + y: y + }); + i++; + } + return series; + } +export default { + namespaced: true, + state, + mutations, + actions, + getters +} \ No newline at end of file diff --git a/src/views/admin/js/store/modules/report/mutations.js b/src/views/admin/js/store/modules/report/mutations.js new file mode 100644 index 000000000..02393ee3e --- /dev/null +++ b/src/views/admin/js/store/modules/report/mutations.js @@ -0,0 +1,3 @@ +export const setReports = (state, reports) => { + state.reports = reports; +}; \ No newline at end of file diff --git a/src/views/admin/js/store/store.js b/src/views/admin/js/store/store.js index 592cca62f..95dc1efb2 100644 --- a/src/views/admin/js/store/store.js +++ b/src/views/admin/js/store/store.js @@ -14,6 +14,7 @@ import bulkedition from './modules/bulk-edition'; import exporter from './modules/exporter'; import exposer from './modules/exposer'; import capability from './modules/capability'; +import report from './modules/report'; // Vue Dev Tools! Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development'; @@ -41,6 +42,7 @@ export default new Vuex.Store({ bulkedition, exporter, exposer, - capability + capability, + report } }) \ No newline at end of file diff --git a/src/views/reports/pages/reports-list.vue b/src/views/reports/pages/reports-list.vue index edefd660f..7b9652c4c 100644 --- a/src/views/reports/pages/reports-list.vue +++ b/src/views/reports/pages/reports-list.vue @@ -17,44 +17,59 @@
-
+
-
+
-
- +
+ class="postbox" + :chart-series="reports[0].chartSeries" + :chart-options="reports[0].chartOptions" />
- +
- +
- + +
+
+ +
+
+
@@ -69,218 +84,19 @@ export default { return { selectedCollection: 'default', isLoadingCollections: false, - chartSeries1: [44, 55, 13, 43, 22], - chartOptions1: { - chart: { - width: 200, - type: 'pie', - }, - legend: { - position: 'bottom' - }, - labels: ['Team A', 'Team B', 'Team C', 'Team D', 'Team E'], - title: { - text: 'Pie chart' - }, - responsive: [{ - breakpoint: 1216, - options: { - chart: { - width: 380 - }, - legend: { - position: 'left' - } - } - }] - }, - chartSeries2: [ - { - name: 'Marine Sprite', - data: [44, 55, 41, 37, 22] - }, { - name: 'Striking Calf', - data: [53, 32, 33, 52, 13] - }, { - name: 'Tank Picture', - data: [12, 17, 11, 9, 15] - }, { - name: 'Bucket Slope', - data: [9, 7, 5, 8, 6] - } - ], - chartOptions2: { - chart: { - type: 'bar', - height: 350, - stacked: true, - stackType: '100%' - }, - plotOptions: { - bar: { - horizontal: true, - }, - }, - stroke: { - width: 1, - colors: ['#fff'] - }, - title: { - text: '100% Stacked Bar' - }, - xaxis: { - categories: [2008, 2009, 2010, 2011, 2012], - }, - tooltip: { - y: { - formatter: function (val) { - return val + "K" - } - } - }, - fill: { - opacity: 1 - }, - legend: { - position: 'top', - horizontalAlign: 'left', - offsetX: 40 - } - }, - chartSeries3: [ - { - data: [ - { - x: 'New Delhi', - y: 218 - }, - { - x: 'Kolkata', - y: 149 - }, - { - x: 'Mumbai', - y: 184 - }, - { - x: 'Ahmedabad', - y: 55 - }, - { - x: 'Bangaluru', - y: 84 - }, - { - x: 'Pune', - y: 31 - }, - { - x: 'Chennai', - y: 70 - }, - { - x: 'Jaipur', - y: 30 - }, - { - x: 'Surat', - y: 44 - }, - { - x: 'Hyderabad', - y: 68 - }, - { - x: 'Lucknow', - y: 28 - }, - { - x: 'Indore', - y: 19 - }, - { - x: 'Kanpur', - y: 29 - } - ] - } - ], - chartOptions3: { - legend: { - show: false - }, - chart: { - height: 350, - type: 'treemap' - }, - title: { - text: 'Basic Treemap' - } - }, - chartSeries4: [ - { - name: 'Net Profit', - data: [44, 55, 57, 56, 61, 58, 63, 60, 66] - }, { - name: 'Revenue', - data: [76, 85, 101, 98, 87, 105, 91, 114, 94] - }, { - name: 'Free Cash Flow', - data: [35, 41, 36, 26, 45, 48, 52, 53, 41] - } - ], - chartOptions4: { - chart: { - type: 'bar', - height: 350 - }, - plotOptions: { - bar: { - horizontal: false, - columnWidth: '55%', - endingShape: 'rounded' - }, - }, - dataLabels: { - enabled: false - }, - stroke: { - show: true, - width: 2, - colors: ['transparent'] - }, - xaxis: { - categories: ['Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct'], - }, - yaxis: { - title: { - text: '$ (thousands)' - } - }, - title: { - text: 'Vertical columns' - }, - fill: { - opacity: 1 - }, - tooltip: { - y: { - formatter: function (val) { - return "$ " + val + " thousands" - } - } - } - }, } }, computed: { ...mapGetters('collection', { collections: 'getCollections', }), + ...mapGetters('report', { + reports: 'getReports', + }), }, watch: { '$route.query' (to) { - this.selectedCollection = to.query['collection'] ? to.query['collection'] : 'default'; + this.selectedCollection = to['collection'] ? to['collection'] : 'default'; } }, created() { @@ -301,3 +117,10 @@ export default { } + \ No newline at end of file From b031998f1bdb8e6b3a05c708314be5d0252b0092 Mon Sep 17 00:00:00 2001 From: vnmedeiros Date: Tue, 2 Mar 2021 15:51:38 -0300 Subject: [PATCH 07/94] feat: add reports rest controller #483 --- ...class-tainacan-rest-reports-controller.php | 102 ++++++++++++++++++ src/classes/api/tainacan-rest-creator.php | 43 ++++---- src/classes/tainacan-creator.php | 4 +- 3 files changed, 126 insertions(+), 23 deletions(-) create mode 100644 src/classes/api/endpoints/class-tainacan-rest-reports-controller.php diff --git a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php new file mode 100644 index 000000000..2e303267a --- /dev/null +++ b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php @@ -0,0 +1,102 @@ +rest_base = 'reports'; + parent::__construct(); + add_action('init', array(&$this, 'init_objects'), 11); + } + + public function init_objects() { + $this->metadatum_repository = Repositories\Metadata::get_instance(); + $this->collections_repository = Repositories\Collections::get_instance(); + } + + /** + * + * + * @throws \Exception + */ + public function register_routes() { + register_rest_route($this->namespace, $this->rest_base . '/collection/(?P[\d]+)/summary', + array( + array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array($this, 'get_summary'), + 'permission_callback' => array($this, 'reports_permissions_check'), + ), + ) + ); + register_rest_route($this->namespace, $this->rest_base . '/repository/summary', + array( + array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array($this, 'get_summary'), + 'permission_callback' => array($this, 'reports_permissions_check'), + ), + ) + ); + } + + public function reports_permissions_check($request) { + return true; + } + + public function get_summary($request) { + $response = array( + 'total_items' => array( + 'total' => 0, + 'trash' => 0, + 'draft' => 0, + 'publish' => 0, + 'private' => 0 + ) + ); + if(isset($request['collection_id'])) { + $collection_id = $request['collection_id']; + $collection = $this->collections_repository->fetch($collection_id); + $total_items = wp_count_posts( $collection->get_db_identifier(), 'readable' ); + if (isset($total_items->publish) || + isset($total_items->private) || + isset($total_items->trash) || + isset($total_items->draft)) { + + $response['total_items']['trash'] = $total_items->trash; + $response['total_items']['draft'] = $total_items->draft; + $response['total_items']['publish'] = $total_items->publish; + $response['total_items']['private'] = $total_items->private; + } + } else { + $collections = $this->collections_repository->fetch([]); + if($collections->have_posts()) { + while ($collections->have_posts()) { + $collections->the_post(); + $collection = new Entities\Collection($collections->post); + $total_items = wp_count_posts( $collection->get_db_identifier(), 'readable' ); + + if (isset($total_items->publish) || isset($total_items->private) || + isset($total_items->trash) || isset($total_items->draft)) { + $response['total_items']['trash'] += $total_items->trash; + $response['total_items']['draft'] += $total_items->draft; + $response['total_items']['publish'] += $total_items->publish; + $response['total_items']['private'] += $total_items->private; + } + } + wp_reset_postdata(); + } + } + $response['total_items']['total'] = ($response['total_items']['trash'] + $response['total_items']['draft'] + $response['total_items']['publish'] + $response['total_items']['private']); + + return new \WP_REST_Response($response, 200); + } + +} + +?> \ No newline at end of file diff --git a/src/classes/api/tainacan-rest-creator.php b/src/classes/api/tainacan-rest-creator.php index a04a0d118..adb894efb 100644 --- a/src/classes/api/tainacan-rest-creator.php +++ b/src/classes/api/tainacan-rest-creator.php @@ -2,27 +2,28 @@ const TAINACAN_REST_NAMESPACE = 'tainacan/v2'; -//$rest_controller = new \Tainacan\API\REST_Controller(); -$rest_collections_controller = new \Tainacan\API\EndPoints\REST_Collections_Controller(); -$rest_items_controller = new \Tainacan\API\EndPoints\REST_Items_Controller(); -$rest_metadata_controller = new \Tainacan\API\EndPoints\REST_Metadata_Controller(); -$rest_taxonomies_controller = new \Tainacan\API\EndPoints\REST_Taxonomies_Controller(); -$rest_terms_controller = new \Tainacan\API\EndPoints\REST_Terms_Controller(); -$rest_filters_controller = new \Tainacan\API\EndPoints\REST_Filters_Controller(); -$rest_item_metadata_controller = new \Tainacan\API\EndPoints\REST_Item_Metadata_Controller(); -$rest_logs_controller = new \Tainacan\API\EndPoints\REST_Logs_Controller(); -$rest_metadata_types_controller = new \Tainacan\API\EndPoints\REST_Metadata_Types_Controller(); -$rest_filter_types_controller = new \Tainacan\API\EndPoints\REST_Filter_Types_Controller(); -$rest_importers_controller = new \Tainacan\API\EndPoints\REST_Importers_Controller(); -$rest_exporters_controller = new \Tainacan\API\EndPoints\REST_Exporters_Controller(); -$rest_background_processes_controller = new \Tainacan\API\EndPoints\REST_Background_Processes_Controller(); -$rest_bulkedit_controller = new \Tainacan\API\EndPoints\REST_Bulkedit_Controller(); -$rest_exposers_controller = new \Tainacan\API\EndPoints\REST_Exposers_Controller(); -$rest_roles_controller = new \Tainacan\API\EndPoints\REST_Roles_Controller(); -new \Tainacan\API\EndPoints\REST_Metadatum_Mappers_Controller(); -$rest_facets_controller = new \Tainacan\API\EndPoints\REST_Facets_Controller(); -$rest_oaipmh_expose_controller = new \Tainacan\API\EndPoints\REST_Oaipmh_Expose_Controller(); -$rest_sequence_edit_controller = new \Tainacan\API\EndPoints\REST_Sequence_Edit_Controller(); +//$rest_controller = new \Tainacan\API\REST_Controller(); +$rest_items_controller = new \Tainacan\API\EndPoints\REST_Items_Controller(); +$rest_terms_controller = new \Tainacan\API\EndPoints\REST_Terms_Controller(); +$rest_logs_controller = new \Tainacan\API\EndPoints\REST_Logs_Controller(); +$rest_roles_controller = new \Tainacan\API\EndPoints\REST_Roles_Controller(); +$rest_facets_controller = new \Tainacan\API\EndPoints\REST_Facets_Controller(); +$rest_reports_controller = new \Tainacan\API\EndPoints\REST_Reports_Controller(); +$rest_filters_controller = new \Tainacan\API\EndPoints\REST_Filters_Controller(); +$rest_exposers_controller = new \Tainacan\API\EndPoints\REST_Exposers_Controller(); +$rest_bulkedit_controller = new \Tainacan\API\EndPoints\REST_Bulkedit_Controller(); +$rest_metadata_controller = new \Tainacan\API\EndPoints\REST_Metadata_Controller(); +$rest_importers_controller = new \Tainacan\API\EndPoints\REST_Importers_Controller(); +$rest_exporters_controller = new \Tainacan\API\EndPoints\REST_Exporters_Controller(); +$rest_taxonomies_controller = new \Tainacan\API\EndPoints\REST_Taxonomies_Controller(); +$rest_collections_controller = new \Tainacan\API\EndPoints\REST_Collections_Controller(); +$rest_filter_types_controller = new \Tainacan\API\EndPoints\REST_Filter_Types_Controller(); +$rest_oaipmh_expose_controller = new \Tainacan\API\EndPoints\REST_Oaipmh_Expose_Controller(); +$rest_item_metadata_controller = new \Tainacan\API\EndPoints\REST_Item_Metadata_Controller(); +$rest_sequence_edit_controller = new \Tainacan\API\EndPoints\REST_Sequence_Edit_Controller(); +$rest_metadata_types_controller = new \Tainacan\API\EndPoints\REST_Metadata_Types_Controller(); +$rest_metadatum_mappers_controller = new \Tainacan\API\EndPoints\REST_Metadatum_Mappers_Controller(); +$rest_background_processes_controller = new \Tainacan\API\EndPoints\REST_Background_Processes_Controller(); // Add here other endpoints imports ?> diff --git a/src/classes/tainacan-creator.php b/src/classes/tainacan-creator.php index 188137afd..b3e8023b9 100644 --- a/src/classes/tainacan-creator.php +++ b/src/classes/tainacan-creator.php @@ -92,8 +92,8 @@ function tainacan_autoload($class_name) { $dir = TAINACAN_TAPI_DIR; if(count($class_path) > 3) $dir .= strtolower($class_path[2]).DIRECTORY_SEPARATOR; } else if( isset( $class_path[1] ) && $class_path[1] === 'OAIPMHExpose' ){ - $dir = TAINACAN_OAIPMH_DIR; - if(count($class_path) > 3) $dir .= strtolower($class_path[2]).DIRECTORY_SEPARATOR; + $dir = TAINACAN_OAIPMH_DIR; + if(count($class_path) > 3) $dir .= strtolower($class_path[2]).DIRECTORY_SEPARATOR; } else if( isset( $class_path[1] ) && substr($class_path[1], 0, 3) === 'Cli' ){ $dir = TAINACAN_CLI_DIR; } else if( isset( $class_path[1] ) && $class_path[1] === 'Metadata_Types' ) { From 37072a4512a018c7b57d9ca8b47f8ea79a350d43 Mon Sep 17 00:00:00 2001 From: vnmedeiros Date: Tue, 2 Mar 2021 16:09:42 -0300 Subject: [PATCH 08/94] feat: add totals for collections #483 --- ...class-tainacan-rest-reports-controller.php | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php index 2e303267a..01a033c0b 100644 --- a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php +++ b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php @@ -51,12 +51,14 @@ class REST_Reports_Controller extends REST_Controller { public function get_summary($request) { $response = array( - 'total_items' => array( - 'total' => 0, - 'trash' => 0, - 'draft' => 0, - 'publish' => 0, - 'private' => 0 + 'totals'=> array( + 'items' => array( + 'total' => 0, + 'trash' => 0, + 'draft' => 0, + 'publish' => 0, + 'private' => 0 + ) ) ); if(isset($request['collection_id'])) { @@ -68,32 +70,39 @@ class REST_Reports_Controller extends REST_Controller { isset($total_items->trash) || isset($total_items->draft)) { - $response['total_items']['trash'] = $total_items->trash; - $response['total_items']['draft'] = $total_items->draft; - $response['total_items']['publish'] = $total_items->publish; - $response['total_items']['private'] = $total_items->private; + $response['totals']['items']['trash'] = $total_items->trash; + $response['totals']['items']['draft'] = $total_items->draft; + $response['totals']['items']['publish'] = $total_items->publish; + $response['totals']['items']['private'] = $total_items->private; } } else { $collections = $this->collections_repository->fetch([]); + $response['totals']['collections'] = array( + 'total' => 0, + 'trash' => 0, + 'publish' => 0, + 'private' => 0 + ); if($collections->have_posts()) { while ($collections->have_posts()) { $collections->the_post(); $collection = new Entities\Collection($collections->post); + $response['totals']['collections'][$collection->get_status()]++; + $response['totals']['collections']['total']++; $total_items = wp_count_posts( $collection->get_db_identifier(), 'readable' ); if (isset($total_items->publish) || isset($total_items->private) || isset($total_items->trash) || isset($total_items->draft)) { - $response['total_items']['trash'] += $total_items->trash; - $response['total_items']['draft'] += $total_items->draft; - $response['total_items']['publish'] += $total_items->publish; - $response['total_items']['private'] += $total_items->private; + $response['totals']['items']['trash'] += $total_items->trash; + $response['totals']['items']['draft'] += $total_items->draft; + $response['totals']['items']['publish'] += $total_items->publish; + $response['totals']['items']['private'] += $total_items->private; } } wp_reset_postdata(); } } - $response['total_items']['total'] = ($response['total_items']['trash'] + $response['total_items']['draft'] + $response['total_items']['publish'] + $response['total_items']['private']); - + $response['totals']['items']['total'] = ($response['totals']['items']['trash'] + $response['totals']['items']['draft'] + $response['totals']['items']['publish'] + $response['totals']['items']['private']); return new \WP_REST_Response($response, 200); } From 87174e3f8c5d55306cba945f6270e2a37f2179f2 Mon Sep 17 00:00:00 2001 From: vnmedeiros Date: Tue, 2 Mar 2021 16:30:17 -0300 Subject: [PATCH 09/94] feat: add totals for taxonomies #483 --- ...class-tainacan-rest-reports-controller.php | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php index 01a033c0b..a10b64494 100644 --- a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php +++ b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php @@ -70,10 +70,10 @@ class REST_Reports_Controller extends REST_Controller { isset($total_items->trash) || isset($total_items->draft)) { - $response['totals']['items']['trash'] = $total_items->trash; - $response['totals']['items']['draft'] = $total_items->draft; - $response['totals']['items']['publish'] = $total_items->publish; - $response['totals']['items']['private'] = $total_items->private; + $response['totals']['items']['trash'] = intval($total_items->trash); + $response['totals']['items']['draft'] = intval($total_items->draft); + $response['totals']['items']['publish'] = intval($total_items->publish); + $response['totals']['items']['private'] = intval($total_items->private); } } else { $collections = $this->collections_repository->fetch([]); @@ -101,6 +101,27 @@ class REST_Reports_Controller extends REST_Controller { } wp_reset_postdata(); } + + $response['totals']['taxonomies'] = array( + 'total' => 0, + 'trash' => 0, + 'publish' => 0, + 'draft' => 0, + 'private' => 0 + ); + $total_taxonomies = wp_count_posts( 'tainacan-taxonomy', 'readable' ); + + if (isset($total_taxonomies->publish) || + isset($total_taxonomies->private) || + isset($total_taxonomies->trash) || + isset($total_taxonomies->draft)) { + + $response['totals']['taxonomies']['trash'] = intval($total_taxonomies->trash); + $response['totals']['taxonomies']['publish'] = intval($total_taxonomies->publish); + $response['totals']['taxonomies']['draft'] = intval($total_taxonomies->draft); + $response['totals']['taxonomies']['private'] = intval($total_taxonomies->private); + $response['totals']['taxonomies']['total'] = $response['totals']['taxonomies']['trash'] + $response['totals']['taxonomies']['publish'] + $response['totals']['taxonomies']['draft'] + $response['totals']['taxonomies']['private']; + } } $response['totals']['items']['total'] = ($response['totals']['items']['trash'] + $response['totals']['items']['draft'] + $response['totals']['items']['publish'] + $response['totals']['items']['private']); return new \WP_REST_Response($response, 200); From 0a52fd416ec195c427af5fef4c52542c3287659e Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Tue, 2 Mar 2021 18:38:26 -0300 Subject: [PATCH 10/94] First usage of summary endpoints #483. --- .../admin/js/store/modules/report/actions.js | 21 +++++++++ .../admin/js/store/modules/report/getters.js | 6 ++- .../admin/js/store/modules/report/index.js | 3 +- .../js/store/modules/report/mutations.js | 4 ++ src/views/reports/components/number-block.vue | 43 ++++++------------- src/views/reports/js/reports-main.js | 9 ---- src/views/reports/pages/reports-list.vue | 41 ++++++++++++++---- 7 files changed, 77 insertions(+), 50 deletions(-) diff --git a/src/views/admin/js/store/modules/report/actions.js b/src/views/admin/js/store/modules/report/actions.js index 1d471fc89..be36e2630 100644 --- a/src/views/admin/js/store/modules/report/actions.js +++ b/src/views/admin/js/store/modules/report/actions.js @@ -19,3 +19,24 @@ export const fetchReports = ({ commit }, {} ) => { .catch(error => reject(error)); }); }; + +export const fetchSummary = ({ commit }, { collectionId } ) => { + + let endpoint = '/reports'; + + if (collectionId && collectionId != 'default') + endpoint += '/collection/' + collectionId + '/summary'; + else + endpoint += '/repository/summary'; + + return new Promise((resolve, reject) => { + axios.tainacan.get(endpoint) + .then(res => { + let summary = res.data; + + commit('setSummary', summary); + resolve(summary); + }) + .catch(error => reject(error)); + }); +}; \ No newline at end of file diff --git a/src/views/admin/js/store/modules/report/getters.js b/src/views/admin/js/store/modules/report/getters.js index cefe6d749..b412a902a 100644 --- a/src/views/admin/js/store/modules/report/getters.js +++ b/src/views/admin/js/store/modules/report/getters.js @@ -1,3 +1,7 @@ export const getReports = state => { return state.reports; -}; \ No newline at end of file +}; + +export const getSummary = state => { + return state.summary; +}; diff --git a/src/views/admin/js/store/modules/report/index.js b/src/views/admin/js/store/modules/report/index.js index 711c11e58..5c9c808fa 100644 --- a/src/views/admin/js/store/modules/report/index.js +++ b/src/views/admin/js/store/modules/report/index.js @@ -644,7 +644,8 @@ const state = { }, }, } - ] + ], + summary: {} }; function generateData (count, yrange) { var i = 0; diff --git a/src/views/admin/js/store/modules/report/mutations.js b/src/views/admin/js/store/modules/report/mutations.js index 02393ee3e..233011f3c 100644 --- a/src/views/admin/js/store/modules/report/mutations.js +++ b/src/views/admin/js/store/modules/report/mutations.js @@ -1,3 +1,7 @@ export const setReports = (state, reports) => { state.reports = reports; +}; + +export const setSummary = (state, summary) => { + state.summary = summary; }; \ No newline at end of file diff --git a/src/views/reports/components/number-block.vue b/src/views/reports/components/number-block.vue index a00294ab3..3f347a7b0 100644 --- a/src/views/reports/components/number-block.vue +++ b/src/views/reports/components/number-block.vue @@ -33,38 +33,19 @@ export default { props: { sourceCollection: String, - entityType: String + entityType: String, + summary: Object }, - data() { - return { - total: 0, - totalByStatus: {} - } - }, - mounted() { - // Fake data until we fetch and load this from store - if (this.entityType === 'items') { - this.total = 2344; - this.totalByStatus = { - 'publish': 2326, - 'private': 8, - 'draft': 9, - 'trash': 1 - } - } else if (this.entityType === 'collections') { - this.total = 23; - this.totalByStatus = { - 'publish': 18, - 'private': 2, - 'trash': 3 - } - } else if (this.entityType === 'taxonomies') { - this.total = 8; - this.totalByStatus = { - 'publish': 5, - 'private': 0, - 'draft': 1, - 'trash': 1 + computed: { + total() { + return this.summary.totals[this.entityType].total; + }, + totalByStatus() { + return { + 'publish': this.summary.totals[this.entityType].publish, + 'private': this.summary.totals[this.entityType].private, + 'draft': this.summary.totals[this.entityType].draft, + 'trash': this.summary.totals[this.entityType].trash } } } diff --git a/src/views/reports/js/reports-main.js b/src/views/reports/js/reports-main.js index aed2bd100..a4a1d6de7 100644 --- a/src/views/reports/js/reports-main.js +++ b/src/views/reports/js/reports-main.js @@ -19,14 +19,6 @@ import NumberBlock from '../components/number-block.vue'; Vue.use(VueApexCharts) -// Apex.theme = { -// monochrome: { -// enabled: true, -// color: '#298596', -// shadeTo: 'light', -// shadeIntensity: 0.65 -// } -// } Apex.colors = [ '#298596', // Tainacan Turquoise '#01295c', // Tainacan Blue @@ -37,7 +29,6 @@ Apex.colors = [ '#ed4f63' // Tainacan Pink ]; - Vue.use(I18NPlugin); Vue.use(UserCapabilitiesPlugin); Vue.use(StatusHelperPlugin); diff --git a/src/views/reports/pages/reports-list.vue b/src/views/reports/pages/reports-list.vue index 7b9652c4c..5c81793fb 100644 --- a/src/views/reports/pages/reports-list.vue +++ b/src/views/reports/pages/reports-list.vue @@ -17,22 +17,32 @@
-
+
-
+
@@ -83,7 +93,8 @@ export default { data() { return { selectedCollection: 'default', - isLoadingCollections: false, + isFetchingCollections: false, + isFetchingSummary: false } }, computed: { @@ -92,11 +103,13 @@ export default { }), ...mapGetters('report', { reports: 'getReports', - }), + summary: 'getSummary' + }) }, watch: { '$route.query' (to) { this.selectedCollection = to['collection'] ? to['collection'] : 'default'; + this.loadSummary(); } }, created() { @@ -104,15 +117,27 @@ export default { this.selectedCollection = this.$route.query['collection'] ? this.$route.query['collection'] : 'default'; // Loads collection for the select input - this.isLoadingCollections = true; + this.isFetchingCollections = true; this.fetchAllCollectionNames() - .then(() => this.isLoadingCollections = false) - .catch(() => this.isLoadingCollections = false); + .then(() => { + this.loadSummary(); + this.isFetchingCollections = false; + }) + .catch(() => this.isFetchingCollections = false); }, methods: { ...mapActions('collection', [ 'fetchAllCollectionNames' - ]) + ]), + ...mapActions('report', [ + 'fetchSummary', + ]), + loadSummary() { + this.isFetchingSummary = true; + this.fetchSummary({ collectionId: this.selectedCollection }) + .then(() => this.isFetchingSummary = false) + .catch(() => this.isFetchingSummary = false); + } } } From e3a07bc70bdf3c1c551436963389a2c431689559 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Wed, 3 Mar 2021 10:01:59 -0300 Subject: [PATCH 11/94] Adds loading state to number block and countup component to animate numbers. #483 --- package-lock.json | 10 +++++++ package.json | 2 ++ src/views/reports/components/number-block.vue | 28 ++++++++++++++----- src/views/reports/pages/reports-list.vue | 19 ++++++++----- src/views/reports/reports.vue | 1 + 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6efb55564..ce25176e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3005,6 +3005,11 @@ } } }, + "countup.js": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/countup.js/-/countup.js-2.0.7.tgz", + "integrity": "sha512-FO0nQdvG1iQwHp28wdvkErxnNUSbdkzztqZ6YNHKLHydngD2tdiKEW8dFrqpahF3tj+Ma70h0vyYrCBzxlVWdg==" + }, "create-ecdh": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", @@ -10791,6 +10796,11 @@ "resolved": "https://registry.npmjs.org/vue-blurhash/-/vue-blurhash-0.1.4.tgz", "integrity": "sha512-B76GgfHXHkdmYgAfI2rZl3BgCMD9OxAgn4Jw2Ro0a8ZoAKa6gqTWUrTo5EGXOftm/EKuMYi1Cc+UcAvV0jnoRw==" }, + "vue-countup-v2": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vue-countup-v2/-/vue-countup-v2-4.0.0.tgz", + "integrity": "sha512-XjKeHo1ndRlJtXvHd6B1eWOpbrJDdNU3rdYZwVPv2YlUXbvthsBT4kms5Fc/mn9RdXPrMX2H/ktAAQtKjWFisw==" + }, "vue-eslint-parser": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-5.0.0.tgz", diff --git a/package.json b/package.json index c77aa34c9..c80a72740 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "blurhash": "^1.1.3", "buefy": "^0.9.4", "bulma": "^0.9.1", + "countup.js": "^2.0.7", "css-vars-ponyfill": "^2.3.1", "mdi": "^2.2.43", "moment": "^2.25.3", @@ -27,6 +28,7 @@ "vue-apexcharts": "^1.6.0", "vue-awesome-swiper": "^4.1.1", "vue-blurhash": "^0.1.4", + "vue-countup-v2": "^4.0.0", "vue-masonry-css": "^1.0.3", "vue-router": "^3.1.6", "vue-the-mask": "^0.11.1", diff --git a/src/views/reports/components/number-block.vue b/src/views/reports/components/number-block.vue index 3f347a7b0..2ff9d63fb 100644 --- a/src/views/reports/components/number-block.vue +++ b/src/views/reports/components/number-block.vue @@ -1,6 +1,10 @@ \ No newline at end of file diff --git a/src/views/reports/components/number-block.vue b/src/views/reports/components/number-block.vue index 2ff9d63fb..ffeb98e2e 100644 --- a/src/views/reports/components/number-block.vue +++ b/src/views/reports/components/number-block.vue @@ -1,9 +1,10 @@ From de29aaeef52f65dfc42e12891434386a94f1423a Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Tue, 30 Mar 2021 12:06:45 -0300 Subject: [PATCH 56/94] Adds list of activities by user #483 --- .../admin/js/store/modules/report/index.js | 1 - .../reports/components/activities-block.vue | 213 +++++++++++------- 2 files changed, 135 insertions(+), 79 deletions(-) diff --git a/src/views/admin/js/store/modules/report/index.js b/src/views/admin/js/store/modules/report/index.js index f2d2fdc6b..dd87990d3 100644 --- a/src/views/admin/js/store/modules/report/index.js +++ b/src/views/admin/js/store/modules/report/index.js @@ -158,7 +158,6 @@ const state = { } }, }, - colors: ['#7BD39A'], dataLabels: { enabled: false }, diff --git a/src/views/reports/components/activities-block.vue b/src/views/reports/components/activities-block.vue index 8a42102c8..5fe9667d4 100644 --- a/src/views/reports/components/activities-block.vue +++ b/src/views/reports/components/activities-block.vue @@ -1,9 +1,29 @@ \ No newline at end of file + + + \ No newline at end of file From 3dfbc0abb938d02353de9b473b718c298207d79e Mon Sep 17 00:00:00 2001 From: vnmedeiros Date: Tue, 30 Mar 2021 14:53:01 -0300 Subject: [PATCH 57/94] feat: add cache to all reports #483 --- ...class-tainacan-rest-reports-controller.php | 213 +++++++++++++++++- 1 file changed, 209 insertions(+), 4 deletions(-) diff --git a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php index f648f8b2e..1d50c454f 100644 --- a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php +++ b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php @@ -32,6 +32,18 @@ class REST_Reports_Controller extends REST_Controller { 'methods' => \WP_REST_Server::READABLE, 'callback' => array($this, 'get_collections'), 'permission_callback' => array($this, 'reports_permissions_check'), + 'args' => [ + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] ), ) ); @@ -41,6 +53,18 @@ class REST_Reports_Controller extends REST_Controller { 'methods' => \WP_REST_Server::READABLE, 'callback' => array($this, 'get_summary'), 'permission_callback' => array($this, 'reports_permissions_check'), + 'args' => [ + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] ), ) ); @@ -50,6 +74,18 @@ class REST_Reports_Controller extends REST_Controller { 'methods' => \WP_REST_Server::READABLE, 'callback' => array($this, 'get_stats_collection_metadata'), 'permission_callback' => array($this, 'reports_permissions_check'), + 'args' => [ + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] ), ) ); @@ -59,6 +95,18 @@ class REST_Reports_Controller extends REST_Controller { 'methods' => \WP_REST_Server::READABLE, 'callback' => array($this, 'get_stats_metadata'), 'permission_callback' => array($this, 'reports_permissions_check'), + 'args' => [ + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] ), ) ); @@ -68,6 +116,18 @@ class REST_Reports_Controller extends REST_Controller { 'methods' => \WP_REST_Server::READABLE, 'callback' => array($this, 'get_stats_metadata'), 'permission_callback' => array($this, 'reports_permissions_check'), + 'args' => [ + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] ), ) ); @@ -77,6 +137,18 @@ class REST_Reports_Controller extends REST_Controller { 'methods' => \WP_REST_Server::READABLE, 'callback' => array($this, 'get_stats_collection_metadata'), 'permission_callback' => array($this, 'reports_permissions_check'), + 'args' => [ + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] ), ) ); @@ -86,6 +158,18 @@ class REST_Reports_Controller extends REST_Controller { 'methods' => \WP_REST_Server::READABLE, 'callback' => array($this, 'get_summary'), 'permission_callback' => array($this, 'reports_permissions_check'), + 'args' => [ + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] ), ) ); @@ -95,6 +179,18 @@ class REST_Reports_Controller extends REST_Controller { 'methods' => \WP_REST_Server::READABLE, 'callback' => array($this, 'get_taxonomies_list'), 'permission_callback' => array($this, 'reports_permissions_check'), + 'args' => [ + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] ), ) ); @@ -104,6 +200,18 @@ class REST_Reports_Controller extends REST_Controller { 'methods' => \WP_REST_Server::READABLE, 'callback' => array($this, 'get_taxonomy'), 'permission_callback' => array($this, 'reports_permissions_check'), + 'args' => [ + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] ), ) ); @@ -123,7 +231,18 @@ class REST_Reports_Controller extends REST_Controller { 'title' => __( 'start Date', 'tainacan' ), 'type' => 'string', 'format' => 'date-time', // RFC3339. https://tools.ietf.org/html/rfc3339#section-5.8 - ]] + ], + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] ), ) ); @@ -133,6 +252,28 @@ class REST_Reports_Controller extends REST_Controller { 'methods' => \WP_REST_Server::READABLE, 'callback' => array($this, 'get_activities'), 'permission_callback' => array($this, 'reports_permissions_check'), + 'args' => [ + 'start' => [ + 'title' => __( 'start Date', 'tainacan' ), + 'type' => 'string', + 'format' => 'date-time', + ], + 'end' => [ + 'title' => __( 'start Date', 'tainacan' ), + 'type' => 'string', + 'format' => 'date-time', // RFC3339. https://tools.ietf.org/html/rfc3339#section-5.8 + ], + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] ), ) ); @@ -146,6 +287,9 @@ class REST_Reports_Controller extends REST_Controller { $response = array( 'list' => [] ); + $key_cache_object = 'collections'; + $cached_object = $this->get_cache_object($key_cache_object, $request); + if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); $collections = $this->collections_repository->fetch([]); if($collections->have_posts()) { @@ -171,6 +315,7 @@ class REST_Reports_Controller extends REST_Controller { } wp_reset_postdata(); } + $this->set_cache_object($key_cache_object, $response); return new \WP_REST_Response($response, 200); } @@ -188,6 +333,11 @@ class REST_Reports_Controller extends REST_Controller { ); if(isset($request['collection_id'])) { $collection_id = $request['collection_id']; + + $key_cache_object = 'summary_' . $collection_id; + $cached_object = $this->get_cache_object($key_cache_object, $request); + if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); + $collection = $this->collections_repository->fetch($collection_id); $total_items = wp_count_posts( $collection->get_db_identifier(), 'readable' ); if (isset($total_items->publish) || @@ -201,6 +351,10 @@ class REST_Reports_Controller extends REST_Controller { $response['totals']['items']['private'] = intval($total_items->private); } } else { + $key_cache_object = 'summary'; + $cached_object = $this->get_cache_object($key_cache_object, $request); + if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); + $collections = $this->collections_repository->fetch([]); $response['totals']['collections'] = array( 'total' => 0, @@ -253,6 +407,7 @@ class REST_Reports_Controller extends REST_Controller { } } $response['totals']['items']['total'] = ($response['totals']['items']['trash'] + $response['totals']['items']['draft'] + $response['totals']['items']['publish'] + $response['totals']['items']['private']); + $this->set_cache_object($key_cache_object, $response); return new \WP_REST_Response($response, 200); } @@ -263,6 +418,10 @@ class REST_Reports_Controller extends REST_Controller { ) ); + $key_cache_object = 'taxonomies_list'; + $cached_object = $this->get_cache_object($key_cache_object, $request); + if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); + $taxonomies = $this->taxonomy_repository->fetch(); if($taxonomies->have_posts()){ while ($taxonomies->have_posts()){ @@ -283,6 +442,7 @@ class REST_Reports_Controller extends REST_Controller { } wp_reset_postdata(); } + $this->set_cache_object($key_cache_object, $response); return new \WP_REST_Response($response, 200); } @@ -299,6 +459,10 @@ class REST_Reports_Controller extends REST_Controller { if ( !$taxonomy_total_terms) { $taxonomy_total_terms = 0; + } else { + $key_cache_object = 'taxonomy_' . $taxonomy_identifier; + $cached_object = $this->get_cache_object($key_cache_object, $request); + if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); } while($offset < $taxonomy_total_terms) { @@ -317,6 +481,7 @@ class REST_Reports_Controller extends REST_Controller { } $offset+=$limit; } + $this->set_cache_object($key_cache_object, $response); return new \WP_REST_Response($response, 200); } @@ -333,6 +498,10 @@ class REST_Reports_Controller extends REST_Controller { $parent_id = (int) $request['parent']; } + $key_cache_object = "stats_metadata_$metadata_id-$collection_id-$parent_id"; + $cached_object = $this->get_cache_object($key_cache_object, $request); + if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); + $args = [ 'collection_id' => $collection_id, 'parent_id' => $parent_id, @@ -350,6 +519,8 @@ class REST_Reports_Controller extends REST_Controller { 'total_children' => intval($item['total_children']), ]; }, $data['values']); + + $this->set_cache_object($key_cache_object, $response); return new \WP_REST_Response($response, 200); } @@ -370,6 +541,11 @@ class REST_Reports_Controller extends REST_Controller { if(isset($request['collection_id'])) { $collection_id = $request['collection_id']; + + $key_cache_object = 'stats_collection_metadata_' . $collection_id; + $cached_object = $this->get_cache_object($key_cache_object, $request); + if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); + $collection = new Entities\Collection( $collection_id ); $result_metadatum = $this->metadatum_repository->fetch_by_collection( $collection, [] ); $response['totals']['metadata']['total'] = count($result_metadatum); @@ -401,8 +577,12 @@ class REST_Reports_Controller extends REST_Controller { ] ] ]; - $result_metadatum = $this->metadatum_repository->fetch( $args, 'OBJECT' ); + $key_cache_object = 'stats_collection_metadata'; + $cached_object = $this->get_cache_object($key_cache_object, $request); + if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); + + $result_metadatum = $this->metadatum_repository->fetch( $args, 'OBJECT' ); $meta_ids=[]; foreach($result_metadatum as $metadatum) { $meta_type = explode('\\', $metadatum->get_metadata_type()) ; @@ -422,6 +602,7 @@ class REST_Reports_Controller extends REST_Controller { $response['distribution'] = $this->query_item_metadata_distribution($meta_ids, 'default'); } + $this->set_cache_object($key_cache_object, $response); return new \WP_REST_Response($response, 200); } @@ -497,6 +678,11 @@ class REST_Reports_Controller extends REST_Controller { if(isset($request['start']) && isset($request['end'])) { $start = new \DateTime($request['start']); $end = new \DateTime($request['end']); + + $key_cache_object = 'activities_' . $start->format('Y-m-d') . '_' . $collection_id; + $cached_object = $this->get_cache_object($key_cache_object, $request); + if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); + $end_limit = $start->add(new \DateInterval('P1Y')); if($end > $end_limit) $end = $end_limit; @@ -505,13 +691,15 @@ class REST_Reports_Controller extends REST_Controller { 'end' => $end->format('Y-m-d H:i:s') ]; } else { + $key_cache_object = 'activities_' . $collection_id; + $cached_object = $this->get_cache_object($key_cache_object, $request); + if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); $interval = [ 'end' => (new \DateTime())->format('Y-m-d H:i:s'), 'start' => (new \DateTime($request['end']))->sub(new \DateInterval('P1Y')) ->format('Y-m-d H:i:s') ]; } - - + $response['totals'] = array( 'by_interval' => array( 'start' => $interval['start'], @@ -521,6 +709,7 @@ class REST_Reports_Controller extends REST_Controller { ), 'by_user' => $this->get_activities_users($collection_id) ); + $this->set_cache_object($key_cache_object, $response); return new \WP_REST_Response($response, 200); } @@ -598,6 +787,22 @@ class REST_Reports_Controller extends REST_Controller { } return array_values($response); } + + private $prefix_transient_cahce = 'reports_tnc_'; + + private function get_cache_object($key, $request) { + if ( !isset($request['force']) || $request['force'] == 'no' ) { + $transient = get_transient($this->prefix_transient_cahce . $key); + return $transient; + } + return false; + } + + private function set_cache_object($key, $data) { + $expiration = 604800; //one week + $data['report_cached_on'] = (new \DateTime())->format('Y-m-d H:i:s'); + return set_transient($this->prefix_transient_cahce . $key, $data, $expiration); + } } ?> \ No newline at end of file From d1d9cf22ea44d6d615804a4f063c212d29d2ea8c Mon Sep 17 00:00:00 2001 From: vnmedeiros Date: Tue, 30 Mar 2021 16:26:22 -0300 Subject: [PATCH 58/94] fix: remove endpoint `metadata` on reports #483 --- ...class-tainacan-rest-reports-controller.php | 81 ------------------- 1 file changed, 81 deletions(-) diff --git a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php index 1d50c454f..ff90d838e 100644 --- a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php +++ b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php @@ -89,48 +89,6 @@ class REST_Reports_Controller extends REST_Controller { ), ) ); - register_rest_route($this->namespace, $this->rest_base . '/collection/(?P[\d]+)/metadata/(?P[\d]+)', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array($this, 'get_stats_metadata'), - 'permission_callback' => array($this, 'reports_permissions_check'), - 'args' => [ - 'force' => [ - 'title' => __( 'Force regenerete', 'tainacan' ), - 'type' => 'string', - 'default' => 'no', - 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), - 'enum' => array( - 'no', - 'yes' - ) - ] - ] - ), - ) - ); - register_rest_route($this->namespace, $this->rest_base . '/metadata/(?P[\d]+)', - array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array($this, 'get_stats_metadata'), - 'permission_callback' => array($this, 'reports_permissions_check'), - 'args' => [ - 'force' => [ - 'title' => __( 'Force regenerete', 'tainacan' ), - 'type' => 'string', - 'default' => 'no', - 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), - 'enum' => array( - 'no', - 'yes' - ) - ] - ] - ), - ) - ); register_rest_route($this->namespace, $this->rest_base . '/metadata', array( array( @@ -485,45 +443,6 @@ class REST_Reports_Controller extends REST_Controller { return new \WP_REST_Response($response, 200); } - public function get_stats_metadata($request) { - // Free php session early so simultaneous requests dont get queued - session_write_close(); - $response = array( - 'list' => array() - ); - $metadata_id = $request['metadata_id']; - $collection_id = ( isset($request['collection_id']) ) ? $request['collection_id'] : null; - $parent_id = 0; - if ( isset($request['parent']) ) { - $parent_id = (int) $request['parent']; - } - - $key_cache_object = "stats_metadata_$metadata_id-$collection_id-$parent_id"; - $cached_object = $this->get_cache_object($key_cache_object, $request); - if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); - - $args = [ - 'collection_id' => $collection_id, - 'parent_id' => $parent_id, - 'count_items'=> true, - ]; - - $data = $this->metadatum_repository->fetch_all_metadatum_values($metadata_id, $args); - $response['list'] = array_map(function($item) { - return [ - 'type' => $item['type'], - 'value' => $item['value'], - 'label' => $item['label'], - 'parent' => $item['parent'] == null ? 0 : $item['parent'], - 'total_items' => intval($item['total_items']), - 'total_children' => intval($item['total_children']), - ]; - }, $data['values']); - - $this->set_cache_object($key_cache_object, $response); - return new \WP_REST_Response($response, 200); - } - public function get_stats_collection_metadata($request) { $response = array( 'totals'=> array( From 5a3fc13113d1b1a9de7b990b442795fd0ce048b4 Mon Sep 17 00:00:00 2001 From: vnmedeiros Date: Tue, 30 Mar 2021 16:32:46 -0300 Subject: [PATCH 59/94] feat: update reponse for `activities` by user in interval #483 --- .../class-tainacan-rest-reports-controller.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php index ff90d838e..7d031b310 100644 --- a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php +++ b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php @@ -668,9 +668,17 @@ class REST_Reports_Controller extends REST_Controller { $data =$wpdb->get_results($sql_statement); $arr = array(); foreach ($data as $item) { - $arr[$item->user_id][] = $item; + if(!isset($arr[$item->user_id])) { + $arr[$item->user_id] = [ + 'user_id' => $item->user_id, + 'total' => 0, + 'by_date' => [] + ]; + } + $arr[$item->user_id]['by_date'][] = $item; + $arr[$item->user_id]['total'] += $item->total; } - return $arr; + return array_values($arr); } private function get_activities_users($collection_id = false) { From 56693d4c136eaa2c71b53e4335debd53ab3e10bd Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Tue, 30 Mar 2021 16:36:29 -0300 Subject: [PATCH 60/94] Continues implementation of per user activities charts. #483 --- .../admin/js/store/modules/report/index.js | 24 +-- .../reports/components/activities-block.vue | 156 +++++++++++------- src/views/tainacan-admin-i18n.php | 1 + 3 files changed, 107 insertions(+), 74 deletions(-) diff --git a/src/views/admin/js/store/modules/report/index.js b/src/views/admin/js/store/modules/report/index.js index dd87990d3..15a349a88 100644 --- a/src/views/admin/js/store/modules/report/index.js +++ b/src/views/admin/js/store/modules/report/index.js @@ -146,17 +146,6 @@ const state = { toolbar: { autoSelected: 'selection', }, - // brush: { - // enabled: true, - // target: 'chartyear' - // }, - selection: { - enabled: true, - xaxis: { - min: new Date('2010-03-29').getTime(), - max: new Date('2020-03-29').getTime() - } - }, }, dataLabels: { enabled: false @@ -167,7 +156,13 @@ const state = { }, fill: { opacity: 1, - type: 'solid' + type: 'gradient', + gradient: { + shade: 'light', + type: "vertical", + opacityFrom: 0.9, + opacityTo: 0.85, + } }, legend: { position: 'top', @@ -176,6 +171,11 @@ const state = { xaxis: { type: 'datetime' }, + yaxis: { + labels: { + minWidth: 64 + } + } } }; diff --git a/src/views/reports/components/activities-block.vue b/src/views/reports/components/activities-block.vue index 5fe9667d4..49b19441c 100644 --- a/src/views/reports/components/activities-block.vue +++ b/src/views/reports/components/activities-block.vue @@ -3,23 +3,33 @@
-
- +
+ +
+

{{ users[chartSeries[0].userId].name }}

+ {{ chartSeries[0].total }} +
+
+ +
{ - this.users = resp.users; + resp.users.forEach((user) => { + this.users[user.id] = user; + }); this.isFetchingUsers = false; }) .catch(() => { @@ -82,25 +94,19 @@ export default { const daysWithActivities = (this.chartData.totals.by_interval && this.chartData.totals.by_interval.general) ? this.chartData.totals.by_interval.general : []; - this.chartSeries = [{ - data: daysWithActivities.map((activity) => { - return { - x: new Date(activity.date).getTime(), - y: activity.total - } - }) - }]; - const daysWithActivitiesByUser = this.chartData.totals.by_interval.by_user; - Object.keys(daysWithActivitiesByUser).forEach((userId) => { - this.chartSeriesByUser[userId] = [{ - data: daysWithActivitiesByUser[userId].map((activity) => { - return { - x: new Date(activity.date).getTime(), - y: activity.total - } - }) - }]; - }); + this.chartSeries = [{ + data: [] + }]; + let maximumOfActivitiesInADay = 0; + daysWithActivities.forEach((activity) => { + this.chartSeries[0].data.push({ + x: new Date(activity.date).getTime(), + y: activity.total + }); + if (maximumOfActivitiesInADay < activity.total) + maximumOfActivitiesInADay = activity.total + }); + console.log(maximumOfActivitiesInADay); this.chartOptions = { ...this.areaChartOptions, title: { @@ -118,23 +124,41 @@ export default { colors: ['#01295c'], }; - this.chartOptionsByUser = { - ...this.areaChartOptions, - title: { - text: '' - }, - chart: { - id: 'userschart', - height: 160, - type: 'area', - group: 'activities', - toolbar: { - show: false, - autoSelected: 'pan' + const daysWithActivitiesByUser = this.chartData.totals.by_interval.by_user; + const totalOfActivitiesByUser = this.chartData.totals.by_user.sort((a, b) => b.total - a.total); + + totalOfActivitiesByUser.forEach((totalActivityByUser) => { + this.chartSeriesByUser.push([{ + total: totalActivityByUser.total, + userId: totalActivityByUser.user_id, + data: daysWithActivitiesByUser[totalActivityByUser.user_id] ? daysWithActivitiesByUser[totalActivityByUser.user_id].map((activity) => { + return { + x: new Date(activity.date).getTime(), + y: activity.total + } + }) : [{ + x: null, + y: 0 + }] + }]); + this.chartOptionsByUser.push({ + ...this.areaChartOptions, + title: { + text: '' + }, + chart: { + id: 'userschart-' + totalActivityByUser.user_id, + height: 160, + type: 'area', + group: 'activities', + toolbar: { + show: false, + autoSelected: 'pan' + } } - } - } - + }); + }); + setTimeout(() => this.isBuildingChart = false, 500); } } @@ -147,28 +171,36 @@ export default { flex-direction: column-reverse; } .users-charts { - display: flex; - flex-wrap: wrap; - justify-content: space-evenly; + padding: 12px; .users-charts__card { - width: calc(33.3333% - 48px); - max-width: calc(33.3333% - 48px); padding: 24px; .users-charts__card--header { display: flex; align-items: center; - img { + img, + .anonymous-user-avatar { margin-right: 0.75em; border-radius: 2px; width: 32px; height: 32px; + background-color: var(--tainacan-gray1, #f2f2f2); } - p { - font-weight: bold; - font-size: 1.125em; + + .users-charts__card--header-text { + display: flex; + flex-direction: column; + + p { + font-weight: bold; + font-size: 1.0em; + margin: 0; + } + span { + color: var(--tainacan-secondary, #298596); + } } } } diff --git a/src/views/tainacan-admin-i18n.php b/src/views/tainacan-admin-i18n.php index 55b3ca3b6..f1f1f8de5 100644 --- a/src/views/tainacan-admin-i18n.php +++ b/src/views/tainacan-admin-i18n.php @@ -563,6 +563,7 @@ return apply_filters( 'tainacan-admin-i18n', [ 'label_pie_chart' => __( 'Pie chart', 'tainacan'), 'label_bar_chart' => __( 'Bar chart', 'tainacan'), 'label_terms_per_page' => __( 'Terms per page', 'tainacan'), + 'label_anonymous_user' => __( 'Anonymous User', 'tainacan'), // Instructions. More complex sentences to guide user and placeholders 'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ), From 52dd5b64851ade86d6fceb34cf92a853340263a1 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Tue, 30 Mar 2021 17:39:29 -0300 Subject: [PATCH 61/94] Several fixes and improvements to per user activities chart #483 --- .../admin/js/store/modules/report/index.js | 16 ++- .../reports/components/activities-block.vue | 110 +++++++++++++----- 2 files changed, 93 insertions(+), 33 deletions(-) diff --git a/src/views/admin/js/store/modules/report/index.js b/src/views/admin/js/store/modules/report/index.js index 15a349a88..9266cf340 100644 --- a/src/views/admin/js/store/modules/report/index.js +++ b/src/views/admin/js/store/modules/report/index.js @@ -144,14 +144,22 @@ const state = { height: 200, type: 'area', toolbar: { - autoSelected: 'selection', + show: true, + tools: { + download: true, + selection: false, + zoom: true, + zoomin: true, + zoomout: true, + pan: true, + } }, }, dataLabels: { enabled: false }, stroke: { - width: 0, + width: 1, curve: 'smooth' }, fill: { @@ -160,8 +168,8 @@ const state = { gradient: { shade: 'light', type: "vertical", - opacityFrom: 0.9, - opacityTo: 0.85, + opacityFrom: 0.65, + opacityTo: 0.35, } }, legend: { diff --git a/src/views/reports/components/activities-block.vue b/src/views/reports/components/activities-block.vue index 49b19441c..d3743dd09 100644 --- a/src/views/reports/components/activities-block.vue +++ b/src/views/reports/components/activities-block.vue @@ -5,15 +5,17 @@ class="postbox">
-

{{ $i18n.get('label_anonymous_user') }}

- {{ chartSeries[0].total }} +
+

{{ $i18n.get('label_anonymous_user') }}

+ {{ chartSeries[0].total }} +
{ + const startDate = new Date(this.chartData.totals.by_interval.start).getTime(); + const endDate = new Date(this.chartData.totals.by_interval.end).getTime(); + + this.chartSeries = [{ + data: [] + }]; + + let maximumOfActivitiesInADay = 0; + daysWithActivities.forEach((activity) => { this.chartSeries[0].data.push({ x: new Date(activity.date).getTime(), - y: activity.total + y: parseInt(activity.total) }); - if (maximumOfActivitiesInADay < activity.total) - maximumOfActivitiesInADay = activity.total + if (maximumOfActivitiesInADay < parseInt(activity.total)) + maximumOfActivitiesInADay = parseInt(activity.total) }); - console.log(maximumOfActivitiesInADay); + this.chartOptions = { ...this.areaChartOptions, title: { @@ -118,28 +123,44 @@ export default { type: 'area', group: 'activities', toolbar: { - autoSelected: 'selection', + show: true, + tools: { + download: true, + selection: false, + zoom: true, + zoomin: true, + zoomout: true, + pan: true, + } }, }, + xaxis: { + type: 'datetime', + min: startDate, + max: endDate + }, + yaxis: { + max: maximumOfActivitiesInADay, + tickAmount: 4, + labels: { + minWidth: 48 + } + }, colors: ['#01295c'], }; - const daysWithActivitiesByUser = this.chartData.totals.by_interval.by_user; - const totalOfActivitiesByUser = this.chartData.totals.by_user.sort((a, b) => b.total - a.total); + const daysWithActivitiesByUser = JSON.parse(JSON.stringify(this.chartData.totals.by_interval.by_user)).sort((a, b) => parseInt(b.total) - parseInt(a.total)); - totalOfActivitiesByUser.forEach((totalActivityByUser) => { + daysWithActivitiesByUser.forEach((daysWithActivityByUser) => { this.chartSeriesByUser.push([{ - total: totalActivityByUser.total, - userId: totalActivityByUser.user_id, - data: daysWithActivitiesByUser[totalActivityByUser.user_id] ? daysWithActivitiesByUser[totalActivityByUser.user_id].map((activity) => { + total: daysWithActivityByUser.total, + userId: daysWithActivityByUser.user_id, + data: daysWithActivityByUser.by_date.map((activity) => { return { x: new Date(activity.date).getTime(), - y: activity.total + y: parseInt(activity.total) } - }) : [{ - x: null, - y: 0 - }] + }) }]); this.chartOptionsByUser.push({ ...this.areaChartOptions, @@ -147,13 +168,32 @@ export default { text: '' }, chart: { - id: 'userschart-' + totalActivityByUser.user_id, + id: 'userschart-' + daysWithActivityByUser.user_id, height: 160, type: 'area', group: 'activities', toolbar: { - show: false, - autoSelected: 'pan' + show: true, + tools: { + download: true, + selection: false, + zoom: true, + zoomin: true, + zoomout: true, + pan: true, + } + }, + }, + xaxis: { + type: 'datetime', + min: startDate, + max: endDate + }, + yaxis: { + max: maximumOfActivitiesInADay, + tickAmount: 4, + labels: { + minWidth: 48 } } }); @@ -179,6 +219,7 @@ export default { .users-charts__card--header { display: flex; align-items: center; + padding: 6px 12px 2px 12px; img, .anonymous-user-avatar { @@ -186,7 +227,18 @@ export default { border-radius: 2px; width: 32px; height: 32px; - background-color: var(--tainacan-gray1, #f2f2f2); + background-color: var(--tainacan-gray2, #dbdbdb); + } + .anonymous-user-avatar:before { + content: "?"; + color: var(--tainacan-gray5, #454647); + font-size: 1.5em; + font-weight: bold; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; } .users-charts__card--header-text { From 3634edafa163cc736a59c745fb197ade526d43e8 Mon Sep 17 00:00:00 2001 From: vnmedeiros Date: Wed, 31 Mar 2021 11:41:35 -0300 Subject: [PATCH 62/94] feat: add reports to taxonomy metadata of collection #483 --- ...class-tainacan-rest-reports-controller.php | 73 ++++++++++++++++++- .../class-tainacan-taxonomies.php | 6 +- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php index 7d031b310..fa8ade726 100644 --- a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php +++ b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php @@ -15,8 +15,9 @@ class REST_Reports_Controller extends REST_Controller { } public function init_objects() { - $this->metadatum_repository = Repositories\Metadata::get_instance(); + $this->items_repository = Repositories\Items::get_instance(); $this->taxonomy_repository = Repositories\Taxonomies::get_instance(); + $this->metadatum_repository = Repositories\Metadata::get_instance(); $this->collections_repository = Repositories\Collections::get_instance(); } @@ -235,6 +236,31 @@ class REST_Reports_Controller extends REST_Controller { ), ) ); + register_rest_route($this->namespace, $this->rest_base . '/collection/(?P[\d]+)/metadata/(?P[\d]+)', + array( + array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array($this, 'get_metadata'), + 'permission_callback' => array($this, 'reports_permissions_check'), + 'args' => [ + 'parent' => [ + 'title' => __( 'parent', 'tainacan' ), + 'type' => 'integer', + ], + 'force' => [ + 'title' => __( 'Force regenerete', 'tainacan' ), + 'type' => 'string', + 'default' => 'no', + 'description' => __( 'Force generates the reports graphic.', 'tainacan' ), + 'enum' => array( + 'no', + 'yes' + ) + ] + ] + ), + ) + ); } public function reports_permissions_check($request) { @@ -443,6 +469,51 @@ class REST_Reports_Controller extends REST_Controller { return new \WP_REST_Response($response, 200); } + public function get_metadata($request) { + $response = array( + 'list' => array() + ); + $collection_id = $request['collection_id']; + $taxonomy_metadata_id = $request['metadata_id'];; + $parent_id = 0; + if ( isset($request['parent']) ) { + $parent_id = (int) $request['parent']; + } + + $key_cache_object = "facet_taxonomy_$taxonomy_metadata_id-$collection_id-$parent_id"; + $cached_object = $this->get_cache_object($key_cache_object, $request); + if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); + + $metadatum = $this->metadatum_repository->fetch($taxonomy_metadata_id); + $metadatum_type = $metadatum->get_metadata_type(); + if($metadatum_type != 'Tainacan\Metadata_Types\Taxonomy') { + return new \WP_REST_Response([ + 'error_message' => __('Only taxonomy metadata type has allowed.', 'tainacan'), + 'metadatum_type' => $metadatum_type + ], 400); + } + + $args = [ + 'collection_id' => $collection_id, + 'parent_id' => $parent_id, + 'count_items'=> true, + ]; + $data = $this->metadatum_repository->fetch_all_metadatum_values($taxonomy_metadata_id, $args); + $response['list'] = array_map(function($item) { + return [ + 'type' => $item['type'], + 'value' => $item['value'], + 'label' => $item['label'], + 'parent' => $item['parent'] == null ? 0 : $item['parent'], + 'total_items' => intval($item['total_items']), + 'total_children' => intval($item['total_children']), + ]; + }, $data['values']); + + $this->set_cache_object($key_cache_object, $response); + return new \WP_REST_Response($response, 200); + } + public function get_stats_collection_metadata($request) { $response = array( 'totals'=> array( diff --git a/src/classes/repositories/class-tainacan-taxonomies.php b/src/classes/repositories/class-tainacan-taxonomies.php index 5aa6d8482..b9e71553c 100644 --- a/src/classes/repositories/class-tainacan-taxonomies.php +++ b/src/classes/repositories/class-tainacan-taxonomies.php @@ -210,9 +210,7 @@ class Taxonomies extends Repository { * @return array Entities\Taxonomy * @throws \Exception */ - public function fetch_by_collection( Entities\Collection $collection, $args = [] ) { - $collection_id = $collection->get_id(); - + public function fetch_by_collection( Entities\Collection $collection, $args = [], $output = 'OBJECT' ) { $Tainacan_Metadata = Metadata::get_instance(); // get all taxonomy metadata in this collection @@ -236,7 +234,7 @@ class Taxonomies extends Repository { ]; $args = array_merge($args, $newargs); - return $this->fetch($args, 'OBJECT'); + return $this->fetch($args, $output); } From 2293fbc0be943bca5eea2559065ad50648eb3423 Mon Sep 17 00:00:00 2001 From: vnmedeiros Date: Wed, 31 Mar 2021 11:50:50 -0300 Subject: [PATCH 63/94] feat: makes the `end` parameter as optional for activities reports #483 --- .../api/endpoints/class-tainacan-rest-reports-controller.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php index fa8ade726..1dbf82b54 100644 --- a/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php +++ b/src/classes/api/endpoints/class-tainacan-rest-reports-controller.php @@ -665,15 +665,15 @@ class REST_Reports_Controller extends REST_Controller { $collection_id = $request['collection_id']; } - if(isset($request['start']) && isset($request['end'])) { + if( isset($request['start']) ) { $start = new \DateTime($request['start']); - $end = new \DateTime($request['end']); $key_cache_object = 'activities_' . $start->format('Y-m-d') . '_' . $collection_id; $cached_object = $this->get_cache_object($key_cache_object, $request); if($cached_object !== false ) return new \WP_REST_Response($cached_object, 200); $end_limit = $start->add(new \DateInterval('P1Y')); + $end = isset($request['end']) ? new \DateTime($request['end']) : $end_limit; if($end > $end_limit) $end = $end_limit; $interval = [ From c565f0a0cb60ffde0e927242fc0d64fc18626f63 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Wed, 31 Mar 2021 11:54:10 -0300 Subject: [PATCH 64/94] Adds start year input to report charts #483 --- src/assets/css/tainacan-reports.css | 3 +- src/assets/css/tainacan-reports.css.map | 2 +- .../admin/js/store/modules/report/actions.js | 12 +- .../reports/components/activities-block.vue | 177 +++++++++++++----- .../components/items-per-term-block.vue | 8 +- src/views/reports/pages/reports-list.vue | 16 +- src/views/reports/tainacan-reports.scss | 1 + 7 files changed, 146 insertions(+), 73 deletions(-) diff --git a/src/assets/css/tainacan-reports.css b/src/assets/css/tainacan-reports.css index 9acafcd4e..cc2212c58 100644 --- a/src/assets/css/tainacan-reports.css +++ b/src/assets/css/tainacan-reports.css @@ -34,7 +34,8 @@ justify-content: space-between; flex-wrap: wrap; } #tainacan-reports-app .postbox .box-header .box-header__item { - margin-bottom: 10px; } + margin-bottom: 10px; + line-height: 2rem; } #tainacan-reports-app .graph-mode-switch { display: inline-block; } #tainacan-reports-app .graph-mode-switch button { diff --git a/src/assets/css/tainacan-reports.css.map b/src/assets/css/tainacan-reports.css.map index c37e87ca0..ad404a8ad 100644 --- a/src/assets/css/tainacan-reports.css.map +++ b/src/assets/css/tainacan-reports.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "AAAA,qBAAsB;EAClB,OAAO,EAAE,iBAAiB;EAC1B,MAAM,EAAE,CAAC;EAGT,4CAAuB;IACnB,OAAO,EAAE,GAAG;EAGhB,6BAAQ;IACJ,MAAM,EAAE,OAAO;EAGnB,wCAAmB;IACf,aAAa,EAAE,IAAI;EAGvB,8BAAS;IACL,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,UAAU;IACvB,eAAe,EAAE,MAAM;IAEvB,sCAAQ;MACJ,SAAS,EAAE,IAAI;MACf,OAAO,EAAE,CAAC;MAEV,+CAAS;QACL,MAAM,EAAE,OAAO;EAK3B,8BAAS;IACL,OAAO,EAAE,gBAAgB;IACzB,aAAa,EAAE,CAAC;IAChB,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,oCAAoC;IAEtD,oCAAM;MACF,WAAW,EAAE,IAAI;MACjB,SAAS,EAAE,QAAQ;IAEvB,wDAA4B;MACxB,MAAM,EAAE,iCAAiC;MACzC,UAAU,EAAE,IAAI;IAGpB,0CAAY;MACR,OAAO,EAAE,IAAI;MACb,WAAW,EAAE,QAAQ;MACrB,eAAe,EAAE,aAAa;MAC9B,SAAS,EAAE,IAAI;MAEf,4DAAkB;QACd,aAAa,EAAE,IAAI;EAI/B,wCAAmB;IACf,OAAO,EAAE,YAAY;IACrB,+CAAO;MACH,MAAM,EAAE,eAAe;MACvB,UAAU,EAAE,eAAe;MAC3B,UAAU,EAAE,eAAe;MAC3B,OAAO,EAAE,CAAC;MACV,MAAM,EAAE,OAAO;MAEf,uDAAU;QACN,KAAK,EAAE,oCAAoC", +"mappings": "AAAA,qBAAsB;EAClB,OAAO,EAAE,iBAAiB;EAC1B,MAAM,EAAE,CAAC;EAGT,4CAAuB;IACnB,OAAO,EAAE,GAAG;EAGhB,6BAAQ;IACJ,MAAM,EAAE,OAAO;EAGnB,wCAAmB;IACf,aAAa,EAAE,IAAI;EAGvB,8BAAS;IACL,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,UAAU;IACvB,eAAe,EAAE,MAAM;IAEvB,sCAAQ;MACJ,SAAS,EAAE,IAAI;MACf,OAAO,EAAE,CAAC;MAEV,+CAAS;QACL,MAAM,EAAE,OAAO;EAK3B,8BAAS;IACL,OAAO,EAAE,gBAAgB;IACzB,aAAa,EAAE,CAAC;IAChB,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,oCAAoC;IAEtD,oCAAM;MACF,WAAW,EAAE,IAAI;MACjB,SAAS,EAAE,QAAQ;IAEvB,wDAA4B;MACxB,MAAM,EAAE,iCAAiC;MACzC,UAAU,EAAE,IAAI;IAGpB,0CAAY;MACR,OAAO,EAAE,IAAI;MACb,WAAW,EAAE,QAAQ;MACrB,eAAe,EAAE,aAAa;MAC9B,SAAS,EAAE,IAAI;MAEf,4DAAkB;QACd,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,IAAI;EAI7B,wCAAmB;IACf,OAAO,EAAE,YAAY;IACrB,+CAAO;MACH,MAAM,EAAE,eAAe;MACvB,UAAU,EAAE,eAAe;MAC3B,UAAU,EAAE,eAAe;MAC3B,OAAO,EAAE,CAAC;MACV,MAAM,EAAE,OAAO;MAEf,uDAAU;QACN,KAAK,EAAE,oCAAoC", "sources": ["../../views/reports/tainacan-reports.scss"], "names": [], "file": "tainacan-reports.css" diff --git a/src/views/admin/js/store/modules/report/actions.js b/src/views/admin/js/store/modules/report/actions.js index 10c2555c2..0872e91f8 100644 --- a/src/views/admin/js/store/modules/report/actions.js +++ b/src/views/admin/js/store/modules/report/actions.js @@ -111,14 +111,20 @@ export const fetchTaxonomyTerms = ({ commit }, taxonomyId) => { }); }; -export const fetchActivities = ({ commit }, { collectionId } ) => { +export const fetchActivities = ({ commit }, { collectionId, startDate, force } ) => { let endpoint = '/reports'; if (collectionId && collectionId != 'default') - endpoint += '/collection/' + collectionId + '/activities'; + endpoint += '/collection/' + collectionId + '/activities?'; else - endpoint += '/activities'; + endpoint += '/activities?'; + + if (startDate) + endpoint += '&start=' + startDate; + + if (startDate || force) + endpoint += '&force=yes'; return new Promise((resolve, reject) => { axios.tainacan.get(endpoint) diff --git a/src/views/reports/components/activities-block.vue b/src/views/reports/components/activities-block.vue index d3743dd09..e3bdade64 100644 --- a/src/views/reports/components/activities-block.vue +++ b/src/views/reports/components/activities-block.vue @@ -1,48 +1,87 @@ @@ -57,7 +96,11 @@ export default { isFetchingUsers: false, users: {}, chartSeriesByUser: [], - chartOptionsByUser: [] + chartOptionsByUser: [], + maxYear: new Date().getFullYear() + 1, + minYear: 2018, + currentStart: '', + currentEnd: '' } }, computed: { @@ -72,7 +115,7 @@ export default { this.buildActivitiesChart(); }, immediate: true - } + }, }, created() { this.isFetchingUsers = true; @@ -91,16 +134,33 @@ export default { ...mapActions('activity', { fetchUsers: 'fetchUsers', }), + increaseYear() { + this.setStartYear(this.currentEnd.getFullYear()); + }, + decreaseYear() { + let currentStartDate = new Date(this.currentStart.getTime()); + this.setStartYear(new Date(currentStartDate.setFullYear(currentStartDate.getFullYear() - 1)).getFullYear()); + }, + setStartYear(newStartYear) { + let currentStartDate = new Date(this.currentStart.getTime()); + const newStart = new Date(currentStartDate.setFullYear(newStartYear)); + + this.$emit('time-range-update', newStart.toISOString()); + }, buildActivitiesChart() { this.isBuildingChart = true; const daysWithActivities = (this.chartData.totals.by_interval && this.chartData.totals.by_interval.general) ? this.chartData.totals.by_interval.general : []; - const startDate = new Date(this.chartData.totals.by_interval.start).getTime(); - const endDate = new Date(this.chartData.totals.by_interval.end).getTime(); + this.currentStart = new Date(this.chartData.totals.by_interval.start); + this.currentEnd = new Date(this.chartData.totals.by_interval.end); - this.chartSeries = [{ - data: [] - }]; + if (daysWithActivities.length) + this.chartSeries = [{ + name: this.$i18n.get('activities'), + data: [] + }]; + else + this.chartSeries = []; let maximumOfActivitiesInADay = 0; daysWithActivities.forEach((activity) => { @@ -115,7 +175,10 @@ export default { this.chartOptions = { ...this.areaChartOptions, title: { - text: this.$i18n.get('label_activities_last_year') + text: '' + }, + noData: { + text: daysWithActivities.length ? this.$i18n.get('label_loading_report') : this.$i18n.get('info_no_activities') }, chart: { id: 'generalchart', @@ -136,10 +199,11 @@ export default { }, xaxis: { type: 'datetime', - min: startDate, - max: endDate + min: this.currentStart.getTime(), + max: this.currentEnd.getTime() }, yaxis: { + show: daysWithActivities.length, max: maximumOfActivitiesInADay, tickAmount: 4, labels: { @@ -148,9 +212,11 @@ export default { }, colors: ['#01295c'], }; - + console.log(this.chartSeries, this.chartOptions, this.currentStart, this.currentEnd); const daysWithActivitiesByUser = JSON.parse(JSON.stringify(this.chartData.totals.by_interval.by_user)).sort((a, b) => parseInt(b.total) - parseInt(a.total)); - + + this.chartSeriesByUser = []; + this.chartOptionsByUser = [] daysWithActivitiesByUser.forEach((daysWithActivityByUser) => { this.chartSeriesByUser.push([{ total: daysWithActivityByUser.total, @@ -186,8 +252,8 @@ export default { }, xaxis: { type: 'datetime', - min: startDate, - max: endDate + min: this.currentStart.getTime(), + max: this.currentEnd.getTime() }, yaxis: { max: maximumOfActivitiesInADay, @@ -208,9 +274,16 @@ export default { \ No newline at end of file diff --git a/src/views/reports/components/metadata-distribution-block.vue b/src/views/reports/components/metadata-distribution-block.vue index 1e4ddec14..da5ffe173 100644 --- a/src/views/reports/components/metadata-distribution-block.vue +++ b/src/views/reports/components/metadata-distribution-block.vue @@ -24,11 +24,6 @@ import { reportsChartMixin } from '../js/reports-mixin'; export default { mixins: [ reportsChartMixin ], - data() { - return { - metadataDistributionChartHeight: 730 - } - }, computed: { ...mapGetters('report', { horizontalBarChartOptions: 'getHorizontalBarChartOptions', @@ -104,4 +99,11 @@ export default { } } } - \ No newline at end of file + + + \ No newline at end of file diff --git a/src/views/reports/js/reports-main.js b/src/views/reports/js/reports-main.js index 51feb2574..3f52508ed 100644 --- a/src/views/reports/js/reports-main.js +++ b/src/views/reports/js/reports-main.js @@ -22,6 +22,7 @@ import MetadataTypesBlock from '../components/metadata-types-block.vue'; import MetadataDistributionBlock from '../components/metadata-distribution-block.vue'; import CollectionsListBlock from '../components/collections-list-block.vue'; import ActivitiesBlock from '../components/activities-block.vue'; +import ActivitiesPerUserBlock from '../components/activities-per-user-block.vue'; Vue.use(VueApexCharts) @@ -49,6 +50,7 @@ Vue.component('metadata-types-block', MetadataTypesBlock); Vue.component('metadata-distribution-block', MetadataDistributionBlock); Vue.component('collections-list-block', CollectionsListBlock); Vue.component('activities-block', ActivitiesBlock); +Vue.component('activities-per-user-block', ActivitiesPerUserBlock); Vue.component('apexchart', VueApexCharts); // Changing title of pages diff --git a/src/views/reports/pages/reports-list.vue b/src/views/reports/pages/reports-list.vue index ab1071d76..c639e98f4 100644 --- a/src/views/reports/pages/reports-list.vue +++ b/src/views/reports/pages/reports-list.vue @@ -88,10 +88,15 @@ v-if="isRepositoryLevel" /> + +
diff --git a/src/views/reports/tainacan-reports.scss b/src/views/reports/tainacan-reports.scss index 07a33f02d..e5c7eb7cd 100644 --- a/src/views/reports/tainacan-reports.scss +++ b/src/views/reports/tainacan-reports.scss @@ -41,10 +41,6 @@ font-weight: bold; font-size: 0.875rem; } - &.metadata-distribution-box { - margin: 0px 0px 0.75rem 1.5rem !important; - overflow-y: auto; - } .box-header { display: flex; diff --git a/src/views/tainacan-admin-i18n.php b/src/views/tainacan-admin-i18n.php index 13da3cc7a..b73f2cf45 100644 --- a/src/views/tainacan-admin-i18n.php +++ b/src/views/tainacan-admin-i18n.php @@ -566,6 +566,7 @@ return apply_filters( 'tainacan-admin-i18n', [ 'label_anonymous_user' => __( 'Anonymous User', 'tainacan'), 'label_select_a_year' => __( 'Select a year', 'tainacan'), 'label_all_users' => __( 'All users', 'tainacan'), + 'label_activitiy_per_user' => __( 'Activities per user', 'tainacan'), // Instructions. More complex sentences to guide user and placeholders 'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ), @@ -846,6 +847,20 @@ return apply_filters( 'tainacan-admin-i18n', [ 'info_form_not_loaded' => __( 'There are probably not enought permissions to display it here.', 'tainacan'), 'info_validating_slug' => __( 'Validating slug...', 'tainacan'), + /* Activity actions */ + 'action_update-metadata-value' => __( 'Item Metadata Value Updates', 'tainacan'), + 'action_update' => __( 'General Updates', 'tainacan'), + 'action_create' => __( 'General Creations', 'tainacan'), + 'action_update-metadata-order' => __( 'Metadata Order Updates', 'tainacan'), + 'action_trash' => __( 'Trashing', 'tainacan'), + 'action_new-attachment' => __( 'Addition of Attachments', 'tainacan'), + 'action_update-filters-order' => __( 'Filter Order Updates', 'tainacan'), + 'action_update-document' => __( 'Document Updates', 'tainacan'), + 'action_delete' => __( 'General Deletions', 'tainacan'), + 'action_delete-attachment' => __( 'Deletion of Attachments', 'tainacan'), + 'action_update-thumbnail' => __( 'Thumbnail Updates', 'tainacan'), + 'action_others' => __( 'Other Actions', 'tainacan'), + // Datepicker months 'datepicker_month_january' => __( 'January', 'tainacan' ), 'datepicker_month_february' => __( 'February', 'tainacan' ), From 05e4983e3491348e0078cf68ef7b304f72574b0d Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Thu, 1 Apr 2021 14:36:34 -0300 Subject: [PATCH 70/94] Readjust width of metadata distribution chart labels. #483 --- src/views/admin/js/store/modules/report/index.js | 6 +----- .../components/activities-per-user-block.vue | 1 + .../components/metadata-distribution-block.vue | 16 +++++++++++++++- src/views/reports/pages/reports-list.vue | 10 ++++++---- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/views/admin/js/store/modules/report/index.js b/src/views/admin/js/store/modules/report/index.js index 9266cf340..036ddbeb4 100644 --- a/src/views/admin/js/store/modules/report/index.js +++ b/src/views/admin/js/store/modules/report/index.js @@ -123,11 +123,7 @@ const state = { tooltip: { enabled: true } }, tooltip: { - y: { - formatter: function (val) { - return val + "%" - } - } + enabled: true }, fill: { opacity: 1 diff --git a/src/views/reports/components/activities-per-user-block.vue b/src/views/reports/components/activities-per-user-block.vue index 16103f41a..184c8b94f 100644 --- a/src/views/reports/components/activities-per-user-block.vue +++ b/src/views/reports/components/activities-per-user-block.vue @@ -85,6 +85,7 @@ export default { }) this.chartSeries = activityPerUserValues; + this.chartOptions = { ...this.horizontalBarChartOptions, ...{ diff --git a/src/views/reports/components/metadata-distribution-block.vue b/src/views/reports/components/metadata-distribution-block.vue index da5ffe173..d981511af 100644 --- a/src/views/reports/components/metadata-distribution-block.vue +++ b/src/views/reports/components/metadata-distribution-block.vue @@ -90,7 +90,21 @@ export default { text: this.$i18n.get('label_metadata_fill_distribution') }, labels: metadataDistributionLabels, - colors: ['#25a189', '#a23939'] + colors: ['#25a189', '#a23939'], + tooltip: { + y: { + formatter: (val) => val + "%" + } + }, + yaxis: { + title: { + text: '' + }, + labels: { + maxWidth: 100 + }, + tooltip: { enabled: true } + }, } } } diff --git a/src/views/reports/pages/reports-list.vue b/src/views/reports/pages/reports-list.vue index c639e98f4..3d5063221 100644 --- a/src/views/reports/pages/reports-list.vue +++ b/src/views/reports/pages/reports-list.vue @@ -19,6 +19,7 @@
+ + -
From 091f42cf8116800369069a9e8936a6ed85232883 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Thu, 1 Apr 2021 15:59:24 -0300 Subject: [PATCH 71/94] Uses new source for usr data. Adds tooltip with user image in the activities per user chart. #483 --- src/assets/css/tainacan-reports.css | 8 +++-- src/assets/css/tainacan-reports.css.map | 2 +- .../reports/components/activities-block.vue | 32 +++++-------------- .../components/activities-per-user-block.vue | 23 +++++++++++-- src/views/reports/tainacan-reports.scss | 7 ++++ 5 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/assets/css/tainacan-reports.css b/src/assets/css/tainacan-reports.css index cc2212c58..a40eb7c2c 100644 --- a/src/assets/css/tainacan-reports.css +++ b/src/assets/css/tainacan-reports.css @@ -25,9 +25,6 @@ #tainacan-reports-app .postbox label { font-weight: bold; font-size: 0.875rem; } - #tainacan-reports-app .postbox.metadata-distribution-box { - margin: 0px 0px 0.75rem 1.5rem !important; - overflow-y: auto; } #tainacan-reports-app .postbox .box-header { display: flex; align-items: baseline; @@ -46,5 +43,10 @@ cursor: pointer; } #tainacan-reports-app .graph-mode-switch button.current { color: var(--wp-admin-theme-color, #007cba); } + #tainacan-reports-app .user-activity-tooltip { + padding: 12px; + display: flex; + justify-content: center; + align-items: center; } /*# sourceMappingURL=tainacan-reports.css.map */ diff --git a/src/assets/css/tainacan-reports.css.map b/src/assets/css/tainacan-reports.css.map index ad404a8ad..8ca981b5a 100644 --- a/src/assets/css/tainacan-reports.css.map +++ b/src/assets/css/tainacan-reports.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "AAAA,qBAAsB;EAClB,OAAO,EAAE,iBAAiB;EAC1B,MAAM,EAAE,CAAC;EAGT,4CAAuB;IACnB,OAAO,EAAE,GAAG;EAGhB,6BAAQ;IACJ,MAAM,EAAE,OAAO;EAGnB,wCAAmB;IACf,aAAa,EAAE,IAAI;EAGvB,8BAAS;IACL,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,UAAU;IACvB,eAAe,EAAE,MAAM;IAEvB,sCAAQ;MACJ,SAAS,EAAE,IAAI;MACf,OAAO,EAAE,CAAC;MAEV,+CAAS;QACL,MAAM,EAAE,OAAO;EAK3B,8BAAS;IACL,OAAO,EAAE,gBAAgB;IACzB,aAAa,EAAE,CAAC;IAChB,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,oCAAoC;IAEtD,oCAAM;MACF,WAAW,EAAE,IAAI;MACjB,SAAS,EAAE,QAAQ;IAEvB,wDAA4B;MACxB,MAAM,EAAE,iCAAiC;MACzC,UAAU,EAAE,IAAI;IAGpB,0CAAY;MACR,OAAO,EAAE,IAAI;MACb,WAAW,EAAE,QAAQ;MACrB,eAAe,EAAE,aAAa;MAC9B,SAAS,EAAE,IAAI;MAEf,4DAAkB;QACd,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,IAAI;EAI7B,wCAAmB;IACf,OAAO,EAAE,YAAY;IACrB,+CAAO;MACH,MAAM,EAAE,eAAe;MACvB,UAAU,EAAE,eAAe;MAC3B,UAAU,EAAE,eAAe;MAC3B,OAAO,EAAE,CAAC;MACV,MAAM,EAAE,OAAO;MAEf,uDAAU;QACN,KAAK,EAAE,oCAAoC", +"mappings": "AAAA,qBAAsB;EAClB,OAAO,EAAE,iBAAiB;EAC1B,MAAM,EAAE,CAAC;EAGT,4CAAuB;IACnB,OAAO,EAAE,GAAG;EAGhB,6BAAQ;IACJ,MAAM,EAAE,OAAO;EAGnB,wCAAmB;IACf,aAAa,EAAE,IAAI;EAGvB,8BAAS;IACL,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,UAAU;IACvB,eAAe,EAAE,MAAM;IAEvB,sCAAQ;MACJ,SAAS,EAAE,IAAI;MACf,OAAO,EAAE,CAAC;MAEV,+CAAS;QACL,MAAM,EAAE,OAAO;EAK3B,8BAAS;IACL,OAAO,EAAE,gBAAgB;IACzB,aAAa,EAAE,CAAC;IAChB,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,oCAAoC;IAEtD,oCAAM;MACF,WAAW,EAAE,IAAI;MACjB,SAAS,EAAE,QAAQ;IAGvB,0CAAY;MACR,OAAO,EAAE,IAAI;MACb,WAAW,EAAE,QAAQ;MACrB,eAAe,EAAE,aAAa;MAC9B,SAAS,EAAE,IAAI;MAEf,4DAAkB;QACd,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,IAAI;EAI7B,wCAAmB;IACf,OAAO,EAAE,YAAY;IACrB,+CAAO;MACH,MAAM,EAAE,eAAe;MACvB,UAAU,EAAE,eAAe;MAC3B,UAAU,EAAE,eAAe;MAC3B,OAAO,EAAE,CAAC;MACV,MAAM,EAAE,OAAO;MAEf,uDAAU;QACN,KAAK,EAAE,oCAAoC;EAKvD,4CAAuB;IACnB,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,MAAM;IACvB,WAAW,EAAE,MAAM", "sources": ["../../views/reports/tainacan-reports.scss"], "names": [], "file": "tainacan-reports.css" diff --git a/src/views/reports/components/activities-block.vue b/src/views/reports/components/activities-block.vue index 14852d110..2e051b46b 100644 --- a/src/views/reports/components/activities-block.vue +++ b/src/views/reports/components/activities-block.vue @@ -1,7 +1,7 @@