@necrolab/dashboard 0.4.61 → 0.4.209
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierrc +1 -27
- package/.vscode/extensions.json +1 -1
- package/README.md +2 -64
- package/backend/api.js +48 -40
- package/backend/auth.js +3 -3
- package/backend/batching.js +1 -1
- package/backend/endpoints.js +76 -12
- package/backend/index.js +2 -2
- package/backend/mock-data.js +36 -27
- package/backend/mock-src/classes/logger.js +8 -8
- package/backend/mock-src/classes/utils.js +3 -7
- package/backend/mock-src/database.js +0 -0
- package/backend/mock-src/ticketmaster.js +79 -79
- package/backend/validator.js +2 -2
- package/config/configs.json +3 -2
- package/config/filter.json +3 -2
- package/index.html +8 -79
- package/index.js +1 -1
- package/package.json +25 -40
- package/postcss.config.js +1 -1
- package/postinstall.js +17 -98
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/manifest.json +7 -12
- package/public/sw.js +2 -0
- package/public/workbox-49fdaf31.js +2 -0
- package/public/workbox-49fdaf31.js.map +1 -0
- package/public/workbox-88575b92.js +2 -0
- package/public/workbox-88575b92.js.map +1 -0
- package/public/workbox-a67a7b11.js +2 -0
- package/public/workbox-a67a7b11.js.map +1 -0
- package/public/workbox-d4314735.js +2 -0
- package/public/workbox-d4314735.js.map +1 -0
- package/public/workbox-e0f89ef3.js +2 -0
- package/public/workbox-e0f89ef3.js.map +1 -0
- package/run +9 -176
- package/src/App.vue +85 -498
- package/src/assets/css/_input.scss +99 -144
- package/src/assets/css/main.scss +99 -450
- package/src/assets/img/background.svg +2 -2
- package/src/assets/img/logo_icon.png +0 -0
- package/src/components/Auth/LoginForm.vue +11 -62
- package/src/components/Editors/Account/Account.vue +40 -116
- package/src/components/Editors/Account/AccountCreator.vue +39 -88
- package/src/components/Editors/Account/AccountView.vue +34 -102
- package/src/components/Editors/Account/CreateAccount.vue +32 -80
- package/src/components/Editors/Profile/CreateProfile.vue +83 -269
- package/src/components/Editors/Profile/Profile.vue +47 -132
- package/src/components/Editors/Profile/ProfileCountryChooser.vue +20 -82
- package/src/components/Editors/Profile/ProfileView.vue +34 -91
- package/src/components/Editors/TagLabel.vue +6 -67
- package/src/components/Filter/Filter.vue +72 -289
- package/src/components/Filter/FilterPreview.vue +30 -171
- package/src/components/Filter/PriceSortToggle.vue +4 -74
- package/src/components/Table/Header.vue +1 -1
- package/src/components/Table/Row.vue +1 -1
- package/src/components/Table/Table.vue +2 -19
- package/src/components/Tasks/CheckStock.vue +13 -28
- package/src/components/Tasks/Controls/DesktopControls.vue +17 -17
- package/src/components/Tasks/Controls/MobileControls.vue +45 -8
- package/src/components/Tasks/CreateTaskAXS.vue +73 -79
- package/src/components/Tasks/CreateTaskTM.vue +142 -94
- package/src/components/Tasks/MassEdit.vue +7 -9
- package/src/components/Tasks/QuickSettings.vue +55 -169
- package/src/components/Tasks/ScrapeVenue.vue +4 -7
- package/src/components/Tasks/Stats.vue +23 -52
- package/src/components/Tasks/Task.vue +135 -377
- package/src/components/Tasks/TaskView.vue +47 -107
- package/src/components/Tasks/Utilities.vue +6 -5
- package/src/components/icons/Bag.vue +1 -1
- package/src/components/icons/Loyalty.vue +1 -1
- package/src/components/icons/Mail.vue +2 -2
- package/src/components/icons/Play.vue +2 -2
- package/src/components/icons/Reload.vue +5 -4
- package/src/components/icons/Sandclock.vue +2 -2
- package/src/components/icons/Stadium.vue +1 -1
- package/src/components/icons/index.js +1 -24
- package/src/components/ui/Modal.vue +13 -105
- package/src/components/ui/Navbar.vue +37 -170
- package/src/components/ui/ReconnectIndicator.vue +55 -351
- package/src/components/ui/Splash.vue +35 -5
- package/src/components/ui/controls/CountryChooser.vue +62 -200
- package/src/components/ui/controls/atomic/Checkbox.vue +10 -119
- package/src/components/ui/controls/atomic/Dropdown.vue +39 -208
- package/src/components/ui/controls/atomic/MultiDropdown.vue +37 -300
- package/src/libs/Filter.js +170 -200
- package/src/registerServiceWorker.js +1 -1
- package/src/stores/connection.js +53 -51
- package/src/stores/logger.js +3 -11
- package/src/stores/sampleData.js +201 -173
- package/src/stores/ui.js +44 -112
- package/src/stores/utils.js +6 -90
- package/src/views/Accounts.vue +35 -44
- package/src/views/Console.vue +90 -341
- package/src/views/Editor.vue +123 -1176
- package/src/views/FilterBuilder.vue +251 -607
- package/src/views/Login.vue +14 -76
- package/src/views/Profiles.vue +25 -44
- package/src/views/Tasks.vue +100 -187
- package/static/offline.html +50 -192
- package/tailwind.config.js +26 -104
- package/vite.config.js +16 -73
- package/vue.config.js +32 -0
- package/workbox-config.js +11 -0
- package/artwork/image.png +0 -0
- package/dev-server.js +0 -136
- package/exit +0 -209
- package/jsconfig.json +0 -16
- package/src/assets/css/_utilities.scss +0 -388
- package/src/assets/img/background.svg.backup +0 -11
- package/src/components/icons/Check.vue +0 -5
- package/src/components/icons/Close.vue +0 -21
- package/src/components/icons/CloseX.vue +0 -5
- package/src/components/icons/Key.vue +0 -21
- package/src/components/icons/Pencil.vue +0 -21
- package/src/components/icons/Profile.vue +0 -18
- package/src/components/icons/Sell.vue +0 -21
- package/src/components/icons/Spinner.vue +0 -42
- package/src/components/icons/SquareCheck.vue +0 -18
- package/src/components/icons/SquareUncheck.vue +0 -18
- package/src/components/icons/Wildcard.vue +0 -18
- package/src/components/ui/controls/atomic/LoadingButton.vue +0 -45
- package/src/composables/useClickOutside.js +0 -21
- package/src/composables/useDropdownPosition.js +0 -174
- package/src/types/index.js +0 -41
- package/src/utils/debug.js +0 -1
- package/switch-branch.sh +0 -41
- package/workbox-config.cjs +0 -63
- /package/src/assets/img/{logo_icon-old.png → logo_icon_2.png} +0 -0
package/src/libs/Filter.js
CHANGED
|
@@ -4,31 +4,27 @@ const log = (...args) => debug && console.log("[filter]", ...args);
|
|
|
4
4
|
const colors = {
|
|
5
5
|
HIGHLIGHT: "#d3f8e2",
|
|
6
6
|
SELECTED: "#a9def9",
|
|
7
|
-
SELECTED_EXPANDED: "#6bb6ff",
|
|
8
7
|
EXCLUDED: "#f694c1",
|
|
9
|
-
EXCLUDED_EXPANDED: "#f472b6",
|
|
10
8
|
UNSELECTABLE: "#311432"
|
|
11
9
|
};
|
|
12
10
|
|
|
13
|
-
const BASE_CSS =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
return element.attributes[attributeName]?.nodeValue?.trim() || "";
|
|
18
|
-
} catch {
|
|
19
|
-
return "";
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const getTextContent = (element) => {
|
|
24
|
-
return element.innerHTML?.trim() || "";
|
|
25
|
-
};
|
|
11
|
+
const BASE_CSS =
|
|
12
|
+
`path[row]:hover {stroke: ${colors.HIGHLIGHT};pointer-events:all;cursor:pointer;}` +
|
|
13
|
+
`path[generaladmission]:hover {fill: ${colors.HIGHLIGHT};pointer-events:all;cursor:pointer;}`;
|
|
26
14
|
|
|
27
15
|
const isWheelchair = (p) => {
|
|
28
16
|
if (p.row === "W" || p.sectionName === "W") return false;
|
|
29
17
|
return [("W", "ADA")].some((part) => p.row !== "W" && (p.row?.includes(part) || p.sectionName?.includes(part)));
|
|
30
18
|
};
|
|
31
19
|
|
|
20
|
+
const getWheelChairRows = () => {
|
|
21
|
+
const rows = [...document.querySelectorAll("path[row]")];
|
|
22
|
+
return rows
|
|
23
|
+
.map((p) => {
|
|
24
|
+
return { row: p.attributes.row.nodeValue, sectionName: p.attributes.sectionname.nodeValue };
|
|
25
|
+
})
|
|
26
|
+
.filter(isWheelchair);
|
|
27
|
+
};
|
|
32
28
|
const sortAlphaNum = (a, b) => {
|
|
33
29
|
var reA = /[^a-zA-Z]/g;
|
|
34
30
|
var reN = /[^0-9]/g;
|
|
@@ -97,60 +93,52 @@ const cleanupFilter = (f) => {
|
|
|
97
93
|
return ret;
|
|
98
94
|
}
|
|
99
95
|
|
|
100
|
-
if (f.rows && document.querySelectorAll(`path[
|
|
96
|
+
if (f.rows && document.querySelectorAll(`path[sectionname="${f.section}"]`)?.length === f.rows?.length)
|
|
97
|
+
delete f.rows;
|
|
101
98
|
if (f.rows) ret.rows = f.rows.sort(sortAlphaNum);
|
|
102
99
|
|
|
103
100
|
return ret;
|
|
104
101
|
};
|
|
105
102
|
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const sec = getAttributeValue(t, "section");
|
|
111
|
-
const secName = getAttributeValue(t, "sectionname");
|
|
112
|
-
if (sec && secName) {
|
|
113
|
-
sectionRealName[sec] = secName;
|
|
114
|
-
}
|
|
103
|
+
const getFirstRows = (rows) => {
|
|
104
|
+
const firstRows = {};
|
|
105
|
+
const parsedRows = rows.map((row) => {
|
|
106
|
+
return { sec: row.attributes.sectionname.nodeValue, row: row.attributes.row.nodeValue };
|
|
115
107
|
});
|
|
108
|
+
// log("getFirstRows: parsedRows=", parsedRows);
|
|
109
|
+
parsedRows.forEach((row) => {
|
|
110
|
+
if (!firstRows[row.sec]) firstRows[row.sec] = [];
|
|
111
|
+
firstRows[row.sec].push(row.row);
|
|
112
|
+
});
|
|
113
|
+
// log("A getFirstRows: firstRows=", firstRows);
|
|
114
|
+
Object.entries(firstRows).forEach(([sec, rows]) => {
|
|
115
|
+
log(`sort:`, sec, rows);
|
|
116
|
+
firstRows[sec] = rows.sort(sortAlphaNum);
|
|
117
|
+
});
|
|
118
|
+
// log("B getFirstRows: firstRows=", firstRows);
|
|
119
|
+
return firstRows;
|
|
120
|
+
};
|
|
116
121
|
|
|
122
|
+
const getSectionNameMapping = () => {
|
|
123
|
+
const sectionRealName = {};
|
|
117
124
|
[...document.querySelectorAll("tspan")].forEach((t) => {
|
|
118
|
-
const sec =
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (sec && content) {
|
|
122
|
-
if (!sectionRealName[sec]) {
|
|
123
|
-
sectionRealName[sec] = content;
|
|
124
|
-
} else if (!sectionRealName[sec].includes(content)) {
|
|
125
|
-
sectionRealName[sec] += " " + content;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
125
|
+
const sec = t.attributes.section.nodeValue.trim();
|
|
126
|
+
if (!sectionRealName[sec]) sectionRealName[sec] = t.innerHTML.trim();
|
|
127
|
+
else if (!sectionRealName[sec]?.includes(t.innerHTML)) sectionRealName[sec] += " " + t.innerHTML.trim();
|
|
128
128
|
});
|
|
129
129
|
|
|
130
130
|
log("getSectionNameMapping:", sectionRealName);
|
|
131
131
|
return sectionRealName;
|
|
132
132
|
};
|
|
133
133
|
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (!reverseSectionName[secName]) {
|
|
143
|
-
reverseSectionName[secName] = [];
|
|
144
|
-
}
|
|
145
|
-
if (!reverseSectionName[secName].includes(sec)) {
|
|
146
|
-
reverseSectionName[secName].push(sec);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
log("getReverseSectionNameMapping", reverseSectionName);
|
|
152
|
-
return reverseSectionName;
|
|
153
|
-
};
|
|
134
|
+
// const getFloorSections = () => {
|
|
135
|
+
// const tspans = [...document.querySelectorAll("tspan")];
|
|
136
|
+
// const blacklist = ["BL", "BARSTOOLS", "BW", "NL"];
|
|
137
|
+
// return tspans
|
|
138
|
+
// .map((t) => t.attributes.section.nodeValue)
|
|
139
|
+
// .filter((t) => t.match(/^[a-zA-Z]+\s?[\w\d]?$/))
|
|
140
|
+
// .filter((name) => !blacklist.some((b) => name.includes(b)));
|
|
141
|
+
// };
|
|
154
142
|
|
|
155
143
|
export default class FilterBuilder {
|
|
156
144
|
constructor() {
|
|
@@ -169,6 +157,7 @@ export default class FilterBuilder {
|
|
|
169
157
|
CATCH_ALL_GA: 1,
|
|
170
158
|
NORMAL: 2,
|
|
171
159
|
NORMAL_FIRSTROW: 3,
|
|
160
|
+
GLOBAL_FIRSTROW: 4,
|
|
172
161
|
CATCH_ALL_FLOOR: 5
|
|
173
162
|
};
|
|
174
163
|
|
|
@@ -181,9 +170,6 @@ export default class FilterBuilder {
|
|
|
181
170
|
this.reverseSectionNameMapping = {};
|
|
182
171
|
this.getSectionNameMapping = getSectionNameMapping;
|
|
183
172
|
this.updateHooks = [];
|
|
184
|
-
this.unselectable = [];
|
|
185
|
-
this.isDragging = false;
|
|
186
|
-
this.highlightedSeatColor = "#d3f8e2";
|
|
187
173
|
}
|
|
188
174
|
|
|
189
175
|
onUpdate(fn) {
|
|
@@ -192,8 +178,6 @@ export default class FilterBuilder {
|
|
|
192
178
|
|
|
193
179
|
setExpandedFilter(f) {
|
|
194
180
|
this.expandedFilter = f;
|
|
195
|
-
this.updateCss();
|
|
196
|
-
this.updateHooks.forEach((fn) => fn());
|
|
197
181
|
}
|
|
198
182
|
|
|
199
183
|
selectFilter(f) {
|
|
@@ -210,80 +194,24 @@ export default class FilterBuilder {
|
|
|
210
194
|
if (filter.buyAny) return this.filterTypes.CATCH_ALL;
|
|
211
195
|
else if (filter.floor) return this.filterTypes.CATCH_ALL_FLOOR;
|
|
212
196
|
else if (filter.generalAdmission) return this.filterTypes.CATCH_ALL_GA;
|
|
197
|
+
// else if (!!filter.section && filter.firstRow) return this.filterTypes.NORMAL_FIRSTROW;
|
|
198
|
+
// else if (!filter.section && filter.firstRow) return this.filterTypes.GLOBAL_FIRSTROW;
|
|
213
199
|
else if (filter.section) return this.filterTypes.NORMAL;
|
|
214
200
|
else return this.filterTypes.INVALID;
|
|
215
201
|
}
|
|
216
202
|
|
|
217
|
-
addRowHandlers() {
|
|
218
|
-
for (let i = 0; i < this.rows.length; i++) {
|
|
219
|
-
const row = this.rows[i];
|
|
220
|
-
row.onclick = () => {
|
|
221
|
-
const parsed = {
|
|
222
|
-
section: getAttributeValue(row, "section"),
|
|
223
|
-
row: getAttributeValue(row, "row"),
|
|
224
|
-
id: getAttributeValue(row, "id")
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
log(`Adding filter ${parsed.section}`);
|
|
228
|
-
const matchingFilter = this.filters.find(
|
|
229
|
-
(f) =>
|
|
230
|
-
this.isForCurrentEvent(f) &&
|
|
231
|
-
f.section === parsed.section &&
|
|
232
|
-
(f.rows?.includes(parsed.row) || !Array.isArray(f.rows))
|
|
233
|
-
);
|
|
234
|
-
|
|
235
|
-
if (matchingFilter) {
|
|
236
|
-
log(`Filter for ${parsed.section}/${parsed.row} already exists (${matchingFilter.id})`);
|
|
237
|
-
// Toggle expanded state
|
|
238
|
-
if (this.expandedFilter === matchingFilter.id) {
|
|
239
|
-
this.setExpandedFilter(null);
|
|
240
|
-
} else {
|
|
241
|
-
this.setExpandedFilter(matchingFilter.id);
|
|
242
|
-
}
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
this.addFilter({
|
|
247
|
-
section: parsed.section,
|
|
248
|
-
event: this.currentEventId
|
|
249
|
-
});
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
row.onmouseover = () => {
|
|
253
|
-
const parsed = {
|
|
254
|
-
section: getAttributeValue(row, "section"),
|
|
255
|
-
row: getAttributeValue(row, "row"),
|
|
256
|
-
id: getAttributeValue(row, "id")
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
const matchingFilter = this.filters.find(
|
|
260
|
-
(f) =>
|
|
261
|
-
this.isForCurrentEvent(f) &&
|
|
262
|
-
f.section === parsed.section &&
|
|
263
|
-
(f.rows?.includes(parsed.row) || !Array.isArray(f.rows))
|
|
264
|
-
);
|
|
265
|
-
|
|
266
|
-
if (!matchingFilter) return;
|
|
267
|
-
if (Array.isArray(matchingFilter.rows))
|
|
268
|
-
matchingFilter.rows.forEach((row) => this.highlight({ section: parsed.section, row: row }));
|
|
269
|
-
else this.highlight({ section: matchingFilter.section });
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
row.onmouseout = () => {
|
|
273
|
-
if (!this.isDragging) this.clearHighlight();
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
203
|
reload(eventId) {
|
|
279
204
|
const paths = document.querySelectorAll("path");
|
|
280
205
|
this.rows = [...paths].filter((r) => r.id.startsWith("s_"));
|
|
281
206
|
|
|
282
207
|
this.addLabelHandlers();
|
|
283
|
-
this.addGAHandlers();
|
|
284
208
|
this.addRowHandlers();
|
|
209
|
+
this.addGAHandlers();
|
|
285
210
|
this.currentEventId = eventId;
|
|
286
211
|
|
|
212
|
+
const wcRows = getWheelChairRows();
|
|
213
|
+
log("wcRows:", wcRows);
|
|
214
|
+
wcRows.forEach((r) => this.makeRowUnselectable(r.sectionName, r.row));
|
|
287
215
|
this.updateCss();
|
|
288
216
|
}
|
|
289
217
|
|
|
@@ -305,18 +233,6 @@ export default class FilterBuilder {
|
|
|
305
233
|
addFilter(filter) {
|
|
306
234
|
if (!this.filters) this.filters = [];
|
|
307
235
|
|
|
308
|
-
// Check if a filter with the same properties (excluding id) already exists
|
|
309
|
-
const existingFilter = this.filters.find((f) => {
|
|
310
|
-
const n = { ...f };
|
|
311
|
-
delete n.id;
|
|
312
|
-
return JSON.stringify(n) === JSON.stringify(filter);
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
if (existingFilter) {
|
|
316
|
-
console.log("Filter already exists:", existingFilter);
|
|
317
|
-
return; // Don't add the filter if it already exists
|
|
318
|
-
}
|
|
319
|
-
|
|
320
236
|
if (this.expandedFilter) {
|
|
321
237
|
const parent = this.filters.find((f) => f.event === filter.event && f.section === filter.section);
|
|
322
238
|
if (parent) return this.addFilterToParent(filter, parent);
|
|
@@ -357,7 +273,23 @@ export default class FilterBuilder {
|
|
|
357
273
|
this.rows = [];
|
|
358
274
|
if (hard) this.unselectable = [];
|
|
359
275
|
this.updateCss();
|
|
360
|
-
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
selectFirstRow() {
|
|
279
|
+
const paths = document.querySelectorAll("path");
|
|
280
|
+
const rows = [...paths].filter((r) => r.id.startsWith("s_"));
|
|
281
|
+
const firstRows = getFirstRows(rows);
|
|
282
|
+
|
|
283
|
+
Object.entries(firstRows).forEach(([sec, rows]) => {
|
|
284
|
+
if (this.filters.some((f) => f.section === sec && f.rows.includes(rows[0]) && this.isForCurrentEvent(f))) {
|
|
285
|
+
log(`Filter for ${sec}/${rows[0]} already exists`);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (this.isUnselectable(sec, rows[0])) return;
|
|
289
|
+
this.addFilter({ event: this.currentEventId, section: sec, rows: [rows[0]] });
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
this.updateCss();
|
|
361
293
|
}
|
|
362
294
|
|
|
363
295
|
updateCss() {
|
|
@@ -368,9 +300,9 @@ export default class FilterBuilder {
|
|
|
368
300
|
if (!this.isForCurrentEvent(filter)) return;
|
|
369
301
|
|
|
370
302
|
const tryFindRealName = Object.entries(gaSectionNameMapping).find(
|
|
371
|
-
|
|
303
|
+
// eslint-disable-next-line no-unused-vars
|
|
304
|
+
([_, v]) => v === filter.section && v.includes(" ")
|
|
372
305
|
)?.[0];
|
|
373
|
-
|
|
374
306
|
if (tryFindRealName) {
|
|
375
307
|
log(`Real name for ${filter.section}: ${tryFindRealName}`);
|
|
376
308
|
} else {
|
|
@@ -379,44 +311,33 @@ export default class FilterBuilder {
|
|
|
379
311
|
|
|
380
312
|
const type = this.getFilterType(filter);
|
|
381
313
|
|
|
382
|
-
let color;
|
|
383
|
-
if (filter.
|
|
384
|
-
color = this.expandedFilter === filter.id ? colors.EXCLUDED_EXPANDED : colors.EXCLUDED;
|
|
385
|
-
} else {
|
|
386
|
-
color = this.expandedFilter === filter.id ? colors.SELECTED_EXPANDED : colors.SELECTED;
|
|
387
|
-
}
|
|
388
|
-
|
|
314
|
+
let color = filter.exclude ? colors.EXCLUDED : colors.SELECTED;
|
|
315
|
+
if (this.expandedFilter === filter.id) color = colors.HIGHLIGHT;
|
|
389
316
|
switch (type) {
|
|
390
317
|
case this.filterTypes.NORMAL:
|
|
391
318
|
// If it has no 'rows' property
|
|
392
319
|
if (!Array.isArray(filter.rows)) {
|
|
393
|
-
const isGA = document.querySelectorAll(`path[
|
|
320
|
+
const isGA = document.querySelectorAll(`path[sectionname='${filter.section}']`)?.length === 0;
|
|
394
321
|
|
|
395
|
-
if (isGA
|
|
396
|
-
|
|
397
|
-
} else {
|
|
398
|
-
this.cssClasses += `.svg-wrapper path[section="${filter.section}"] {stroke: ${color} !important;}\n`;
|
|
399
|
-
}
|
|
322
|
+
if (isGA) this.cssClasses += `path[name="${tryFindRealName}"] {fill: ${color} !important}`;
|
|
323
|
+
else this.cssClasses += `path[sectionname="${filter.section}"] {stroke: ${color} !important}`;
|
|
400
324
|
} else {
|
|
401
325
|
this.cssClasses += filter.rows
|
|
402
326
|
.map(
|
|
403
|
-
(row) =>
|
|
327
|
+
(row) =>
|
|
328
|
+
`path[sectionname="${filter.section}"][row="${row}"] {stroke: ${color} !important}`
|
|
404
329
|
)
|
|
405
|
-
|
|
330
|
+
?.join("\n");
|
|
406
331
|
}
|
|
407
|
-
break;
|
|
408
332
|
|
|
409
|
-
case this.filterTypes.CATCH_ALL:
|
|
410
|
-
// Scope to SVG paths only to prevent global CSS leak
|
|
411
|
-
this.cssClasses += `.svg-wrapper path {stroke: ${color} !important;}\n`;
|
|
412
333
|
break;
|
|
413
334
|
|
|
414
335
|
case this.filterTypes.CATCH_ALL_GA:
|
|
415
|
-
this.cssClasses +=
|
|
336
|
+
// this.cssClasses += `path[generaladmission] {fill: ${color} !important}`;
|
|
416
337
|
break;
|
|
417
338
|
|
|
418
339
|
case this.filterTypes.CATCH_ALL_FLOOR:
|
|
419
|
-
// this.cssClasses += floors.map((f) => `path[name="${f}"] {fill: ${color} !important
|
|
340
|
+
// this.cssClasses += floors.map((f) => `path[name="${f}"] {fill: ${color} !important}`).join("\n");
|
|
420
341
|
break;
|
|
421
342
|
|
|
422
343
|
case this.filterTypes.INVALID:
|
|
@@ -427,13 +348,12 @@ export default class FilterBuilder {
|
|
|
427
348
|
});
|
|
428
349
|
|
|
429
350
|
this.unselectable.forEach((unselectable) => {
|
|
430
|
-
const [
|
|
431
|
-
log("UpdateCSS: adding unselectable",
|
|
351
|
+
const [sectionName, row] = unselectable.split("/");
|
|
352
|
+
log("UpdateCSS: adding unselectable", sectionName, row);
|
|
432
353
|
const color = colors.UNSELECTABLE;
|
|
433
|
-
this.cssClasses +=
|
|
354
|
+
this.cssClasses += `path[sectionname="${sectionName}"][row="${row}"] {stroke: ${color} !important} `;
|
|
434
355
|
});
|
|
435
|
-
|
|
436
|
-
log("Generated CSS:", this.cssClasses);
|
|
356
|
+
log(this.cssClasses);
|
|
437
357
|
}
|
|
438
358
|
|
|
439
359
|
addLabelHandlers() {
|
|
@@ -443,7 +363,7 @@ export default class FilterBuilder {
|
|
|
443
363
|
|
|
444
364
|
for (let i = 0; i < labels.length; i++) {
|
|
445
365
|
const label = labels[i];
|
|
446
|
-
const section =
|
|
366
|
+
const section = label.attributes.section.nodeValue;
|
|
447
367
|
|
|
448
368
|
label.onclick = () => {
|
|
449
369
|
// filter exists already for section - return
|
|
@@ -452,40 +372,33 @@ export default class FilterBuilder {
|
|
|
452
372
|
if (f.section !== section && f.section !== gaSectionNameMapping[section]) return false;
|
|
453
373
|
return true;
|
|
454
374
|
});
|
|
455
|
-
|
|
375
|
+
// (((f.section === section || f.section === gaSectionNameMapping[section]) && !f.rows) ||
|
|
376
|
+
// (f.section === section &&
|
|
377
|
+
// document.querySelectorAll(`path[sectionname="${section}"]`).length ===
|
|
378
|
+
// f.rows.length)) &&
|
|
379
|
+
// this.isForCurrentEvent(f)
|
|
456
380
|
if (matchingFilter) {
|
|
457
381
|
log(`Filter for ${section} already exists (${matchingFilter.id})`);
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
} else {
|
|
462
|
-
this.setExpandedFilter(matchingFilter.id);
|
|
463
|
-
}
|
|
382
|
+
if (this.expandedFilter === matchingFilter.id) this.setExpandedFilter(null);
|
|
383
|
+
else this.setExpandedFilter(matchingFilter.id);
|
|
384
|
+
this.updateCss();
|
|
464
385
|
return;
|
|
465
386
|
}
|
|
466
387
|
|
|
467
388
|
if (isWheelchair({ section: gaSectionNameMapping[section] || section })) return;
|
|
468
389
|
|
|
469
|
-
const isGA = document.querySelectorAll(`path[sectionname="${section}"][row]`).length === 0;
|
|
390
|
+
const isGA = document.querySelectorAll(`path[sectionname="${section.trim()}"][row]`).length === 0;
|
|
470
391
|
|
|
471
392
|
try {
|
|
472
393
|
if (isGA) {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
this.
|
|
476
|
-
|
|
477
|
-
event: this.currentEventId
|
|
478
|
-
});
|
|
479
|
-
}
|
|
394
|
+
this.addFilter({
|
|
395
|
+
section: gaSectionNameMapping[section].trim(),
|
|
396
|
+
event: this.currentEventId
|
|
397
|
+
});
|
|
480
398
|
} else {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
sections.forEach((s) => {
|
|
485
|
-
this.addFilter({
|
|
486
|
-
section: s,
|
|
487
|
-
event: this.currentEventId
|
|
488
|
-
});
|
|
399
|
+
this.addFilter({
|
|
400
|
+
section: section.trim(),
|
|
401
|
+
event: this.currentEventId
|
|
489
402
|
});
|
|
490
403
|
}
|
|
491
404
|
log("Added labelHandler filter", section);
|
|
@@ -506,23 +419,21 @@ export default class FilterBuilder {
|
|
|
506
419
|
|
|
507
420
|
for (let i = 0; i < GASections.length; i++) {
|
|
508
421
|
const path = GASections[i];
|
|
509
|
-
const section =
|
|
422
|
+
const section = path.attributes.name.nodeValue;
|
|
510
423
|
const sectionName = gaSectionNameMapping[section];
|
|
511
424
|
|
|
512
425
|
path.onclick = () => {
|
|
513
|
-
// filter exists already for section
|
|
426
|
+
// filter exists already for section - return
|
|
514
427
|
const matchingFilter = this.filters.find((f) => f.section === sectionName && this.isForCurrentEvent(f));
|
|
515
428
|
if (matchingFilter) {
|
|
516
429
|
log(`Filter for ${sectionName} (GA) already exists (${matchingFilter.id})`);
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
} else {
|
|
521
|
-
this.setExpandedFilter(matchingFilter.id);
|
|
522
|
-
}
|
|
430
|
+
if (this.expandedFilter === matchingFilter.id) this.setExpandedFilter(null);
|
|
431
|
+
else this.setExpandedFilter(matchingFilter.id);
|
|
432
|
+
this.updateCss();
|
|
523
433
|
return;
|
|
524
434
|
}
|
|
525
435
|
log(`GAHandler: adding filter for ${section} (realname: ${sectionName})`, section, sectionName);
|
|
436
|
+
|
|
526
437
|
this.addFilter({
|
|
527
438
|
section: sectionName,
|
|
528
439
|
event: this.currentEventId
|
|
@@ -531,12 +442,67 @@ export default class FilterBuilder {
|
|
|
531
442
|
}
|
|
532
443
|
}
|
|
533
444
|
|
|
445
|
+
addRowHandlers() {
|
|
446
|
+
for (let i = 0; i < this.rows.length; i++) {
|
|
447
|
+
const row = this.rows[i];
|
|
448
|
+
row.onclick = () => {
|
|
449
|
+
const parsed = {
|
|
450
|
+
section: row.attributes.sectionname.nodeValue,
|
|
451
|
+
row: row.attributes.row.nodeValue,
|
|
452
|
+
id: row.attributes.id.nodeValue
|
|
453
|
+
};
|
|
454
|
+
log(`Adding filter ${parsed.section}/${parsed.row}`);
|
|
455
|
+
const matchingFilter = this.filters.find(
|
|
456
|
+
(f) =>
|
|
457
|
+
this.isForCurrentEvent(f) &&
|
|
458
|
+
f.section === parsed.section &&
|
|
459
|
+
(f.rows?.includes(parsed.row) || !Array.isArray(f.rows))
|
|
460
|
+
);
|
|
461
|
+
if (matchingFilter) {
|
|
462
|
+
log(`Filter for ${parsed.section}/${parsed.row} already exists (${matchingFilter.id})`);
|
|
463
|
+
if (this.expandedFilter === matchingFilter.id) this.setExpandedFilter(null);
|
|
464
|
+
else this.setExpandedFilter(matchingFilter.id);
|
|
465
|
+
this.updateCss();
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
if (this.isUnselectable(parsed.section, parsed.row)) return;
|
|
470
|
+
|
|
471
|
+
this.addFilter({
|
|
472
|
+
section: parsed.section,
|
|
473
|
+
rows: [parsed.row],
|
|
474
|
+
event: this.currentEventId
|
|
475
|
+
});
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
row.onmouseover = () => {
|
|
479
|
+
const parsed = {
|
|
480
|
+
section: row.attributes.sectionname.nodeValue,
|
|
481
|
+
row: row.attributes.row.nodeValue,
|
|
482
|
+
id: row.attributes.id.nodeValue
|
|
483
|
+
};
|
|
484
|
+
const matchingFilter = this.filters.find(
|
|
485
|
+
(f) =>
|
|
486
|
+
this.isForCurrentEvent(f) &&
|
|
487
|
+
f.section === parsed.section &&
|
|
488
|
+
(f.rows?.includes(parsed.row) || !Array.isArray(f.rows))
|
|
489
|
+
);
|
|
490
|
+
if (!matchingFilter) return;
|
|
491
|
+
if (Array.isArray(matchingFilter.rows))
|
|
492
|
+
matchingFilter.rows.forEach((row) => this.highlight({ section: parsed.section, row: row }));
|
|
493
|
+
else this.highlight({ section: matchingFilter.section });
|
|
494
|
+
};
|
|
495
|
+
row.onmouseout = () => {
|
|
496
|
+
if (!this.isDragging) this.clearHighlight();
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
534
501
|
deleteFilterById(id) {
|
|
535
502
|
this.filters = this.filters.filter((f) => f.id !== id);
|
|
536
503
|
// this.updateHooks = this.updateHooks.filter((i) => id !== i);
|
|
537
504
|
if (this.expandedFilter === id) this.expandedFilter = "";
|
|
538
505
|
this.updateCss();
|
|
539
|
-
this.updateHooks.forEach((fn) => fn());
|
|
540
506
|
}
|
|
541
507
|
|
|
542
508
|
replaceById(id, filter) {
|
|
@@ -554,7 +520,6 @@ export default class FilterBuilder {
|
|
|
554
520
|
id: this.filters[index].id
|
|
555
521
|
};
|
|
556
522
|
this.updateCss();
|
|
557
|
-
this.updateHooks.forEach((fn) => fn());
|
|
558
523
|
return this.filters[index];
|
|
559
524
|
}
|
|
560
525
|
|
|
@@ -574,11 +539,11 @@ export default class FilterBuilder {
|
|
|
574
539
|
|
|
575
540
|
if (isGA) {
|
|
576
541
|
if (this.filters.find((f) => f.section === filter.name)) return;
|
|
577
|
-
newCSS +=
|
|
542
|
+
newCSS += `path[name="${filter.section || filter.name}"] {fill: ${colors.HIGHLIGHT} !important}`;
|
|
578
543
|
} else if (filter.row) {
|
|
579
|
-
newCSS +=
|
|
544
|
+
newCSS += `path[sectionname="${filter.section}"][row="${filter.row}"] {stroke: ${colors.HIGHLIGHT} !important}`;
|
|
580
545
|
} else {
|
|
581
|
-
newCSS +=
|
|
546
|
+
newCSS += `path[sectionname="${filter.section}"] {stroke: ${colors.HIGHLIGHT} !important}`;
|
|
582
547
|
}
|
|
583
548
|
this.temporaryCSS += newCSS;
|
|
584
549
|
}
|
|
@@ -587,6 +552,11 @@ export default class FilterBuilder {
|
|
|
587
552
|
this.temporaryCSS = "";
|
|
588
553
|
}
|
|
589
554
|
|
|
555
|
+
makeRowUnselectable(section, row) {
|
|
556
|
+
log("adding unselectable:", section, row);
|
|
557
|
+
this.unselectable.push(`${section}/${row}`);
|
|
558
|
+
}
|
|
559
|
+
|
|
590
560
|
isUnselectable(section, row) {
|
|
591
561
|
return this.unselectable.includes(`${section}/${row}`);
|
|
592
562
|
}
|