Big scary buttons (#1471)

This commit is contained in:
Matt
2024-10-24 20:48:02 -07:00
committed by GitHub
parent 9b61ed156c
commit 385059c233
14 changed files with 375 additions and 24 deletions

View File

@@ -79,10 +79,10 @@ onBeforeUnmount(() => {
<div class="stream-container" :style="containerStyle">
<img :src="loadingImage" class="stream-loading" />
<img
:id="id"
class="stream-video"
ref="mjpgStream"
v-show="streamSrc !== emptyStreamSrc"
:id="id"
ref="mjpgStream"
class="stream-video"
crossorigin="anonymous"
:src="streamSrc"
:alt="streamDesc"

View File

@@ -3,8 +3,9 @@ import PvSelect from "@/components/common/pv-select.vue";
import PvNumberInput from "@/components/common/pv-number-input.vue";
import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore";
import { useStateStore } from "@/stores/StateStore";
import { computed, ref, watchEffect } from "vue";
import { computed, inject, ref, watchEffect } from "vue";
import { type CameraSettingsChangeRequest, ValidQuirks } from "@/types/SettingTypes";
import axios from "axios";
const tempSettingsStruct = ref<CameraSettingsChangeRequest>({
fov: useCameraSettingsStore().currentCameraSettings.fov.value,
@@ -108,6 +109,49 @@ watchEffect(() => {
// Reset temp settings on remote camera settings change
resetTempSettingsStruct();
});
const showDeleteCamera = ref(false);
const address = inject<string>("backendHost");
const exportSettings = ref();
const openExportSettingsPrompt = () => {
exportSettings.value.click();
};
const yesDeleteMySettingsText = ref("");
const deleteThisCamera = () => {
const payload = {
cameraUniqueName: useCameraSettingsStore().cameraUniqueNames[useStateStore().currentCameraIndex]
};
axios
.post("/utils/nukeOneCamera", payload)
.then(() => {
useStateStore().showSnackbarMessage({
message: "Successfully dispatched the delete command. Waiting for backend to start back up",
color: "success"
});
})
.catch((error) => {
if (error.response) {
useStateStore().showSnackbarMessage({
message: "The backend is unable to fulfil the request to delete this camera.",
color: "error"
});
} else if (error.request) {
useStateStore().showSnackbarMessage({
message: "Error while trying to process the request! The backend didn't respond.",
color: "error"
});
} else {
useStateStore().showSnackbarMessage({
message: "An error occurred while trying to process the request.",
color: "error"
});
}
});
showDeleteCamera.value = false;
};
</script>
<template>
@@ -144,17 +188,82 @@ watchEffect(() => {
:select-cols="8"
/>
<br />
<v-btn
class="mt-2 mb-3"
style="width: 100%"
small
color="secondary"
:disabled="!settingsHaveChanged()"
@click="saveCameraSettings"
>
<v-icon left> mdi-content-save </v-icon>
Save Changes
</v-btn>
<v-row>
<v-col cols="6">
<v-btn
class="mt-2 mb-3"
style="width: 100%"
small
color="secondary"
:disabled="!settingsHaveChanged()"
@click="saveCameraSettings"
>
<v-icon left> mdi-content-save </v-icon>
Save Changes
</v-btn>
</v-col>
<v-col cols="6">
<v-btn class="mt-2 mb-3" style="width: 100%" small color="red" @click="() => (showDeleteCamera = true)">
<v-icon left> mdi-bomb </v-icon>
Delete Camera
</v-btn>
</v-col>
</v-row>
</div>
<v-dialog v-model="showDeleteCamera" dark width="1500">
<v-card dark class="dialog-container pa-6" color="primary" flat>
<v-card-title
>Delete camera "{{ useCameraSettingsStore().cameraNames[useStateStore().currentCameraIndex] }}"</v-card-title
>
<v-row class="pl-3 align-center pa-6">
<v-col cols="12" md="6">
<span class="mt-3"> This will delete ALL OF YOUR SETTINGS and restart PhotonVision. </span>
</v-col>
<v-col cols="12" md="6">
<v-btn color="secondary" style="float: right" @click="openExportSettingsPrompt">
<v-icon left class="open-icon"> mdi-export </v-icon>
<span class="open-label">Backup Settings</span>
<a
ref="exportSettings"
style="color: black; text-decoration: none; display: none"
:href="`http://${address}/api/settings/photonvision_config.zip`"
download="photonvision-settings.zip"
target="_blank"
/>
</v-btn>
</v-col>
</v-row>
<v-divider class="mt-4 mb-4" />
<v-row class="pl-3 align-center pa-6">
<v-col>
<pv-input
v-model="yesDeleteMySettingsText"
:label="'Type &quot;' + useCameraSettingsStore().currentCameraName + '&quot;:'"
:label-cols="12"
:input-cols="12"
/>
</v-col>
<v-btn
color="red"
:disabled="
yesDeleteMySettingsText.toLowerCase() !== useCameraSettingsStore().currentCameraName.toLowerCase()
"
@click="deleteThisCamera"
>
<v-icon left class="open-icon"> mdi-skull </v-icon>
<span class="open-label">DELETE (UNRECOVERABLE)</span>
</v-btn>
</v-row>
</v-card>
</v-dialog>
</v-card>
</template>
<style scoped>
.v-divider {
border-color: white !important;
}
</style>

View File

@@ -201,6 +201,39 @@ const handleSettingsImport = () => {
importType.value = -1;
importFile.value = null;
};
const showFactoryReset = ref(false);
const expected = "Delete Everything";
const yesDeleteMySettingsText = ref("");
const nukePhotonConfigDirectory = () => {
axios
.post("/utils/nukeConfigDirectory")
.then(() => {
useStateStore().showSnackbarMessage({
message: "Successfully dispatched the reset command. Waiting for backend to start back up",
color: "success"
});
})
.catch((error) => {
if (error.response) {
useStateStore().showSnackbarMessage({
message: "The backend is unable to fulfil the request to reset the device.",
color: "error"
});
} else if (error.request) {
useStateStore().showSnackbarMessage({
message: "Error while trying to process the request! The backend didn't respond.",
color: "error"
});
} else {
useStateStore().showSnackbarMessage({
message: "An error occurred while trying to process the request.",
color: "error"
});
}
});
showFactoryReset.value = false;
};
</script>
<template>
@@ -322,11 +355,85 @@ const handleSettingsImport = () => {
</v-btn>
</v-col>
</v-row>
<v-divider style="margin: 12px 0" />
<v-row>
<v-col cols="12">
<v-btn color="red" @click="() => (showFactoryReset = true)">
<v-icon left class="open-icon"> mdi-skull-crossbones </v-icon>
<span class="open-icon">
{{
$vuetify.breakpoint.mdAndUp
? "Factory Reset PhotonVision and delete EVERYTHING (big scary button)"
: "Factory Reset PhotonVision"
}}
</span>
</v-btn>
</v-col>
</v-row>
</div>
<v-dialog v-model="showFactoryReset" width="1500" dark>
<v-card dark class="dialog-container pa-6" color="primary" flat>
<v-card-title>
<span class="open-label">
<v-icon right color="red" class="open-icon">mdi-nuke</v-icon>
Factory Reset PhotonVision
<v-icon right color="red" class="open-icon">mdi-nuke</v-icon>
</span>
</v-card-title>
<v-row class="pl-3 align-center pa-6">
<v-col cols="12" md="6">
<span class="mt-3"> This will delete ALL OF YOUR SETTINGS and restart PhotonVision. </span>
</v-col>
<v-col cols="12" md="6">
<v-btn color="secondary" style="float: right" @click="openExportSettingsPrompt">
<v-icon left class="open-icon"> mdi-export </v-icon>
<span class="open-label">Backup Settings</span>
<a
ref="exportSettings"
style="color: black; text-decoration: none; display: none"
:href="`http://${address}/api/settings/photonvision_config.zip`"
download="photonvision-settings.zip"
target="_blank"
/>
</v-btn>
</v-col>
</v-row>
<v-divider class="mt-4 mb-4" />
<v-row class="pl-3 align-center pa-6">
<v-col>
<pv-input
v-model="yesDeleteMySettingsText"
:label="'Type &quot;' + expected + '&quot;:'"
:label-cols="2"
:input-cols="10"
/>
</v-col>
</v-row>
<v-btn
color="red"
:disabled="yesDeleteMySettingsText.toLowerCase() !== expected.toLowerCase()"
@click="nukePhotonConfigDirectory"
>
<v-icon left class="open-icon"> mdi-skull-crossbones </v-icon>
<span class="open-label">
{{ $vuetify.breakpoint.mdAndUp ? "Delete everything, I have backed up what I need" : "Delete Everything" }}
</span>
</v-btn>
</v-card>
</v-dialog>
</v-card>
</template>
<style scoped>
.dialog-container {
min-height: 300px !important;
}
.v-divider {
border-color: white !important;
}