@dcrackel/hematournamentui 1.0.688 → 1.0.690
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 +6958 -6940
- package/dist/HemaTournamentUI-lib.umd.js +21 -21
- package/dist/hematournamentui.css +1 -1
- package/package.json +1 -1
- package/src/stories/Organisms/Cards/BoutCard/BoutCard.vue +1 -1
- package/src/stories/Organisms/Containers/Tableau/Tableau.vue +168 -108
- package/src/stories/Templates/EventManagement/Bracket/Bracket.stories.js +31 -10
- package/src/stories/Templates/EventManagement/Bracket/Bracket.vue +79 -22
- package/src/stories/Templates/EventManagement/PoolLive/PoolLive.stories.js +0 -2
- package/src/stories/Templates/EventManagement/PoolLive/PoolLive.vue +11 -102
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
* Released under the MIT license
|
|
7
7
|
*
|
|
8
8
|
* Date: 2024-04-21T07:43:02.731Z
|
|
9
|
-
*/.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;touch-action:none;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.cropper-container img{backface-visibility:hidden;display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-wrap-box,.cropper-canvas,.cropper-drag-box,.cropper-crop-box,.cropper-modal{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-wrap-box,.cropper-canvas{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:#3399ffbf;overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:calc(100% / 3);left:0;top:calc(100% / 3);width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:calc(100% / 3);top:0;width:calc(100% / 3)}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:before,.cropper-center:after{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media(min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media(min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media(min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}[data-v-a1dce3ee] .ProseMirror>*+*{margin-top:.75em}[data-v-a1dce3ee] .ProseMirror ol{padding:0 1rem;list-style:decimal!important}[data-v-a1dce3ee] .ProseMirror ul{padding:0 1rem;list-style:disc!important}
|
|
9
|
+
*/.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;touch-action:none;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.cropper-container img{backface-visibility:hidden;display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-wrap-box,.cropper-canvas,.cropper-drag-box,.cropper-crop-box,.cropper-modal{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-wrap-box,.cropper-canvas{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:#3399ffbf;overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:calc(100% / 3);left:0;top:calc(100% / 3);width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:calc(100% / 3);top:0;width:calc(100% / 3)}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:before,.cropper-center:after{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media(min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media(min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media(min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}[data-v-a1dce3ee] .ProseMirror>*+*{margin-top:.75em}[data-v-a1dce3ee] .ProseMirror ol{padding:0 1rem;list-style:decimal!important}[data-v-a1dce3ee] .ProseMirror ul{padding:0 1rem;list-style:disc!important}.fade-in-down-enter-active[data-v-507c44cb]{animation:fadeInDown-507c44cb .3s ease-out}.fade-in-down-leave-active[data-v-507c44cb]{animation:fadeOutUp-507c44cb .3s ease-in;max-height:100px;overflow:hidden}.fade-in-down-leave-to[data-v-507c44cb]{opacity:0;transform:translateY(-10px);max-height:0;overflow:hidden}@keyframes fadeInDown-507c44cb{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeOutUp-507c44cb{0%{opacity:1;transform:translateY(0);max-height:100px}to{opacity:0;transform:translateY(-10px);max-height:0}}
|
package/package.json
CHANGED
|
@@ -108,7 +108,7 @@ export default {
|
|
|
108
108
|
if (!fromDragId || !toDragId || String(fromDragId) === String(toDragId)) return;
|
|
109
109
|
this.$emit('reorder:swap', { fromBoutId: fromDragId, toBoutId: toDragId });
|
|
110
110
|
},
|
|
111
|
-
onAssign(ids) { this.$emit('action:
|
|
111
|
+
onAssign(ids) { this.$emit('action:assignBout', ids); },
|
|
112
112
|
},
|
|
113
113
|
};
|
|
114
114
|
</script>
|
|
@@ -1,44 +1,90 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<section v-if="listView" class="flex flex-col items-center">
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
|
|
4
|
+
<!-- Assigned Bouts -->
|
|
5
|
+
<div v-if="hasAssignedBouts" class="w-full flex-col md:w-3/4 my-4">
|
|
6
|
+
<div class="flex flex-row justify-between">
|
|
7
|
+
<BaseText class="my-5" color="primaryHighlight" size="sm" text="Assigned Bouts" weight="bold"/>
|
|
8
|
+
<div class="flex mr-1">
|
|
9
|
+
<BaseText class="my-5 ml-5" color="primaryHighlight" size="sm" text="Assigned:"/>
|
|
10
|
+
<BaseText
|
|
11
|
+
:text="assignedBoutsToMe.length"
|
|
12
|
+
class="my-5 ml-2"
|
|
13
|
+
color="primaryHighlight"
|
|
14
|
+
size="sm"
|
|
15
|
+
weight="bold"
|
|
11
16
|
/>
|
|
12
|
-
</
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="border-b border-dropdownSelect mb-5"></div>
|
|
20
|
+
|
|
21
|
+
<div v-for="bout in assignedBoutsToMe" :key="bout.BoutId" class="mb-4">
|
|
22
|
+
<BoutCard
|
|
23
|
+
:bout="bout"
|
|
24
|
+
:hostingClubColors="hostingClubColors"
|
|
25
|
+
:editMode="false"
|
|
26
|
+
:reorderMode="false"
|
|
27
|
+
:isAdmin="isAdmin"
|
|
28
|
+
@action:startBout="handleDirectingFromIds"
|
|
29
|
+
@action:resumeBout="handleDirectingFromIds"
|
|
30
|
+
@action:editBout="handleEditFromIds"
|
|
31
|
+
@action:assignBout="handleAssignBout"
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<!-- Existing rounds -->
|
|
37
|
+
<div
|
|
38
|
+
v-for="(bouts, roundName) in filteredBouts"
|
|
39
|
+
:key="bouts[0].BoutId"
|
|
40
|
+
class="w-full flex-col md:w-3/4 my-4"
|
|
41
|
+
>
|
|
42
|
+
<BaseText class="my-5" color="primaryHighlight" size="sm" :text="roundName" weight="bold"/>
|
|
43
|
+
|
|
44
|
+
<div v-for="bout in bouts" :key="bout.BoutId" class="mb-4">
|
|
45
|
+
<BoutCard
|
|
46
|
+
:bout="bout"
|
|
47
|
+
:hostingClubColors="hostingClubColors"
|
|
48
|
+
:editMode="false"
|
|
49
|
+
:reorderMode="false"
|
|
50
|
+
:isAdmin="isAdmin"
|
|
51
|
+
@action:startBout="handleDirectingFromIds"
|
|
52
|
+
@action:resumeBout="handleDirectingFromIds"
|
|
53
|
+
@action:editBout="handleEditFromIds"
|
|
54
|
+
@action:assignBout="handleAssignBout"
|
|
55
|
+
/>
|
|
13
56
|
</div>
|
|
14
57
|
</div>
|
|
15
58
|
</section>
|
|
16
59
|
|
|
17
|
-
<section v-
|
|
60
|
+
<section v-else class="flex w-full overflow-x-auto mt-4 scrollbar-thin">
|
|
18
61
|
<div class="min-w-full flex">
|
|
19
62
|
<div v-for="(bouts, roundName) in groupedBouts.winnerBouts" :key="roundName">
|
|
20
|
-
<TableauColumn
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
63
|
+
<TableauColumn
|
|
64
|
+
:bouts="bouts"
|
|
65
|
+
:hostingClubColors="hostingClubColors"
|
|
66
|
+
:roundName="roundName"
|
|
67
|
+
:bracketSize="bracketSize"
|
|
68
|
+
:largeCards="largeCards"
|
|
69
|
+
:isCountingBackwardsMaxScore="isCountingBackwardsMaxScore"
|
|
70
|
+
@action:editBout="handleEditBout"
|
|
71
|
+
@action:directingBout="handleDirectorBout"
|
|
28
72
|
/>
|
|
29
73
|
</div>
|
|
30
74
|
</div>
|
|
31
|
-
|
|
75
|
+
|
|
76
|
+
<!-- Loser bracket -->
|
|
32
77
|
<div class="min-w-full flex">
|
|
33
78
|
<div v-for="(bouts, roundName) in groupedBouts.loserBouts" :key="roundName">
|
|
34
|
-
<TableauColumn
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
79
|
+
<TableauColumn
|
|
80
|
+
:bouts="bouts"
|
|
81
|
+
:hostingClubColors="hostingClubColors"
|
|
82
|
+
:roundName="roundName"
|
|
83
|
+
:bracketSize="bracketSize"
|
|
84
|
+
:largeCards="largeCards"
|
|
85
|
+
:isCountingBackwardsMaxScore="isCountingBackwardsMaxScore"
|
|
86
|
+
@action:editBout="handleEditBout"
|
|
87
|
+
@action:directingBout="handleDirectorBout"
|
|
42
88
|
/>
|
|
43
89
|
</div>
|
|
44
90
|
</div>
|
|
@@ -52,56 +98,68 @@ import BoutCard from "../../../Organisms/Cards/BoutCard/BoutCard.vue";
|
|
|
52
98
|
import BaseText from "../../../Atoms/Text/BaseText.vue";
|
|
53
99
|
|
|
54
100
|
export default {
|
|
55
|
-
name:
|
|
56
|
-
components: {BaseText, BoutCard, TableauBoutCard, TableauColumn},
|
|
101
|
+
name: "Tableau",
|
|
102
|
+
components: { BaseText, BoutCard, TableauBoutCard, TableauColumn },
|
|
103
|
+
emits: ["action:editBout", "action:directingBout", "action:assignBout"],
|
|
57
104
|
props: {
|
|
58
|
-
bouts: {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
105
|
+
bouts: { type: Array, required: true },
|
|
106
|
+
bracketSize: { type: String, required: true },
|
|
107
|
+
hostingClubColors: { type: Object, required: true },
|
|
108
|
+
largeCards: { type: Boolean, required: true },
|
|
109
|
+
listView: { type: Boolean, required: false },
|
|
110
|
+
isCountingBackwardsMaxScore: { type: Number, default: 0 },
|
|
111
|
+
|
|
112
|
+
// use role (already present upstream) instead of passing isAdmin
|
|
113
|
+
role: { type: String, default: "Admin" },
|
|
114
|
+
|
|
115
|
+
// needed for "Assigned Bouts" section
|
|
116
|
+
currentUserId: { type: [Number, String], default: null },
|
|
117
|
+
},
|
|
118
|
+
computed: {
|
|
119
|
+
isAdmin() {
|
|
120
|
+
return String(this.role || "").toLowerCase() === "admin";
|
|
69
121
|
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
122
|
+
|
|
123
|
+
assignedBoutsToMe() {
|
|
124
|
+
const me = Number(this.currentUserId);
|
|
125
|
+
if (!me) return [];
|
|
126
|
+
return (this.bouts || [])
|
|
127
|
+
.filter(
|
|
128
|
+
(b) =>
|
|
129
|
+
Number(b.RefereeId) === me &&
|
|
130
|
+
String(b.Status || "").toLowerCase() !== "completed"
|
|
131
|
+
)
|
|
132
|
+
.slice()
|
|
133
|
+
.sort((a, b) => Number(a.DEBoutId ?? 0) - Number(b.DEBoutId ?? 0));
|
|
73
134
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
135
|
+
|
|
136
|
+
hasAssignedBouts() {
|
|
137
|
+
return this.assignedBoutsToMe.length > 0;
|
|
77
138
|
},
|
|
78
|
-
|
|
79
|
-
type: Number,
|
|
80
|
-
default: 0
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
emits: ['action:editBout', 'action:directingBout'],
|
|
84
|
-
computed: {
|
|
139
|
+
|
|
85
140
|
groupedBouts() {
|
|
86
141
|
const grouped = this.groupBoutsByRound(this.bouts);
|
|
87
142
|
|
|
88
|
-
|
|
89
|
-
const {winnerBouts, loserBouts} = Object.entries(grouped).reduce(
|
|
143
|
+
const { winnerBouts, loserBouts } = Object.entries(grouped).reduce(
|
|
90
144
|
(acc, [roundName, bouts]) => {
|
|
91
|
-
if (roundName.includes(
|
|
145
|
+
if (roundName.includes("Consolation")) {
|
|
92
146
|
acc.loserBouts[roundName] = bouts;
|
|
93
147
|
} else {
|
|
94
148
|
acc.winnerBouts[roundName] = bouts;
|
|
95
149
|
}
|
|
96
150
|
return acc;
|
|
97
151
|
},
|
|
98
|
-
{winnerBouts: {}, loserBouts: {}}
|
|
152
|
+
{ winnerBouts: {}, loserBouts: {} }
|
|
99
153
|
);
|
|
100
154
|
|
|
101
|
-
return {winnerBouts, loserBouts};
|
|
155
|
+
return { winnerBouts, loserBouts };
|
|
102
156
|
},
|
|
157
|
+
|
|
103
158
|
combinedBouts() {
|
|
104
|
-
const combined = {
|
|
159
|
+
const combined = {
|
|
160
|
+
...this.groupedBouts.winnerBouts,
|
|
161
|
+
...this.groupedBouts.loserBouts,
|
|
162
|
+
};
|
|
105
163
|
return Object.keys(combined)
|
|
106
164
|
.sort()
|
|
107
165
|
.reduce((acc, roundName) => {
|
|
@@ -109,21 +167,20 @@ export default {
|
|
|
109
167
|
return acc;
|
|
110
168
|
}, {});
|
|
111
169
|
},
|
|
170
|
+
|
|
112
171
|
filteredBouts() {
|
|
113
172
|
return Object.keys(this.combinedBouts)
|
|
114
173
|
.sort((a, b) => {
|
|
115
174
|
const priority = {
|
|
116
175
|
Final: 1,
|
|
117
176
|
"Third Place Match": 2,
|
|
118
|
-
Semifinal: 3
|
|
177
|
+
Semifinal: 3,
|
|
119
178
|
};
|
|
120
179
|
|
|
121
180
|
const priorityA = priority[a] || 0;
|
|
122
181
|
const priorityB = priority[b] || 0;
|
|
123
182
|
|
|
124
|
-
if (priorityA || priorityB)
|
|
125
|
-
return priorityA - priorityB;
|
|
126
|
-
}
|
|
183
|
+
if (priorityA || priorityB) return priorityA - priorityB;
|
|
127
184
|
|
|
128
185
|
const numA = parseInt(a.match(/\d+/)?.[0] || 0, 10);
|
|
129
186
|
const numB = parseInt(b.match(/\d+/)?.[0] || 0, 10);
|
|
@@ -131,69 +188,72 @@ export default {
|
|
|
131
188
|
return numB - numA;
|
|
132
189
|
})
|
|
133
190
|
.reduce((acc, roundName) => {
|
|
134
|
-
const
|
|
191
|
+
const filtered = this.combinedBouts[roundName]
|
|
135
192
|
.filter(
|
|
136
|
-
bout =>
|
|
137
|
-
bout.Person1?.DisplayName !==
|
|
138
|
-
bout.Person2?.DisplayName !==
|
|
139
|
-
bout.Status !==
|
|
193
|
+
(bout) =>
|
|
194
|
+
bout.Person1?.DisplayName !== "BYE" &&
|
|
195
|
+
bout.Person2?.DisplayName !== "BYE" &&
|
|
196
|
+
bout.Status !== "Completed"
|
|
140
197
|
)
|
|
141
198
|
.sort((a, b) => a.DEBoutId - b.DEBoutId);
|
|
142
199
|
|
|
143
|
-
if (
|
|
144
|
-
acc[roundName] = filteredBouts;
|
|
145
|
-
}
|
|
200
|
+
if (filtered.length) acc[roundName] = filtered;
|
|
146
201
|
return acc;
|
|
147
202
|
}, {});
|
|
148
203
|
},
|
|
149
204
|
},
|
|
205
|
+
|
|
150
206
|
methods: {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
207
|
+
// --- helpers ---
|
|
208
|
+
_findBoutByIds(idsOrBout) {
|
|
209
|
+
// BoutCard emits ids for start/resume/edit; assign emits ids too.
|
|
210
|
+
// normalize to actual bout object
|
|
211
|
+
if (!idsOrBout) return null;
|
|
212
|
+
if (idsOrBout.BoutId && idsOrBout.Person1) return idsOrBout; // already a bout-ish object
|
|
213
|
+
|
|
214
|
+
const boutId = idsOrBout?.BoutId ?? idsOrBout?.boutId;
|
|
215
|
+
if (!boutId) return null;
|
|
216
|
+
return (this.bouts || []).find((b) => String(b.BoutId) === String(boutId)) || null;
|
|
157
217
|
},
|
|
218
|
+
|
|
219
|
+
// Assign button from BoutCard (inactive scheduled variant)
|
|
220
|
+
handleAssignBout(ids) {
|
|
221
|
+
const bout = this._findBoutByIds(ids);
|
|
222
|
+
if (!bout) return;
|
|
223
|
+
this.$emit("action:assignBout", bout);
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
// Start/Resume from BoutCard
|
|
227
|
+
handleDirectingFromIds(ids) {
|
|
228
|
+
const bout = this._findBoutByIds(ids);
|
|
229
|
+
if (!bout) return;
|
|
230
|
+
this.$emit("action:directingBout", bout);
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
// Edit from BoutCard
|
|
234
|
+
handleEditFromIds(ids) {
|
|
235
|
+
const bout = this._findBoutByIds(ids);
|
|
236
|
+
if (!bout) return;
|
|
237
|
+
this.$emit("action:editBout", bout);
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
// TableauColumn / non-list view already emits bout objects
|
|
158
241
|
handleEditBout(bout) {
|
|
159
|
-
this.$emit(
|
|
242
|
+
this.$emit("action:editBout", bout);
|
|
160
243
|
},
|
|
161
244
|
handleDirectorBout(bout) {
|
|
162
|
-
this.$emit(
|
|
245
|
+
this.$emit("action:directingBout", bout);
|
|
163
246
|
},
|
|
247
|
+
|
|
164
248
|
groupBoutsByRound(bouts) {
|
|
165
|
-
return bouts.reduce((acc, bout) => {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
acc[bout.RoundLabel].push(bout);
|
|
249
|
+
return (bouts || []).reduce((acc, bout) => {
|
|
250
|
+
const key = bout.RoundLabel || "Unknown Round";
|
|
251
|
+
if (!acc[key]) acc[key] = [];
|
|
252
|
+
acc[key].push(bout);
|
|
170
253
|
return acc;
|
|
171
254
|
}, {});
|
|
172
255
|
},
|
|
173
|
-
}
|
|
256
|
+
},
|
|
174
257
|
};
|
|
175
258
|
</script>
|
|
176
259
|
|
|
177
|
-
<style scoped>
|
|
178
|
-
/* width */
|
|
179
|
-
::-webkit-scrollbar {
|
|
180
|
-
width: 15px;
|
|
181
|
-
height: 15px;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/* Track */
|
|
185
|
-
::-webkit-scrollbar-track {
|
|
186
|
-
background: #f6fafd;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/* Handle */
|
|
190
|
-
::-webkit-scrollbar-thumb {
|
|
191
|
-
background: #d5e4ee;
|
|
192
|
-
border-radius: 5px;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/* Handle on hover */
|
|
196
|
-
::-webkit-scrollbar-thumb:hover {
|
|
197
|
-
background: #c3cce0;
|
|
198
|
-
}
|
|
199
|
-
</style>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Bracket from './Bracket.vue';
|
|
2
|
+
import getDirectors from '../../../../mocks/getDirectors.js';
|
|
2
3
|
//import getDEWithBouts from '../../../../mocks/getDEWithBouts.js';
|
|
3
4
|
import getDEWithBouts6Fencers from '../../../../mocks/getDeBouts-6fencers.js';
|
|
4
5
|
import getDEWithBouts12Fencers from '../../../../mocks/getDeBouts-12fencers.js';
|
|
@@ -17,7 +18,9 @@ export default {
|
|
|
17
18
|
eventRules: getDEWithBouts.eventRules,
|
|
18
19
|
hostingClubColors: getDEWithBouts.hostingClubColors,
|
|
19
20
|
connectedToServer: true,
|
|
20
|
-
role: 'admin'
|
|
21
|
+
role: 'admin',
|
|
22
|
+
directors: getDirectors,
|
|
23
|
+
currentUserId: 79, // optional but useful if you're showing "Assigned Bouts"
|
|
21
24
|
},
|
|
22
25
|
argTypes: {
|
|
23
26
|
bouts: {
|
|
@@ -34,7 +37,9 @@ export default {
|
|
|
34
37
|
},
|
|
35
38
|
role: {
|
|
36
39
|
control: String
|
|
37
|
-
}
|
|
40
|
+
},
|
|
41
|
+
directors: { control: 'object' },
|
|
42
|
+
currentUserId: { control: 'number' },
|
|
38
43
|
},
|
|
39
44
|
};
|
|
40
45
|
|
|
@@ -45,7 +50,9 @@ export const Default = {
|
|
|
45
50
|
hostingClubColors: getDEWithBouts12Fencers.hostingClubColors,
|
|
46
51
|
connectedToServer: true,
|
|
47
52
|
status: 'de',
|
|
48
|
-
role: 'Admin'
|
|
53
|
+
role: 'Admin',
|
|
54
|
+
directors: getDirectors,
|
|
55
|
+
currentUserId: 79,
|
|
49
56
|
}
|
|
50
57
|
};
|
|
51
58
|
|
|
@@ -55,7 +62,9 @@ export const TableOfEight = {
|
|
|
55
62
|
eventRules: getDEWithBouts6Fencers.eventRules,
|
|
56
63
|
hostingClubColors: getDEWithBouts6Fencers.hostingClubColors,
|
|
57
64
|
connectedToServer: true,
|
|
58
|
-
status: 'de'
|
|
65
|
+
status: 'de',
|
|
66
|
+
directors: getDirectors,
|
|
67
|
+
currentUserId: 79,
|
|
59
68
|
}
|
|
60
69
|
};
|
|
61
70
|
|
|
@@ -65,7 +74,9 @@ export const TableWithTwentyTwo = {
|
|
|
65
74
|
eventRules: getDEWithBouts22Fencers.eventRules,
|
|
66
75
|
hostingClubColors: getDEWithBouts22Fencers.hostingClubColors,
|
|
67
76
|
connectedToServer: true,
|
|
68
|
-
status: 'de'
|
|
77
|
+
status: 'de',
|
|
78
|
+
directors: getDirectors,
|
|
79
|
+
currentUserId: 79,
|
|
69
80
|
}
|
|
70
81
|
};
|
|
71
82
|
|
|
@@ -75,7 +86,9 @@ export const tableOfThirtyTwo = {
|
|
|
75
86
|
eventRules: getDEWithBouts.eventRules,
|
|
76
87
|
hostingClubColors: getDEWithBouts.hostingClubColors,
|
|
77
88
|
connectedToServer: true,
|
|
78
|
-
status: 'de'
|
|
89
|
+
status: 'de',
|
|
90
|
+
directors: getDirectors,
|
|
91
|
+
currentUserId: 79,
|
|
79
92
|
}
|
|
80
93
|
};
|
|
81
94
|
|
|
@@ -85,7 +98,9 @@ export const tableOfFourtyTwo = {
|
|
|
85
98
|
eventRules: getDEWithBout42Fencers.eventRules,
|
|
86
99
|
hostingClubColors: getDEWithBout42Fencers.hostingClubColors,
|
|
87
100
|
connectedToServer: true,
|
|
88
|
-
status: 'de'
|
|
101
|
+
status: 'de',
|
|
102
|
+
directors: getDirectors,
|
|
103
|
+
currentUserId: 79,
|
|
89
104
|
}
|
|
90
105
|
};
|
|
91
106
|
|
|
@@ -95,7 +110,9 @@ export const tableOfSixtyFour = {
|
|
|
95
110
|
eventRules: getDEWithBouts67Fencers.eventRules,
|
|
96
111
|
hostingClubColors: getDEWithBouts67Fencers.hostingClubColors,
|
|
97
112
|
connectedToServer: true,
|
|
98
|
-
status: 'de'
|
|
113
|
+
status: 'de',
|
|
114
|
+
directors: getDirectors,
|
|
115
|
+
currentUserId: 79,
|
|
99
116
|
}
|
|
100
117
|
};
|
|
101
118
|
|
|
@@ -105,7 +122,9 @@ export const tableOfOneHundredTwentyEight = {
|
|
|
105
122
|
eventRules: getDEWithBouts128Fencers.eventRules,
|
|
106
123
|
hostingClubColors: getDEWithBouts128Fencers.hostingClubColors,
|
|
107
124
|
connectedToServer: true,
|
|
108
|
-
status: 'de'
|
|
125
|
+
status: 'de',
|
|
126
|
+
directors: getDirectors,
|
|
127
|
+
currentUserId: 79,
|
|
109
128
|
}
|
|
110
129
|
};
|
|
111
130
|
|
|
@@ -115,6 +134,8 @@ export const noBoutsYet = {
|
|
|
115
134
|
eventRules: getDEWithBouts22Fencers.eventRules,
|
|
116
135
|
hostingClubColors: getDEWithBouts22Fencers.hostingClubColors,
|
|
117
136
|
connectedToServer: true,
|
|
118
|
-
status: 'live'
|
|
137
|
+
status: 'live',
|
|
138
|
+
directors: getDirectors,
|
|
139
|
+
currentUserId: 79,
|
|
119
140
|
}
|
|
120
141
|
};
|
|
@@ -11,14 +11,20 @@
|
|
|
11
11
|
:connectedToServer="connectedToServer"
|
|
12
12
|
@update:selection="handleViewChange"
|
|
13
13
|
@update:cardSize="handleCardSizeToggle"/>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
|
|
15
|
+
<Tableau
|
|
16
|
+
:bouts="sortedBouts"
|
|
17
|
+
:hostingClubColors="hostingClubColors"
|
|
18
|
+
:bracketSize="bracketSize"
|
|
19
|
+
:largeCards="largeCards"
|
|
20
|
+
:listView="isListView"
|
|
21
|
+
:isCountingBackwardsMaxScore="isCountingBackwardsMaxScore"
|
|
22
|
+
:role="role"
|
|
23
|
+
:currentUserId="currentUserId"
|
|
24
|
+
@action:editBout="editBout"
|
|
25
|
+
@action:directingBout="directBout"
|
|
26
|
+
@action:assignBout="openAssignDirector"
|
|
27
|
+
/>
|
|
22
28
|
|
|
23
29
|
<div v-if="bouts.length < 1" class="w-full flex justify-center items-center">
|
|
24
30
|
<div class="text-center mb-10">
|
|
@@ -49,6 +55,14 @@
|
|
|
49
55
|
@update:closeModal="handleCloseModal"
|
|
50
56
|
@submit:bout="handleSubmitBout"/>
|
|
51
57
|
|
|
58
|
+
<AssignDirectorModal
|
|
59
|
+
:show="showAssignDirectorModal"
|
|
60
|
+
:bout="assigningBout || {}"
|
|
61
|
+
:directors="directors"
|
|
62
|
+
@update:closeModal="closeAssignDirectorModal"
|
|
63
|
+
@assign="handleAssignDirector"
|
|
64
|
+
/>
|
|
65
|
+
|
|
52
66
|
</section>
|
|
53
67
|
</template>
|
|
54
68
|
|
|
@@ -64,9 +78,11 @@ import TableauColumn from "../../../Organisms/Containers/TableauColumn/TableauCo
|
|
|
64
78
|
import ServerConnected from "../../../Molecules/Indicators/ServerConnected/ServerConnected.vue";
|
|
65
79
|
import emptyDesertIcon from "../../../../assets/empty_desert_icon.png";
|
|
66
80
|
import { tabs } from '../../../Util/tabs.js';
|
|
81
|
+
import AssignDirectorModal from "../../../Molecules/Modals/AssignDirectorModal/AssignDirectorModal.vue";
|
|
67
82
|
|
|
68
83
|
export default {
|
|
69
84
|
components: {
|
|
85
|
+
AssignDirectorModal,
|
|
70
86
|
ServerConnected,
|
|
71
87
|
TableauColumn,
|
|
72
88
|
Tableau,
|
|
@@ -101,9 +117,36 @@ export default {
|
|
|
101
117
|
role: {
|
|
102
118
|
type: String,
|
|
103
119
|
default: 'Admin'
|
|
104
|
-
}
|
|
120
|
+
},
|
|
121
|
+
directors: {
|
|
122
|
+
type: Array,
|
|
123
|
+
default: () => []
|
|
124
|
+
},
|
|
125
|
+
currentUserId: {
|
|
126
|
+
type: [Number, String],
|
|
127
|
+
default: null
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
},
|
|
131
|
+
data() {
|
|
132
|
+
return {
|
|
133
|
+
emptyDesertIcon,
|
|
134
|
+
showDirectorModal: false,
|
|
135
|
+
showEditBoutModal: false,
|
|
136
|
+
selectedBout: {},
|
|
137
|
+
tabs,
|
|
138
|
+
viewName: "Tableau",
|
|
139
|
+
largeCards: true,
|
|
140
|
+
boutsData: [...this.bouts],
|
|
141
|
+
isListView: false,
|
|
142
|
+
showAssignDirectorModal: false,
|
|
143
|
+
assigningBout: null,
|
|
144
|
+
};
|
|
105
145
|
},
|
|
106
146
|
computed: {
|
|
147
|
+
isAdmin() {
|
|
148
|
+
return String(this.role || '').toLowerCase() === 'admin';
|
|
149
|
+
},
|
|
107
150
|
isCountingBackwardsMaxScore() {
|
|
108
151
|
// 1) see if PoolScoreDirection exists and is explicitly "false"
|
|
109
152
|
const dirRule = this.eventRules.find(r => r.Rules?.RuleName === 'PoolScoreDirection');
|
|
@@ -138,19 +181,6 @@ export default {
|
|
|
138
181
|
});
|
|
139
182
|
}
|
|
140
183
|
},
|
|
141
|
-
data() {
|
|
142
|
-
return {
|
|
143
|
-
emptyDesertIcon,
|
|
144
|
-
showDirectorModal: false,
|
|
145
|
-
showEditBoutModal: false,
|
|
146
|
-
selectedBout: {},
|
|
147
|
-
tabs,
|
|
148
|
-
viewName: "Tableau",
|
|
149
|
-
largeCards: true,
|
|
150
|
-
boutsData: [...this.bouts],
|
|
151
|
-
isListView: false
|
|
152
|
-
};
|
|
153
|
-
},
|
|
154
184
|
watch: {
|
|
155
185
|
bouts: {
|
|
156
186
|
handler(newBouts) {
|
|
@@ -168,6 +198,33 @@ export default {
|
|
|
168
198
|
window.removeEventListener('resize', this.updateViewBasedOnScreenSize);
|
|
169
199
|
},
|
|
170
200
|
methods: {
|
|
201
|
+
handleAssignDirector({ bout, director }) {
|
|
202
|
+
const boutId = bout?.BoutId;
|
|
203
|
+
if (!boutId) return;
|
|
204
|
+
|
|
205
|
+
const patched = {
|
|
206
|
+
...bout,
|
|
207
|
+
RefereeId: director.PersonId,
|
|
208
|
+
RefName: director.DisplayName,
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
this.boutsData = this.boutsData.map(b =>
|
|
212
|
+
b.BoutId === boutId ? { ...b, ...patched } : b
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
// bubble up so the real app persists it
|
|
216
|
+
this.$emit('update:bout', patched);
|
|
217
|
+
|
|
218
|
+
this.closeAssignDirectorModal();
|
|
219
|
+
},
|
|
220
|
+
openAssignDirector(bout) {
|
|
221
|
+
this.assigningBout = bout;
|
|
222
|
+
this.showAssignDirectorModal = true;
|
|
223
|
+
},
|
|
224
|
+
closeAssignDirectorModal() {
|
|
225
|
+
this.showAssignDirectorModal = false;
|
|
226
|
+
this.assigningBout = null;
|
|
227
|
+
},
|
|
171
228
|
handleCloseModal(bout) {
|
|
172
229
|
this.showDirectorModal = false;
|
|
173
230
|
this.showEditBoutModal = false;
|
|
@@ -34,8 +34,6 @@ export default {
|
|
|
34
34
|
hostingClubColors: getPoolsWithBoutsByPoolId.hostingClubColors,
|
|
35
35
|
connectedToServer: true,
|
|
36
36
|
editMode: true,
|
|
37
|
-
|
|
38
|
-
// IMPORTANT: these drive Admin + Assigned logic
|
|
39
37
|
role: 'admin',
|
|
40
38
|
currentUserId: 79, // Tom Testerlou
|
|
41
39
|
directors: getDirectors,
|