PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.6.0
Independent Analytics – WordPress Analytics Plugin v2.6.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 / filters_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
filters_controller.js
295 lines
1 import {Controller} from "@hotwired/stimulus"
2 import * as easepick from "@easepick/bundle";
3
4 export default class extends Controller {
5 static values = {
6 filters: Array
7 }
8 static targets = [
9 'modal',
10 'modalButton',
11 'blueprint',
12 'filters',
13 'condition',
14 'reset',
15 'inclusion',
16 'column',
17 'operator',
18 'operand',
19 'conditionButtons'
20 ]
21
22 appliedConditions = 0
23
24 connect() {
25 document.addEventListener('click', this.maybeClose)
26 document.addEventListener('iawp:filtersChanged', this.updateFilters)
27
28 if (this.filtersValue.length > 0) {
29 this.createInitialFilters()
30 this.setResetEnabled(true)
31 } else {
32 this.addCondition()
33 }
34 }
35
36 disconnect() {
37 document.removeEventListener('click', this.maybeClose)
38 document.removeEventListener('iawp:filtersChanged', this.updateFilters)
39 }
40
41 updateFilters = (event) => {
42 this.filtersTarget.innerHTML = ''
43 this.blueprintTarget.innerHTML = event.detail.filtersTemplateHTML
44 this.conditionButtonsTarget.innerHTML = event.detail.filtersButtonsHTML
45 this.filtersValue = event.detail.filters
46 this.setCount(event.detail.filters.length)
47
48 if (this.filtersValue.length > 0) {
49 this.createInitialFilters()
50 } else {
51 this.addCondition()
52 }
53 }
54
55 createInitialFilters() {
56 this.filtersValue.forEach((filter) => {
57 const element = this.blueprintTarget.content.cloneNode(true)
58 this.filtersTarget.appendChild(element)
59 const condition = this.filtersTarget.lastElementChild
60
61 const inclusionTarget = this.inclusionTargets.find((inclusion) => condition.contains(inclusion))
62 const columnTarget = this.columnTargets.find((column) => condition.contains(column))
63
64 inclusionTarget.value = filter.inclusion
65 columnTarget.value = filter.column
66
67 const type = columnTarget.options[columnTarget.selectedIndex].dataset.type
68
69 // Show the correct operator
70 this.operatorTargets.filter((operator) => {
71 return condition.contains(operator)
72 }).forEach((operator) => {
73 const isMatch = operator.dataset.type === type
74
75 operator.classList.toggle('show', isMatch)
76
77 if(isMatch) {
78 operator.value = filter.operator
79 }
80 })
81
82 // Show the correct operand field
83 this.operandTargets.filter((operand) => {
84 return condition.contains(operand)
85 }).forEach((operand) => {
86 const isMatch = operand.dataset.column === columnTarget.value
87
88 operand.classList.toggle('show', isMatch)
89
90 if(isMatch) {
91 operand.value = filter.operand
92
93 setTimeout(() => {
94 const easepickController = this.application.getControllerForElementAndIdentifier(operand, "easepick")
95
96 if(easepickController) {
97 const start = new easepick.DateTime(filter.operand * 1000);
98 operand.easepick.setDate(start)
99 operand.easepick.gotoDate(start)
100 easepickController.unixTimestampValue = filter.operand
101 }
102 }, 0)
103 }
104 })
105 })
106 }
107
108 maybeClose = (event) => {
109 const isOpen = this.modalTarget.classList.contains('show')
110 const isInComponent = this.element.contains(event.target)
111
112 if (isOpen && !isInComponent) {
113 this.closeModal()
114 }
115 }
116
117 toggleModal(e) {
118 e.preventDefault();
119 const isOpen = this.modalTarget.classList.contains('show')
120 isOpen ? this.closeModal() : this.openModal()
121 }
122
123 openModal() {
124 this.modalTarget.classList.add('show')
125 this.modalButtonTarget.classList.add('open')
126 document.getElementById('iawp-layout').classList.add('modal-open');
127 }
128
129 closeModal() {
130 this.modalTarget.classList.remove('show')
131 this.modalButtonTarget.classList.remove('open')
132 document.getElementById('iawp-layout').classList.remove('modal-open');
133 }
134
135 addCondition() {
136 this.filtersTarget.append(this.blueprintTarget.content.cloneNode(true))
137 this.setResetEnabled(true)
138 }
139
140 removeCondition(e) {
141 e.stopPropagation();
142
143 this.conditionTargets.forEach((condition) => {
144 if (condition.contains(e.target)) {
145 condition.remove()
146 }
147 })
148
149 if (this.conditionTargets.length === 0) {
150 this.addCondition()
151 document.dispatchEvent(
152 new CustomEvent('iawp:changeFilters', {
153 detail: {filters: []}
154 })
155 )
156 this.setResetEnabled(false)
157 }
158
159 if (this.conditionTargets.length === 1) {
160 this.setResetEnabled(false)
161 this.setCount(0)
162 }
163
164 if (this.conditionTargets.length === 0) {
165 this.addCondition()
166 }
167
168 if (this.appliedConditions > 1) {
169 this.apply()
170 }
171 }
172
173 apply({showLoadingOverlay = true} = {}) {
174 let errors = false
175
176 this.conditionTargets.forEach((condition) => {
177 const columnTarget = this.columnTargets.find((column) => condition.contains(column))
178 const operandTarget = this.operandTargets.find((operand) => condition.contains(operand) && operand.classList.contains('show'))
179
180 if (columnTarget.value === '') {
181 columnTarget.classList.add('error')
182 errors = true
183 }
184
185 if (operandTarget && operandTarget.value === '') {
186 operandTarget.classList.add('error')
187 errors = true
188 }
189 })
190
191 if (errors) {
192 return
193 }
194
195 const filters = this.conditionTargets.map((condition) => {
196 const inclusionTarget = this.inclusionTargets.find((inclusion) => condition.contains(inclusion))
197 const columnTarget = this.columnTargets.find((column) => condition.contains(column))
198 const operatorTarget = this.operatorTargets.find((operator) => condition.contains(operator) && operator.classList.contains('show'))
199 const operandTarget = this.operandTargets.find((operand) => condition.contains(operand) && operand.classList.contains('show'))
200 const filter = {
201 inclusion: inclusionTarget.value,
202 column: columnTarget.value,
203 operator: operatorTarget.value,
204 operand: operandTarget.value
205 }
206
207 const easepickController = this.application.getControllerForElementAndIdentifier(operandTarget, "easepick")
208 if (easepickController) {
209 filter.operand = easepickController.unixTimestampValue.toString()
210 }
211
212 return filter
213 })
214
215 this.appliedConditions = filters.length
216 this.setResetEnabled(true)
217 this.setCount(filters.length)
218 this.closeModal()
219
220 document.dispatchEvent(
221 new CustomEvent('iawp:changeFilters', {
222 detail: {
223 filters,
224 showLoadingOverlay
225 }
226 })
227 )
228 }
229
230 reset() {
231 this.conditionTargets.forEach((condition) => {
232 condition.remove()
233 })
234 this.addCondition()
235 this.setResetEnabled(false)
236 this.appliedConditions = 0
237 this.setCount(0)
238 this.closeModal()
239 document.dispatchEvent(
240 new CustomEvent('iawp:changeFilters', {
241 detail: {filters: []}
242 })
243 )
244 }
245
246 setCount(count = 0) {
247 document.getElementById('toolbar').setAttribute('data-filter-count', count);
248 }
249
250 setResetEnabled(enable = true) {
251 if (enable) {
252 this.resetTarget.removeAttribute('disabled')
253 } else {
254 this.resetTarget.setAttribute('disabled', 'disabled')
255 }
256 }
257
258 // Todo - Need to clear anything that's been hidden
259 columnSelect(e) {
260 const condition = this.conditionTargets.find((condition) => condition.contains(e.target))
261 const column = e.target.value
262 const type = e.target.options[e.target.selectedIndex].dataset.type
263
264 // Remove error class
265 e.target.classList.remove('error')
266
267 // Show the correct operator
268 this.operatorTargets.filter((operator) => {
269 return condition.contains(operator)
270 }).forEach((operator) => {
271 const matchingType = operator.dataset.type === type
272 operator.classList.toggle('show', matchingType)
273 })
274
275 // Show the correct operand field
276 this.operandTargets.filter((operand) => {
277 return condition.contains(operand)
278 }).forEach((operand) => {
279 const matchingColumn = operand.dataset.column === column
280 operand.classList.toggle('show', matchingColumn)
281 })
282 }
283
284 operandChange(e) {
285 e.target.classList.remove('error')
286 }
287
288 operandKeyDown(e) {
289 if (e.keyCode === 13) {
290 // Enter key pressed
291 this.apply()
292 }
293 }
294 }
295