PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.5.0
Independent Analytics – WordPress Analytics Plugin v2.5.0
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / javascript-source / controllers / report_controller.js
independent-analytics / javascript-source / controllers Last commit date
campaign_builder_controller.js 2 years ago chart_controller.js 2 years ago chart_geo_controller.js 2 years ago chart_interval_controller.js 2 years ago clipboard_controller.js 2 years ago copy_report_controller.js 2 years ago create_report_controller.js 2 years ago dates_controller.js 2 years ago delete_data_controller.js 2 years ago delete_report_controller.js 2 years ago easepick_controller.js 2 years ago export_reports_controller.js 2 years ago filters_controller.js 2 years ago group_controller.js 2 years ago import_reports_controller.js 2 years ago migration_redirect_controller.js 2 years ago modal_controller.js 2 years ago plugin_group_options_controller.js 2 years ago quick_stats_controller.js 2 years ago real_time_controller.js 2 years ago rename_report_controller.js 2 years ago report_controller.js 2 years ago reset_analytics_controller.js 2 years ago save_report_controller.js 2 years ago select_input_controller.js 2 years ago set_favorite_report_controller.js 2 years ago sort_controller.js 2 years ago sortable_reports_controller.js 2 years ago table_columns_controller.js 2 years ago
report_controller.js
377 lines
1 import {Controller} from "@hotwired/stimulus"
2 import {downloadCSV} from '../download'
3 import html2pdf from 'html2pdf.js';
4
5 class Report_Controller extends Controller {
6 /**
7 * Store the jQuery request so that it can be canceled if a new report is requested before the
8 * current one is fetched.
9 */
10 static request;
11 static targets = ['loadMore', 'exportCSV', 'exportPDF']
12 static values = {
13 name: String,
14 relativeRangeId: String,
15 exactStart: String,
16 exactEnd: String,
17 group: String,
18 chartInterval: String,
19 sortColumn: String,
20 sortDirection: String,
21 columns: Array,
22 quickStats: Array,
23 visibleDatasets: Array,
24 filters: Array
25 }
26
27 exactStart = undefined
28 exactEnd = undefined
29 relativeRangeId = undefined
30 columns = undefined
31 quickStats = undefined
32 filters = []
33 sortColumn = undefined
34 sortDirection = undefined
35 group = undefined
36 chartInterval = undefined
37 visibleDatasets = undefined
38 page = 1
39
40 connect() {
41 // If any values are empty strings, set them equal to undefined instead
42 this.exactStart = this.exactStartValue === "" ? undefined : this.exactStartValue;
43 this.exactEnd = this.exactEndValue === "" ? undefined : this.exactEndValue;
44 this.relativeRangeId = this.relativeRangeIdValue === "" ? undefined : this.relativeRangeIdValue
45 this.columns = this.columnsValue
46 this.quickStats = this.quickStatsValue
47 this.group = this.groupValue
48 this.chartInterval = this.chartIntervalValue
49 this.sortColumn = this.sortColumnValue
50 this.sortDirection = this.sortDirectionValue
51 this.visibleDatasets = this.visibleDatasetsValue
52 this.filters = this.filtersValue
53 document.addEventListener('iawp:changeDates', this.datesChanged)
54 document.addEventListener('iawp:changeColumns', this.columnsChanged)
55 document.addEventListener('iawp:changeQuickStats', this.quickStatsChanged)
56 document.addEventListener('iawp:changeFilters', this.filtersChanged)
57 document.addEventListener('iawp:changeSort', this.sortChanged)
58 document.addEventListener('iawp:changeGroup', this.changeGroup)
59 document.addEventListener('iawp:changeChartInterval', this.changeChartInterval)
60 document.addEventListener('iawp:changeVisibleDatasets', this.changeVisibleDatasets)
61 this.fetch({
62 tableOnly: this.filters.length === 0,
63 showLoadingOverlay: false
64 })
65 }
66
67 disconnect() {
68 document.removeEventListener('iawp:changeDates', this.datesChanged)
69 document.removeEventListener('iawp:changeColumns', this.columnsChanged)
70 document.removeEventListener('iawp:changeQuickStats', this.quickStatsChanged)
71 document.removeEventListener('iawp:changeFilters', this.filtersChanged)
72 document.removeEventListener('iawp:changeSort', this.sortChanged)
73 document.removeEventListener('iawp:changeGroup', this.changeGroup)
74 document.removeEventListener('iawp:changeChartInterval', this.changeChartInterval)
75 document.removeEventListener('iawp:changeVisibleDatasets', this.changeVisibleDatasets)
76 }
77
78 emitChangedOption(detail) {
79 document.dispatchEvent(
80 new CustomEvent('iawp:changedOption', {
81 detail
82 })
83 )
84 }
85
86 changeVisibleDatasets = (e) => {
87 this.visibleDatasets = e.detail.visibleDatasets
88 this.emitChangedOption({
89 'visible_datasets': this.visibleDatasets
90 })
91 }
92
93 datesChanged = (e) => {
94 this.exactStart = e.detail.exactStart
95 this.exactEnd = e.detail.exactEnd
96 this.relativeRangeId = e.detail.relativeRangeId
97 this.page = 1;
98
99 this.emitChangedOption({
100 'exact_start': this.exactStart || null,
101 'exact_end': this.exactEnd || null,
102 'relative_range_id': this.relativeRangeId || null
103 })
104 this.fetch({newDateRange: true})
105 }
106
107 columnsChanged = (e) => {
108 this.columns = e.detail.optionIds
109 this.emitChangedOption({
110 'columns': this.columns
111 })
112 }
113
114 quickStatsChanged = (e) => {
115 this.quickStats = e.detail.optionIds
116 this.emitChangedOption({
117 'quick_stats': this.quickStats
118 })
119 }
120
121 filtersChanged = (e) => {
122 this.filters = e.detail.filters
123 this.page = 1;
124
125 this.emitChangedOption({
126 'filters': this.filters
127 })
128 this.fetch({showLoadingOverlay: e.detail.showLoadingOverlay})
129 }
130
131 sortChanged = (e) => {
132 this.sortColumn = e.detail.sortColumn
133 this.sortDirection = e.detail.sortDirection
134 this.page = 1;
135
136 this.emitChangedOption({
137 'sort_column': this.sortColumn,
138 'sort_direction': this.sortDirection
139 })
140 this.fetch({tableOnly: true})
141 }
142
143 changeGroup = (e) => {
144 if (this.group === e.detail.group) {
145 return;
146 }
147
148 this.group = e.detail.group
149 this.page = 1
150 this.emitChangedOption({
151 'group_name': this.group
152 })
153 this.fetch({newGroup: true});
154 }
155
156 changeChartInterval = (e) => {
157 const chartInterval = e.detail.chartInterval
158
159 if (this.chartInterval === chartInterval) {
160 return;
161 }
162
163 this.chartInterval = chartInterval
164 this.emitChangedOption({
165 'chart_interval': this.chartInterval
166 })
167 this.fetch();
168 }
169
170 loadMore = () => {
171 this.page = this.page + 1
172
173 this.fetch({tableOnly: true})
174 }
175
176 fetch({
177 tableOnly = false,
178 showLoadingOverlay = true,
179 newGroup = false,
180 newDateRange = false
181 } = {}) {
182
183 if (showLoadingOverlay) {
184 jQuery('#iawp-parent').addClass('loading');
185 }
186
187 const data = {
188 ...iawpActions.filter,
189 'filters': this.filters,
190 'exact_start': this.exactStart,
191 'exact_end': this.exactEnd,
192 'is_new_date_range': newDateRange,
193 'relative_range_id': this.relativeRangeId,
194 'table_type': jQuery('#data-table').data('table-name'),
195 'columns': this.columns,
196 'report_quick_stats': ['visitors'], // TODO
197 'visible_datasets': this.visibleDatasets,
198 'sort_column': this.sortColumn,
199 'quick_stats': this.quickStats,
200 'sort_direction': this.sortDirection,
201 'group': this.group,
202 'is_new_group': newGroup,
203 'chart_interval': this.chartInterval,
204 'page': this.page,
205 };
206
207 if (Report_Controller.request) {
208 Report_Controller.request.abort();
209 }
210
211 Report_Controller.request = jQuery.post(ajaxurl, data, (response) => {
212 response = response.data
213
214 this.columns = response.columns
215 this.filters = response.filters
216 this.chartInterval = response.chartInterval
217
218 jQuery('#iawp-columns .row-number').text(response.totalNumberOfRows.toLocaleString());
219 document.getElementById('data-table').setAttribute('data-total-number-of-rows', response.totalNumberOfRows)
220
221 if (newGroup) {
222 jQuery('#iawp-table-wrapper').replaceWith(response.table)
223 jQuery('[data-plugin-group-options-option-type-value=columns]').replaceWith(response.columnsHTML)
224
225 document.dispatchEvent(
226 new CustomEvent('iawp:changeColumns', {
227 detail: {
228 optionIds: this.columns
229 }
230 })
231 )
232 } else {
233 jQuery('#iawp-rows').replaceWith(response.rows);
234 }
235
236 if (!tableOnly) {
237 jQuery('#dates-button span:last-child').text(response.label)
238 jQuery('#myChart').closest('.chart-container').replaceWith(response.chart);
239 jQuery('#quick-stats').replaceWith(response.stats);
240 }
241
242 document.dispatchEvent(
243 new CustomEvent('iawp:updateColumnsUserInterface')
244 )
245
246 document.dispatchEvent(
247 new CustomEvent('iawp:groupChanged', {
248 detail: {
249 groupId: response.groupId
250 }
251 })
252 )
253
254 document.dispatchEvent(
255 new CustomEvent('iawp:filtersChanged', {
256 detail: {
257 filtersTemplateHTML: response.filtersTemplateHTML,
258 filtersButtonsHTML: response.filtersButtonsHTML,
259 filters: response.filters
260 }
261 })
262 )
263
264 this.exportPDFTarget.removeAttribute('disabled')
265
266 if (response.isLastPage) {
267 this.loadMoreTarget.setAttribute('disabled', 'disabled')
268 } else {
269 this.loadMoreTarget.removeAttribute('disabled')
270 }
271
272 jQuery('#iawp-parent').removeClass('loading');
273 });
274 }
275
276 exportCSV() {
277 const data = {
278 ...iawpActions.filter,
279 'filters': this.filters,
280 'exact_start': this.exactStart,
281 'exact_end': this.exactEnd,
282 'is_new_date_range': false,
283 'relative_range_id': this.relativeRangeId,
284 'table_type': jQuery('#data-table').data('table-name'),
285 'columns': this.columns,
286 'visible_datasets': this.visibleDatasets,
287 'sort_column': this.sortColumn,
288 'quick_stats': this.quickStats,
289 'sort_direction': this.sortDirection,
290 'group': this.group,
291 'is_new_group': false,
292 'chart_interval': this.chartInterval,
293 'page': this.page,
294 'as_csv': true
295 };
296
297 this.exportCSVTarget.classList.add('sending')
298 this.exportCSVTarget.setAttribute('disabled', 'disabled')
299
300 if (Report_Controller.csvRequest) {
301 Report_Controller.csvRequest.abort();
302 }
303
304 Report_Controller.csvRequest = jQuery.post(ajaxurl, data, (response) => {
305 downloadCSV(this.getFileName('csv'), response)
306 this.exportCSVTarget.classList.add('sent')
307 this.exportCSVTarget.classList.remove('sending')
308 this.exportCSVTarget.removeAttribute('disabled')
309
310 setTimeout(() => {
311 this.exportCSVTarget.classList.remove('sent')
312 }, 1000)
313 })
314 }
315
316 exportPDF() {
317 this.exportPDFTarget.classList.add('sending')
318 this.exportPDFTarget.setAttribute('disabled', 'disabled')
319
320 setTimeout(() => {
321 const element = document.getElementById('wpwrap').cloneNode(true)
322 const options = {
323 filename: this.getFileName('pdf'),
324 jsPDF: {
325 unit: 'in',
326 format: 'letter',
327 orientation: 'landscape'
328 },
329 html2canvas: {
330 windowWidth: 1280
331 }
332 }
333 let base64Image = null
334
335 if (window.iawp_chart) {
336 const chartImageWidth = 1080
337 const chartImageHeight = chartImageWidth * .25
338 window.iawp_chart.resize(chartImageWidth, chartImageHeight)
339 base64Image = window.iawp_chart.toBase64Image('image/png', 1);
340 window.iawp_chart.resize()
341 }
342
343 if(window.iawp_geo_chart) {
344 base64Image = window.iawp_geo_chart.getImageURI()
345 }
346
347 if(base64Image) {
348 const imageElement = document.createElement('img')
349 imageElement.src = base64Image
350
351 element.querySelector('#myChart').replaceWith(imageElement)
352 }
353
354 html2pdf().set(options).from(element).toContainer().save().then(() => {
355 this.exportPDFTarget.classList.add('sent')
356 this.exportPDFTarget.classList.remove('sending')
357 this.exportPDFTarget.removeAttribute('disabled')
358
359 setTimeout(() => {
360 this.exportPDFTarget.classList.remove('sent')
361 }, 1000)
362 })
363 }, 250) // Allow animations to finish before exporting blocks things up
364 }
365
366 getFileName(fileExtension) {
367 const reportTitleElement = document.querySelector('#report-title-bar .report-title')
368
369 if (!reportTitleElement) {
370 return 'report.' + fileExtension
371 }
372
373 return reportTitleElement.innerText.replace(/[^a-zA-Z0-9]+/g, '-').toLowerCase() + '.' + fileExtension
374 }
375 }
376
377 export default Report_Controller;