@dcrackel/hematournamentui 1.0.712 → 1.0.713
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/.prettierignore +7 -7
- package/.storybook/main.js +3 -1
- package/README.md +30 -0
- package/package.json +96 -96
- package/prettier.config.js +16 -16
- package/src/main.js +1 -1
- package/src/mocks/getDEBouts-TableOf128.js +37 -37
- package/src/mocks/getDEBouts-TableOf64.js +35 -35
- package/src/stories/Atoms/Input/BaseInput.test.js +97 -97
- package/src/stories/Atoms/Input/BaseInput.vue +149 -149
- package/src/stories/Molecules/Indicators/MissingHemaRatingsId/MissingHemaRatingsId.stories.js +23 -23
- package/src/stories/Molecules/Indicators/MissingHemaRatingsId/MissingHemaRatingsId.vue +35 -35
- package/src/stories/Molecules/Indicators/RegistrationStatus/RegistrationStatus.vue +30 -30
- package/src/stories/Molecules/Menus/HoverActions/HoverActions.test.js +138 -0
- package/src/stories/Molecules/Menus/HoverActions/HoverActions.vue +212 -0
- package/src/stories/Molecules/Modals/DirectorModal/DirectorModal.stories.js +6 -0
- package/src/stories/Molecules/Modals/DirectorModal/DirectorModal.test.js +18 -18
- package/src/stories/Molecules/Modals/DirectorModal/DirectorModal.vue +1 -1
- package/src/stories/Organisms/Cards/BoutCard/BoutCard.vue +5 -1
- package/src/stories/Organisms/Cards/BoutCard/Variants/BoutCardActive/BoutCardActive.vue +19 -10
- package/src/stories/Organisms/Cards/BoutCard/Variants/BoutCardInactive/BoutCardInactive.vue +11 -7
- package/src/stories/Organisms/Cards/BracketDirectorAssignmentCard/BracketDirectorAssignmentCard.stories.js +33 -33
- package/src/stories/Organisms/Cards/BracketDirectorAssignmentCard/BracketDirectorAssignmentCard.test.js +45 -45
- package/src/stories/Organisms/Cards/BracketDirectorAssignmentCard/BracketDirectorAssignmentCard.vue +103 -103
- package/src/stories/Organisms/Cards/Director/DirectorCard.test.js +82 -0
- package/src/stories/Organisms/Cards/Director/DirectorCard.vue +32 -51
- package/src/stories/Organisms/Cards/EditBout/EditBout.test.js +51 -51
- package/src/stories/Organisms/Cards/EventCard/EventCard.test.js +106 -106
- package/src/stories/Organisms/Cards/FencerCard/FencerCard.vue +298 -298
- package/src/stories/Organisms/Cards/TableauBoutCard/TableauBoutCard.stories.js +77 -60
- package/src/stories/Organisms/Cards/TableauBoutCard/TableauBoutCard.test.js +144 -143
- package/src/stories/Organisms/Cards/TableauBoutCard/TableauBoutCard.vue +289 -256
- package/src/stories/Organisms/Cards/TableauFencerCard/TableauFencerCard.stories.js +69 -69
- package/src/stories/Organisms/Cards/TableauFencerCard/TableauFencerCard.vue +80 -80
- package/src/stories/Organisms/Cards/WaitlistFencerCard/WaitlistFencerCard.vue +153 -153
- package/src/stories/Organisms/ComplexInputs/DropDown/DropDownMenu.vue +4 -0
- package/src/stories/Organisms/ComplexInputs/ImageCropper/ImageCropper.stories.js +31 -31
- package/src/stories/Organisms/ComplexInputs/ImageCropper/ImageCropper.test.js +109 -109
- package/src/stories/Organisms/ComplexInputs/ImageCropper/ImageCropper.vue +192 -192
- package/src/stories/Organisms/Containers/Tableau/Tableau.stories.js +1 -0
- package/src/stories/Organisms/Containers/Tableau/Tableau.test.js +247 -204
- package/src/stories/Organisms/Containers/Tableau/Tableau.vue +89 -15
- package/src/stories/Organisms/Containers/Tableau/components/BracketDirectorAssignmentPanel.test.js +29 -29
- package/src/stories/Organisms/Containers/Tableau/components/BracketDirectorAssignmentPanel.vue +46 -46
- package/src/stories/Organisms/Containers/Tableau/components/TableauSvgOverlay.test.js +21 -21
- package/src/stories/Organisms/Containers/Tableau/components/TableauSvgOverlay.vue +39 -39
- package/src/stories/Organisms/Containers/Tableau/layout/TableauLayoutEngine.js +145 -145
- package/src/stories/Organisms/Containers/Tableau/layout/TableauLayoutEngine.test.js +64 -64
- package/src/stories/Organisms/Containers/Tableau/plannedAssignments.js +36 -57
- package/src/stories/Organisms/Containers/Tableau/plannedAssignments.test.js +101 -65
- package/src/stories/Organisms/Containers/TableauColumn/TableauColumn.vue +14 -1
- package/src/stories/Organisms/Wizards/EditEventWizard/BasicEventInfo/BasicEventInfo.stories.js +52 -52
- package/src/stories/Organisms/Wizards/EditEventWizard/BasicEventInfo/BasicEventInfo.vue +10 -3
- package/src/stories/Organisms/Wizards/EditEventWizard/DirectElimination/DirectElimination.vue +226 -226
- package/src/stories/Organisms/Wizards/EditEventWizard/DirectEliminationPromotion/DirectEliminationPromotion.vue +204 -204
- package/src/stories/Organisms/Wizards/EditEventWizard/EditEventWizard.stories.js +137 -137
- package/src/stories/Organisms/Wizards/EditEventWizard/EventCustomization/EventCustomization.vue +172 -172
- package/src/stories/Organisms/Wizards/EditEventWizard/PoolConfiguration/PoolConfiguration.vue +216 -216
- package/src/stories/Organisms/Wizards/EditEventWizard/PriceFields.test.js +79 -79
- package/src/stories/Organisms/Wizards/EditEventWizard/RuleSerialization.test.js +29 -29
- package/src/stories/Organisms/Wizards/EditEventWizard/WeaponSelection.test.js +138 -0
- package/src/stories/Templates/EventManagement/Bracket/Bracket.stories.js +123 -12
- package/src/stories/Templates/EventManagement/Bracket/Bracket.test.js +178 -166
- package/src/stories/Templates/EventManagement/Bracket/Bracket.vue +35 -7
- package/src/stories/Templates/EventManagement/Bracket/BracketDirectorAssignment.test.js +242 -0
- package/src/stories/Templates/EventManagement/Bracket/BracketMobile.test.js +131 -0
- package/src/stories/Templates/EventManagement/Bracket/BracketPlannedSuggestions.js +42 -39
- package/src/stories/Templates/EventManagement/Bracket/BracketStories.test.js +80 -0
- package/src/stories/Templates/EventManagement/Bracket/BracketStoryAssignments.js +93 -0
- package/src/stories/Templates/EventManagement/Bracket/BracketStoryAssignments.test.js +152 -0
- package/src/stories/Templates/EventManagement/Bracket/BracketStoryHarness.js +39 -39
- package/src/stories/Templates/EventManagement/Bracket/BracketStoryHarness.test.js +79 -79
- package/src/stories/Templates/EventManagement/EditEventInfo/EditEventInfo.stories.js +93 -93
- package/src/stories/Templates/EventManagement/EditEventInfo/EditEventInfo.vue +91 -91
- package/src/stories/Templates/EventManagement/PoolLive/PoolLive.test.js +121 -121
- package/src/stories/Templates/Menus/EditEventsTopMenu/EditEventsTopMenu.stories.js +9 -2
- package/src/stories/Templates/Menus/EditEventsTopMenu/EditEventsTopMenu.vue +5 -4
- package/src/stories/Templates/PersonManagement/Admin/Administration/Administration.stories.js +81 -81
- package/src/stories/Templates/PersonManagement/Admin/Administration/Administration.test.js +39 -39
- package/src/stories/Templates/PersonManagement/Admin/Administration/Administration.vue +101 -101
- package/src/stories/Templates/PersonManagement/Admin/FencerAdmin/FencerAdmin.stories.js +71 -71
- package/src/stories/Templates/PersonManagement/Admin/FencerAdmin/FencerAdmin.vue +86 -86
- package/src/stories/Templates/PersonManagement/Admin/MergeAccounts/MergeAccounts.stories.js +86 -86
- package/src/stories/Templates/PersonManagement/Admin/MergeAccounts/MergeAccounts.vue +247 -247
- package/src/stories/Templates/PersonManagement/Basic/BasicEdit.vue +170 -170
- package/src/stories/Templates/PersonManagement/PersonManagement.stories.js +156 -156
- package/src/stories/Templates/PersonManagement/PersonManagement.test.js +329 -329
- package/src/stories/Templates/PersonManagement/PersonManagement.vue +329 -329
- package/src/stories/Templates/PersonManagement/PersonManagementDraft.js +42 -42
- package/src/stories/Templates/TournamentManagement/TournamentManagement.stories.js +84 -84
- package/src/stories/Templates/TournamentManagement/TournamentManagement.test.js +114 -114
- package/src/stories/Templates/TournamentManagement/TournamentManagement.vue +363 -363
- package/src/stories/Templates/TournamentManagement/TournamentPageOne/TournamentPageOne.stories.js +116 -116
- package/src/stories/Templates/TournamentManagement/TournamentPageOne/TournamentPageOne.vue +307 -307
- package/src/stories/Util/Validations/PersonManagementValidations.js +45 -45
- package/src/stories/Util/Validations/PriceValidation.js +6 -6
- package/src/stories/Util/boutDirectorAssignment.js +46 -0
- package/src/stories/Util/registrationStatus.js +11 -11
- package/src/stories/Util/tabs.js +19 -47
|
@@ -1,166 +1,178 @@
|
|
|
1
|
-
import { shallowMount } from '@vue/test-utils';
|
|
2
|
-
import { describe, expect, it } from 'vitest';
|
|
3
|
-
import DirectorModal from '../../../Molecules/Modals/DirectorModal/DirectorModal.vue';
|
|
4
|
-
import EditBoutModal from '../../../Molecules/Modals/EditBoutModal/EditBoutModal.vue';
|
|
5
|
-
import Tableau from '../../../Organisms/Containers/Tableau/Tableau.vue';
|
|
6
|
-
import BracketDirectorAssignmentPanel from '../../../Organisms/Containers/Tableau/components/BracketDirectorAssignmentPanel.vue';
|
|
7
|
-
import Bracket from './Bracket.vue';
|
|
8
|
-
|
|
9
|
-
const createBout = (overrides = {}) => ({
|
|
10
|
-
BoutId: 42,
|
|
11
|
-
DEBoutId: 1,
|
|
12
|
-
RoundLabel: 'Final',
|
|
13
|
-
Status: 'Scheduled',
|
|
14
|
-
Score1: 4,
|
|
15
|
-
Score2: 3,
|
|
16
|
-
Person1: { PersonId: 1, DisplayName: 'Fencer One' },
|
|
17
|
-
Person2: { PersonId: 2, DisplayName: 'Fencer Two' },
|
|
18
|
-
...overrides
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
const mountBracket = (bouts = [createBout()], optionalProps = {}) =>
|
|
22
|
-
shallowMount(Bracket, {
|
|
23
|
-
props: {
|
|
24
|
-
bouts,
|
|
25
|
-
eventRules: [],
|
|
26
|
-
hostingClubColors: {},
|
|
27
|
-
connectedToServer: true,
|
|
28
|
-
...optionalProps
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
describe('Bracket bout interaction', () => {
|
|
33
|
-
it('emits directing intent for a scheduled bout and waits for Active props', async () => {
|
|
34
|
-
const bout = createBout();
|
|
35
|
-
const wrapper = mountBracket([bout]);
|
|
36
|
-
|
|
37
|
-
wrapper.findComponent(Tableau).vm.$emit('action:directingBout', bout);
|
|
38
|
-
await wrapper.vm.$nextTick();
|
|
39
|
-
|
|
40
|
-
expect(wrapper.emitted('update:directing-bout')).toEqual([[bout]]);
|
|
41
|
-
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(false);
|
|
42
|
-
|
|
43
|
-
await wrapper.setProps({ bouts: [{ ...bout, Status: 'Active' }] });
|
|
44
|
-
|
|
45
|
-
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(true);
|
|
46
|
-
expect(wrapper.findComponent(DirectorModal).props('bout').Status).toBe('Active');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('resumes an active bout through the directing path', async () => {
|
|
50
|
-
const bout = createBout({ Status: 'Active' });
|
|
51
|
-
const wrapper = mountBracket([bout]);
|
|
52
|
-
|
|
53
|
-
wrapper.findComponent(Tableau).vm.$emit('action:directingBout', bout);
|
|
54
|
-
await wrapper.vm.$nextTick();
|
|
55
|
-
|
|
56
|
-
expect(wrapper.emitted('update:directing-bout')).toEqual([[bout]]);
|
|
57
|
-
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(true);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('opens completed bouts for editing instead of directing', async () => {
|
|
61
|
-
const bout = createBout({ Status: 'Completed' });
|
|
62
|
-
const wrapper = mountBracket([bout]);
|
|
63
|
-
|
|
64
|
-
wrapper.findComponent(Tableau).vm.$emit('action:editBout', bout);
|
|
65
|
-
await wrapper.vm.$nextTick();
|
|
66
|
-
|
|
67
|
-
expect(wrapper.findComponent(EditBoutModal).props('show')).toBe(true);
|
|
68
|
-
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(false);
|
|
69
|
-
expect(wrapper.emitted('update:directing-bout')).toBeUndefined();
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('does not direct a BYE bout', async () => {
|
|
73
|
-
const bout = createBout({
|
|
74
|
-
Person2: { PersonId: 0, DisplayName: 'BYE' }
|
|
75
|
-
});
|
|
76
|
-
const wrapper = mountBracket([bout]);
|
|
77
|
-
|
|
78
|
-
wrapper.findComponent(Tableau).vm.$emit('action:directingBout', bout);
|
|
79
|
-
await wrapper.vm.$nextTick();
|
|
80
|
-
|
|
81
|
-
expect(wrapper.emitted('update:directing-bout')).toBeUndefined();
|
|
82
|
-
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(false);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('closes the scoring modal without changing status or scores', async () => {
|
|
86
|
-
const bout = createBout({ Status: 'Active', Score1: 6, Score2: 5 });
|
|
87
|
-
const wrapper = mountBracket([bout]);
|
|
88
|
-
|
|
89
|
-
wrapper.findComponent(Tableau).vm.$emit('action:directingBout', bout);
|
|
90
|
-
await wrapper.vm.$nextTick();
|
|
91
|
-
wrapper.findComponent(DirectorModal).vm.$emit('update:closeModal', bout);
|
|
92
|
-
await wrapper.vm.$nextTick();
|
|
93
|
-
|
|
94
|
-
expect(wrapper.vm.boutsData[0]).toMatchObject({ Status: 'Active', Score1: 6, Score2: 5 });
|
|
95
|
-
expect(wrapper.emitted('update:bout')).toBeUndefined();
|
|
96
|
-
expect(wrapper.emitted('close:directing-bout')).toEqual([[bout]]);
|
|
97
|
-
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(false);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('emits submitted bout data without assigning completion fields', async () => {
|
|
101
|
-
const bout = createBout({ Status: 'Active' });
|
|
102
|
-
const submittedBout = { ...bout, Score1: 7 };
|
|
103
|
-
const wrapper = mountBracket([bout]);
|
|
104
|
-
|
|
105
|
-
wrapper.findComponent(DirectorModal).vm.$emit('submit:bout', submittedBout);
|
|
106
|
-
await wrapper.vm.$nextTick();
|
|
107
|
-
|
|
108
|
-
const emittedBout = wrapper.emitted('submit:bout')[0][0];
|
|
109
|
-
expect(emittedBout).toEqual(submittedBout);
|
|
110
|
-
expect(emittedBout.Status).toBe('Active');
|
|
111
|
-
expect(emittedBout.Ended).toBeUndefined();
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('does not render a director-selection modal', () => {
|
|
115
|
-
const wrapper = mountBracket();
|
|
116
|
-
|
|
117
|
-
expect(wrapper.findComponent({ name: 'AssignDirectorModal' }).exists()).toBe(false);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('renders optional planned suggestions without changing the directing contract', async () => {
|
|
121
|
-
const bout = createBout();
|
|
122
|
-
const plannedDirectingStations = [
|
|
123
|
-
{
|
|
124
|
-
RingId: 1,
|
|
125
|
-
RingName: 'Ring 1',
|
|
126
|
-
Color: '#2563eb',
|
|
127
|
-
Director: { PersonId: 1001, DisplayName: 'Alex Morgan' }
|
|
128
|
-
}
|
|
129
|
-
];
|
|
130
|
-
const plannedBoutAssignments = [{ DEBoutId: bout.DEBoutId, RingId: 1 }];
|
|
131
|
-
const wrapper = mountBracket([bout], {
|
|
132
|
-
plannedDirectingStations,
|
|
133
|
-
plannedBoutAssignments,
|
|
134
|
-
viewerPersonId: 1001
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
expect(wrapper.findComponent(BracketDirectorAssignmentPanel).props('stations')).toEqual(plannedDirectingStations);
|
|
138
|
-
expect(wrapper.findComponent(Tableau).props()).toMatchObject({
|
|
139
|
-
plannedDirectingStations,
|
|
140
|
-
plannedBoutAssignments,
|
|
141
|
-
viewerPersonId: 1001
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
wrapper.findComponent(Tableau).vm.$emit('action:directingBout', bout);
|
|
145
|
-
await wrapper.vm.$nextTick();
|
|
146
|
-
|
|
147
|
-
expect(wrapper.emitted('update:directing-bout')).toEqual([[bout]]);
|
|
148
|
-
expect(wrapper.emitted('assign:director')).toBeUndefined();
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it('emits add-planned-director intent from the assignment panel', async () => {
|
|
152
|
-
const wrapper = mountBracket([], { showPlannedDirectorAssignments: true });
|
|
153
|
-
|
|
154
|
-
wrapper.findComponent(BracketDirectorAssignmentPanel).vm.$emit('request:add-planned-director');
|
|
155
|
-
await wrapper.vm.$nextTick();
|
|
156
|
-
|
|
157
|
-
expect(wrapper.emitted('request:add-planned-director')).toEqual([[]]);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it('does not render planned directing controls when
|
|
161
|
-
const wrapper = mountBracket(
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
1
|
+
import { shallowMount } from '@vue/test-utils';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import DirectorModal from '../../../Molecules/Modals/DirectorModal/DirectorModal.vue';
|
|
4
|
+
import EditBoutModal from '../../../Molecules/Modals/EditBoutModal/EditBoutModal.vue';
|
|
5
|
+
import Tableau from '../../../Organisms/Containers/Tableau/Tableau.vue';
|
|
6
|
+
import BracketDirectorAssignmentPanel from '../../../Organisms/Containers/Tableau/components/BracketDirectorAssignmentPanel.vue';
|
|
7
|
+
import Bracket from './Bracket.vue';
|
|
8
|
+
|
|
9
|
+
const createBout = (overrides = {}) => ({
|
|
10
|
+
BoutId: 42,
|
|
11
|
+
DEBoutId: 1,
|
|
12
|
+
RoundLabel: 'Final',
|
|
13
|
+
Status: 'Scheduled',
|
|
14
|
+
Score1: 4,
|
|
15
|
+
Score2: 3,
|
|
16
|
+
Person1: { PersonId: 1, DisplayName: 'Fencer One' },
|
|
17
|
+
Person2: { PersonId: 2, DisplayName: 'Fencer Two' },
|
|
18
|
+
...overrides
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const mountBracket = (bouts = [createBout()], optionalProps = {}) =>
|
|
22
|
+
shallowMount(Bracket, {
|
|
23
|
+
props: {
|
|
24
|
+
bouts,
|
|
25
|
+
eventRules: [],
|
|
26
|
+
hostingClubColors: {},
|
|
27
|
+
connectedToServer: true,
|
|
28
|
+
...optionalProps
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('Bracket bout interaction', () => {
|
|
33
|
+
it('emits directing intent for a scheduled bout and waits for Active props', async () => {
|
|
34
|
+
const bout = createBout();
|
|
35
|
+
const wrapper = mountBracket([bout]);
|
|
36
|
+
|
|
37
|
+
wrapper.findComponent(Tableau).vm.$emit('action:directingBout', bout);
|
|
38
|
+
await wrapper.vm.$nextTick();
|
|
39
|
+
|
|
40
|
+
expect(wrapper.emitted('update:directing-bout')).toEqual([[bout]]);
|
|
41
|
+
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(false);
|
|
42
|
+
|
|
43
|
+
await wrapper.setProps({ bouts: [{ ...bout, Status: 'Active' }] });
|
|
44
|
+
|
|
45
|
+
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(true);
|
|
46
|
+
expect(wrapper.findComponent(DirectorModal).props('bout').Status).toBe('Active');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('resumes an active bout through the directing path', async () => {
|
|
50
|
+
const bout = createBout({ Status: 'Active' });
|
|
51
|
+
const wrapper = mountBracket([bout]);
|
|
52
|
+
|
|
53
|
+
wrapper.findComponent(Tableau).vm.$emit('action:directingBout', bout);
|
|
54
|
+
await wrapper.vm.$nextTick();
|
|
55
|
+
|
|
56
|
+
expect(wrapper.emitted('update:directing-bout')).toEqual([[bout]]);
|
|
57
|
+
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('opens completed bouts for editing instead of directing', async () => {
|
|
61
|
+
const bout = createBout({ Status: 'Completed' });
|
|
62
|
+
const wrapper = mountBracket([bout]);
|
|
63
|
+
|
|
64
|
+
wrapper.findComponent(Tableau).vm.$emit('action:editBout', bout);
|
|
65
|
+
await wrapper.vm.$nextTick();
|
|
66
|
+
|
|
67
|
+
expect(wrapper.findComponent(EditBoutModal).props('show')).toBe(true);
|
|
68
|
+
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(false);
|
|
69
|
+
expect(wrapper.emitted('update:directing-bout')).toBeUndefined();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('does not direct a BYE bout', async () => {
|
|
73
|
+
const bout = createBout({
|
|
74
|
+
Person2: { PersonId: 0, DisplayName: 'BYE' }
|
|
75
|
+
});
|
|
76
|
+
const wrapper = mountBracket([bout]);
|
|
77
|
+
|
|
78
|
+
wrapper.findComponent(Tableau).vm.$emit('action:directingBout', bout);
|
|
79
|
+
await wrapper.vm.$nextTick();
|
|
80
|
+
|
|
81
|
+
expect(wrapper.emitted('update:directing-bout')).toBeUndefined();
|
|
82
|
+
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(false);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('closes the scoring modal without changing status or scores', async () => {
|
|
86
|
+
const bout = createBout({ Status: 'Active', Score1: 6, Score2: 5 });
|
|
87
|
+
const wrapper = mountBracket([bout]);
|
|
88
|
+
|
|
89
|
+
wrapper.findComponent(Tableau).vm.$emit('action:directingBout', bout);
|
|
90
|
+
await wrapper.vm.$nextTick();
|
|
91
|
+
wrapper.findComponent(DirectorModal).vm.$emit('update:closeModal', bout);
|
|
92
|
+
await wrapper.vm.$nextTick();
|
|
93
|
+
|
|
94
|
+
expect(wrapper.vm.boutsData[0]).toMatchObject({ Status: 'Active', Score1: 6, Score2: 5 });
|
|
95
|
+
expect(wrapper.emitted('update:bout')).toBeUndefined();
|
|
96
|
+
expect(wrapper.emitted('close:directing-bout')).toEqual([[bout]]);
|
|
97
|
+
expect(wrapper.findComponent(DirectorModal).props('show')).toBe(false);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('emits submitted bout data without assigning completion fields', async () => {
|
|
101
|
+
const bout = createBout({ Status: 'Active' });
|
|
102
|
+
const submittedBout = { ...bout, Score1: 7 };
|
|
103
|
+
const wrapper = mountBracket([bout]);
|
|
104
|
+
|
|
105
|
+
wrapper.findComponent(DirectorModal).vm.$emit('submit:bout', submittedBout);
|
|
106
|
+
await wrapper.vm.$nextTick();
|
|
107
|
+
|
|
108
|
+
const emittedBout = wrapper.emitted('submit:bout')[0][0];
|
|
109
|
+
expect(emittedBout).toEqual(submittedBout);
|
|
110
|
+
expect(emittedBout.Status).toBe('Active');
|
|
111
|
+
expect(emittedBout.Ended).toBeUndefined();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('does not render a director-selection modal', () => {
|
|
115
|
+
const wrapper = mountBracket();
|
|
116
|
+
|
|
117
|
+
expect(wrapper.findComponent({ name: 'AssignDirectorModal' }).exists()).toBe(false);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('renders optional planned suggestions without changing the directing contract', async () => {
|
|
121
|
+
const bout = createBout();
|
|
122
|
+
const plannedDirectingStations = [
|
|
123
|
+
{
|
|
124
|
+
RingId: 1,
|
|
125
|
+
RingName: 'Ring 1',
|
|
126
|
+
Color: '#2563eb',
|
|
127
|
+
Director: { PersonId: 1001, DisplayName: 'Alex Morgan' }
|
|
128
|
+
}
|
|
129
|
+
];
|
|
130
|
+
const plannedBoutAssignments = [{ DEBoutId: bout.DEBoutId, RingId: 1 }];
|
|
131
|
+
const wrapper = mountBracket([bout], {
|
|
132
|
+
plannedDirectingStations,
|
|
133
|
+
plannedBoutAssignments,
|
|
134
|
+
viewerPersonId: 1001
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
expect(wrapper.findComponent(BracketDirectorAssignmentPanel).props('stations')).toEqual(plannedDirectingStations);
|
|
138
|
+
expect(wrapper.findComponent(Tableau).props()).toMatchObject({
|
|
139
|
+
plannedDirectingStations,
|
|
140
|
+
plannedBoutAssignments,
|
|
141
|
+
viewerPersonId: 1001
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
wrapper.findComponent(Tableau).vm.$emit('action:directingBout', bout);
|
|
145
|
+
await wrapper.vm.$nextTick();
|
|
146
|
+
|
|
147
|
+
expect(wrapper.emitted('update:directing-bout')).toEqual([[bout]]);
|
|
148
|
+
expect(wrapper.emitted('assign:director')).toBeUndefined();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('emits add-planned-director intent from the assignment panel', async () => {
|
|
152
|
+
const wrapper = mountBracket([], { showPlannedDirectorAssignments: true });
|
|
153
|
+
|
|
154
|
+
wrapper.findComponent(BracketDirectorAssignmentPanel).vm.$emit('request:add-planned-director');
|
|
155
|
+
await wrapper.vm.$nextTick();
|
|
156
|
+
|
|
157
|
+
expect(wrapper.emitted('request:add-planned-director')).toEqual([[]]);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('does not render planned directing controls when explicitly disabled', () => {
|
|
161
|
+
const wrapper = mountBracket(undefined, {
|
|
162
|
+
showPlannedDirectorAssignments: false,
|
|
163
|
+
showBoutDirectorAssignment: false
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
expect(wrapper.findComponent(BracketDirectorAssignmentPanel).exists()).toBe(false);
|
|
167
|
+
expect(wrapper.findComponent(Tableau).props('plannedDirectingStations')).toEqual([]);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
describe('Bracket assignment defaults', () => {
|
|
172
|
+
it('shows assignment actions and the director panel without opt-in props', () => {
|
|
173
|
+
const wrapper = mountBracket();
|
|
174
|
+
expect(wrapper.findComponent(Tableau).props('showBoutDirectorAssignment')).toBe(true);
|
|
175
|
+
expect(wrapper.findComponent(BracketDirectorAssignmentPanel).exists()).toBe(true);
|
|
176
|
+
wrapper.unmount();
|
|
177
|
+
});
|
|
178
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<section>
|
|
3
|
-
<EditEventsTopMenu :currentTab="'Bracket'" :tabs="tabs(role,
|
|
3
|
+
<EditEventsTopMenu :currentTab="'Bracket'" :tabs="tabs(role, isMobile)" @tabMenuClick="handleTabMenuClick" />
|
|
4
4
|
<ToggleHeader
|
|
5
5
|
:currentSelection="viewName"
|
|
6
6
|
:key="viewName"
|
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
@update:selection="handleViewChange"
|
|
12
12
|
/>
|
|
13
13
|
|
|
14
|
+
<ServerConnected
|
|
15
|
+
class="mb-2 md:hidden"
|
|
16
|
+
:connectedToServer="connectedToServer"
|
|
17
|
+
:statusText="connectedToServer ? 'Connected' : 'Disconnected'"
|
|
18
|
+
/>
|
|
19
|
+
|
|
14
20
|
<div class="flex flex-col gap-4 xl:flex-row">
|
|
15
21
|
<div class="min-w-0 flex-1">
|
|
16
22
|
<Tableau
|
|
@@ -22,6 +28,8 @@
|
|
|
22
28
|
:plannedDirectingStations="plannedDirectingStations"
|
|
23
29
|
:plannedBoutAssignments="plannedBoutAssignments"
|
|
24
30
|
:viewerPersonId="viewerPersonId"
|
|
31
|
+
:showBoutDirectorAssignment="canShowBoutDirectorAssignment"
|
|
32
|
+
@request:bout-director="handleBoutDirectorRequest"
|
|
25
33
|
@action:editBout="editBout"
|
|
26
34
|
@action:directingBout="directBout"
|
|
27
35
|
/>
|
|
@@ -38,7 +46,7 @@
|
|
|
38
46
|
|
|
39
47
|
<div v-if="bouts.length < 1" class="w-full flex justify-center items-center">
|
|
40
48
|
<div class="text-center mb-10">
|
|
41
|
-
<img alt="Small desert scene with wind blowing." class="w-96 mx-auto" :src="emptyDesertIcon" />
|
|
49
|
+
<img alt="Small desert scene with wind blowing." class="hidden md:block w-96 mx-auto" :src="emptyDesertIcon" />
|
|
42
50
|
<BaseText text="Nothing to Show Yet!" size="lg" color="quinary" weight="bold" class="text-center" />
|
|
43
51
|
<BaseText
|
|
44
52
|
text="Check Back when this event has progress to Direct Elimination"
|
|
@@ -47,6 +55,7 @@
|
|
|
47
55
|
weight="normal"
|
|
48
56
|
/>
|
|
49
57
|
<BaseText
|
|
58
|
+
class="hidden md:block"
|
|
50
59
|
text="The Generate bracket button will appear on the bottom of the pools screen"
|
|
51
60
|
size="sm"
|
|
52
61
|
color="quinary"
|
|
@@ -84,6 +93,7 @@
|
|
|
84
93
|
<script>
|
|
85
94
|
import EditEventsTopMenu from '../../Menus/EditEventsTopMenu/EditEventsTopMenu.vue';
|
|
86
95
|
import ToggleHeader from '../../../Organisms/Headers/ToggleHeader/ToggleHeader.vue';
|
|
96
|
+
import ServerConnected from '../../../Molecules/Indicators/ServerConnected/ServerConnected.vue';
|
|
87
97
|
import BaseText from '../../../Atoms/Text/BaseText.vue';
|
|
88
98
|
import DirectorModal from '../../../Molecules/Modals/DirectorModal/DirectorModal.vue';
|
|
89
99
|
import EditBoutModal from '../../../Molecules/Modals/EditBoutModal/EditBoutModal.vue';
|
|
@@ -91,6 +101,7 @@ import Tableau from '../../../Organisms/Containers/Tableau/Tableau.vue';
|
|
|
91
101
|
import BracketDirectorAssignmentPanel from '../../../Organisms/Containers/Tableau/components/BracketDirectorAssignmentPanel.vue';
|
|
92
102
|
import emptyDesertIcon from '../../../../assets/empty_desert_icon.png';
|
|
93
103
|
import { tabs } from '../../../Util/tabs.js';
|
|
104
|
+
import { canAssignBoutDirector } from '../../../Util/boutDirectorAssignment.js';
|
|
94
105
|
|
|
95
106
|
const isByeFencer = person => {
|
|
96
107
|
if (!person?.PersonId || Number(person.PersonId) === 0) return true;
|
|
@@ -111,6 +122,7 @@ export default {
|
|
|
111
122
|
'penalty:update',
|
|
112
123
|
'request:add-planned-director',
|
|
113
124
|
'request:bout-active',
|
|
125
|
+
'request:bout-director',
|
|
114
126
|
'submit:bout',
|
|
115
127
|
'tab:menu-click',
|
|
116
128
|
'update:bout',
|
|
@@ -123,9 +135,11 @@ export default {
|
|
|
123
135
|
BracketDirectorAssignmentPanel,
|
|
124
136
|
BaseText,
|
|
125
137
|
ToggleHeader,
|
|
138
|
+
ServerConnected,
|
|
126
139
|
EditEventsTopMenu
|
|
127
140
|
},
|
|
128
141
|
props: {
|
|
142
|
+
showBoutDirectorAssignment: { type: Boolean, default: true },
|
|
129
143
|
bouts: {
|
|
130
144
|
type: Array,
|
|
131
145
|
required: true
|
|
@@ -164,7 +178,7 @@ export default {
|
|
|
164
178
|
},
|
|
165
179
|
showPlannedDirectorAssignments: {
|
|
166
180
|
type: Boolean,
|
|
167
|
-
default:
|
|
181
|
+
default: true
|
|
168
182
|
},
|
|
169
183
|
showAddPlannedDirectorCard: {
|
|
170
184
|
type: Boolean,
|
|
@@ -180,12 +194,21 @@ export default {
|
|
|
180
194
|
tabs,
|
|
181
195
|
viewName: 'Tableau',
|
|
182
196
|
boutsData: this.cloneBouts(this.bouts),
|
|
183
|
-
|
|
197
|
+
windowWidth: typeof window === 'undefined' ? 1024 : window.innerWidth
|
|
184
198
|
};
|
|
185
199
|
},
|
|
186
200
|
computed: {
|
|
201
|
+
isMobile() {
|
|
202
|
+
return this.windowWidth < 768;
|
|
203
|
+
},
|
|
204
|
+
isListView() {
|
|
205
|
+
return this.isMobile || this.viewName === 'List View';
|
|
206
|
+
},
|
|
207
|
+
canShowBoutDirectorAssignment() {
|
|
208
|
+
return !this.isMobile && this.showBoutDirectorAssignment;
|
|
209
|
+
},
|
|
187
210
|
showPlannedAssignmentPanel() {
|
|
188
|
-
return this.showPlannedDirectorAssignments || this.plannedDirectingStations.length > 0;
|
|
211
|
+
return !this.isMobile && (this.showPlannedDirectorAssignments || this.plannedDirectingStations.length > 0);
|
|
189
212
|
},
|
|
190
213
|
isCountingBackwardsMaxScore() {
|
|
191
214
|
// 1) see if PoolScoreDirection exists and is explicitly "false"
|
|
@@ -230,6 +253,12 @@ export default {
|
|
|
230
253
|
window.removeEventListener('resize', this.updateViewBasedOnScreenSize);
|
|
231
254
|
},
|
|
232
255
|
methods: {
|
|
256
|
+
handleBoutDirectorRequest(bout) {
|
|
257
|
+
if (!this.canShowBoutDirectorAssignment) return;
|
|
258
|
+
const currentBout = this.boutsData.find(item => String(item.BoutId) === String(bout?.BoutId));
|
|
259
|
+
if (!canAssignBoutDirector(currentBout)) return;
|
|
260
|
+
this.$emit('request:bout-director', JSON.parse(JSON.stringify(currentBout)));
|
|
261
|
+
},
|
|
233
262
|
handleCloseModal() {
|
|
234
263
|
const closedDirectingBout = this.showDirectorModal && this.selectedBout?.BoutId ? { ...this.selectedBout } : null;
|
|
235
264
|
this.showDirectorModal = false;
|
|
@@ -242,7 +271,6 @@ export default {
|
|
|
242
271
|
},
|
|
243
272
|
handleViewChange(value) {
|
|
244
273
|
this.viewName = value;
|
|
245
|
-
this.isListView = value === 'List View';
|
|
246
274
|
},
|
|
247
275
|
handleUpdateBout(bout) {
|
|
248
276
|
if (!bout?.BoutId) return;
|
|
@@ -279,7 +307,7 @@ export default {
|
|
|
279
307
|
this.selectedBout = updatedBout;
|
|
280
308
|
},
|
|
281
309
|
updateViewBasedOnScreenSize() {
|
|
282
|
-
this.
|
|
310
|
+
this.windowWidth = window.innerWidth;
|
|
283
311
|
},
|
|
284
312
|
handleUpdatePenalty(penalty) {
|
|
285
313
|
this.$emit('penalty:update', penalty);
|