@dcrackel/hematournamentui 1.0.701 → 1.0.702
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/dist/HemaTournamentUI-lib.es.js +1181 -830
- package/dist/HemaTournamentUI-lib.umd.js +1 -1
- package/dist/hematournamentui-tailwind.css +9 -0
- package/package.json +92 -92
- package/src/stories/Molecules/Buttons/ButtonBar/ButtonBar.vue +1 -1
- package/src/stories/Organisms/Cards/KioskCard/KioskCard.vue +26 -7
- package/src/stories/Organisms/Cards/WaitlistFencerCard/WaitlistFencerCard.vue +129 -0
- package/src/stories/Organisms/Containers/KioskContainer/KioskContainer.vue +13 -9
- package/src/stories/Organisms/Headers/AttendanceSummary/AttendanceSummary.vue +45 -19
- package/src/stories/Templates/EventManagement/EventAttendance/EventAttendance.stories.js +49 -14
- package/src/stories/Templates/EventManagement/EventAttendance/EventAttendance.vue +124 -27
- package/src/stories/Templates/EventManagement/KioskDisplay/KioskDisplay.vue +10 -6
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<section>
|
|
3
3
|
<EditEventsTopMenu :currentTab="'Checkin'" :tabs="tabs(role, isMobile)" @tabMenuClick="handleTabMenuClick"/>
|
|
4
|
-
<AttendanceSummary
|
|
4
|
+
<AttendanceSummary
|
|
5
|
+
:event="event"
|
|
6
|
+
:absent="absent"
|
|
7
|
+
:present="present"
|
|
8
|
+
:activeCount="activeRosterCount"
|
|
9
|
+
:waitlistCount="waitlistCount"
|
|
10
|
+
:capacity="eventCapacity"/>
|
|
5
11
|
<div class="w-full flex flex-row justify-center mt-1 md:mt-3">
|
|
6
12
|
<section class="w-full">
|
|
7
13
|
<div class="w-full flex flex-col justify-center items-center" style="text-align: center">
|
|
@@ -30,20 +36,38 @@
|
|
|
30
36
|
</div>
|
|
31
37
|
</section>
|
|
32
38
|
<section v-if="!loading" class="w-full">
|
|
33
|
-
<div v-
|
|
39
|
+
<div v-if="activeRosterCount > 0" class="mb-2 flex items-center justify-between">
|
|
40
|
+
<BaseText text="Active Roster" size="md" color="quaternary" weight="bold"/>
|
|
41
|
+
<BaseText :text="activeRosterSummary" size="sm" color="quinary"/>
|
|
42
|
+
</div>
|
|
43
|
+
<div v-for="(person, index) in sortedActivePersons" :key="person.PersonId || person.Person?.PersonId || index">
|
|
34
44
|
<FencerCard :person="person" class="mb-4"
|
|
35
|
-
:isLast="index ===
|
|
45
|
+
:isLast="index === sortedActivePersons.length - 1"
|
|
36
46
|
:isEdit="event.Status === 'planning' || event.Status === 'preparation'"
|
|
37
|
-
@forward:toProfile="handleForwardToProfile"
|
|
38
|
-
@update:status="handleStatus"
|
|
47
|
+
@forward:toProfile="handleForwardToProfile"
|
|
48
|
+
@update:status="handleStatus"
|
|
39
49
|
@remove:fencer="handleRemoveFencer"
|
|
40
50
|
@update:moveUp="handleMoveUp"
|
|
41
51
|
@update:moveDown="handleMoveDown"
|
|
42
52
|
@request:weaver-sign="openWeaverModal"
|
|
43
53
|
/>
|
|
44
54
|
</div>
|
|
55
|
+
<section v-if="waitlistCount > 0" class="mt-6 w-full">
|
|
56
|
+
<div class="mb-2 flex items-center justify-between">
|
|
57
|
+
<BaseText text="Waitlist" size="md" color="quaternary" weight="bold"/>
|
|
58
|
+
<BaseText :text="waitlistSummary" size="sm" color="quinary"/>
|
|
59
|
+
</div>
|
|
60
|
+
<div v-for="(person, index) in sortedWaitlistedPersons" :key="person.PersonId || person.Person?.PersonId || index" class="mb-3">
|
|
61
|
+
<WaitlistFencerCard
|
|
62
|
+
:person="person"
|
|
63
|
+
:queuePosition="index + 1"
|
|
64
|
+
@forward:toProfile="handleForwardToProfile"
|
|
65
|
+
@move:active="handleMoveWaitlistToActive"
|
|
66
|
+
@remove:fencer="handleRemoveWaitlistFencer"/>
|
|
67
|
+
</div>
|
|
68
|
+
</section>
|
|
45
69
|
</section>
|
|
46
|
-
<div v-if="!loading && personsInTournament.length === 0" class="mb-10">
|
|
70
|
+
<div v-if="!loading && personsInTournament.length === 0" class="mb-10">
|
|
47
71
|
<div class="flex items-center border border-dropdownSelect rounded-lg shadow-lg bg-poolBox">
|
|
48
72
|
<BaseText text="Remember to assign staff to your event!" size="lg" color="quaternary" weight="bold" class="w-full text-center py-2 px-8"/>
|
|
49
73
|
</div>
|
|
@@ -74,7 +98,8 @@
|
|
|
74
98
|
<script>
|
|
75
99
|
import BaseText from "../../../Atoms/Text/BaseText.vue";
|
|
76
100
|
import emptyDesertIcon from '../../../../assets/empty_desert_icon.png';
|
|
77
|
-
import FencerCard from "../../../Organisms/Cards/FencerCard/FencerCard.vue";
|
|
101
|
+
import FencerCard from "../../../Organisms/Cards/FencerCard/FencerCard.vue";
|
|
102
|
+
import WaitlistFencerCard from "../../../Organisms/Cards/WaitlistFencerCard/WaitlistFencerCard.vue";
|
|
78
103
|
import EditEventsTopMenu from "../../Menus/EditEventsTopMenu/EditEventsTopMenu.vue";
|
|
79
104
|
import DropDownMenu from "../../../Organisms/ComplexInputs/DropDown/DropDownMenu.vue";
|
|
80
105
|
import FindOrAddPerson from "../../../Organisms/ComplexInputs/FindOrAddPerson/FindOrAddPerson.vue";
|
|
@@ -98,10 +123,27 @@ const personSorters = {
|
|
|
98
123
|
}
|
|
99
124
|
};
|
|
100
125
|
|
|
126
|
+
const waitlistStatuses = new Set(['waitlist', 'waitlisted', 'waitinglist']);
|
|
127
|
+
|
|
128
|
+
const normalizeStatus = (status) => String(status || '').toLocaleLowerCase().replace(/[\s_-]/g, '');
|
|
129
|
+
|
|
130
|
+
const isWaitlistedPerson = (person) => waitlistStatuses.has(normalizeStatus(person?.Status));
|
|
131
|
+
|
|
132
|
+
const getEventRuleValue = (event, ruleName) => {
|
|
133
|
+
const rule = event?.EventRules?.find(eventRule => eventRule?.Rules?.RuleName === ruleName);
|
|
134
|
+
return rule?.RuleValue;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const getWaitlistOrderValue = (person) => {
|
|
138
|
+
const order = person?.WaitlistPosition ?? person?.WaitlistOrder ?? person?.CreatedAt ?? person?.Seed ?? person?.PoolPosition ?? 0;
|
|
139
|
+
return Number.isNaN(Number(order)) ? order : Number(order);
|
|
140
|
+
};
|
|
141
|
+
|
|
101
142
|
export default {
|
|
102
|
-
emits: ['add:existing-person', 'add:person', 'forward:toProfile', 'remove:fencer', 'tab:menu-click', 'update:moveDown', 'update:moveUp', 'update:person', 'weaver:sign'],
|
|
103
|
-
components: {
|
|
104
|
-
|
|
143
|
+
emits: ['add:existing-person', 'add:person', 'forward:toProfile', 'move:waitlist-to-active', 'remove:fencer', 'remove:waitlist-fencer', 'tab:menu-click', 'update:moveDown', 'update:moveUp', 'update:person', 'weaver:sign'],
|
|
144
|
+
components: {
|
|
145
|
+
WaitlistFencerCard,
|
|
146
|
+
FencerCardSkeleton,
|
|
105
147
|
AttendanceSummary,
|
|
106
148
|
FindOrAddPerson,
|
|
107
149
|
DropDownMenu,
|
|
@@ -166,15 +208,28 @@ export default {
|
|
|
166
208
|
isMobile() {
|
|
167
209
|
return this.windowWidth <= 748;
|
|
168
210
|
},
|
|
169
|
-
|
|
170
|
-
if (!Array.isArray(this.personsInTournament) || this.personsInTournament.length === 0) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
211
|
+
activePersons() {
|
|
212
|
+
if (!Array.isArray(this.personsInTournament) || this.personsInTournament.length === 0) {
|
|
213
|
+
return [];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return this.personsInTournament.filter(person => !isWaitlistedPerson(person));
|
|
217
|
+
},
|
|
218
|
+
waitlistedPersons() {
|
|
219
|
+
if (!Array.isArray(this.personsInTournament) || this.personsInTournament.length === 0) {
|
|
220
|
+
return [];
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return this.personsInTournament.filter(isWaitlistedPerson);
|
|
224
|
+
},
|
|
225
|
+
sortedActivePersons() {
|
|
226
|
+
if (this.activePersons.length === 0) {
|
|
227
|
+
return [];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
let sortedArray = [...this.activePersons]; // Clone array to prevent modifying props
|
|
231
|
+
|
|
232
|
+
sortedArray.sort((a, b) => {
|
|
178
233
|
if (!a || !b || !a.Person || !b.Person) {
|
|
179
234
|
console.warn("Undefined person object detected:", a, b);
|
|
180
235
|
return 0;
|
|
@@ -186,14 +241,50 @@ export default {
|
|
|
186
241
|
console.warn("Unknown sorting key:", this.localSelectedItem.link);
|
|
187
242
|
return 0;
|
|
188
243
|
});
|
|
189
|
-
return sortedArray;
|
|
190
|
-
},
|
|
191
|
-
|
|
192
|
-
return this.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
244
|
+
return sortedArray;
|
|
245
|
+
},
|
|
246
|
+
sortedWaitlistedPersons() {
|
|
247
|
+
return [...this.waitlistedPersons].sort((a, b) => {
|
|
248
|
+
const orderA = getWaitlistOrderValue(a);
|
|
249
|
+
const orderB = getWaitlistOrderValue(b);
|
|
250
|
+
|
|
251
|
+
if (typeof orderA === 'number' && typeof orderB === 'number') {
|
|
252
|
+
return orderA - orderB;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return String(orderA).localeCompare(String(orderB));
|
|
256
|
+
});
|
|
257
|
+
},
|
|
258
|
+
activeRosterCount() {
|
|
259
|
+
return this.activePersons.length;
|
|
260
|
+
},
|
|
261
|
+
waitlistCount() {
|
|
262
|
+
return this.waitlistedPersons.length;
|
|
263
|
+
},
|
|
264
|
+
eventCapacity() {
|
|
265
|
+
const capacity = this.event?.CutOffNumber ?? this.event?.MaxFencers ?? getEventRuleValue(this.event, 'CutOffNumber');
|
|
266
|
+
if (capacity === 0 || capacity === '0') {
|
|
267
|
+
return 'Unlimited';
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return capacity || '';
|
|
271
|
+
},
|
|
272
|
+
activeRosterSummary() {
|
|
273
|
+
if (!this.eventCapacity) {
|
|
274
|
+
return `${this.activeRosterCount} active`;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return `${this.activeRosterCount} / ${this.eventCapacity}`;
|
|
278
|
+
},
|
|
279
|
+
waitlistSummary() {
|
|
280
|
+
return `${this.waitlistCount} waiting`;
|
|
281
|
+
},
|
|
282
|
+
absent() {
|
|
283
|
+
return this.activePersons.filter(person => person.Status === 'Absent').length;
|
|
284
|
+
},
|
|
285
|
+
present() {
|
|
286
|
+
return this.activePersons.filter(person => person.Status === 'Present').length;
|
|
287
|
+
},
|
|
197
288
|
},
|
|
198
289
|
methods: {
|
|
199
290
|
openWeaverModal(person) {
|
|
@@ -226,6 +317,12 @@ export default {
|
|
|
226
317
|
handleRemoveFencer(value) {
|
|
227
318
|
this.$emit('remove:fencer', value);
|
|
228
319
|
},
|
|
320
|
+
handleMoveWaitlistToActive(person) {
|
|
321
|
+
this.$emit('move:waitlist-to-active', person);
|
|
322
|
+
},
|
|
323
|
+
handleRemoveWaitlistFencer(person) {
|
|
324
|
+
this.$emit('remove:waitlist-fencer', person);
|
|
325
|
+
},
|
|
229
326
|
handleMoveUp(person){
|
|
230
327
|
this.$emit('update:moveUp', person);
|
|
231
328
|
},
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
:displays="localDisplays"
|
|
6
6
|
:eventDropDown="eventDropDown"
|
|
7
7
|
:staffDropDown="staffDropDown"
|
|
8
|
-
:userRole="role"
|
|
9
|
-
@remove:kiosk="handleRemove"
|
|
10
|
-
@
|
|
8
|
+
:userRole="role"
|
|
9
|
+
@remove:kiosk="handleRemove"
|
|
10
|
+
@test:scoreboard="handleScoreboardTest"
|
|
11
|
+
@update:ringChange="handleRingChange"
|
|
11
12
|
@update:selectedStaff="handleAssignmentStaff"
|
|
12
13
|
@update:selectedEvent="handleAssignmentEvent"
|
|
13
14
|
@update:selectedType="handleSelectedType"
|
|
@@ -30,7 +31,7 @@ export default {
|
|
|
30
31
|
EditEventsTopMenu
|
|
31
32
|
|
|
32
33
|
},
|
|
33
|
-
emits: ['remove:kiosk', 'update:selectedStaff', 'update:selectedEvent', 'update:selectedType', 'update:ringChange', 'submit:kiosk', 'update:assignToMe','tab:menu-click'],
|
|
34
|
+
emits: ['remove:kiosk', 'test:scoreboard', 'update:selectedStaff', 'update:selectedEvent', 'update:selectedType', 'update:ringChange', 'submit:kiosk', 'update:assignToMe','tab:menu-click'],
|
|
34
35
|
props: {
|
|
35
36
|
displays: {
|
|
36
37
|
type: Array,
|
|
@@ -75,8 +76,11 @@ export default {
|
|
|
75
76
|
return this.windowWidth <= 748;
|
|
76
77
|
},
|
|
77
78
|
},
|
|
78
|
-
methods: {
|
|
79
|
-
|
|
79
|
+
methods: {
|
|
80
|
+
handleScoreboardTest(display) {
|
|
81
|
+
this.$emit('test:scoreboard', display);
|
|
82
|
+
},
|
|
83
|
+
handleTabMenuClick(value) {
|
|
80
84
|
this.$emit('tab:menu-click', value);
|
|
81
85
|
},
|
|
82
86
|
handleRingChange(item){
|