From 0a97b31d6ba860e3cacdc8d48ee8400ba3cdbf6d Mon Sep 17 00:00:00 2001 From: Svante Bengtson Date: Sun, 27 Oct 2024 00:46:59 +0200 Subject: [PATCH] IJRU Scoring with RS rulesets support --- src/components/ModelCard.vue | 2 + src/components/ServoEntryLink.vue | 3 +- src/hooks/scoresheet.ts | 113 ++++++++++++++++--------- src/models.ts | 2 + src/views/Home.vue | 12 +-- src/views/scoring/ddc@2023/Judge.vue | 4 +- src/views/scoring/ijru@1.1.0/Speed.vue | 4 +- 7 files changed, 88 insertions(+), 52 deletions(-) diff --git a/src/components/ModelCard.vue b/src/components/ModelCard.vue index 25d31bf..27d1f56 100644 --- a/src/components/ModelCard.vue +++ b/src/components/ModelCard.vue @@ -95,6 +95,8 @@ const rulesetList = computed(() => Array.isArray(props.model.rulesId) ? props.mo onMounted(() => { if (props.model.localAlternativeCompetitionEvents) { competitionEventLookupCode.value = props.model.localAlternativeCompetitionEvents[0][1] + } else if (props.model.localCompetitionEvent) { + competitionEventLookupCode.value = props.model.localCompetitionEvent } }) diff --git a/src/components/ServoEntryLink.vue b/src/components/ServoEntryLink.vue index 1027b63..e0eb3ed 100644 --- a/src/components/ServoEntryLink.vue +++ b/src/components/ServoEntryLink.vue @@ -135,9 +135,10 @@ async function createScoresheet () { competitionId: props.competitionId, entryId: entry.value.EntryNumber, judgeSequence: judge.value.JudgeSequence, + judgeType: judge.value.JudgeType, scoringModel: entry.value.ScoringModelName, competitionEventId: entry.value.EventTypeCode, - options: entry.value.ScoringRulesConfig + options: entry.value.EntryExtraData?.options }) openScoresheet(scoresheetId) } finally { diff --git a/src/hooks/scoresheet.ts b/src/hooks/scoresheet.ts index fda108a..c93a652 100644 --- a/src/hooks/scoresheet.ts +++ b/src/hooks/scoresheet.ts @@ -98,7 +98,7 @@ export interface ServoEntry { EventDefinitionName: string EventDefinitionAbbr: number ScoringModelName: string - EventTypeCode: string // competitionEventLookupCode + EventTypeCode: string // competitionEventLookupCode - without version IsScored: boolean IsScratched: boolean IsLocked: boolean @@ -111,6 +111,12 @@ export interface ServoEntry { TeamName: string }> ScoringRulesConfig: Record + EntryExtraData?: { options?: Record } + EntryMeta: { + entryId: string + participantId: string + competitionEvent: string + } } export interface ServoSession { @@ -122,7 +128,7 @@ export interface ServoSession { export interface ServoJudge { JudgeSequence: number - JudgeType: null // TODO + JudgeType: string } export interface ServoCompetition { @@ -458,12 +464,12 @@ const closeServo = async ({ save }: CloseScoresheetOptions) => { } const rulesId = scoresheet.value.rulesId const judgeType = scoresheet.value.judgeType - const model = models.find(model => model.rulesId.includes(rulesId) && model.judgeType === judgeType) + const model = models.find(model => model.rulesId.includes(rulesId) && (Array.isArray(model.judgeType) ? model.judgeType.includes(judgeType) : model.judgeType === judgeType)) if (!model) { throw new Error('Could not find model for scoresheet') } if (model.converters?.servo == null) { - throw new Error('Model does not have a converter for servo scoring') + console.warn('Model does not have a converter for servo scoring - using new structure') } const [,competitionId, entryId, judgeSequence] = scoresheet.value.id.split('::') @@ -486,7 +492,7 @@ const closeServo = async ({ save }: CloseScoresheetOptions) => { method = 'POST' } - const scores = model.converters.servo(scoresheet.value) + const scores = model.converters?.servo?.(scoresheet.value) // store the remote copy const response = await fetch(url, { @@ -504,7 +510,10 @@ const closeServo = async ({ save }: CloseScoresheetOptions) => { DeviceID: deviceId.value, RoutineStartTime: scoresheet.value.openedAt ?? scoresheet.value.createdAt, BatteryLevel: battery.isSupported ? Math.round(battery.level.value * 100) : undefined, - ...scores + ...(scores ?? {}), + MarkSheet: { + marks: scoresheet.value.marks + } } }) }) @@ -622,47 +631,69 @@ export interface CreateServoScoresheetArgs { competitionId: number entryId: number judgeSequence: number + judgeType?: string scoringModel: string competitionEventId: string options?: Record | null } -export async function createServoScoresheet ({ competitionId, entryId, judgeSequence, scoringModel, competitionEventId, options }: CreateServoScoresheetArgs) { +export async function createServoScoresheet ({ competitionId, entryId, judgeSequence, judgeType: _judgeType, scoringModel, competitionEventId, options }: CreateServoScoresheetArgs) { try { - let judgeType: string - if (scoringModel.startsWith('ijru.freestyle.') || scoringModel.startsWith('ijru.teamshow.')) { - if (judgeSequence >= 1 && judgeSequence <= 9) judgeType = 'Pa' - else if (judgeSequence >= 11 && judgeSequence <= 19) judgeType = 'Pr' - else if (judgeSequence >= 21 && judgeSequence <= 29) judgeType = 'R' - else if (judgeSequence >= 31 && judgeSequence <= 39) judgeType = 'D' - else throw new TypeError(`Invalid judge sequence ${judgeSequence} for scoring model ${scoringModel}`) - } else if (scoringModel.startsWith('ijru.speed.')) { - if (judgeSequence === 1) judgeType = 'Shj' - else judgeType = 'S' - } else if (scoringModel.startsWith('ijru.ddcf.') || scoringModel.startsWith('ijru.ddc.')) { - switch (judgeSequence) { - case 1: - case 2: - judgeType = 'J' - break - case 3: - case 4: - judgeType = 'T' - break - case 5: - case 6: - case 7: - judgeType = 'E' - break - case 8: - case 9: - case 10: - judgeType = 'S' - break - default: - throw new TypeError(`Invalid judge sequence ${judgeSequence} for scoring model ${scoringModel}`) + let judgeType = _judgeType + if (judgeType == null) { + if (scoringModel.startsWith('ijru.freestyle.sr@4.0.0')) { + if (judgeSequence >= 1 && judgeSequence <= 9) judgeType = 'P' + else if (judgeSequence >= 11 && judgeSequence <= 19) judgeType = 'T' + else if (judgeSequence >= 21 && judgeSequence <= 29) judgeType = 'Dp' + else if (judgeSequence >= 31 && judgeSequence <= 39) judgeType = 'Dm' + else if (judgeSequence >= 41 && judgeSequence <= 49) judgeType = 'Dr' + else throw new TypeError(`Invalid judge sequence ${judgeSequence} for scoring model ${scoringModel}`) + } else if (scoringModel.startsWith('ijru.freestyle.wh@4.0.0')) { + if (judgeSequence >= 1 && judgeSequence <= 9) judgeType = 'P' + else if (judgeSequence >= 11 && judgeSequence <= 19) judgeType = 'T' + else if (judgeSequence >= 21 && judgeSequence <= 29) judgeType = 'Da' + else if (judgeSequence >= 31 && judgeSequence <= 39) judgeType = 'Db' + else throw new TypeError(`Invalid judge sequence ${judgeSequence} for scoring model ${scoringModel}`) + } else if (scoringModel.startsWith('ijru.freestyle.dd@4.0.0')) { + if (judgeSequence >= 1 && judgeSequence <= 9) judgeType = 'P' + else if (judgeSequence >= 11 && judgeSequence <= 19) judgeType = 'T' + else if (judgeSequence >= 21 && judgeSequence <= 29) judgeType = 'Dj' + else if (judgeSequence >= 31 && judgeSequence <= 39) judgeType = 'Dt' + else throw new TypeError(`Invalid judge sequence ${judgeSequence} for scoring model ${scoringModel}`) + } else if (scoringModel.startsWith('ijru.freestyle.') || scoringModel.startsWith('ijru.teamshow.')) { + if (judgeSequence >= 1 && judgeSequence <= 9) judgeType = 'Pa' + else if (judgeSequence >= 11 && judgeSequence <= 19) judgeType = 'Pr' + else if (judgeSequence >= 21 && judgeSequence <= 29) judgeType = 'R' + else if (judgeSequence >= 31 && judgeSequence <= 39) judgeType = 'D' + else throw new TypeError(`Invalid judge sequence ${judgeSequence} for scoring model ${scoringModel}`) + } else if (scoringModel.startsWith('ijru.speed.')) { + if (judgeSequence === 1) judgeType = 'Shj' + else judgeType = 'S' + } else if (scoringModel.startsWith('ijru.ddcf.') || scoringModel.startsWith('ijru.ddc.')) { + switch (judgeSequence) { + case 1: + case 2: + judgeType = 'J' + break + case 3: + case 4: + judgeType = 'T' + break + case 5: + case 6: + case 7: + judgeType = 'E' + break + case 8: + case 9: + case 10: + judgeType = 'S' + break + default: + throw new TypeError(`Invalid judge sequence ${judgeSequence} for scoring model ${scoringModel}`) + } + } else { + throw new TypeError(`scoring model ${scoringModel} not supported`) } - } else { - throw new TypeError(`scoring model ${scoringModel} not supported`) } const newScoresheet: ServoIntermediateScoresheet = { diff --git a/src/models.ts b/src/models.ts index 4ce6f1c..8c20fe3 100644 --- a/src/models.ts +++ b/src/models.ts @@ -29,6 +29,7 @@ export interface Model { allowScroll?: boolean component: Component localAlternativeCompetitionEvents?: Array<[string, string]> + localCompetitionEvent?: string localOptions?: Option[] hidden?: boolean historic?: boolean @@ -568,6 +569,7 @@ const models: Model[] = [ rulesId: ['ijru.freestyle.dd@4.0.0'], judgeType: 'T', name: 'Technical (Double Dutch)', + localCompetitionEvent: 'e.ijru.fs.dd.ddsf.1.75@4.0.0', component: defineAsyncComponent(async () => await import('./views/scoring/ijru@4.0.0/Technical.vue')), steps: ['marks', 'timeViolations'], }, diff --git a/src/views/Home.vue b/src/views/Home.vue index d39579a..9e7512a 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -66,6 +66,12 @@ > Practice + + Judge an IJRU Scoring Competition + Stored Scoresheets - - Judge an IJRU Scoring Competition -
diff --git a/src/views/scoring/ddc@2023/Judge.vue b/src/views/scoring/ddc@2023/Judge.vue index d5c3b53..0fbe021 100644 --- a/src/views/scoring/ddc@2023/Judge.vue +++ b/src/views/scoring/ddc@2023/Judge.vue @@ -65,7 +65,7 @@ missHints[0] = '(no-miss bonus)' missHints[7] = '(or more)' const scoreLabel = computed(() => { - switch (model.value.judgeType) { + switch (Array.isArray(model.value.judgeType) ? model.value.judgeType[0] : model.value.judgeType) { case 'J': return 'Jumper Score' case 'T': @@ -80,7 +80,7 @@ const scoreLabel = computed(() => { }) const scoreMark = computed(() => { - switch (model.value.judgeType) { + switch (Array.isArray(model.value.judgeType) ? model.value.judgeType[0] : model.value.judgeType) { case 'J': return 'jumperScore' case 'T': diff --git a/src/views/scoring/ijru@1.1.0/Speed.vue b/src/views/scoring/ijru@1.1.0/Speed.vue index fb7b346..98fda27 100644 --- a/src/views/scoring/ijru@1.1.0/Speed.vue +++ b/src/views/scoring/ijru@1.1.0/Speed.vue @@ -64,7 +64,7 @@ import type { Model } from '../../../models' export type Schema = 'step' | 'falseStart' | 'falseSwitch' -const props = defineProps({ +defineProps({ model: { type: Object as PropType, required: true @@ -73,7 +73,7 @@ const props = defineProps({ const { addMark, tally, scoresheet } = useScoresheet() -const isHeadJudge = computed(() => props.model.judgeType === 'Shj') +const isHeadJudge = computed(() => scoresheet.value?.judgeType === 'Shj') // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const hasSwitches = computed(() => /\.\d+x\d+@.*$/.test(scoresheet.value?.competitionEventId ?? ''))