@necrolab/dashboard 0.4.220 → 0.5.1
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 +27 -1
- package/.vscode/extensions.json +1 -1
- package/README.md +64 -2
- package/artwork/image.png +0 -0
- package/backend/api.js +26 -24
- package/backend/auth.js +2 -2
- package/backend/batching.js +1 -1
- package/backend/endpoints.js +8 -11
- package/backend/index.js +2 -2
- package/backend/mock-data.js +27 -36
- package/backend/mock-src/classes/logger.js +5 -7
- package/backend/mock-src/classes/utils.js +3 -2
- package/backend/mock-src/ticketmaster.js +4 -4
- package/backend/validator.js +2 -2
- package/config/configs.json +0 -1
- package/dev-server.js +134 -0
- package/exit +209 -0
- package/index.html +78 -8
- package/index.js +1 -1
- package/jsconfig.json +16 -0
- package/package.json +39 -25
- package/postcss.config.js +1 -1
- package/postinstall.js +124 -20
- 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/img/logo_trans.png +0 -0
- package/public/img/necro_logo.png +0 -0
- package/public/manifest.json +16 -10
- package/run +176 -9
- package/src/App.vue +498 -85
- package/src/assets/css/base/reset.scss +43 -0
- package/src/assets/css/base/scroll.scss +114 -0
- package/src/assets/css/base/typography.scss +37 -0
- package/src/assets/css/components/buttons.scss +216 -0
- package/src/assets/css/components/forms.scss +221 -0
- package/src/assets/css/components/modals.scss +13 -0
- package/src/assets/css/components/tables.scss +27 -0
- package/src/assets/css/components/toasts.scss +100 -0
- package/src/assets/css/main.scss +201 -122
- package/src/assets/img/background.svg +2 -2
- package/src/assets/img/background.svg.backup +11 -0
- package/src/assets/img/logo_trans.png +0 -0
- package/src/components/Auth/LoginForm.vue +62 -11
- package/src/components/Editors/Account/Account.vue +116 -40
- package/src/components/Editors/Account/AccountCreator.vue +88 -39
- package/src/components/Editors/Account/AccountView.vue +102 -34
- package/src/components/Editors/Account/CreateAccount.vue +80 -32
- package/src/components/Editors/Profile/CreateProfile.vue +269 -83
- package/src/components/Editors/Profile/Profile.vue +132 -47
- package/src/components/Editors/Profile/ProfileCountryChooser.vue +82 -20
- package/src/components/Editors/Profile/ProfileView.vue +89 -32
- package/src/components/Editors/TagLabel.vue +67 -6
- package/src/components/Editors/TagToggle.vue +7 -2
- package/src/components/Filter/Filter.vue +288 -71
- package/src/components/Filter/FilterPreview.vue +202 -31
- package/src/components/Filter/PriceSortToggle.vue +76 -6
- package/src/components/Table/Header.vue +1 -1
- package/src/components/Table/Row.vue +1 -1
- package/src/components/Table/Table.vue +19 -2
- package/src/components/Tasks/CheckStock.vue +6 -8
- package/src/components/Tasks/Controls/DesktopControls.vue +27 -17
- package/src/components/Tasks/Controls/MobileControls.vue +8 -45
- package/src/components/Tasks/CreateTaskAXS.vue +80 -72
- package/src/components/Tasks/CreateTaskTM.vue +95 -141
- package/src/components/Tasks/MassEdit.vue +4 -6
- package/src/components/Tasks/QuickSettings.vue +199 -30
- package/src/components/Tasks/ScrapeVenue.vue +5 -6
- package/src/components/Tasks/Stats.vue +50 -24
- package/src/components/Tasks/Task.vue +384 -179
- package/src/components/Tasks/TaskLabel.vue +2 -2
- package/src/components/Tasks/TaskView.vue +136 -48
- package/src/components/Tasks/Utilities.vue +25 -10
- package/src/components/Tasks/ViewTask.vue +321 -0
- package/src/components/icons/Bag.vue +1 -1
- package/src/components/icons/Check.vue +5 -0
- package/src/components/icons/Close.vue +21 -0
- package/src/components/icons/CloseX.vue +5 -0
- package/src/components/icons/Eye.vue +6 -0
- package/src/components/icons/Key.vue +21 -0
- package/src/components/icons/Loyalty.vue +1 -1
- package/src/components/icons/Mail.vue +2 -2
- package/src/components/icons/Pencil.vue +21 -0
- package/src/components/icons/Play.vue +2 -2
- package/src/components/icons/Profile.vue +18 -0
- package/src/components/icons/Reload.vue +4 -5
- package/src/components/icons/Sandclock.vue +2 -2
- package/src/components/icons/Sell.vue +21 -0
- package/src/components/icons/Spinner.vue +42 -0
- package/src/components/icons/SquareCheck.vue +18 -0
- package/src/components/icons/SquareUncheck.vue +18 -0
- package/src/components/icons/Stadium.vue +1 -1
- package/src/components/icons/Wildcard.vue +18 -0
- package/src/components/icons/index.js +26 -1
- package/src/components/ui/Modal.vue +107 -13
- package/src/components/ui/Navbar.vue +175 -40
- package/src/components/ui/ReconnectIndicator.vue +351 -55
- package/src/components/ui/Splash.vue +5 -35
- package/src/components/ui/controls/CountryChooser.vue +200 -62
- package/src/components/ui/controls/atomic/Checkbox.vue +119 -10
- package/src/components/ui/controls/atomic/Dropdown.vue +216 -39
- package/src/components/ui/controls/atomic/LoadingButton.vue +45 -0
- package/src/components/ui/controls/atomic/MultiDropdown.vue +300 -37
- package/src/components/ui/controls/atomic/Switch.vue +53 -25
- package/src/composables/useClickOutside.js +21 -0
- package/src/composables/useDropdownPosition.js +174 -0
- package/src/libs/Filter.js +60 -24
- package/src/registerServiceWorker.js +1 -1
- package/src/stores/connection.js +4 -4
- package/src/stores/sampleData.js +172 -199
- package/src/stores/ui.js +55 -20
- package/src/stores/utils.js +30 -4
- package/src/types/index.js +41 -0
- package/src/utils/debug.js +1 -0
- package/src/views/Accounts.vue +116 -50
- package/src/views/Console.vue +394 -79
- package/src/views/Editor.vue +1176 -123
- package/src/views/FilterBuilder.vue +528 -250
- package/src/views/Login.vue +76 -14
- package/src/views/Profiles.vue +119 -34
- package/src/views/Tasks.vue +266 -98
- package/static/offline.html +192 -50
- package/switch-branch.sh +41 -0
- package/tailwind.config.js +119 -27
- package/vite.config.js +73 -16
- package/workbox-config.cjs +63 -0
- package/ICONS.md +0 -21
- package/public/img/background.svg +0 -14
- package/public/img/logo.png +0 -0
- package/public/img/logo_icon.png +0 -0
- package/public/img/logo_icon_2.png +0 -0
- package/src/assets/css/_input.scss +0 -143
- package/src/assets/img/logo.png +0 -0
- package/src/assets/img/logo_icon.png +0 -0
- package/src/assets/img/logo_icon_2.png +0 -0
- package/vue.config.js +0 -32
- package/workbox-config.js +0 -7
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { ref, nextTick, onMounted, onUnmounted } from "vue";
|
|
2
|
+
|
|
3
|
+
export function useDropdownPosition(dropdownRef, options = {}) {
|
|
4
|
+
const menuStyle = ref({});
|
|
5
|
+
const {
|
|
6
|
+
offset = { x: -1, y: 4 },
|
|
7
|
+
zIndex = 50000,
|
|
8
|
+
minWidth = null,
|
|
9
|
+
maxHeight = 160,
|
|
10
|
+
estimateHeight = null,
|
|
11
|
+
includeAdjacentButtons = false,
|
|
12
|
+
containerSelector = null
|
|
13
|
+
} = options;
|
|
14
|
+
|
|
15
|
+
const calculateMenuPosition = () => {
|
|
16
|
+
if (!dropdownRef.value) return;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const rect = dropdownRef.value.getBoundingClientRect();
|
|
20
|
+
const viewportHeight = window.innerHeight;
|
|
21
|
+
const viewportWidth = window.innerWidth;
|
|
22
|
+
|
|
23
|
+
// Calculate menu dimensions
|
|
24
|
+
const menuHeight = estimateHeight ? estimateHeight() : maxHeight;
|
|
25
|
+
|
|
26
|
+
// Calculate width including adjacent buttons if specified
|
|
27
|
+
let menuWidth = minWidth || rect.width + 2;
|
|
28
|
+
|
|
29
|
+
if (includeAdjacentButtons) {
|
|
30
|
+
// Look for parent container with buttons
|
|
31
|
+
const parentContainer = dropdownRef.value.closest(
|
|
32
|
+
".flex, .flex-responsive-wrap, .proxy-controls-row, .filter-controls, .dropdown-container"
|
|
33
|
+
);
|
|
34
|
+
if (parentContainer) {
|
|
35
|
+
const containerRect = parentContainer.getBoundingClientRect();
|
|
36
|
+
// Use the full container width for better alignment
|
|
37
|
+
menuWidth = Math.max(menuWidth, containerRect.width);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Determine if menu should open upward
|
|
42
|
+
const spaceBelow = viewportHeight - rect.bottom;
|
|
43
|
+
const spaceAbove = rect.top;
|
|
44
|
+
const openUpward = spaceBelow < menuHeight && spaceAbove > spaceBelow;
|
|
45
|
+
|
|
46
|
+
// Calculate position with improved logic
|
|
47
|
+
let top, left;
|
|
48
|
+
|
|
49
|
+
if (openUpward) {
|
|
50
|
+
// Position above with better spacing
|
|
51
|
+
top = rect.top - menuHeight - Math.abs(offset.y) - 2;
|
|
52
|
+
} else {
|
|
53
|
+
// Position below with improved spacing
|
|
54
|
+
top = rect.bottom + offset.y + 2;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Improved horizontal positioning
|
|
58
|
+
if (includeAdjacentButtons) {
|
|
59
|
+
// Align with the start of the container for better visual consistency
|
|
60
|
+
const parentContainer = dropdownRef.value.closest(
|
|
61
|
+
".flex, .flex-responsive-wrap, .proxy-controls-row, .filter-controls, .dropdown-container"
|
|
62
|
+
);
|
|
63
|
+
if (parentContainer) {
|
|
64
|
+
const containerRect = parentContainer.getBoundingClientRect();
|
|
65
|
+
left = containerRect.left + offset.x;
|
|
66
|
+
} else {
|
|
67
|
+
left = rect.left + offset.x;
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
left = rect.left + offset.x;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Enhanced boundary checking
|
|
74
|
+
const padding = 12; // Increased padding from screen edges
|
|
75
|
+
|
|
76
|
+
// Horizontal boundary checking
|
|
77
|
+
if (left + menuWidth > viewportWidth - padding) {
|
|
78
|
+
left = viewportWidth - menuWidth - padding;
|
|
79
|
+
}
|
|
80
|
+
if (left < padding) {
|
|
81
|
+
left = padding;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Vertical boundary checking with better logic
|
|
85
|
+
if (top < padding) {
|
|
86
|
+
top = padding;
|
|
87
|
+
} else if (top + menuHeight > viewportHeight - padding) {
|
|
88
|
+
if (openUpward) {
|
|
89
|
+
// If opening upward and still doesn't fit, position at top
|
|
90
|
+
top = padding;
|
|
91
|
+
} else {
|
|
92
|
+
// If opening downward and doesn't fit, try upward
|
|
93
|
+
const upwardTop = rect.top - menuHeight - Math.abs(offset.y) - 2;
|
|
94
|
+
if (upwardTop >= padding) {
|
|
95
|
+
top = upwardTop;
|
|
96
|
+
} else {
|
|
97
|
+
// If neither direction fits well, center vertically
|
|
98
|
+
top = Math.max(padding, (viewportHeight - menuHeight) / 2);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
menuStyle.value = {
|
|
104
|
+
position: "fixed",
|
|
105
|
+
top: `${Math.round(top)}px`,
|
|
106
|
+
left: `${Math.round(left)}px`,
|
|
107
|
+
width: `${Math.round(menuWidth)}px`,
|
|
108
|
+
zIndex,
|
|
109
|
+
maxHeight: `${maxHeight}px`
|
|
110
|
+
};
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.warn("Error calculating dropdown position:", error);
|
|
113
|
+
// Fallback to basic positioning
|
|
114
|
+
menuStyle.value = {
|
|
115
|
+
position: "fixed",
|
|
116
|
+
top: "0px",
|
|
117
|
+
left: "0px",
|
|
118
|
+
width: "200px",
|
|
119
|
+
zIndex,
|
|
120
|
+
maxHeight: `${maxHeight}px`
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// Event handlers with ultra-smooth responsiveness using requestAnimationFrame
|
|
126
|
+
let resizeFrame;
|
|
127
|
+
const handleResize = () => {
|
|
128
|
+
if (resizeFrame) {
|
|
129
|
+
cancelAnimationFrame(resizeFrame);
|
|
130
|
+
}
|
|
131
|
+
resizeFrame = requestAnimationFrame(() => {
|
|
132
|
+
calculateMenuPosition();
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
let scrollFrame;
|
|
137
|
+
const handleScroll = () => {
|
|
138
|
+
if (scrollFrame) {
|
|
139
|
+
cancelAnimationFrame(scrollFrame);
|
|
140
|
+
}
|
|
141
|
+
scrollFrame = requestAnimationFrame(() => {
|
|
142
|
+
calculateMenuPosition();
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// Setup event listeners
|
|
147
|
+
onMounted(() => {
|
|
148
|
+
window.addEventListener("resize", handleResize, { passive: true });
|
|
149
|
+
window.addEventListener("scroll", handleScroll, { passive: true, capture: true });
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
onUnmounted(() => {
|
|
153
|
+
if (resizeFrame) {
|
|
154
|
+
cancelAnimationFrame(resizeFrame);
|
|
155
|
+
}
|
|
156
|
+
if (scrollFrame) {
|
|
157
|
+
cancelAnimationFrame(scrollFrame);
|
|
158
|
+
}
|
|
159
|
+
window.removeEventListener("resize", handleResize);
|
|
160
|
+
window.removeEventListener("scroll", handleScroll, true);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const updatePosition = () => {
|
|
164
|
+
nextTick(() => {
|
|
165
|
+
calculateMenuPosition();
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
menuStyle,
|
|
171
|
+
updatePosition,
|
|
172
|
+
calculateMenuPosition
|
|
173
|
+
};
|
|
174
|
+
}
|
package/src/libs/Filter.js
CHANGED
|
@@ -4,11 +4,13 @@ const log = (...args) => debug && console.log("[filter]", ...args);
|
|
|
4
4
|
const colors = {
|
|
5
5
|
HIGHLIGHT: "#d3f8e2",
|
|
6
6
|
SELECTED: "#a9def9",
|
|
7
|
+
SELECTED_EXPANDED: "#6bb6ff",
|
|
7
8
|
EXCLUDED: "#f694c1",
|
|
9
|
+
EXCLUDED_EXPANDED: "#f472b6",
|
|
8
10
|
UNSELECTABLE: "#311432"
|
|
9
11
|
};
|
|
10
12
|
|
|
11
|
-
const BASE_CSS =
|
|
13
|
+
const BASE_CSS = `.svg-wrapper path[generaladmission]:hover {fill: ${colors.HIGHLIGHT};pointer-events:all;cursor:pointer;}`;
|
|
12
14
|
|
|
13
15
|
const getAttributeValue = (element, attributeName) => {
|
|
14
16
|
try {
|
|
@@ -179,6 +181,9 @@ export default class FilterBuilder {
|
|
|
179
181
|
this.reverseSectionNameMapping = {};
|
|
180
182
|
this.getSectionNameMapping = getSectionNameMapping;
|
|
181
183
|
this.updateHooks = [];
|
|
184
|
+
this.unselectable = [];
|
|
185
|
+
this.isDragging = false;
|
|
186
|
+
this.highlightedSeatColor = "#d3f8e2";
|
|
182
187
|
}
|
|
183
188
|
|
|
184
189
|
onUpdate(fn) {
|
|
@@ -187,6 +192,8 @@ export default class FilterBuilder {
|
|
|
187
192
|
|
|
188
193
|
setExpandedFilter(f) {
|
|
189
194
|
this.expandedFilter = f;
|
|
195
|
+
this.updateCss();
|
|
196
|
+
this.updateHooks.forEach((fn) => fn());
|
|
190
197
|
}
|
|
191
198
|
|
|
192
199
|
selectFilter(f) {
|
|
@@ -227,9 +234,12 @@ export default class FilterBuilder {
|
|
|
227
234
|
|
|
228
235
|
if (matchingFilter) {
|
|
229
236
|
log(`Filter for ${parsed.section}/${parsed.row} already exists (${matchingFilter.id})`);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
237
|
+
// Toggle expanded state
|
|
238
|
+
if (this.expandedFilter === matchingFilter.id) {
|
|
239
|
+
this.setExpandedFilter(null);
|
|
240
|
+
} else {
|
|
241
|
+
this.setExpandedFilter(matchingFilter.id);
|
|
242
|
+
}
|
|
233
243
|
return;
|
|
234
244
|
}
|
|
235
245
|
|
|
@@ -347,6 +357,7 @@ export default class FilterBuilder {
|
|
|
347
357
|
this.rows = [];
|
|
348
358
|
if (hard) this.unselectable = [];
|
|
349
359
|
this.updateCss();
|
|
360
|
+
this.updateHooks.forEach((fn) => fn());
|
|
350
361
|
}
|
|
351
362
|
|
|
352
363
|
updateCss() {
|
|
@@ -368,32 +379,44 @@ export default class FilterBuilder {
|
|
|
368
379
|
|
|
369
380
|
const type = this.getFilterType(filter);
|
|
370
381
|
|
|
371
|
-
let color
|
|
372
|
-
if (
|
|
382
|
+
let color;
|
|
383
|
+
if (filter.exclude) {
|
|
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
|
+
|
|
373
389
|
switch (type) {
|
|
374
390
|
case this.filterTypes.NORMAL:
|
|
375
391
|
// If it has no 'rows' property
|
|
376
392
|
if (!Array.isArray(filter.rows)) {
|
|
377
393
|
const isGA = document.querySelectorAll(`path[section='${filter.section}']`)?.length === 0;
|
|
378
394
|
|
|
379
|
-
if (isGA
|
|
380
|
-
|
|
395
|
+
if (isGA && tryFindRealName) {
|
|
396
|
+
this.cssClasses += `.svg-wrapper path[name="${tryFindRealName}"] {fill: ${color} !important;}\n`;
|
|
397
|
+
} else {
|
|
398
|
+
this.cssClasses += `.svg-wrapper path[section="${filter.section}"] {stroke: ${color} !important;}\n`;
|
|
399
|
+
}
|
|
381
400
|
} else {
|
|
382
401
|
this.cssClasses += filter.rows
|
|
383
402
|
.map(
|
|
384
|
-
(row) =>
|
|
403
|
+
(row) => `.svg-wrapper path[section="${filter.section}"][row="${row}"] {stroke: ${color} !important;}`
|
|
385
404
|
)
|
|
386
|
-
|
|
405
|
+
.join("\n") + "\n";
|
|
387
406
|
}
|
|
407
|
+
break;
|
|
388
408
|
|
|
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`;
|
|
389
412
|
break;
|
|
390
413
|
|
|
391
414
|
case this.filterTypes.CATCH_ALL_GA:
|
|
392
|
-
|
|
415
|
+
this.cssClasses += `.svg-wrapper path[generaladmission] {fill: ${color} !important;}\n`;
|
|
393
416
|
break;
|
|
394
417
|
|
|
395
418
|
case this.filterTypes.CATCH_ALL_FLOOR:
|
|
396
|
-
// this.cssClasses += floors.map((f) => `path[name="${f}"] {fill: ${color} !important}`).join("\n");
|
|
419
|
+
// this.cssClasses += floors.map((f) => `path[name="${f}"] {fill: ${color} !important;}`).join("\n") + "\n";
|
|
397
420
|
break;
|
|
398
421
|
|
|
399
422
|
case this.filterTypes.INVALID:
|
|
@@ -407,9 +430,10 @@ export default class FilterBuilder {
|
|
|
407
430
|
const [section, row] = unselectable.split("/");
|
|
408
431
|
log("UpdateCSS: adding unselectable", section, row);
|
|
409
432
|
const color = colors.UNSELECTABLE;
|
|
410
|
-
this.cssClasses +=
|
|
433
|
+
this.cssClasses += `.svg-wrapper path[section="${section}"][row="${row}"] {stroke: ${color} !important;}\n`;
|
|
411
434
|
});
|
|
412
|
-
|
|
435
|
+
|
|
436
|
+
log("Generated CSS:", this.cssClasses);
|
|
413
437
|
}
|
|
414
438
|
|
|
415
439
|
addLabelHandlers() {
|
|
@@ -431,9 +455,12 @@ export default class FilterBuilder {
|
|
|
431
455
|
|
|
432
456
|
if (matchingFilter) {
|
|
433
457
|
log(`Filter for ${section} already exists (${matchingFilter.id})`);
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
458
|
+
// Toggle expanded state
|
|
459
|
+
if (this.expandedFilter === matchingFilter.id) {
|
|
460
|
+
this.setExpandedFilter(null);
|
|
461
|
+
} else {
|
|
462
|
+
this.setExpandedFilter(matchingFilter.id);
|
|
463
|
+
}
|
|
437
464
|
return;
|
|
438
465
|
}
|
|
439
466
|
|
|
@@ -483,13 +510,16 @@ export default class FilterBuilder {
|
|
|
483
510
|
const sectionName = gaSectionNameMapping[section];
|
|
484
511
|
|
|
485
512
|
path.onclick = () => {
|
|
486
|
-
// filter exists already for section
|
|
513
|
+
// filter exists already for section
|
|
487
514
|
const matchingFilter = this.filters.find((f) => f.section === sectionName && this.isForCurrentEvent(f));
|
|
488
515
|
if (matchingFilter) {
|
|
489
516
|
log(`Filter for ${sectionName} (GA) already exists (${matchingFilter.id})`);
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
517
|
+
// Toggle expanded state
|
|
518
|
+
if (this.expandedFilter === matchingFilter.id) {
|
|
519
|
+
this.setExpandedFilter(null);
|
|
520
|
+
} else {
|
|
521
|
+
this.setExpandedFilter(matchingFilter.id);
|
|
522
|
+
}
|
|
493
523
|
return;
|
|
494
524
|
}
|
|
495
525
|
log(`GAHandler: adding filter for ${section} (realname: ${sectionName})`, section, sectionName);
|
|
@@ -506,6 +536,7 @@ export default class FilterBuilder {
|
|
|
506
536
|
// this.updateHooks = this.updateHooks.filter((i) => id !== i);
|
|
507
537
|
if (this.expandedFilter === id) this.expandedFilter = "";
|
|
508
538
|
this.updateCss();
|
|
539
|
+
this.updateHooks.forEach((fn) => fn());
|
|
509
540
|
}
|
|
510
541
|
|
|
511
542
|
replaceById(id, filter) {
|
|
@@ -523,6 +554,7 @@ export default class FilterBuilder {
|
|
|
523
554
|
id: this.filters[index].id
|
|
524
555
|
};
|
|
525
556
|
this.updateCss();
|
|
557
|
+
this.updateHooks.forEach((fn) => fn());
|
|
526
558
|
return this.filters[index];
|
|
527
559
|
}
|
|
528
560
|
|
|
@@ -542,11 +574,11 @@ export default class FilterBuilder {
|
|
|
542
574
|
|
|
543
575
|
if (isGA) {
|
|
544
576
|
if (this.filters.find((f) => f.section === filter.name)) return;
|
|
545
|
-
newCSS +=
|
|
577
|
+
newCSS += `.svg-wrapper path[name="${filter.section || filter.name}"] {fill: ${colors.HIGHLIGHT} !important}`;
|
|
546
578
|
} else if (filter.row) {
|
|
547
|
-
newCSS +=
|
|
579
|
+
newCSS += `.svg-wrapper path[section="${filter.section}"][row="${filter.row}"] {stroke: ${colors.HIGHLIGHT} !important}`;
|
|
548
580
|
} else {
|
|
549
|
-
newCSS +=
|
|
581
|
+
newCSS += `.svg-wrapper path[section="${filter.section}"] {stroke: ${colors.HIGHLIGHT} !important}`;
|
|
550
582
|
}
|
|
551
583
|
this.temporaryCSS += newCSS;
|
|
552
584
|
}
|
|
@@ -554,4 +586,8 @@ export default class FilterBuilder {
|
|
|
554
586
|
clearHighlight() {
|
|
555
587
|
this.temporaryCSS = "";
|
|
556
588
|
}
|
|
589
|
+
|
|
590
|
+
isUnselectable(section, row) {
|
|
591
|
+
return this.unselectable.includes(`${section}/${row}`);
|
|
592
|
+
}
|
|
557
593
|
}
|
package/src/stores/connection.js
CHANGED
|
@@ -164,7 +164,7 @@ export class ConnectionHandler {
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
case "add-account": {
|
|
167
|
-
const exists = this.ui.accounts.findIndex((p) => p.
|
|
167
|
+
const exists = this.ui.accounts.findIndex((p) => p.id === msg.account.id);
|
|
168
168
|
if (exists !== -1) {
|
|
169
169
|
Object.keys(msg.account).forEach((k) => (this.ui.accounts[exists][k] = msg.account[k]));
|
|
170
170
|
} else this.ui.accounts.push(msg.account);
|
|
@@ -172,7 +172,7 @@ export class ConnectionHandler {
|
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
case "add-profile": {
|
|
175
|
-
const exists = this.ui.profiles.findIndex((p) => p.
|
|
175
|
+
const exists = this.ui.profiles.findIndex((p) => p.id === msg.profile.id);
|
|
176
176
|
if (exists !== -1) {
|
|
177
177
|
Object.keys(msg.profile).forEach((k) => (this.ui.profiles[exists][k] = msg.profile[k]));
|
|
178
178
|
} else this.ui.profiles.push(msg.profile);
|
|
@@ -180,7 +180,7 @@ export class ConnectionHandler {
|
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
case "delete-profile":
|
|
183
|
-
this.ui.profiles = this.ui.profiles.filter((p) => p.
|
|
183
|
+
this.ui.profiles = this.ui.profiles.filter((p) => p.id !== msg.profile.id);
|
|
184
184
|
break;
|
|
185
185
|
|
|
186
186
|
default:
|
|
@@ -380,7 +380,7 @@ export class ConnectionHandler {
|
|
|
380
380
|
sendDeleteProfile(id) {
|
|
381
381
|
this.sendMessage({
|
|
382
382
|
event: "profiles/delete",
|
|
383
|
-
data: {
|
|
383
|
+
data: { id: id }
|
|
384
384
|
});
|
|
385
385
|
}
|
|
386
386
|
|