@necrolab/dashboard 0.4.49 → 0.4.50
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 +12 -1
- package/package.json +1 -1
- package/src/components/Auth/LoginForm.vue +51 -8
- package/src/components/Tasks/Stats.vue +1 -2
- package/src/components/Tasks/Task.vue +33 -23
- package/src/components/Tasks/TaskView.vue +185 -123
- package/src/stores/sampleData.js +4 -2
- package/src/stores/ui.js +4 -3
- package/src/views/Accounts.vue +10 -17
- package/src/views/Console.vue +10 -3
- package/src/views/Editor.vue +1 -1
- package/src/views/Login.vue +65 -119
- package/src/views/Tasks.vue +5 -5
- package/static/offline.html +192 -50
package/.prettierrc
CHANGED
|
@@ -11,12 +11,23 @@
|
|
|
11
11
|
"htmlWhitespaceSensitivity": "ignore",
|
|
12
12
|
"bracketSameLine": true,
|
|
13
13
|
"singleAttributePerLine": false,
|
|
14
|
+
"endOfLine": "lf",
|
|
14
15
|
"overrides": [
|
|
15
16
|
{
|
|
16
17
|
"files": "*.vue",
|
|
17
18
|
"options": {
|
|
18
19
|
"vueIndentScriptAndStyle": false,
|
|
19
|
-
"htmlWhitespaceSensitivity": "ignore"
|
|
20
|
+
"htmlWhitespaceSensitivity": "ignore",
|
|
21
|
+
"singleAttributePerLine": false,
|
|
22
|
+
"bracketSameLine": true,
|
|
23
|
+
"printWidth": 120,
|
|
24
|
+
"tabWidth": 4,
|
|
25
|
+
"useTabs": false,
|
|
26
|
+
"semi": true,
|
|
27
|
+
"singleQuote": false,
|
|
28
|
+
"trailingComma": "none",
|
|
29
|
+
"bracketSpacing": true,
|
|
30
|
+
"arrowParens": "always"
|
|
20
31
|
}
|
|
21
32
|
}
|
|
22
33
|
]
|
package/package.json
CHANGED
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
<div class="form-section">
|
|
3
3
|
<!-- Username -->
|
|
4
4
|
<div class="input-wrapper mb-4">
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
<label class="label-override">
|
|
6
|
+
<span>Username</span>
|
|
7
|
+
<ProfileIcon class="ml-2" />
|
|
8
|
+
</label>
|
|
9
9
|
<div class="input-default">
|
|
10
10
|
<input v-model="user" placeholder="Username" />
|
|
11
11
|
</div>
|
|
12
12
|
</div>
|
|
13
13
|
<!-- Password -->
|
|
14
14
|
<div class="input-wrapper">
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
<label class="label-override">
|
|
16
|
+
<span>Password</span>
|
|
17
|
+
<KeyIcon class="ml-2" />
|
|
18
|
+
</label>
|
|
19
19
|
<div class="input-default">
|
|
20
20
|
<input v-model="password" type="password" placeholder="Password" />
|
|
21
21
|
</div>
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
</button>
|
|
31
31
|
</div>
|
|
32
32
|
</template>
|
|
33
|
+
|
|
33
34
|
<script setup>
|
|
34
35
|
import { useUIStore } from "@/stores/ui";
|
|
35
36
|
import { ref } from "vue";
|
|
@@ -53,3 +54,45 @@ async function login() {
|
|
|
53
54
|
buttonDisabled.value = false;
|
|
54
55
|
}
|
|
55
56
|
</script>
|
|
57
|
+
|
|
58
|
+
<style lang="scss" scoped>
|
|
59
|
+
.label-override {
|
|
60
|
+
@apply flex items-center text-sm mb-2;
|
|
61
|
+
color: #e1e1e4 !important;
|
|
62
|
+
|
|
63
|
+
svg {
|
|
64
|
+
width: 16px;
|
|
65
|
+
height: 16px;
|
|
66
|
+
path {
|
|
67
|
+
fill: #e1e1e4 !important;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.input-default {
|
|
73
|
+
@apply bg-dark-400 border border-dark-650 rounded-lg px-4 py-2 flex items-center;
|
|
74
|
+
min-height: 40px;
|
|
75
|
+
|
|
76
|
+
input {
|
|
77
|
+
@apply bg-transparent border-none outline-none w-full text-white;
|
|
78
|
+
&::placeholder {
|
|
79
|
+
color: #a0a0a6;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@media (max-height: 500px) and (orientation: landscape) {
|
|
85
|
+
.label-override {
|
|
86
|
+
@apply text-xs mb-1;
|
|
87
|
+
|
|
88
|
+
svg {
|
|
89
|
+
width: 14px;
|
|
90
|
+
height: 14px;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.input-default {
|
|
95
|
+
min-height: 36px;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="flex text-white font-bold lg:gap-5 gap-1 lg:mb-1 min-h-[2.5rem]" v-if="show" :key="key">
|
|
2
|
+
<div class="flex text-white font-bold lg:gap-5 gap-1 lg:mb-1 min-h-[2.5rem]" v-if="ui.queueStats.show" :key="key">
|
|
3
3
|
<div
|
|
4
4
|
v-if="ui.queueStats.total"
|
|
5
5
|
class="stats-card lg:mb-2 mb-1 text-sm rounded-xl lg:p-3 p-2 lg:gap-3 gap-2 flex justify-between items-center min-w-0 h-8">
|
|
@@ -68,7 +68,6 @@ const getQueuePassAmount = (width) => {
|
|
|
68
68
|
return 1;
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
-
let show = ref(true);
|
|
72
71
|
let key = ref(0);
|
|
73
72
|
let queuePassAmount = ref(getQueuePassAmount(window.innerWidth));
|
|
74
73
|
|
|
@@ -330,83 +330,93 @@ h4 {
|
|
|
330
330
|
@media (max-width: 480px) and (orientation: portrait) {
|
|
331
331
|
/* Position adjustment for mobile taskId */
|
|
332
332
|
.block.md\\:hidden {
|
|
333
|
-
left: 4rem !important;
|
|
333
|
+
left: 4rem !important;
|
|
334
334
|
top: 0.25rem !important;
|
|
335
335
|
z-index: 1 !important;
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
-
/*
|
|
338
|
+
/* Improved button layout for mobile portrait */
|
|
339
339
|
.task-buttons {
|
|
340
340
|
padding: 1px;
|
|
341
|
-
gap:
|
|
341
|
+
gap: 1px;
|
|
342
342
|
border-radius: 4px;
|
|
343
|
-
border:
|
|
344
|
-
box-shadow: 0 1px
|
|
343
|
+
border: 1px solid #3d3e44 !important;
|
|
344
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) !important;
|
|
345
345
|
max-width: 100%;
|
|
346
|
-
|
|
346
|
+
min-height: 28px;
|
|
347
|
+
height: auto;
|
|
347
348
|
flex-wrap: wrap;
|
|
348
349
|
justify-content: center;
|
|
349
|
-
|
|
350
|
-
|
|
350
|
+
align-items: center;
|
|
351
|
+
background: #2e2f34;
|
|
351
352
|
|
|
352
353
|
button {
|
|
353
|
-
width:
|
|
354
|
-
height:
|
|
355
|
-
border-radius:
|
|
356
|
-
min-width:
|
|
354
|
+
width: 20px;
|
|
355
|
+
height: 20px;
|
|
356
|
+
border-radius: 3px;
|
|
357
|
+
min-width: 20px;
|
|
357
358
|
border: none !important;
|
|
358
359
|
flex-shrink: 0;
|
|
359
360
|
margin: 0.5px;
|
|
361
|
+
background: transparent;
|
|
360
362
|
|
|
361
363
|
&:hover {
|
|
362
|
-
|
|
364
|
+
background: rgba(255, 255, 255, 0.1);
|
|
365
|
+
transform: scale(1.05);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
&:active {
|
|
369
|
+
background: rgba(255, 255, 255, 0.15);
|
|
370
|
+
transform: scale(0.95);
|
|
363
371
|
}
|
|
364
372
|
}
|
|
365
373
|
|
|
366
374
|
svg,
|
|
367
375
|
img {
|
|
368
|
-
width:
|
|
369
|
-
height:
|
|
376
|
+
width: 10px;
|
|
377
|
+
height: 10px;
|
|
370
378
|
}
|
|
371
379
|
|
|
372
380
|
span {
|
|
373
|
-
font-size: 0.
|
|
381
|
+
font-size: 0.7rem;
|
|
374
382
|
line-height: 1;
|
|
375
383
|
}
|
|
376
384
|
|
|
377
|
-
/*
|
|
385
|
+
/* Improved list item layout */
|
|
378
386
|
li {
|
|
379
387
|
display: flex;
|
|
380
388
|
margin: 0;
|
|
389
|
+
padding: 0;
|
|
381
390
|
}
|
|
382
391
|
}
|
|
383
392
|
|
|
384
|
-
/* Make the actions column
|
|
393
|
+
/* Make the actions column more flexible */
|
|
385
394
|
.col-span-2.lg\\:col-span-3 {
|
|
386
395
|
min-width: 0;
|
|
387
396
|
flex-shrink: 0;
|
|
388
397
|
display: flex;
|
|
389
398
|
align-items: center;
|
|
390
399
|
justify-content: center;
|
|
400
|
+
padding: 0 2px;
|
|
391
401
|
}
|
|
392
402
|
|
|
393
403
|
/* Compact status container */
|
|
394
404
|
.status-container {
|
|
395
405
|
border: none !important;
|
|
396
|
-
box-shadow: 0 1px
|
|
397
|
-
padding:
|
|
398
|
-
font-size: 0.
|
|
406
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) !important;
|
|
407
|
+
padding: 2px 4px;
|
|
408
|
+
font-size: 0.7rem;
|
|
399
409
|
max-width: 100%;
|
|
400
410
|
}
|
|
401
411
|
|
|
402
412
|
.status-text {
|
|
403
|
-
font-size: 0.
|
|
413
|
+
font-size: 0.65rem;
|
|
404
414
|
letter-spacing: 0;
|
|
405
415
|
}
|
|
406
416
|
|
|
407
417
|
/* Reduce row height to accommodate smaller elements */
|
|
408
418
|
.task-row-container {
|
|
409
|
-
min-height:
|
|
419
|
+
min-height: 45px !important;
|
|
410
420
|
}
|
|
411
421
|
}
|
|
412
422
|
|
|
@@ -1,138 +1,188 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
</div>
|
|
12
|
-
</div>
|
|
13
|
-
<div class="col-span-2 flex-center" v-once>
|
|
14
|
-
<TicketIcon class="mr-0 lg:mr-3" />
|
|
15
|
-
<h4 class="hidden lg:flex">Tickets</h4>
|
|
16
|
-
</div>
|
|
17
|
-
<div class="col-span-5 md:col-span-4 lg:col-span-5 flex-center" @click="ui.toggleSort('status')">
|
|
18
|
-
<StatusIcon class="mr-0 lg:mr-3" />
|
|
19
|
-
<h4 class="hidden lg:flex">Status</h4>
|
|
20
|
-
<DownIcon v-if="ui.sortData.sortBy === 'status' && !ui.sortData.reversed" class="ml-1" />
|
|
21
|
-
<UpIcon v-if="ui.sortData.sortBy === 'status' && ui.sortData.reversed" class="ml-1" />
|
|
22
|
-
</div>
|
|
23
|
-
<div class="col-span-2 lg:col-span-3 flex-center" v-once>
|
|
24
|
-
<ClickIcon class="mr-0 lg:mr-3" />
|
|
25
|
-
<h4 class="hidden lg:flex">Actions</h4>
|
|
26
|
-
</div>
|
|
27
|
-
<div class="absolute right-5 hidden lg:flex items-center top-3.5" @click="ui.toggleSort('taskId')">
|
|
28
|
-
<h4 class="text-center text-xs">ID</h4>
|
|
29
|
-
<DownIcon v-if="ui.sortData.sortBy === 'taskId' && !ui.sortData.reversed" class="ml-1" />
|
|
30
|
-
<UpIcon v-if="ui.sortData.sortBy === 'taskId' && ui.sortData.reversed" class="ml-1" />
|
|
31
|
-
</div>
|
|
32
|
-
</Header>
|
|
2
|
+
<div class="table-component">
|
|
3
|
+
<Header class="text-center grid-cols-10 gap-2 lg:grid-cols-12">
|
|
4
|
+
<div class="col-span-1 lg:col-span-2 flex items-center justify-start">
|
|
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
|
+
/>
|
|
33
11
|
<div
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
<div v-else>
|
|
48
|
-
<TasksIcon class="w-12 h-12 text-dark-400 mb-3 opacity-50 mx-auto" />
|
|
49
|
-
<p class="text-light-400 text-sm">
|
|
50
|
-
{{ ui.queueStats.total }} hidden task{{ ui.queueStats.total === 1 ? "" : "s" }}
|
|
51
|
-
</p>
|
|
52
|
-
<p class="text-light-500 text-xs mt-1">Adjust filters to see tasks</p>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
12
|
+
class="mx-auto hidden lg:flex items-center"
|
|
13
|
+
@click="ui.toggleSort('eventId')"
|
|
14
|
+
>
|
|
15
|
+
<EventIcon class="lg:mr-3" />
|
|
16
|
+
<h4 class="hidden lg:flex">Event</h4>
|
|
17
|
+
<DownIcon
|
|
18
|
+
v-if="ui.sortData.sortBy === 'eventId' && !ui.sortData.reversed"
|
|
19
|
+
class="ml-1"
|
|
20
|
+
/>
|
|
21
|
+
<UpIcon
|
|
22
|
+
v-if="ui.sortData.sortBy === 'eventId' && ui.sortData.reversed"
|
|
23
|
+
class="ml-1"
|
|
24
|
+
/>
|
|
55
25
|
</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>
|
|
56
97
|
</div>
|
|
98
|
+
</div>
|
|
57
99
|
</template>
|
|
58
100
|
<style lang="scss" scoped>
|
|
59
101
|
h4 {
|
|
60
|
-
|
|
102
|
+
@apply text-white;
|
|
61
103
|
}
|
|
62
104
|
|
|
63
105
|
.stop-pan {
|
|
64
|
-
|
|
106
|
+
touch-action: pan-y pan-up pan-down;
|
|
65
107
|
}
|
|
66
108
|
|
|
67
109
|
.task-row-container {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
110
|
+
min-height: 69px;
|
|
111
|
+
flex-shrink: 0;
|
|
112
|
+
transition: background-color 0.15s ease;
|
|
71
113
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
114
|
+
&:hover {
|
|
115
|
+
@apply bg-dark-550 !important;
|
|
116
|
+
}
|
|
75
117
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
118
|
+
@media (max-width: 768px) {
|
|
119
|
+
min-height: 58px;
|
|
120
|
+
}
|
|
79
121
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
122
|
+
@media (max-width: 480px) and (orientation: portrait) {
|
|
123
|
+
min-height: 50px;
|
|
124
|
+
}
|
|
83
125
|
}
|
|
84
126
|
|
|
85
127
|
.empty-state {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
128
|
+
@apply bg-dark-400;
|
|
129
|
+
color: #969696;
|
|
130
|
+
font-size: 14px;
|
|
131
|
+
font-weight: 500;
|
|
90
132
|
}
|
|
91
133
|
</style>
|
|
92
134
|
<script setup>
|
|
93
135
|
import { computed, ref, onMounted, onUnmounted } from "vue";
|
|
94
136
|
import { Table, Header } from "@/components/Table";
|
|
95
|
-
import {
|
|
137
|
+
import {
|
|
138
|
+
EventIcon,
|
|
139
|
+
TicketIcon,
|
|
140
|
+
StatusIcon,
|
|
141
|
+
ClickIcon,
|
|
142
|
+
DownIcon,
|
|
143
|
+
UpIcon,
|
|
144
|
+
TasksIcon,
|
|
145
|
+
} from "@/components/icons";
|
|
96
146
|
import Task from "./Task.vue";
|
|
97
147
|
import Checkbox from "@/components/ui/controls/atomic/Checkbox.vue";
|
|
98
148
|
import { useUIStore } from "@/stores/ui";
|
|
99
149
|
|
|
100
150
|
const props = defineProps({
|
|
101
|
-
|
|
151
|
+
tasks: { type: Object },
|
|
102
152
|
});
|
|
103
153
|
|
|
104
154
|
const shouldTaskShow = (task) => {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
155
|
+
if (ui.taskFilter === "All") return true;
|
|
156
|
+
else if (ui.taskFilter === "Checkout") return task.expirationTime || task.noCartholds;
|
|
157
|
+
else return true;
|
|
108
158
|
};
|
|
109
159
|
|
|
110
160
|
const ui = useUIStore();
|
|
111
161
|
|
|
112
162
|
const siteIdEdgeCases = {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
163
|
+
LN_US: ["TM_US"],
|
|
164
|
+
TM_CA: ["TM_US"],
|
|
165
|
+
TM_IE: ["TM_UK"],
|
|
166
|
+
TM_NZ: ["TM_AU"],
|
|
117
167
|
};
|
|
118
168
|
|
|
119
169
|
const getTasksInOrder = () => {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
170
|
+
let out = [];
|
|
171
|
+
ui.taskIdOrder.forEach((id) => {
|
|
172
|
+
if (props.tasks[id] && !props.tasks[id]?.hidden) {
|
|
173
|
+
const task = props.tasks[id];
|
|
174
|
+
|
|
175
|
+
if (
|
|
176
|
+
task.siteId !== ui.currentCountry.siteId &&
|
|
177
|
+
!siteIdEdgeCases[task.siteId]?.includes(ui.currentCountry.siteId)
|
|
178
|
+
)
|
|
179
|
+
return;
|
|
180
|
+
if (ui.currentEvent && task.eventId !== ui.currentEvent) return;
|
|
181
|
+
if (!shouldTaskShow(task)) return;
|
|
182
|
+
out.push(task);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
return out;
|
|
136
186
|
};
|
|
137
187
|
|
|
138
188
|
// Dynamic height calculation to prevent page scrolling
|
|
@@ -140,42 +190,54 @@ const windowHeight = ref(window.innerHeight);
|
|
|
140
190
|
const windowWidth = ref(window.innerWidth);
|
|
141
191
|
|
|
142
192
|
const updateDimensions = () => {
|
|
143
|
-
|
|
144
|
-
|
|
193
|
+
windowHeight.value = window.innerHeight;
|
|
194
|
+
windowWidth.value = window.innerWidth;
|
|
145
195
|
};
|
|
146
196
|
|
|
147
197
|
onMounted(() => {
|
|
148
|
-
|
|
198
|
+
window.addEventListener("resize", updateDimensions);
|
|
149
199
|
});
|
|
150
200
|
|
|
151
201
|
onUnmounted(() => {
|
|
152
|
-
|
|
202
|
+
window.removeEventListener("resize", updateDimensions);
|
|
153
203
|
});
|
|
154
204
|
|
|
155
205
|
const dynamicTableHeight = computed(() => {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
206
|
+
// Calculate available space for table
|
|
207
|
+
const headerHeight = 60; // Header + navbar
|
|
208
|
+
const titleHeight = 50; // Tasks title and mobile controls
|
|
209
|
+
const statsHeight = 50; // Queue stats
|
|
210
|
+
const controlsHeight = windowWidth.value >= 650 ? 60 : 0; // Desktop controls
|
|
211
|
+
const filtersHeight = 50; // Event dropdown and filter toggle
|
|
212
|
+
const utilitiesHeight =
|
|
213
|
+
windowWidth.value <= 480 && windowHeight.value > windowWidth.value ? 150 : 200; // Reduce utilities height in mobile portrait
|
|
214
|
+
const margins =
|
|
215
|
+
windowWidth.value >= 1024
|
|
216
|
+
? 40
|
|
217
|
+
: windowWidth.value <= 480 && windowHeight.value > windowWidth.value
|
|
218
|
+
? 15
|
|
219
|
+
: 20; // Reduce margins in mobile portrait
|
|
220
|
+
|
|
221
|
+
const totalUsedSpace =
|
|
222
|
+
headerHeight +
|
|
223
|
+
titleHeight +
|
|
224
|
+
statsHeight +
|
|
225
|
+
controlsHeight +
|
|
226
|
+
filtersHeight +
|
|
227
|
+
utilitiesHeight +
|
|
228
|
+
margins;
|
|
229
|
+
const availableHeight = windowHeight.value - totalUsedSpace;
|
|
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";
|
|
180
242
|
});
|
|
181
243
|
</script>
|
package/src/stores/sampleData.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const queueStats = false;
|
|
2
|
+
|
|
1
3
|
export default {
|
|
2
4
|
Profile: {
|
|
3
5
|
name: "Admin",
|
|
@@ -17,7 +19,7 @@ export default {
|
|
|
17
19
|
email: "grantelam@hotmail.com",
|
|
18
20
|
password: "Dkstrhf4srth56Gksj",
|
|
19
21
|
status: "Event already happened long long long long long long longlong long long long",
|
|
20
|
-
inQueue:
|
|
22
|
+
inQueue: queueStats,
|
|
21
23
|
statusColor: "red",
|
|
22
24
|
manual: false,
|
|
23
25
|
incapsulaBypass: false,
|
|
@@ -324,7 +326,7 @@ export default {
|
|
|
324
326
|
active: true,
|
|
325
327
|
email: "taylortaxjbr26248@gmail.com",
|
|
326
328
|
password: "OwZz9PfKtWsrS7",
|
|
327
|
-
status: "Waiting for Queue",
|
|
329
|
+
status: queueStats ? "Waiting for Queue" : "Waiting for Stock",
|
|
328
330
|
statusColor: "white",
|
|
329
331
|
manual: false,
|
|
330
332
|
incapsulaBypass: false,
|
package/src/stores/ui.js
CHANGED
|
@@ -233,10 +233,7 @@ export const useUIStore = defineStore("ui", () => {
|
|
|
233
233
|
let relevantTasks = Object.values(tasks.value).filter((t) => t.siteId === currentCountry.value.siteId);
|
|
234
234
|
if (currentEvent.value) relevantTasks = relevantTasks.filter((t) => t.eventId === currentEvent.value);
|
|
235
235
|
|
|
236
|
-
queueStats.value.total = 0;
|
|
237
236
|
queueStats.value.queued = relevantTasks.filter((t) => t.inQueue).length || 0;
|
|
238
|
-
// if (DEBUG) queueStats.value.queued += 50000;
|
|
239
|
-
queueStats.value.show = queueStats.value.total > 0;
|
|
240
237
|
const sleepingStatuses = ["sleeping in queue", "waiting for drop", "waiting for carting", "waiting for queue"];
|
|
241
238
|
queueStats.value.sleeping = relevantTasks.filter((t) =>
|
|
242
239
|
sleepingStatuses.includes(t.status.toLowerCase())
|
|
@@ -246,6 +243,10 @@ export const useUIStore = defineStore("ui", () => {
|
|
|
246
243
|
.filter((e) => !isNaN(e))
|
|
247
244
|
.filter(Boolean);
|
|
248
245
|
queueStats.value.nextQueuePasses = positions.sort((a, b) => a - b);
|
|
246
|
+
|
|
247
|
+
// Only show stats if there are any queued tasks, sleeping tasks, or queue positions
|
|
248
|
+
queueStats.value.show =
|
|
249
|
+
queueStats.value.queued > 0 || queueStats.value.sleeping > 0 || queueStats.value.nextQueuePasses.length > 0;
|
|
249
250
|
};
|
|
250
251
|
|
|
251
252
|
const toggleModal = (name, clearValue = false) => {
|