diff --git a/frontend/src/components/tournament/TournamentGroupsTab.vue b/frontend/src/components/tournament/TournamentGroupsTab.vue index a3e0e06a..45cc1e92 100644 --- a/frontend/src/components/tournament/TournamentGroupsTab.vue +++ b/frontend/src/components/tournament/TournamentGroupsTab.vue @@ -42,9 +42,10 @@ @@ -59,8 +60,9 @@ type="number" :value="numberOfGroups" min="1" - @input="$emit('update:numberOfGroups', Math.max(1, parseInt($event.target.value || '1', 10) || 1))" - @change="$emit('group-count-change')" + @input="$emit('update:numberOfGroups', normalizeNumberInput($event.target.value, { min: 1, allowEmpty: true }))" + @keydown.enter.prevent="onNumberOfGroupsBlur($event.target.value)" + @blur="onNumberOfGroupsBlur($event.target.value)" /> @@ -226,11 +228,11 @@ export default { default: null }, groupsPerClassInput: { - type: Number, + type: [Number, String], default: 0 }, numberOfGroups: { - type: Number, + type: [Number, String], required: true }, groups: { @@ -306,6 +308,26 @@ export default { } }, methods: { + normalizeNumberInput(rawValue, { min = 0, allowEmpty = false } = {}) { + if (rawValue === '' || rawValue === null || rawValue === undefined) { + return allowEmpty ? '' : min; + } + const parsed = parseInt(String(rawValue), 10); + if (!Number.isFinite(parsed)) { + return allowEmpty ? '' : min; + } + return Math.max(min, parsed); + }, + onGroupsPerClassBlur(rawValue) { + const normalized = this.normalizeNumberInput(rawValue, { min: 0, allowEmpty: false }); + this.$emit('update:groupsPerClassInput', normalized); + this.$emit('group-count-change'); + }, + onNumberOfGroupsBlur(rawValue) { + const normalized = this.normalizeNumberInput(rawValue, { min: 1, allowEmpty: false }); + this.$emit('update:numberOfGroups', normalized); + this.$emit('group-count-change'); + }, groupRankingsForGroup(group) { const key = `${group.groupId}-${group.classId ?? 'null'}`; return this.groupRankings[key] || []; diff --git a/frontend/src/views/TournamentTab.vue b/frontend/src/views/TournamentTab.vue index 85707c1c..a76467ea 100644 --- a/frontend/src/views/TournamentTab.vue +++ b/frontend/src/views/TournamentTab.vue @@ -939,10 +939,10 @@ export default { return 0; } if (this.selectedViewClass === '__none__') { - return this.groupsPerClass['null'] || 0; + return this.groupsPerClass['null'] ?? 0; } const classId = Number(this.selectedViewClass); - return this.groupsPerClass[classId] || 0; + return this.groupsPerClass[classId] ?? 0; }, set(value) { if (this.selectedViewClass === null || this.selectedViewClass === undefined || this.selectedViewClass === '' || this.selectedViewClass === '__all__' || this.selectedViewClass === 'all') {