mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-06 20:43:46 +08:00
Add toggle defaults reset to Software
This commit is contained in:
@@ -42,3 +42,58 @@ await ToggleBackup.methods.restoreBackup.call(moving)
|
||||
assert.equal(writes,1)
|
||||
assert.match(moving.error,/Park/)
|
||||
console.log("Portable layout files and legacy restore through Toggle backup passed")
|
||||
|
||||
assert.match(ToggleBackup.template, /Reset toggles to default/)
|
||||
assert.ok(ToggleBackup.template.indexOf('Restore toggles') < ToggleBackup.template.indexOf('Reset toggles to default'))
|
||||
const resetCalls = []
|
||||
const reset = { ...ToggleBackup.data(), request: async (path, body) => {
|
||||
resetCalls.push([path, body])
|
||||
if (path.endsWith('non-defaults')) return {view:'fresh-view', count:3, rows:[
|
||||
{id:0,resetAvailable:true}, {id:1,resetAvailable:false}, {id:2,resetAvailable:true}]}
|
||||
if (path.endsWith('preview')) return {intent:'fresh-intent', question:'Reset 2 settings?'}
|
||||
return {saved:true,applied:['First','Second']}
|
||||
} }
|
||||
await ToggleBackup.methods.reviewResetDefaults.call(reset)
|
||||
assert.deepEqual(resetCalls, [['./api/settings/non-defaults',undefined],
|
||||
['./api/settings/recovery/preview',{view:'fresh-view',selected:[0,2]}]])
|
||||
assert.equal(reset.resetDraft.intent,'fresh-intent')
|
||||
assert.equal(resetCalls.some(([path]) => path.endsWith('confirm')),false,'Review must not change settings')
|
||||
await Promise.all([ToggleBackup.methods.resetDefaults.call(reset),ToggleBackup.methods.resetDefaults.call(reset)])
|
||||
assert.deepEqual(resetCalls.at(-1),['./api/settings/recovery/confirm',{intent:'fresh-intent',confirmed:true}])
|
||||
assert.equal(resetCalls.filter(([path]) => path.endsWith('confirm')).length,1)
|
||||
assert.equal(reset.resetDraft,null)
|
||||
assert.equal(reset.notice,'2 settings reset to default.')
|
||||
|
||||
const alreadyDefault = {...ToggleBackup.data(),request:async path => {
|
||||
assert.equal(path,'./api/settings/non-defaults'); return {count:0,rows:[]}
|
||||
} }
|
||||
await ToggleBackup.methods.reviewResetDefaults.call(alreadyDefault)
|
||||
assert.match(alreadyDefault.notice,/already use their defaults/)
|
||||
assert.equal(alreadyDefault.resetDraft,null)
|
||||
|
||||
const cannotReset = {...ToggleBackup.data(),request:async path => {
|
||||
assert.equal(path,'./api/settings/non-defaults');return {count:1,rows:[{id:0,resetAvailable:false}]}
|
||||
} }
|
||||
await ToggleBackup.methods.reviewResetDefaults.call(cannotReset)
|
||||
assert.match(cannotReset.error,/Park/)
|
||||
assert.equal(cannotReset.resetDraft,null)
|
||||
|
||||
const interrupted = {...ToggleBackup.data(),resetDraft:{intent:'approved'},request:async () =>
|
||||
({saved:false,applied:['First'],reason:'Vehicle state changed'})}
|
||||
await ToggleBackup.methods.resetDefaults.call(interrupted)
|
||||
assert.match(interrupted.error,/1 settings reset.*Vehicle state changed/)
|
||||
assert.equal(interrupted.notice,'')
|
||||
assert.equal(interrupted.resetDraft,null)
|
||||
|
||||
const failedReview = {...ToggleBackup.data(),request:async () => {throw new Error('Sign in to Galaxy')}}
|
||||
await ToggleBackup.methods.reviewResetDefaults.call(failedReview)
|
||||
assert.equal(failedReview.error,'Sign in to Galaxy')
|
||||
assert.equal(failedReview.resetDraft,null)
|
||||
assert.equal(failedReview.busy,false)
|
||||
|
||||
let busyRequests=0
|
||||
const busyReset = {...ToggleBackup.data(),busy:true,resetDraft:{intent:'old'},request:async () => {busyRequests++}}
|
||||
await ToggleBackup.methods.reviewResetDefaults.call(busyReset)
|
||||
await ToggleBackup.methods.resetDefaults.call(busyReset)
|
||||
assert.equal(busyRequests,0)
|
||||
console.log('Software-screen default reset uses guarded preview and explicit confirmation')
|
||||
|
||||
@@ -8,7 +8,7 @@ export const ToggleBackup = {
|
||||
name: "ToggleBackup",
|
||||
components: { GxDialog, GxNotice },
|
||||
props: { unauthorized: { type: Function, required: true } },
|
||||
data: () => ({ busy: false, draft: null, legacy: false, error: "", notice: "" }),
|
||||
data: () => ({ busy: false, draft: null, resetDraft: null, legacy: false, error: "", notice: "" }),
|
||||
methods: {
|
||||
async request(path, payload) {
|
||||
try {
|
||||
@@ -51,6 +51,32 @@ export const ToggleBackup = {
|
||||
}
|
||||
} catch (error) { this.draft = null; this.error = error.message || "Could not read toggle backup." }
|
||||
},
|
||||
async reviewResetDefaults() {
|
||||
if (this.busy) return
|
||||
this.busy = true; this.resetDraft = null; this.error = this.notice = ""
|
||||
try {
|
||||
const snapshot = await this.request("./api/settings/non-defaults")
|
||||
const selected = snapshot.rows.filter(row => row.resetAvailable === true).map(row => row.id)
|
||||
if (!selected.length) {
|
||||
if (snapshot.count) throw new Error("Park the vehicle before resetting available toggles.")
|
||||
this.notice = "All available toggles already use their defaults."
|
||||
return
|
||||
}
|
||||
this.resetDraft = await this.request("./api/settings/recovery/preview", { view: snapshot.view, selected })
|
||||
} catch (error) { this.error = error.message || "Could not prepare toggle reset." }
|
||||
finally { this.busy = false }
|
||||
},
|
||||
async resetDefaults() {
|
||||
if (this.busy || !this.resetDraft) return
|
||||
const pending = this.resetDraft
|
||||
this.resetDraft = null; this.busy = true; this.error = this.notice = ""
|
||||
try {
|
||||
const result = await this.request("./api/settings/recovery/confirm", { intent: pending.intent, confirmed: true })
|
||||
if (!result.saved) throw new Error(`${result.applied.length} settings reset. ${result.reason || "Review Toggles before retrying."}`)
|
||||
this.notice = `${result.applied.length} ${result.applied.length === 1 ? "setting" : "settings"} reset to default.`
|
||||
} catch (error) { this.error = error.message || "Could not reset toggles. Review Toggles before retrying." }
|
||||
finally { this.busy = false }
|
||||
},
|
||||
async restoreBackup() {
|
||||
if (this.busy || !this.draft) return
|
||||
const draft = this.draft, legacy = this.legacy
|
||||
@@ -75,6 +101,7 @@ export const ToggleBackup = {
|
||||
<div class="gx-section__header"><i class="bi bi-cloud-arrow-down" aria-hidden="true"></i><span class="gx-section__title">Toggle backup</span></div><p class="gx-note">Save your editable toggles, onroad layout and colors. Restore compatible settings while parked.</p>
|
||||
<div class="gx-actions"><button type="button" class="gx-btn gx-btn--tonal" @click="exportBackup">Back up toggles</button>
|
||||
<button type="button" class="gx-btn gx-btn--tonal" @click="$refs.file.click()">Restore toggles</button>
|
||||
<button type="button" class="gx-btn gx-btn--tonal" @click="reviewResetDefaults">Reset toggles to default</button>
|
||||
<input ref="file" type="file" accept=".json,application/json" class="gx-sr-only" tabindex="-1" aria-label="Choose toggle backup" @change="chooseFile"></div>
|
||||
<p v-if="busy" class="gx-note" role="status"><span class="gx-spinner" aria-hidden="true"></span> Working…</p>
|
||||
<GxNotice v-if="notice" tone="success">{{ notice }}</GxNotice><GxNotice v-if="error" tone="danger">{{ error }}</GxNotice>
|
||||
@@ -82,5 +109,12 @@ export const ToggleBackup = {
|
||||
<p>{{ legacy ? 'Replace your saved layout and colors?' : 'Apply the compatible saved toggles, layout and colors from this backup? Unavailable settings will be skipped.' }} Keep the vehicle parked.</p>
|
||||
<div class="gx-actions"><button type="button" class="gx-btn gx-btn--tonal" @click="draft=null">Cancel</button><button type="button" class="gx-btn" @click="restoreBackup">Restore</button></div>
|
||||
</GxDialog>
|
||||
<GxDialog v-if="resetDraft" :inert="busy" labelledby="gx-toggle-reset-title" @close="resetDraft=null">
|
||||
<h3 id="gx-toggle-reset-title">Reset toggles to default?</h3>
|
||||
<p>{{ resetDraft.question }}</p>
|
||||
<p>Keep the vehicle parked. Settings unavailable for this vehicle are left unchanged. Calibration, downloaded models, accounts and network credentials are kept.</p>
|
||||
<div class="gx-actions"><button type="button" class="gx-btn gx-btn--tonal" @click="resetDraft=null">Cancel</button>
|
||||
<button type="button" class="gx-btn" @click="resetDefaults">Reset toggles</button></div>
|
||||
</GxDialog>
|
||||
</section>`,
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "8730d7ea0d5a470b442f0838daf18cab804ee48e3ebef293dc1e9fa7ccb2c59e", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "859a6c9567fc9ae7352b9dc0787eb96769307adeb21e62fc085a4d2a120ff452", "schema_version": 1}
|
||||
|
||||
Reference in New Issue
Block a user