@necrolab/dashboard 0.4.32 → 0.4.34
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/.claude/settings.local.json +4 -1
- package/package.json +1 -1
- package/src/App.vue +0 -8
- package/src/assets/css/_input.scss +1 -1
- package/src/assets/css/main.scss +52 -5
- package/src/components/Editors/Account/Account.vue +101 -8
- package/src/components/Editors/Account/AccountView.vue +1 -0
- package/src/components/Editors/Account/CreateAccount.vue +10 -4
- package/src/components/Editors/Profile/CreateProfile.vue +134 -40
- package/src/components/Editors/Profile/Profile.vue +101 -8
- package/src/components/Editors/Profile/ProfileView.vue +1 -0
- package/src/components/Filter/Filter.vue +15 -3
- package/src/components/Tasks/Stats.vue +6 -6
- package/src/components/Tasks/Task.vue +140 -24
- package/src/components/Tasks/TaskView.vue +68 -21
- package/src/components/Tasks/Utilities.vue +4 -5
- package/src/components/ui/Modal.vue +12 -1
- package/src/components/ui/controls/atomic/Checkbox.vue +119 -9
- package/src/components/ui/controls/atomic/Dropdown.vue +8 -2
- package/src/components/ui/controls/atomic/MultiDropdown.vue +2 -1
- package/src/stores/sampleData.js +45 -79
- package/src/utils/debug.js +1 -1
- package/src/views/Console.vue +16 -9
- package/src/views/FilterBuilder.vue +43 -21
- package/src/views/Tasks.vue +19 -73
|
@@ -77,28 +77,76 @@ h4 {
|
|
|
77
77
|
@apply text-center;
|
|
78
78
|
}
|
|
79
79
|
.task-buttons {
|
|
80
|
-
@apply flex
|
|
81
|
-
|
|
80
|
+
@apply flex items-center justify-center mx-auto;
|
|
81
|
+
background: linear-gradient(135deg, rgba(45, 47, 74, 0.8), rgba(32, 32, 54, 0.9));
|
|
82
|
+
border: 1px solid rgba(74, 74, 97, 0.3);
|
|
83
|
+
border-radius: 10px;
|
|
84
|
+
padding: 2px;
|
|
85
|
+
gap: 1px;
|
|
86
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
87
|
+
backdrop-filter: blur(8px);
|
|
88
|
+
|
|
82
89
|
button {
|
|
83
|
-
@apply
|
|
90
|
+
@apply flex items-center justify-center text-white transition-all duration-150 border-0 outline-0 relative;
|
|
91
|
+
background: transparent;
|
|
92
|
+
border-radius: 7px;
|
|
93
|
+
width: 28px;
|
|
94
|
+
height: 28px;
|
|
95
|
+
position: relative;
|
|
96
|
+
|
|
97
|
+
&:hover {
|
|
98
|
+
background: rgba(74, 74, 97, 0.3);
|
|
99
|
+
transform: scale(1.05);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
&:active {
|
|
103
|
+
background: rgba(74, 74, 97, 0.5);
|
|
104
|
+
transform: scale(0.95);
|
|
105
|
+
}
|
|
84
106
|
}
|
|
85
|
-
|
|
107
|
+
|
|
86
108
|
svg {
|
|
87
|
-
|
|
109
|
+
width: 14px;
|
|
110
|
+
height: 14px;
|
|
111
|
+
position: relative;
|
|
112
|
+
z-index: 1;
|
|
113
|
+
|
|
114
|
+
path {
|
|
115
|
+
fill: currentColor;
|
|
116
|
+
}
|
|
88
117
|
}
|
|
89
|
-
|
|
118
|
+
|
|
90
119
|
img {
|
|
91
|
-
|
|
120
|
+
width: 14px;
|
|
121
|
+
height: 14px;
|
|
122
|
+
position: relative;
|
|
123
|
+
z-index: 1;
|
|
92
124
|
}
|
|
93
125
|
}
|
|
94
126
|
|
|
127
|
+
// Tablet optimization
|
|
95
128
|
@media (max-width: 1024px) {
|
|
96
129
|
h4 {
|
|
97
130
|
font-size: 10px !important;
|
|
98
131
|
}
|
|
132
|
+
|
|
99
133
|
.task-buttons {
|
|
100
|
-
|
|
134
|
+
padding: 2px;
|
|
135
|
+
gap: 1px;
|
|
136
|
+
border-radius: 8px;
|
|
137
|
+
|
|
138
|
+
button {
|
|
139
|
+
width: 26px;
|
|
140
|
+
height: 26px;
|
|
141
|
+
border-radius: 6px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
svg, img {
|
|
145
|
+
width: 13px;
|
|
146
|
+
height: 13px;
|
|
147
|
+
}
|
|
101
148
|
}
|
|
149
|
+
|
|
102
150
|
.task-id {
|
|
103
151
|
font-size: 6px !important;
|
|
104
152
|
margin-right: -12px;
|
|
@@ -108,6 +156,51 @@ h4 {
|
|
|
108
156
|
font-size: 7px !important;
|
|
109
157
|
}
|
|
110
158
|
}
|
|
159
|
+
|
|
160
|
+
// Mobile optimization
|
|
161
|
+
@media (max-width: 768px) {
|
|
162
|
+
.task-buttons {
|
|
163
|
+
padding: 1px;
|
|
164
|
+
gap: 0;
|
|
165
|
+
border-radius: 7px;
|
|
166
|
+
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
167
|
+
|
|
168
|
+
button {
|
|
169
|
+
width: 22px;
|
|
170
|
+
height: 22px;
|
|
171
|
+
border-radius: 5px;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
svg, img {
|
|
175
|
+
width: 11px;
|
|
176
|
+
height: 11px;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// iPhone vertical (portrait) specific
|
|
182
|
+
@media (max-width: 480px) and (orientation: portrait) {
|
|
183
|
+
.task-buttons {
|
|
184
|
+
padding: 1px;
|
|
185
|
+
gap: 0;
|
|
186
|
+
border-radius: 6px;
|
|
187
|
+
|
|
188
|
+
button {
|
|
189
|
+
width: 18px;
|
|
190
|
+
height: 18px;
|
|
191
|
+
border-radius: 4px;
|
|
192
|
+
|
|
193
|
+
&:hover {
|
|
194
|
+
transform: scale(1.1);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
svg, img {
|
|
199
|
+
width: 9px;
|
|
200
|
+
height: 9px;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
111
204
|
</style>
|
|
112
205
|
<script setup>
|
|
113
206
|
import { Row } from "@/components/Table";
|
|
@@ -288,11 +288,23 @@ props.filterBuilder.onUpdate(() => {
|
|
|
288
288
|
|
|
289
289
|
<style scoped>
|
|
290
290
|
.filter-card {
|
|
291
|
-
@apply bg-dark-500 border
|
|
291
|
+
@apply bg-dark-500 border-dark-550 relative;
|
|
292
|
+
border: 1px solid rgba(74, 74, 97, 0.3);
|
|
293
|
+
margin-bottom: 8px;
|
|
294
|
+
transition: all 0.15s ease-out;
|
|
292
295
|
}
|
|
293
296
|
|
|
294
|
-
.filter-card:not(
|
|
295
|
-
border-
|
|
297
|
+
.filter-card:hover:not(.expanded-filter) {
|
|
298
|
+
border-color: rgba(74, 74, 97, 0.6);
|
|
299
|
+
background-color: rgba(45, 47, 74, 0.8);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.expanded-filter:hover {
|
|
303
|
+
border-color: rgba(74, 74, 97, 0.8);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.filter-card + .filter-card {
|
|
307
|
+
border-top: 1px solid rgba(74, 74, 97, 0.2);
|
|
296
308
|
}
|
|
297
309
|
|
|
298
310
|
.filter-type-badge {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="flex text-white font-bold lg:gap-5 gap-1" v-if="show" :key="key">
|
|
2
|
+
<div class="flex text-white font-bold lg:gap-5 gap-1 lg:mb-2 mb-1" v-if="show" :key="key">
|
|
3
3
|
<div
|
|
4
4
|
v-if="ui.queueStats.total"
|
|
5
|
-
class="bg-dark-500 mb-
|
|
5
|
+
class="bg-dark-500 lg:mb-2 mb-1 text-sm rounded-lg lg:p-2 p-1 lg:gap-3 gap-2 flex justify-between"
|
|
6
6
|
>
|
|
7
7
|
<h2 class="font-bold text-sm flex items-center gap-1 scale-100">
|
|
8
8
|
<img width="14px" src="@/assets/img/wildcard.svg" />Total MQM
|
|
@@ -11,21 +11,21 @@
|
|
|
11
11
|
</div>
|
|
12
12
|
<div
|
|
13
13
|
v-if="ui.queueStats.queued"
|
|
14
|
-
class="bg-dark-500 mb-
|
|
14
|
+
class="bg-dark-500 lg:mb-2 mb-1 text-sm rounded-lg lg:p-2 p-1 lg:gap-3 gap-2 flex justify-between"
|
|
15
15
|
>
|
|
16
16
|
<h2 class="font-bold text-sm flex items-center gap-1"><SkiIcon />Queued</h2>
|
|
17
17
|
<span class="text-light-400 text-sm font-black flex justify-center">{{ ui.queueStats.queued }} </span>
|
|
18
18
|
</div>
|
|
19
19
|
<div
|
|
20
20
|
v-if="ui.queueStats.sleeping"
|
|
21
|
-
class="bg-dark-500 mb-
|
|
21
|
+
class="bg-dark-500 lg:mb-2 mb-1 text-sm rounded-lg lg:p-2 p-1 lg:gap-3 gap-2 flex justify-between"
|
|
22
22
|
>
|
|
23
23
|
<h2 class="font-bold text-sm flex items-center gap-1"><TimerIcon />Sleeping</h2>
|
|
24
24
|
<span class="text-light-400 text-sm font-black flex justify-center">{{ ui.queueStats.sleeping }} </span>
|
|
25
25
|
</div>
|
|
26
26
|
<div
|
|
27
27
|
v-if="ui.queueStats.nextQueuePasses.length > 0"
|
|
28
|
-
class="bg-dark-500 mb-5 rounded-lg text-sm flex justify-between lg:p-2 p-1 lg:gap-3 gap-2"
|
|
28
|
+
class="bg-dark-500 lg:mb-5 mb-2 rounded-lg text-sm flex justify-between lg:p-2 p-1 lg:gap-3 gap-2"
|
|
29
29
|
>
|
|
30
30
|
<h2 class="font-bold flex text-sm items-center gap-1">
|
|
31
31
|
<CartIcon /><span class="sm:block hidden">Next Passes</span>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
</div>
|
|
38
38
|
<!-- <div
|
|
39
39
|
v-if="ui.queueStats.carts"
|
|
40
|
-
class="bg-dark-500 mb-
|
|
40
|
+
class="bg-dark-500 mb-2 text-sm rounded-lg lg:p-2 p-1 lg:gap-3 gap-2 flex justify-between"
|
|
41
41
|
>
|
|
42
42
|
<h2 class="font-bold text-sm flex items-center gap-1"><CartIcon />Carts</h2>
|
|
43
43
|
<span class="text-light-400 text-sm font-black flex justify-center">{{ ui.queueStats.sleeping }} </span>
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
{{ console.log(task) }}
|
|
3
2
|
<Row
|
|
4
3
|
class="relative text-white grid-cols-12 gap-2"
|
|
5
4
|
@click="ui.setOpenContextMenu('')"
|
|
6
5
|
@click.right.prevent="ui.setOpenContextMenu('')"
|
|
7
6
|
>
|
|
8
|
-
<div class="block md:hidden absolute left-1 top-
|
|
9
|
-
<h4 class="text-xs task-id text-white">
|
|
7
|
+
<div class="block md:hidden absolute left-1 top-1">
|
|
8
|
+
<h4 class="text-xs task-id text-white font-bold">
|
|
10
9
|
{{ props.task.taskId }}
|
|
11
10
|
</h4>
|
|
12
11
|
</div>
|
|
13
|
-
<div class="col-span-1 lg:col-span-2 flex">
|
|
12
|
+
<div class="col-span-1 lg:col-span-2 flex items-center justify-start">
|
|
14
13
|
<Checkbox
|
|
15
|
-
class="ml-
|
|
14
|
+
class="ml-2 mr-4 flex-shrink-0"
|
|
16
15
|
:toggled="props.task.selected"
|
|
17
16
|
@valueUpdate="ui.toggleTaskSelected(props.task.taskId)"
|
|
18
17
|
/>
|
|
19
|
-
<h4 class="task-id
|
|
18
|
+
<h4 class="task-event-id mx-auto hidden lg:block text-white cursor-pointer hover:text-light-300" @click="copy(props.task.eventId)">
|
|
20
19
|
{{ props.task.eventId }}
|
|
21
20
|
</h4>
|
|
22
21
|
</div>
|
|
23
|
-
<div class="col-span-2 hidden
|
|
22
|
+
<div class="col-span-2 hidden lg:block">
|
|
24
23
|
<h4 class="text-white">{{ props.task.quantity }}</h4>
|
|
25
24
|
</div>
|
|
26
25
|
<div class="col-span-2">
|
|
@@ -86,12 +85,9 @@
|
|
|
86
85
|
<TrashIcon />
|
|
87
86
|
</button>
|
|
88
87
|
</li>
|
|
89
|
-
<li
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
>
|
|
93
|
-
<button class="mt-1" @click="props.task.isExpanded = !props.task.isExpanded">
|
|
94
|
-
<span>{{ props.task.isExpanded ? "-" : "+" }}</span>
|
|
88
|
+
<li @click.right.prevent="window.setTimeout(() => ui.setOpenContextMenu(task.taskId), 10)">
|
|
89
|
+
<button @click="props.task.isExpanded = !props.task.isExpanded">
|
|
90
|
+
<span>{{ props.task.isExpanded ? "−" : "+" }}</span>
|
|
95
91
|
</button>
|
|
96
92
|
</li>
|
|
97
93
|
</ul>
|
|
@@ -129,7 +125,6 @@
|
|
|
129
125
|
/>
|
|
130
126
|
<TaskLabel v-if="!props.task.email && !props.task.password" image="mail" text="No account chosen yet" />
|
|
131
127
|
<TaskLabel v-if="props.task.profileName" image="profile" :text="props.task.profileName" />
|
|
132
|
-
<TaskLabel image="camera" :text="props.task.proxy" @click="copy(props.task.proxy)" />
|
|
133
128
|
<TaskLabel image="timer" :text="props.task.smartTimer ? 'On' : 'Off'" />
|
|
134
129
|
<TaskLabel image="groups" :text="props.task.loginAfterCart ? 'On' : 'Off'" />
|
|
135
130
|
<TaskLabel image="hand" :text="props.task.manual ? 'On' : 'Off'" />
|
|
@@ -184,18 +179,73 @@ h4 {
|
|
|
184
179
|
}
|
|
185
180
|
|
|
186
181
|
.task-buttons {
|
|
187
|
-
@apply flex
|
|
182
|
+
@apply flex items-center justify-center mx-auto;
|
|
183
|
+
background: linear-gradient(135deg, rgba(45, 47, 74, 0.8), rgba(32, 32, 54, 0.9));
|
|
184
|
+
border: 1px solid rgba(74, 74, 97, 0.3);
|
|
185
|
+
border-radius: 10px;
|
|
186
|
+
padding: 2px;
|
|
187
|
+
gap: 1px;
|
|
188
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
189
|
+
backdrop-filter: blur(8px);
|
|
188
190
|
|
|
189
191
|
button {
|
|
190
|
-
@apply
|
|
191
|
-
|
|
192
|
+
@apply flex items-center justify-center text-white transition-all duration-150 border-0 outline-0 relative;
|
|
193
|
+
background: transparent;
|
|
194
|
+
border-radius: 7px;
|
|
195
|
+
width: 28px;
|
|
196
|
+
height: 28px;
|
|
192
197
|
|
|
193
|
-
|
|
194
|
-
|
|
198
|
+
&:hover {
|
|
199
|
+
background: rgba(74, 74, 97, 0.3);
|
|
200
|
+
transform: scale(1.05);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
&:active {
|
|
204
|
+
background: rgba(74, 74, 97, 0.5);
|
|
205
|
+
transform: scale(0.95);
|
|
206
|
+
}
|
|
195
207
|
}
|
|
196
208
|
|
|
209
|
+
svg,
|
|
197
210
|
img {
|
|
198
|
-
|
|
211
|
+
width: 14px;
|
|
212
|
+
height: 14px;
|
|
213
|
+
position: relative;
|
|
214
|
+
z-index: 1;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
svg path {
|
|
218
|
+
fill: currentColor;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
span {
|
|
222
|
+
@apply text-sm font-medium relative z-[1];
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.task-id {
|
|
227
|
+
font-size: 10px;
|
|
228
|
+
font-weight: 600;
|
|
229
|
+
letter-spacing: 0.5px;
|
|
230
|
+
margin: 0;
|
|
231
|
+
color: #a7a8af;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.task-id-alt {
|
|
235
|
+
font-size: 7px;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.task-event-id {
|
|
239
|
+
font-size: 11px;
|
|
240
|
+
font-weight: 500;
|
|
241
|
+
text-align: center;
|
|
242
|
+
|
|
243
|
+
@media (max-width: 1024px) {
|
|
244
|
+
font-size: 10px;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
@media (max-width: 768px) {
|
|
248
|
+
font-size: 9px;
|
|
199
249
|
}
|
|
200
250
|
}
|
|
201
251
|
|
|
@@ -205,15 +255,81 @@ h4 {
|
|
|
205
255
|
}
|
|
206
256
|
|
|
207
257
|
.task-buttons {
|
|
208
|
-
|
|
258
|
+
padding: 2px;
|
|
259
|
+
gap: 1px;
|
|
260
|
+
border-radius: 8px;
|
|
261
|
+
|
|
262
|
+
button {
|
|
263
|
+
width: 26px;
|
|
264
|
+
height: 26px;
|
|
265
|
+
border-radius: 6px;
|
|
266
|
+
}
|
|
267
|
+
svg,
|
|
268
|
+
img {
|
|
269
|
+
width: 13px;
|
|
270
|
+
height: 13px;
|
|
271
|
+
}
|
|
209
272
|
}
|
|
210
273
|
|
|
211
274
|
.task-id {
|
|
212
|
-
font-size:
|
|
275
|
+
font-size: 8px;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
@media (max-width: 768px) {
|
|
280
|
+
.task-buttons {
|
|
281
|
+
padding: 1px;
|
|
282
|
+
gap: 0;
|
|
283
|
+
border-radius: 7px;
|
|
284
|
+
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
285
|
+
|
|
286
|
+
button {
|
|
287
|
+
width: 22px;
|
|
288
|
+
height: 22px;
|
|
289
|
+
border-radius: 5px;
|
|
290
|
+
}
|
|
291
|
+
svg,
|
|
292
|
+
img {
|
|
293
|
+
width: 11px;
|
|
294
|
+
height: 11px;
|
|
295
|
+
}
|
|
296
|
+
span {
|
|
297
|
+
font-size: 10px;
|
|
298
|
+
}
|
|
213
299
|
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
@media (max-width: 480px) and (orientation: portrait) {
|
|
303
|
+
.task-id {
|
|
304
|
+
font-size: 11px;
|
|
305
|
+
font-weight: 600;
|
|
306
|
+
letter-spacing: 0.4px;
|
|
307
|
+
color: #c9cad1;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.task-buttons {
|
|
311
|
+
padding: 1px;
|
|
312
|
+
gap: 0;
|
|
313
|
+
border-radius: 6px;
|
|
314
|
+
|
|
315
|
+
button {
|
|
316
|
+
width: 18px;
|
|
317
|
+
height: 18px;
|
|
318
|
+
border-radius: 4px;
|
|
319
|
+
|
|
320
|
+
&:hover {
|
|
321
|
+
transform: scale(1.1);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
214
324
|
|
|
215
|
-
|
|
216
|
-
|
|
325
|
+
svg,
|
|
326
|
+
img {
|
|
327
|
+
width: 9px;
|
|
328
|
+
height: 9px;
|
|
329
|
+
}
|
|
330
|
+
span {
|
|
331
|
+
font-size: 9px;
|
|
332
|
+
}
|
|
217
333
|
}
|
|
218
334
|
}
|
|
219
335
|
</style>
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Table>
|
|
3
3
|
<Header class="text-center grid-cols-12 gap-2">
|
|
4
|
-
<div class="col-span-1 lg:col-span-2 flex">
|
|
5
|
-
<Checkbox
|
|
6
|
-
|
|
4
|
+
<div class="col-span-1 lg:col-span-2 flex items-center justify-start">
|
|
5
|
+
<Checkbox
|
|
6
|
+
class="ml-2 mr-4"
|
|
7
|
+
:toggled="ui.mainCheckbox.tasks"
|
|
8
|
+
@valueUpdate="ui.toggleMainCheckbox('tasks')"
|
|
9
|
+
:isHeader="true"
|
|
10
|
+
/>
|
|
11
|
+
<div class="mx-auto hidden lg:flex items-center" @click="ui.toggleSort('eventId')">
|
|
7
12
|
<EventIcon class="ipadlg:mr-3" />
|
|
8
13
|
<h4 class="hidden ipadlg:flex">Event</h4>
|
|
9
14
|
<DownIcon v-if="ui.sortData.sortBy === 'eventId' && !ui.sortData.reversed" class="ml-1" />
|
|
10
15
|
<UpIcon v-if="ui.sortData.sortBy === 'eventId' && ui.sortData.reversed" class="ml-1" />
|
|
11
16
|
</div>
|
|
12
17
|
</div>
|
|
13
|
-
<div class="col-span-2 items-center justify-center hidden
|
|
18
|
+
<div class="col-span-2 items-center justify-center hidden lg:flex" v-once>
|
|
14
19
|
<CartIcon class="mr-0 ipadlg:mr-3" />
|
|
15
20
|
|
|
16
21
|
<h4 class="hidden ipadlg:flex">Quantity</h4>
|
|
@@ -39,14 +44,20 @@
|
|
|
39
44
|
</div>
|
|
40
45
|
</Header>
|
|
41
46
|
<div
|
|
42
|
-
class="flex flex-col divide-y-2 divide-border overflow-y-auto hidden-scrollbars overflow-x-hidden stop-pan
|
|
47
|
+
class="flex flex-col divide-y-2 divide-border overflow-y-auto hidden-scrollbars overflow-x-hidden stop-pan border-l-2 border-r-2 border-b-2 border-border"
|
|
48
|
+
:style="{ maxHeight: dynamicTableHeight }"
|
|
43
49
|
>
|
|
44
|
-
<div
|
|
45
|
-
|
|
50
|
+
<div
|
|
51
|
+
v-for="(task, i) in getTasksInOrder()"
|
|
52
|
+
:key="task.taskId"
|
|
53
|
+
:class="[i % 2 == 1 ? 'bg-dark-500' : 'bg-dark-550']"
|
|
54
|
+
class="task-row-container"
|
|
55
|
+
>
|
|
56
|
+
<Task :task="task" />
|
|
46
57
|
</div>
|
|
47
58
|
<div
|
|
48
59
|
v-if="getTasksInOrder().length === 0"
|
|
49
|
-
class="flex justify-center text-light-400 py-2 bg-dark-500
|
|
60
|
+
class="flex justify-center text-light-400 py-2 bg-dark-500"
|
|
50
61
|
>
|
|
51
62
|
<span v-if="ui.queueStats.total === 0"> No tasks yet.</span>
|
|
52
63
|
<span v-else>{{ ui.queueStats.total }} hidden task{{ ui.queueStats.total === 1 ? "" : "s" }}</span>
|
|
@@ -63,23 +74,17 @@ h4 {
|
|
|
63
74
|
touch-action: pan-y pan-up pan-down;
|
|
64
75
|
}
|
|
65
76
|
|
|
66
|
-
.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@media
|
|
71
|
-
|
|
72
|
-
max-height: 45vh !important;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
@media only screen and (min-device-width: 768px) and (max-device-width: 1366px) and (orientation: portrait) and (-webkit-min-device-pixel-ratio: 2) {
|
|
77
|
-
.tasks-table-height {
|
|
78
|
-
max-height: 58vh !important;
|
|
77
|
+
.task-row-container {
|
|
78
|
+
min-height: 69px;
|
|
79
|
+
flex-shrink: 0;
|
|
80
|
+
|
|
81
|
+
@media (max-width: 768px) {
|
|
82
|
+
min-height: 58px;
|
|
79
83
|
}
|
|
80
84
|
}
|
|
81
85
|
</style>
|
|
82
86
|
<script setup>
|
|
87
|
+
import { computed, ref, onMounted, onUnmounted } from "vue";
|
|
83
88
|
import { Table, Header } from "@/components/Table";
|
|
84
89
|
import { EventIcon, CartIcon, TicketIcon, StatusIcon, ClickIcon, DownIcon, UpIcon } from "@/components/icons";
|
|
85
90
|
import Task from "./Task.vue";
|
|
@@ -123,4 +128,46 @@ const getTasksInOrder = () => {
|
|
|
123
128
|
});
|
|
124
129
|
return out;
|
|
125
130
|
};
|
|
131
|
+
|
|
132
|
+
// Dynamic height calculation to prevent page scrolling
|
|
133
|
+
const windowHeight = ref(window.innerHeight);
|
|
134
|
+
const windowWidth = ref(window.innerWidth);
|
|
135
|
+
|
|
136
|
+
const updateDimensions = () => {
|
|
137
|
+
windowHeight.value = window.innerHeight;
|
|
138
|
+
windowWidth.value = window.innerWidth;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
onMounted(() => {
|
|
142
|
+
window.addEventListener('resize', updateDimensions);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
onUnmounted(() => {
|
|
146
|
+
window.removeEventListener('resize', updateDimensions);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const dynamicTableHeight = computed(() => {
|
|
150
|
+
// Calculate available space for table
|
|
151
|
+
const headerHeight = 60; // Header + navbar
|
|
152
|
+
const titleHeight = 50; // Tasks title and mobile controls
|
|
153
|
+
const statsHeight = 50; // Queue stats
|
|
154
|
+
const controlsHeight = windowWidth.value >= 650 ? 60 : 0; // Desktop controls
|
|
155
|
+
const filtersHeight = 50; // Event dropdown and filter toggle
|
|
156
|
+
const utilitiesHeight = windowWidth.value <= 480 && windowHeight.value > windowWidth.value ? 150 : 200; // Reduce utilities height in mobile portrait
|
|
157
|
+
const margins = windowWidth.value >= 1024 ? 40 : (windowWidth.value <= 480 && windowHeight.value > windowWidth.value ? 15 : 20); // Reduce margins in mobile portrait
|
|
158
|
+
|
|
159
|
+
const totalUsedSpace = headerHeight + titleHeight + statsHeight + controlsHeight + filtersHeight + utilitiesHeight + margins;
|
|
160
|
+
const availableHeight = windowHeight.value - totalUsedSpace;
|
|
161
|
+
|
|
162
|
+
// Calculate row height based on screen size
|
|
163
|
+
const rowHeight = windowWidth.value <= 768 ? 58 : 69; // Mobile vs desktop row height
|
|
164
|
+
const minRowsToShow = 2; // Always show at least 2 rows
|
|
165
|
+
const minHeight = minRowsToShow * rowHeight;
|
|
166
|
+
|
|
167
|
+
// Calculate how many complete rows can fit
|
|
168
|
+
const maxCompleteRows = Math.floor(Math.max(availableHeight, minHeight) / rowHeight);
|
|
169
|
+
const exactHeight = maxCompleteRows * rowHeight;
|
|
170
|
+
|
|
171
|
+
return exactHeight + 'px';
|
|
172
|
+
});
|
|
126
173
|
</script>
|
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
<div class="grid grid-cols-1 gap-3 lg:grid-cols-1" v-once v-if="ui.currentModule == 'TM'">
|
|
3
3
|
<div class="lg:justify-self-end">
|
|
4
4
|
<h4 class="hidden lg:block text-white opacity-40 uppercase font-medium">Utils</h4>
|
|
5
|
-
<div class="flex gap-3">
|
|
5
|
+
<div class="flex gap-3 justify-between lg:justify-start">
|
|
6
6
|
<button class="button-default active:opacity-50 w-44" @click="ui.toggleModal('scrape-venue')">
|
|
7
|
-
<ScrapeIcon />
|
|
8
|
-
Scrape Venue
|
|
7
|
+
<ScrapeIcon />Scrape Venue
|
|
9
8
|
</button>
|
|
10
9
|
<button class="button-default w-44" @click="ui.toggleModal('check-stock')">
|
|
11
10
|
<BoxIcon />Check Stock
|
|
12
11
|
</button>
|
|
13
|
-
<!-- Mobile Label -->
|
|
14
12
|
</div>
|
|
15
13
|
<h4 class="text-white opacity-40 uppercase font-medium block lg:hidden">Utils</h4>
|
|
16
14
|
</div>
|
|
@@ -24,9 +22,10 @@ const ui = useUIStore();
|
|
|
24
22
|
</script>
|
|
25
23
|
<style lang="scss" scoped>
|
|
26
24
|
button {
|
|
27
|
-
height: 50px;
|
|
28
25
|
@apply bg-dark-400 text-xs flex items-center justify-center gap-x-2 border border-light-300 hover:border-light-400;
|
|
26
|
+
height: 50px;
|
|
29
27
|
}
|
|
28
|
+
|
|
30
29
|
h4 {
|
|
31
30
|
font-size: 12px;
|
|
32
31
|
}
|
|
@@ -33,6 +33,7 @@ onClickOutside(target, (event) => {
|
|
|
33
33
|
background-color: rgba(17, 17, 17, 0.85);
|
|
34
34
|
backdrop-filter: blur(4px);
|
|
35
35
|
}
|
|
36
|
+
|
|
36
37
|
.component-modal {
|
|
37
38
|
margin: auto;
|
|
38
39
|
width: 640px;
|
|
@@ -50,12 +51,22 @@ onClickOutside(target, (event) => {
|
|
|
50
51
|
@apply flex flex-col;
|
|
51
52
|
}
|
|
52
53
|
}
|
|
54
|
+
|
|
53
55
|
@media (max-width: 810px) {
|
|
56
|
+
.modal-mask {
|
|
57
|
+
@apply items-start pt-4;
|
|
58
|
+
padding-bottom: 2rem;
|
|
59
|
+
}
|
|
60
|
+
|
|
54
61
|
.component-modal {
|
|
55
62
|
width: calc(100vw - 2rem);
|
|
56
|
-
max-height: calc(100vh -
|
|
63
|
+
max-height: calc(100vh - 6rem);
|
|
57
64
|
overflow-y: auto;
|
|
58
65
|
margin: 1rem;
|
|
59
66
|
}
|
|
67
|
+
|
|
68
|
+
.modal-body {
|
|
69
|
+
padding-bottom: 1rem;
|
|
70
|
+
}
|
|
60
71
|
}
|
|
61
72
|
</style>
|