@necrolab/dashboard 0.4.52 → 0.4.54
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 +3 -1
- package/.vscode/extensions.json +1 -1
- package/backend/mock-src/ticketmaster.js +2 -2
- package/package.json +4 -2
- package/src/components/Tasks/Task.vue +18 -18
- package/src/components/Tasks/TaskView.vue +128 -185
- package/src/stores/sampleData.js +2 -2
- package/src/stores/ui.js +4 -2
package/.prettierrc
CHANGED
package/.vscode/extensions.json
CHANGED
|
@@ -24,7 +24,7 @@ export default class TicketMaster {
|
|
|
24
24
|
this.data.eventDate = Date.now();
|
|
25
25
|
this.data.eventLocalDate = Date.now();
|
|
26
26
|
this.data.eventName = "Test Event";
|
|
27
|
-
this.data.reservedTicketsList = "
|
|
27
|
+
this.data.reservedTicketsList = "• 2x 301/E ($86.47) \n• 2x 306/U ($86.47) \n$345.88";
|
|
28
28
|
|
|
29
29
|
refreshTaskOnFrontEnd(taskData);
|
|
30
30
|
}
|
|
@@ -89,4 +89,4 @@ export default class TicketMaster {
|
|
|
89
89
|
scrapeSeats() {
|
|
90
90
|
this.logger.Info("Scraping seats");
|
|
91
91
|
}
|
|
92
|
-
}
|
|
92
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@necrolab/dashboard",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.54",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "rm -rf dist && npx workbox-cli generateSW workbox-config.cjs && vite build",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@faker-js/faker": "^7.6.0",
|
|
17
17
|
"@msgpack/msgpack": "^3.0.0-beta2",
|
|
18
|
-
"@necrolab/tm-renderer": "^0.1.
|
|
18
|
+
"@necrolab/tm-renderer": "^0.1.10",
|
|
19
19
|
"@vitejs/plugin-vue": "^5.2.1",
|
|
20
20
|
"@vueuse/core": "^11.3.0",
|
|
21
21
|
"autoprefixer": "^10.4.21",
|
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
"ipaddr.js": "^2.2.0",
|
|
29
29
|
"pinia": "^2.3.0",
|
|
30
30
|
"postcss": "^8.4.49",
|
|
31
|
+
"prettier": "^3.5.3",
|
|
32
|
+
"prettier-plugin-tailwindcss": "^0.6.12",
|
|
31
33
|
"register-service-worker": "^1.7.2",
|
|
32
34
|
"sass": "^1.83.0",
|
|
33
35
|
"tailwindcss": "^3.4.17",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Row class="relative
|
|
3
|
-
<div class="
|
|
2
|
+
<Row class="relative grid-cols-10 gap-2 text-white lg:grid-cols-12" @click="ui.setOpenContextMenu('')">
|
|
3
|
+
<div class="absolute left-1 top-1 block md:hidden">
|
|
4
4
|
<h4
|
|
5
|
-
class="text-xs text-white
|
|
5
|
+
class="text-xs font-bold text-white"
|
|
6
6
|
style="
|
|
7
7
|
background: transparent !important;
|
|
8
8
|
border: none !important;
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
{{ props.task.taskId }}
|
|
17
17
|
</h4>
|
|
18
18
|
</div>
|
|
19
|
-
<div class="col-span-1
|
|
19
|
+
<div class="col-span-1 flex items-center justify-start lg:col-span-2">
|
|
20
20
|
<Checkbox
|
|
21
21
|
class="ml-2 mr-4 flex-shrink-0"
|
|
22
22
|
:toggled="props.task.selected"
|
|
23
23
|
@valueUpdate="ui.toggleTaskSelected(props.task.taskId)" />
|
|
24
24
|
<h4
|
|
25
|
-
class="task-event-id mx-auto hidden
|
|
25
|
+
class="task-event-id mx-auto hidden cursor-pointer text-white hover:text-light-300 lg:block"
|
|
26
26
|
@click="copy(props.task.eventId)">
|
|
27
27
|
{{ props.task.eventId }}
|
|
28
28
|
</h4>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<h4 class="text-white">
|
|
32
32
|
<span v-if="!props.task.reservedTicketsList">-</span>
|
|
33
33
|
<div v-else>
|
|
34
|
-
<div v-for="l in props.task.reservedTicketsList.split('
|
|
34
|
+
<div v-for="l in props.task.reservedTicketsList.split('\n')" :key="l">
|
|
35
35
|
<span v-if="!!l.trim()">{{ l.trim() }}</span>
|
|
36
36
|
</div>
|
|
37
37
|
</div>
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
</span>
|
|
46
46
|
</h4>
|
|
47
47
|
</div>
|
|
48
|
-
<div class="col-span-5 md:col-span-4 lg:col-span-5
|
|
48
|
+
<div class="col-span-5 justify-center text-center md:col-span-4 lg:col-span-5">
|
|
49
49
|
<div class="status-container">
|
|
50
50
|
<div
|
|
51
51
|
class="status-indicator"
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
<span class="status-text">{{ props.task.status }}</span>
|
|
60
60
|
</div>
|
|
61
61
|
</div>
|
|
62
|
-
<div class="col-span-2 lg:col-span-3
|
|
62
|
+
<div class="col-span-2 flex lg:col-span-3">
|
|
63
63
|
<ul class="task-buttons">
|
|
64
64
|
<li>
|
|
65
65
|
<button v-if="task.active" @click="ui.stopTask(task.taskId)">
|
|
@@ -91,14 +91,14 @@
|
|
|
91
91
|
</li>
|
|
92
92
|
</ul>
|
|
93
93
|
</div>
|
|
94
|
-
<div class="
|
|
95
|
-
<h4 class="text-center text-xs
|
|
94
|
+
<div class="absolute right-5 top-4 col-span-1 hidden items-center justify-center md:block lg:flex">
|
|
95
|
+
<h4 class="task-id text-center text-xs text-white">
|
|
96
96
|
{{ props.task.taskId }}
|
|
97
97
|
</h4>
|
|
98
98
|
</div>
|
|
99
99
|
<transition name="fade">
|
|
100
100
|
<div
|
|
101
|
-
class="col-span-10
|
|
101
|
+
class="col-span-10 flex flex-wrap gap-x-4 gap-y-4 pb-2 pt-8 will-change-auto lg:col-span-12 lg:gap-x-10 xl:justify-around"
|
|
102
102
|
v-if="props.task.isExpanded">
|
|
103
103
|
<!-- Details -->
|
|
104
104
|
<TaskLabel
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
<div
|
|
150
150
|
v-if="ui.openContextMenu === task.taskId"
|
|
151
151
|
ref="contextMenuRef"
|
|
152
|
-
class="
|
|
152
|
+
class="w-42 context-menu z-max fixed grid grid-cols-1 gap-1 rounded-lg border border-dark-650 bg-dark-500 p-1 text-white shadow-xl"
|
|
153
153
|
:style="contextMenuPosition">
|
|
154
154
|
<button class="btn-primary" @click="openInNewTab(`${ui.currentCountry.url}/event/${task.eventId}`)">
|
|
155
155
|
Open Event
|
|
@@ -171,30 +171,30 @@ h4 {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
.status-container {
|
|
174
|
-
@apply flex items-center justify-center
|
|
174
|
+
@apply mx-auto flex w-fit items-center justify-center rounded-lg border border-dark-650 bg-dark-500;
|
|
175
175
|
padding: 6px 12px;
|
|
176
176
|
gap: 6px;
|
|
177
177
|
transition: all 0.15s ease;
|
|
178
178
|
max-width: 100%;
|
|
179
179
|
|
|
180
180
|
&:hover {
|
|
181
|
-
@apply
|
|
181
|
+
@apply border-dark-700 bg-dark-550;
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
.status-text {
|
|
186
|
-
@apply
|
|
186
|
+
@apply truncate text-sm font-medium uppercase;
|
|
187
187
|
color: #e2e2e5;
|
|
188
188
|
letter-spacing: 0.025em;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
.task-buttons {
|
|
192
|
-
@apply flex items-center justify-center
|
|
192
|
+
@apply mx-auto flex items-center justify-center rounded border border-dark-650 bg-dark-500;
|
|
193
193
|
padding: 2px;
|
|
194
194
|
gap: 1px;
|
|
195
195
|
|
|
196
196
|
button {
|
|
197
|
-
@apply flex items-center justify-center
|
|
197
|
+
@apply relative flex items-center justify-center rounded border-0 outline-0 transition-all duration-150;
|
|
198
198
|
background: transparent;
|
|
199
199
|
width: 22px;
|
|
200
200
|
height: 22px;
|
|
@@ -226,7 +226,7 @@ h4 {
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
span {
|
|
229
|
-
@apply text-xs font-medium
|
|
229
|
+
@apply relative z-[1] text-xs font-medium;
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
|
|
@@ -1,188 +1,143 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
<div class="table-component">
|
|
3
|
+
<Header class="grid-cols-10 gap-2 text-center lg:grid-cols-12">
|
|
4
|
+
<div class="col-span-1 flex items-center justify-start lg:col-span-2">
|
|
5
|
+
<Checkbox
|
|
6
|
+
class="ml-2 mr-4 flex-shrink-0"
|
|
7
|
+
:toggled="ui.mainCheckbox.tasks"
|
|
8
|
+
@valueUpdate="ui.toggleMainCheckbox('tasks')"
|
|
9
|
+
:isHeader="true" />
|
|
10
|
+
<div class="mx-auto hidden items-center lg:flex" @click="ui.toggleSort('eventId')">
|
|
11
|
+
<EventIcon class="lg:mr-3" />
|
|
12
|
+
<h4 class="hidden lg:flex">Event</h4>
|
|
13
|
+
<DownIcon v-if="ui.sortData.sortBy === 'eventId' && !ui.sortData.reversed" class="ml-1" />
|
|
14
|
+
<UpIcon v-if="ui.sortData.sortBy === 'eventId' && ui.sortData.reversed" class="ml-1" />
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="flex-center col-span-2" v-once>
|
|
18
|
+
<TicketIcon class="mr-0 lg:mr-3" />
|
|
19
|
+
<h4 class="hidden lg:flex">Tickets</h4>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="flex-center col-span-5 md:col-span-4 lg:col-span-5" @click="ui.toggleSort('status')">
|
|
22
|
+
<StatusIcon class="mr-0 lg:mr-3" />
|
|
23
|
+
<h4 class="hidden lg:flex">Status</h4>
|
|
24
|
+
<DownIcon v-if="ui.sortData.sortBy === 'status' && !ui.sortData.reversed" class="ml-1" />
|
|
25
|
+
<UpIcon v-if="ui.sortData.sortBy === 'status' && ui.sortData.reversed" class="ml-1" />
|
|
26
|
+
</div>
|
|
27
|
+
<div class="flex-center col-span-2 lg:col-span-3" v-once>
|
|
28
|
+
<ClickIcon class="mr-0 lg:mr-3" />
|
|
29
|
+
<h4 class="hidden lg:flex">Actions</h4>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="absolute right-5 top-3.5 hidden items-center lg:flex" @click="ui.toggleSort('taskId')">
|
|
32
|
+
<h4 class="text-center text-xs">ID</h4>
|
|
33
|
+
<DownIcon v-if="ui.sortData.sortBy === 'taskId' && !ui.sortData.reversed" class="ml-1" />
|
|
34
|
+
<UpIcon v-if="ui.sortData.sortBy === 'taskId' && ui.sortData.reversed" class="ml-1" />
|
|
35
|
+
</div>
|
|
36
|
+
</Header>
|
|
11
37
|
<div
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
38
|
+
class="hidden-scrollbars stop-pan flex flex-col divide-y divide-dark-650 overflow-y-auto overflow-x-hidden"
|
|
39
|
+
:style="{ maxHeight: dynamicTableHeight }">
|
|
40
|
+
<div v-for="(task, i) in getTasksInOrder()" :key="task.taskId" class="task-row-container">
|
|
41
|
+
<Task :task="task" :class="i % 2 == 1 ? 'table-row-even' : 'table-row-odd'" />
|
|
42
|
+
</div>
|
|
43
|
+
<div
|
|
44
|
+
v-if="getTasksInOrder().length === 0"
|
|
45
|
+
class="empty-state flex flex-col items-center justify-center py-8 text-center">
|
|
46
|
+
<div
|
|
47
|
+
v-if="
|
|
48
|
+
!ui.queueStats.queued && !ui.queueStats.sleeping && ui.queueStats.nextQueuePasses.length === 0
|
|
49
|
+
">
|
|
50
|
+
<TasksIcon class="mx-auto mb-3 h-12 w-12 text-dark-400 opacity-50" />
|
|
51
|
+
<p class="text-sm text-light-400">No tasks yet</p>
|
|
52
|
+
<p class="mt-1 text-xs text-light-500">Create tasks to get started</p>
|
|
53
|
+
</div>
|
|
54
|
+
<div v-else>
|
|
55
|
+
<TasksIcon class="mx-auto mb-3 h-12 w-12 text-dark-400 opacity-50" />
|
|
56
|
+
<p class="text-sm text-light-400">No tasks match current filters</p>
|
|
57
|
+
<p class="mt-1 text-xs text-light-500">Adjust filters to see tasks</p>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
25
60
|
</div>
|
|
26
|
-
</div>
|
|
27
|
-
<div class="col-span-2 flex-center" v-once>
|
|
28
|
-
<TicketIcon class="mr-0 lg:mr-3" />
|
|
29
|
-
<h4 class="hidden lg:flex">Tickets</h4>
|
|
30
|
-
</div>
|
|
31
|
-
<div
|
|
32
|
-
class="col-span-5 md:col-span-4 lg:col-span-5 flex-center"
|
|
33
|
-
@click="ui.toggleSort('status')"
|
|
34
|
-
>
|
|
35
|
-
<StatusIcon class="mr-0 lg:mr-3" />
|
|
36
|
-
<h4 class="hidden lg:flex">Status</h4>
|
|
37
|
-
<DownIcon
|
|
38
|
-
v-if="ui.sortData.sortBy === 'status' && !ui.sortData.reversed"
|
|
39
|
-
class="ml-1"
|
|
40
|
-
/>
|
|
41
|
-
<UpIcon
|
|
42
|
-
v-if="ui.sortData.sortBy === 'status' && ui.sortData.reversed"
|
|
43
|
-
class="ml-1"
|
|
44
|
-
/>
|
|
45
|
-
</div>
|
|
46
|
-
<div class="col-span-2 lg:col-span-3 flex-center" v-once>
|
|
47
|
-
<ClickIcon class="mr-0 lg:mr-3" />
|
|
48
|
-
<h4 class="hidden lg:flex">Actions</h4>
|
|
49
|
-
</div>
|
|
50
|
-
<div
|
|
51
|
-
class="absolute right-5 hidden lg:flex items-center top-3.5"
|
|
52
|
-
@click="ui.toggleSort('taskId')"
|
|
53
|
-
>
|
|
54
|
-
<h4 class="text-center text-xs">ID</h4>
|
|
55
|
-
<DownIcon
|
|
56
|
-
v-if="ui.sortData.sortBy === 'taskId' && !ui.sortData.reversed"
|
|
57
|
-
class="ml-1"
|
|
58
|
-
/>
|
|
59
|
-
<UpIcon
|
|
60
|
-
v-if="ui.sortData.sortBy === 'taskId' && ui.sortData.reversed"
|
|
61
|
-
class="ml-1"
|
|
62
|
-
/>
|
|
63
|
-
</div>
|
|
64
|
-
</Header>
|
|
65
|
-
<div
|
|
66
|
-
class="flex flex-col divide-y divide-dark-650 overflow-y-auto hidden-scrollbars overflow-x-hidden stop-pan"
|
|
67
|
-
:style="{ maxHeight: dynamicTableHeight }"
|
|
68
|
-
>
|
|
69
|
-
<div
|
|
70
|
-
v-for="(task, i) in getTasksInOrder()"
|
|
71
|
-
:key="task.taskId"
|
|
72
|
-
class="task-row-container"
|
|
73
|
-
>
|
|
74
|
-
<Task :task="task" :class="i % 2 == 1 ? 'table-row-even' : 'table-row-odd'" />
|
|
75
|
-
</div>
|
|
76
|
-
<div
|
|
77
|
-
v-if="getTasksInOrder().length === 0"
|
|
78
|
-
class="flex flex-col items-center justify-center py-8 empty-state text-center"
|
|
79
|
-
>
|
|
80
|
-
<div
|
|
81
|
-
v-if="
|
|
82
|
-
!ui.queueStats.queued &&
|
|
83
|
-
!ui.queueStats.sleeping &&
|
|
84
|
-
ui.queueStats.nextQueuePasses.length === 0
|
|
85
|
-
"
|
|
86
|
-
>
|
|
87
|
-
<TasksIcon class="w-12 h-12 text-dark-400 mb-3 opacity-50 mx-auto" />
|
|
88
|
-
<p class="text-light-400 text-sm">No tasks yet</p>
|
|
89
|
-
<p class="text-light-500 text-xs mt-1">Create tasks to get started</p>
|
|
90
|
-
</div>
|
|
91
|
-
<div v-else>
|
|
92
|
-
<TasksIcon class="w-12 h-12 text-dark-400 mb-3 opacity-50 mx-auto" />
|
|
93
|
-
<p class="text-light-400 text-sm">No tasks match current filters</p>
|
|
94
|
-
<p class="text-light-500 text-xs mt-1">Adjust filters to see tasks</p>
|
|
95
|
-
</div>
|
|
96
|
-
</div>
|
|
97
61
|
</div>
|
|
98
|
-
</div>
|
|
99
62
|
</template>
|
|
100
63
|
<style lang="scss" scoped>
|
|
101
64
|
h4 {
|
|
102
|
-
|
|
65
|
+
@apply text-white;
|
|
103
66
|
}
|
|
104
67
|
|
|
105
68
|
.stop-pan {
|
|
106
|
-
|
|
69
|
+
touch-action: pan-y pan-up pan-down;
|
|
107
70
|
}
|
|
108
71
|
|
|
109
72
|
.task-row-container {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
73
|
+
min-height: 69px;
|
|
74
|
+
flex-shrink: 0;
|
|
75
|
+
transition: background-color 0.15s ease;
|
|
113
76
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
77
|
+
&:hover {
|
|
78
|
+
@apply bg-dark-550 !important;
|
|
79
|
+
}
|
|
117
80
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
81
|
+
@media (max-width: 768px) {
|
|
82
|
+
min-height: 58px;
|
|
83
|
+
}
|
|
121
84
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
85
|
+
@media (max-width: 480px) and (orientation: portrait) {
|
|
86
|
+
min-height: 50px;
|
|
87
|
+
}
|
|
125
88
|
}
|
|
126
89
|
|
|
127
90
|
.empty-state {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
91
|
+
@apply bg-dark-400;
|
|
92
|
+
color: #969696;
|
|
93
|
+
font-size: 14px;
|
|
94
|
+
font-weight: 500;
|
|
132
95
|
}
|
|
133
96
|
</style>
|
|
134
97
|
<script setup>
|
|
135
98
|
import { computed, ref, onMounted, onUnmounted } from "vue";
|
|
136
99
|
import { Table, Header } from "@/components/Table";
|
|
137
|
-
import {
|
|
138
|
-
EventIcon,
|
|
139
|
-
TicketIcon,
|
|
140
|
-
StatusIcon,
|
|
141
|
-
ClickIcon,
|
|
142
|
-
DownIcon,
|
|
143
|
-
UpIcon,
|
|
144
|
-
TasksIcon,
|
|
145
|
-
} from "@/components/icons";
|
|
100
|
+
import { EventIcon, TicketIcon, StatusIcon, ClickIcon, DownIcon, UpIcon, TasksIcon } from "@/components/icons";
|
|
146
101
|
import Task from "./Task.vue";
|
|
147
102
|
import Checkbox from "@/components/ui/controls/atomic/Checkbox.vue";
|
|
148
103
|
import { useUIStore } from "@/stores/ui";
|
|
149
104
|
|
|
150
105
|
const props = defineProps({
|
|
151
|
-
|
|
106
|
+
tasks: { type: Object }
|
|
152
107
|
});
|
|
153
108
|
|
|
154
109
|
const shouldTaskShow = (task) => {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
110
|
+
if (ui.taskFilter === "All") return true;
|
|
111
|
+
else if (ui.taskFilter === "Checkout") return task.expirationTime;
|
|
112
|
+
else return true;
|
|
158
113
|
};
|
|
159
114
|
|
|
160
115
|
const ui = useUIStore();
|
|
161
116
|
|
|
162
117
|
const siteIdEdgeCases = {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
118
|
+
LN_US: ["TM_US"],
|
|
119
|
+
TM_CA: ["TM_US"],
|
|
120
|
+
TM_IE: ["TM_UK"],
|
|
121
|
+
TM_NZ: ["TM_AU"]
|
|
167
122
|
};
|
|
168
123
|
|
|
169
124
|
const getTasksInOrder = () => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
125
|
+
let out = [];
|
|
126
|
+
ui.taskIdOrder.forEach((id) => {
|
|
127
|
+
if (props.tasks[id] && !props.tasks[id]?.hidden) {
|
|
128
|
+
const task = props.tasks[id];
|
|
129
|
+
|
|
130
|
+
if (
|
|
131
|
+
task.siteId !== ui.currentCountry.siteId &&
|
|
132
|
+
!siteIdEdgeCases[task.siteId]?.includes(ui.currentCountry.siteId)
|
|
133
|
+
)
|
|
134
|
+
return;
|
|
135
|
+
if (ui.currentEvent && task.eventId !== ui.currentEvent) return;
|
|
136
|
+
if (!shouldTaskShow(task)) return;
|
|
137
|
+
out.push(task);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
return out;
|
|
186
141
|
};
|
|
187
142
|
|
|
188
143
|
// Dynamic height calculation to prevent page scrolling
|
|
@@ -190,54 +145,42 @@ const windowHeight = ref(window.innerHeight);
|
|
|
190
145
|
const windowWidth = ref(window.innerWidth);
|
|
191
146
|
|
|
192
147
|
const updateDimensions = () => {
|
|
193
|
-
|
|
194
|
-
|
|
148
|
+
windowHeight.value = window.innerHeight;
|
|
149
|
+
windowWidth.value = window.innerWidth;
|
|
195
150
|
};
|
|
196
151
|
|
|
197
152
|
onMounted(() => {
|
|
198
|
-
|
|
153
|
+
window.addEventListener("resize", updateDimensions);
|
|
199
154
|
});
|
|
200
155
|
|
|
201
156
|
onUnmounted(() => {
|
|
202
|
-
|
|
157
|
+
window.removeEventListener("resize", updateDimensions);
|
|
203
158
|
});
|
|
204
159
|
|
|
205
160
|
const dynamicTableHeight = computed(() => {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
// Calculate row height based on screen size
|
|
232
|
-
const rowHeight = windowWidth.value <= 768 ? 58 : 69; // Mobile vs desktop row height
|
|
233
|
-
const minRowsToShow = 2; // Always show at least 2 rows
|
|
234
|
-
const minHeight = minRowsToShow * rowHeight;
|
|
235
|
-
|
|
236
|
-
// Calculate how many complete rows can fit
|
|
237
|
-
const maxCompleteRows =
|
|
238
|
-
Math.floor(Math.max(availableHeight, minHeight) / rowHeight) + 1;
|
|
239
|
-
const exactHeight = maxCompleteRows * rowHeight;
|
|
240
|
-
|
|
241
|
-
return exactHeight + "px";
|
|
161
|
+
// Calculate available space for table
|
|
162
|
+
const headerHeight = 60; // Header + navbar
|
|
163
|
+
const titleHeight = 50; // Tasks title and mobile controls
|
|
164
|
+
const statsHeight = 50; // Queue stats
|
|
165
|
+
const controlsHeight = windowWidth.value >= 650 ? 60 : 0; // Desktop controls
|
|
166
|
+
const filtersHeight = 50; // Event dropdown and filter toggle
|
|
167
|
+
const utilitiesHeight = windowWidth.value <= 480 && windowHeight.value > windowWidth.value ? 150 : 200; // Reduce utilities height in mobile portrait
|
|
168
|
+
const margins =
|
|
169
|
+
windowWidth.value >= 1024 ? 40 : windowWidth.value <= 480 && windowHeight.value > windowWidth.value ? 15 : 20; // Reduce margins in mobile portrait
|
|
170
|
+
|
|
171
|
+
const totalUsedSpace =
|
|
172
|
+
headerHeight + titleHeight + statsHeight + controlsHeight + filtersHeight + utilitiesHeight + margins;
|
|
173
|
+
const availableHeight = windowHeight.value - totalUsedSpace;
|
|
174
|
+
|
|
175
|
+
// Calculate row height based on screen size
|
|
176
|
+
const rowHeight = windowWidth.value <= 768 ? 58 : 69; // Mobile vs desktop row height
|
|
177
|
+
const minRowsToShow = 2; // Always show at least 2 rows
|
|
178
|
+
const minHeight = minRowsToShow * rowHeight;
|
|
179
|
+
|
|
180
|
+
// Calculate how many complete rows can fit
|
|
181
|
+
const maxCompleteRows = Math.floor(Math.max(availableHeight, minHeight) / rowHeight) + 1;
|
|
182
|
+
const exactHeight = maxCompleteRows * rowHeight;
|
|
183
|
+
|
|
184
|
+
return exactHeight + "px";
|
|
242
185
|
});
|
|
243
186
|
</script>
|
package/src/stores/sampleData.js
CHANGED
|
@@ -28,7 +28,7 @@ export default {
|
|
|
28
28
|
quantity: 8,
|
|
29
29
|
proxy: "http://events1597:yEXBe4Hs@23.26.22.61:61234",
|
|
30
30
|
eventId: "01005D5C92031D57",
|
|
31
|
-
reservedTicketsList: "
|
|
31
|
+
reservedTicketsList: "• 2x 301/E ($86.47) \n• 2x 306/U ($86.47) \n$345.88",
|
|
32
32
|
expirationTime: null,
|
|
33
33
|
doNotPay: false,
|
|
34
34
|
agedAccount: true,
|
|
@@ -63,7 +63,7 @@ export default {
|
|
|
63
63
|
quantity: 8,
|
|
64
64
|
proxy: "http://events1338:xN4PBVze@23.26.21.58:61234",
|
|
65
65
|
eventId: "01005D85964A1747",
|
|
66
|
-
reservedTicketsList: "
|
|
66
|
+
reservedTicketsList: "• 2x 301/E ($86.47) \n• 2x 306/U ($86.47) \n$345.88",
|
|
67
67
|
expirationTime: null,
|
|
68
68
|
doNotPay: false,
|
|
69
69
|
agedAccount: false,
|
package/src/stores/ui.js
CHANGED
|
@@ -103,8 +103,10 @@ export const useUIStore = defineStore("ui", () => {
|
|
|
103
103
|
const t1 = new Date();
|
|
104
104
|
for (const [key, value] of Object.entries(tasks.value)) {
|
|
105
105
|
if (value.expirationTime)
|
|
106
|
-
tasks.value[key]._timeLeftString =
|
|
107
|
-
|
|
106
|
+
tasks.value[key]._timeLeftString =
|
|
107
|
+
value.expirationTime == "Invalid Date"
|
|
108
|
+
? "No Cartholds"
|
|
109
|
+
: timeDifference(Date.parse(value.expirationTime), t1.getTime());
|
|
108
110
|
else tasks.value[key]._timeLeftString = undefined;
|
|
109
111
|
}
|
|
110
112
|
|