11<template >
2- <div
3- v-if =" !sheet"
4- :key =" sheetID"
5- >
6- <v-progress-linear
7- indeterminate
2+ <div v-if =" !sheet"
3+ :key =" sheetID" >
4+ <v-progress-linear indeterminate
85 color =" primary"
96 height =" 20"
10- class =" my-5"
11- />
7+ class =" my-5" />
128 <div class =" text-center text-cc-overline" >Loading pilot sheet...</div >
139 </div >
1410 <div v-else >
1814 <v-container fluid >
1915 <div >
2016 <div v-if =" panel && sheet" >
21- <component
22- :is =" panelMap[panel]"
17+ <component :is =" panelMap[panel]"
2318 :key =" panel"
2419 :combatant =" combatant"
2520 :encounter =" encounterInstance.Encounter"
2621 :selected =" pilot"
2722 :sheet =" sheet"
2823 pc
29- :encounter-instance =" encounterInstance"
30- />
24+ :encounter-instance =" encounterInstance" />
3125 </div >
3226
33- <v-row
34- dense
35- justify =" end"
36- >
27+ <v-row dense
28+ justify =" end" >
3729 <v-col cols =" auto" >
38- <actor-telemetry
39- :actor =" pilot"
40- :encounter =" encounterInstance"
41- />
30+ <actor-telemetry :actor =" pilot"
31+ :encounter =" encounterInstance" />
4232 </v-col >
4333 <v-col cols =" auto" >
44- <actor-logs
45- :actor =" pilot"
46- :encounter =" encounterInstance"
47- />
34+ <actor-logs :actor =" pilot"
35+ :encounter =" encounterInstance" />
4836 </v-col >
4937 <v-col cols =" auto" >
50- <combat-statblock-export
51- :actor =" pilot"
52- :encounter =" encounterInstance"
53- />
38+ <combat-statblock-export :actor =" pilot"
39+ :encounter =" encounterInstance" />
5440 </v-col >
5541 </v-row >
5642 </div >
5743 </v-container >
5844 </v-main >
5945
60- <div
61- style =" position : absolute ; z-index : 999 "
62- :style =" `right: ${showRight ? (mobile ? '60' : '256') : mobile ? '6' : '62'}px; top: 6px`"
63- >
64- <cc-button
65- :icon =" showRight ? 'mdi-chevron-double-right' : 'mdi-chevron-double-left'"
46+ <div style =" position : absolute ; z-index : 999 "
47+ :style =" `right: ${showRight ? (mobile ? '60' : '256') : mobile ? '6' : '62'}px; top: 6px`" >
48+ <cc-button :icon =" showRight ? 'mdi-chevron-double-right' : 'mdi-chevron-double-left'"
6649 size =" small"
6750 color =" primary"
68- @click =" showRight = !showRight"
69- />
51+ @click =" showRight = !showRight" />
7052 </div >
7153
72- <v-navigation-drawer
73- v-if =" !mobile"
54+ <v-navigation-drawer v-if =" !mobile"
7455 :rail =" !showRight"
7556 location =" right"
76- permanent
77- >
78- <gm-tool-palette
79- pc
57+ permanent >
58+ <gm-tool-palette pc
8059 :expanded =" showRight"
8160 :selected =" panel"
8261 :combatant =" combatant"
8362 @select-panel =" selectPanel"
8463 @open-dice-roller =" diceDialog = true"
85- @open-table-index =" tableDialog = true"
86- />
64+ @open-table-index =" tableDialog = true" />
8765 </v-navigation-drawer >
8866
89- <v-navigation-drawer
90- v-else
67+ <v-navigation-drawer v-else
9168 v-model =" showRight"
9269 rail
93- location =" right"
94- >
95- <gm-tool-palette
96- pc
70+ location =" right" >
71+ <gm-tool-palette pc
9772 :expanded =" showRight"
9873 :selected =" panel"
9974 :combatant =" combatant"
10075 @select-panel =" selectPanel"
10176 @open-dice-roller =" diceDialog = true"
102- @open-table-index =" tableDialog = true"
103- />
77+ @open-table-index =" tableDialog = true" />
10478 </v-navigation-drawer >
10579
106- <v-footer
107- app
80+ <v-footer app
10881 height =" 36"
109- style =" border-top : 1px solid rgba (255 , 255 , 255 , 0.1 )"
110- >
111- <v-row
112- justify =" space-between"
82+ style =" border-top : 1px solid rgba (255 , 255 , 255 , 0.1 )" >
83+ <v-row justify =" space-between"
11384 align =" center"
114- no-gutters
115- >
85+ no-gutters >
11686 <v-col >
11787 <pc-end-round :sheet =" sheet" />
11888 </v-col >
12494 </v-layout >
12595 </div >
12696
127- <v-dialog
128- v-model =" diceDialog"
97+ <v-dialog v-model =" diceDialog"
12998 :fullscreen =" mobile"
13099 max-height =" 80vh"
131- max-width =" 80vw"
132- >
133- <gm-dice-roller
134- :encounter =" encounterInstance"
100+ max-width =" 80vw" >
101+ <gm-dice-roller :encounter =" encounterInstance"
135102 :selected =" combatant"
136- @close =" diceDialog = false"
137- />
103+ @close =" diceDialog = false" />
138104 </v-dialog >
139105
140- <v-dialog
141- v-model =" tableDialog"
106+ <v-dialog v-model =" tableDialog"
142107 :fullscreen =" mobile"
143- max-width =" 80vw"
144- >
145- <rollable-table-index
146- :instance =" encounterInstance"
108+ max-width =" 80vw" >
109+ <rollable-table-index :instance =" encounterInstance"
147110 :selected =" combatant"
148- @close =" tableDialog = false"
149- />
111+ @close =" tableDialog = false" />
150112 </v-dialog >
113+
114+
115+ <cc-solo-dialog v-model =" leaveDialog"
116+ :close-on-click =" false"
117+ title =" Exit Active Mode?"
118+ :z-index =" 9999" >
119+ <v-card flat
120+ tile >
121+
122+ <div class =" text-center text-text ma-2" >
123+ Do you want to save this encounter before exiting?</div >
124+ <v-divider class =" my-3" />
125+ <v-card-actions class =" pa-0" >
126+ <cc-button variant =" text"
127+ size =" small"
128+ @click =" handleLeave('cancel')" >Cancel</cc-button >
129+ <v-spacer />
130+ <cc-button color =" warning"
131+ size =" small"
132+ variant =" text"
133+ @click =" handleLeave('exit')" >Exit Without Saving</cc-button >
134+ <v-spacer />
135+ <cc-button color =" accent"
136+ size =" small"
137+ @click =" handleLeave('save')" >Save and Exit</cc-button >
138+ </v-card-actions >
139+ </v-card >
140+ </cc-solo-dialog >
151141 </div >
152142</template >
153143
154144<script setup lang="ts">
155145import { ref , computed } from ' vue' ;
156146import { useDisplay } from ' vuetify' ;
157- import { useRoute } from ' vue-router' ;
147+ import { useRoute , onBeforeRouteLeave } from ' vue-router' ;
158148import { PilotStore } from ' @/stores' ;
159149import ActorTelemetry from ' ../gm/EncounterPanels/_components/ActorTelemetry.vue' ;
160150import ActorLogs from ' ../gm/EncounterPanels/_components/ActorLogs.vue' ;
@@ -190,6 +180,8 @@ const showRight = ref(false);
190180const panel = ref (' pc' );
191181const diceDialog = ref (false );
192182const tableDialog = ref (false );
183+ const leaveDialog = ref (false );
184+ let resolveLeaveDialog: ((value : string ) => void ) | null = null ;
193185
194186const sheet = computed (() =>
195187 PilotStore ().GetSheet (props .id || route .params .id as string || PilotStore ().CurrentActiveID )
@@ -202,4 +194,28 @@ const encounterInstance = computed(() => sheet.value!.EncounterInstance);
202194function selectPanel(p : string ) {
203195 panel .value = panel .value === p ? ' pc' : p ;
204196}
197+
198+ function openLeaveDialog(): Promise <string > {
199+ leaveDialog .value = true ;
200+ return new Promise ((resolve ) => {
201+ resolveLeaveDialog = resolve ;
202+ });
203+ }
204+
205+ function handleLeave(choice : ' save' | ' exit' | ' cancel' ) {
206+ leaveDialog .value = false ;
207+ resolveLeaveDialog ?.(choice );
208+ resolveLeaveDialog = null ;
209+ }
210+
211+ onBeforeRouteLeave (async () => {
212+ const choice = await openLeaveDialog ();
213+ if (choice === ' save' ) {
214+ sheet .value ?.Save ();
215+ return true ;
216+ } else if (choice === ' exit' ) {
217+ return true ;
218+ }
219+ return false ;
220+ });
205221 </script >
0 commit comments