From 42c77fcf6498d6a03d4d4dc7becf5cfc07f49789 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Sat, 2 May 2026 15:04:45 +0200 Subject: [PATCH 01/10] Support Back Button in Tech Draft phase (instead of Reset button) --- src/router/index.ts | 5 +++++ src/store/state.ts | 12 ++++++++++++ src/util/NavigationState.ts | 14 +++++++++++--- tests/unit/helper/mockRound.ts | 5 ++++- tests/unit/util/NavigationState.spec.ts | 17 +++++++++++++++++ 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/router/index.ts b/src/router/index.ts index 1b9bac3..882a589 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -38,6 +38,11 @@ const routes: Array = [ name: 'PhaseADrafting', component: PhaseADrafting }, + { + path: '/round/:round/drafting/:step', + name: 'PhaseADraftingStep', + component: PhaseADrafting + }, { path: '/round/:round/prosperity', name: 'PhaseBProsperity', diff --git a/src/store/state.ts b/src/store/state.ts index 3d8275f..0253dc9 100644 --- a/src/store/state.ts +++ b/src/store/state.ts @@ -52,6 +52,18 @@ export interface Round { botCards: BotCardsPersistence rowPlaceholders: RowPlaceholdersPersistence techCardSelection: TechCardSelectionPersistence + techDraftSteps?: TechDraftStep[] + // the following fields are deprecated, latest implementation uses the techDraftSteps field instead + nextStartPlayer?: Player + nextArchitectPlayer?: Player + botTechs?: Tech[] + playerTechs?: Tech[] + playerSpecialActions?: number +} + +export interface TechDraftStep { + step: number + player: Player nextStartPlayer?: Player nextArchitectPlayer?: Player botTechs?: Tech[] diff --git a/src/util/NavigationState.ts b/src/util/NavigationState.ts index ef0c031..c73302d 100644 --- a/src/util/NavigationState.ts +++ b/src/util/NavigationState.ts @@ -1,4 +1,4 @@ -import { Round, State } from '@/store/state' +import { Round, State, TechDraftStep } from '@/store/state' import { RouteLocation } from 'vue-router' import getIntRouteParam from '@brdgm/brdgm-commons/src/util/router/getIntRouteParam' import Player from '@/services/enum/Player' @@ -10,6 +10,7 @@ import TechCardSelection from '@/services/TechCardSelection' export default class NavigationState { readonly round : number + readonly draftingStep: number readonly prosperityCards : ProsperityCards readonly botCards : BotCards readonly rowPlaceholders : RowPlaceholders @@ -19,6 +20,7 @@ export default class NavigationState { constructor(route: RouteLocation, state: State) { this.round = getIntRouteParam(route, 'round') + this.draftingStep = getIntRouteParam(route, 'step') let roundData = state.rounds.find(item => item.round === this.round) if (!roundData) { @@ -42,11 +44,17 @@ export default class NavigationState { } public get startPlayer() : Player { - return this.roundData.nextStartPlayer ?? this.roundData.startPlayer + return this.lastDraftStep?.nextStartPlayer ?? this.roundData.nextStartPlayer ?? this.roundData.startPlayer } public get architectPlayer() : Player { - return this.roundData.nextArchitectPlayer ?? this.roundData.architectPlayer + return this.lastDraftStep?.nextArchitectPlayer ?? this.roundData.nextArchitectPlayer ?? this.roundData.architectPlayer + } + + private get lastDraftStep() : TechDraftStep|undefined { + if (this.roundData.techDraftSteps) { + return this.roundData.techDraftSteps.toSorted((a, b) => a.step - b.step)[this.roundData.techDraftSteps.length - 1] + } } } diff --git a/tests/unit/helper/mockRound.ts b/tests/unit/helper/mockRound.ts index 8c28731..2598ef9 100644 --- a/tests/unit/helper/mockRound.ts +++ b/tests/unit/helper/mockRound.ts @@ -1,5 +1,5 @@ import Player from '@/services/enum/Player' -import { BotCardsPersistence, ProsperityCardsPersistence, Round, RowPlaceholdersPersistence, TechCardSelectionPersistence } from '@/store/state' +import { BotCardsPersistence, ProsperityCardsPersistence, Round, RowPlaceholdersPersistence, TechCardSelectionPersistence, TechDraftStep } from '@/store/state' export default function mockRound(params?: MockRoundParams) : Round { const round : Round = { @@ -15,6 +15,7 @@ export default function mockRound(params?: MockRoundParams) : Round { }, rowPlaceholders: params?.rowPlaceholders ?? { rows: [] }, techCardSelection: params?.techCardSelection ?? { techs: [], removedTechs: [] }, + techDraftSteps: params?.techDraftSteps, nextStartPlayer: params?.nextStartPlayer, nextArchitectPlayer: params?.nextArchitectPlayer } @@ -29,6 +30,8 @@ export interface MockRoundParams { botCards?: BotCardsPersistence rowPlaceholders?: RowPlaceholdersPersistence techCardSelection?: TechCardSelectionPersistence + techDraftSteps?: TechDraftStep[] + // deprecated fields, latest implementation uses the techDraftSteps field instead nextStartPlayer?: Player, nextArchitectPlayer?: Player, } diff --git a/tests/unit/util/NavigationState.spec.ts b/tests/unit/util/NavigationState.spec.ts index 5021352..acbc8b8 100644 --- a/tests/unit/util/NavigationState.spec.ts +++ b/tests/unit/util/NavigationState.spec.ts @@ -19,6 +19,23 @@ describe('util/NavigationState', () => { }) it('nextStartArchitectPlayer', () => { + const route = mockRouteLocation({params:{round:'1',turn:'3'}}) + const state = mockState({startPlayer:Player.BOT,rounds:[ + mockRound({round:1,startPlayer:Player.BOT,architectPlayer:Player.PLAYER, + techDraftSteps:[ + { step: 0, player: Player.BOT }, + { step: 1, player: Player.PLAYER, nextStartPlayer: Player.PLAYER }, + { step: 2, player: Player.PLAYER, nextStartPlayer: Player.PLAYER, nextArchitectPlayer: Player.BOT }, + ]}) + ]}) + const navigationState = new NavigationState(route, state) + + expect(navigationState.round).to.eq(1) + expect(navigationState.startPlayer).to.eq(Player.PLAYER) + expect(navigationState.architectPlayer).to.eq(Player.BOT) + }) + + it('nextStartArchitectPlayer_oldPersistence', () => { const route = mockRouteLocation({params:{round:'1',turn:'3'}}) const state = mockState({startPlayer:Player.BOT,rounds:[ mockRound({round:1,startPlayer:Player.BOT,architectPlayer:Player.PLAYER, From 9e3030f5a7da5d5483472756c11aead1ba6bd70d Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Sat, 2 May 2026 16:31:08 +0200 Subject: [PATCH 02/10] implement back button --- .vscode/settings.json | 6 +- src/components/round/DebugInfo.vue | 1 + src/components/round/TechCardDraft.vue | 80 +++++++++---------- src/locales/de.json | 3 +- src/locales/en.json | 3 +- src/router/index.ts | 6 +- src/services/TechCardSelection.ts | 7 -- src/store/state.ts | 21 +++-- src/util/NavigationState.ts | 28 +++++-- src/views/PhaseADrafting.vue | 7 +- src/views/PhaseBProsperity.vue | 2 +- src/views/PhaseGUpkeep.vue | 2 +- src/views/SetupBot.vue | 2 +- tests/unit/helper/mockRound.ts | 14 ++-- tests/unit/services/TechCardSelection.spec.ts | 6 +- tests/unit/util/NavigationState.spec.ts | 6 +- 16 files changed, 108 insertions(+), 86 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9e26dfe..9c0f343 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1 +1,5 @@ -{} \ No newline at end of file +{ + "i18n-ally.localesPaths": [ + "src/locales" + ] +} \ No newline at end of file diff --git a/src/components/round/DebugInfo.vue b/src/components/round/DebugInfo.vue index 6065c2b..f697756 100644 --- a/src/components/round/DebugInfo.vue +++ b/src/components/round/DebugInfo.vue @@ -6,6 +6,7 @@ draftingPriority:
construction:
war:
+ lastDraftStep: {{navigationState.lastDraftStep}}

diff --git a/src/components/round/TechCardDraft.vue b/src/components/round/TechCardDraft.vue index 8662aa8..aa30913 100644 --- a/src/components/round/TechCardDraft.vue +++ b/src/components/round/TechCardDraft.vue @@ -32,9 +32,6 @@ -
@@ -50,13 +47,12 @@
-