Modal template for deletion confirmation (#2190)

## Description

<!-- What changed? Why? (the code + comments should speak for itself on
the "how") -->

<!-- Fun screenshots or a cool video or something are super helpful as
well. If this touches platform-specific behavior, this is where test
evidence should be collected. -->

<!-- Any issues this pull request closes or pull requests this
supersedes should be linked with `Closes #issuenumber`. -->

This adds a template modal that can be used for confirming that the user
wants to delete something. The main goal is to reduce complication and
duplicated code, and standardize the way we handle deletion.

closes #2175

## Meta

Merge checklist:
- [x] Pull Request title is [short, imperative
summary](https://cbea.ms/git-commit/) of proposed changes
- [x] The description documents the _what_ and _why_
- [x] This PR has been
[linted](https://docs.photonvision.org/en/latest/docs/contributing/linting.html).
- [ ] If this PR changes behavior or adds a feature, user documentation
is updated
- [ ] If this PR touches photon-serde, all messages have been
regenerated and hashes have not changed unexpectedly
- [ ] If this PR touches configuration, this is backwards compatible
with settings back to v2025.3.2
- [ ] If this PR touches pipeline settings or anything related to data
exchange, the frontend typing is updated
- [ ] If this PR addresses a bug, a regression test for it is added

---------

Co-authored-by: Devolian <devondoyle@outlook.com>
This commit is contained in:
Sam Freund
2025-11-18 02:41:20 -06:00
committed by GitHub
parent 77e5545eef
commit d27b3d0775
7 changed files with 188 additions and 337 deletions

View File

@@ -2,8 +2,8 @@
import { ref, computed, inject } from "vue";
import { useStateStore } from "@/stores/StateStore";
import { useSettingsStore } from "@/stores/settings/GeneralSettingsStore";
import type { ObjectDetectionModelProperties } from "@/types/SettingTypes";
import pvInput from "@/components/common/pv-input.vue";
import { type ObjectDetectionModelProperties } from "@/types/SettingTypes";
import PvDeleteModal from "@/components/common/pv-delete-modal.vue";
import { useTheme } from "vuetify";
import { axiosPost } from "@/lib/PhotonUtils";
@@ -73,17 +73,9 @@ const handleImport = async () => {
};
const deleteModel = async (model: ObjectDetectionModelProperties) => {
useStateStore().showSnackbarMessage({
message: "Deleting Object Detection Model...",
color: "secondary",
timeout: -1
});
axiosPost("/objectdetection/delete", "delete an object detection model", {
modelPath: model.modelPath
});
confirmDeleteDialog.value.show = false;
};
const renameModel = async (model: ObjectDetectionModelProperties, newName: string) => {
@@ -123,11 +115,8 @@ const openExportIndividualModelPrompt = () => {
};
const showNukeDialog = ref(false);
const expected = "Delete Models";
const yesDeleteMyModelsText = ref("");
const nukeModels = () => {
axiosPost("/objectdetection/nuke", "clear and reset object detection models");
showNukeDialog.value = false;
};
const showBulkImportDialog = ref(false);
@@ -378,35 +367,20 @@ const handleBulkImport = () => {
</tbody>
</v-table>
<v-dialog v-model="confirmDeleteDialog.show" width="600">
<v-card color="surface" dark>
<v-card-title>Delete Object Detection Model</v-card-title>
<v-card-text class="pt-0">
Are you sure you want to delete the model {{ confirmDeleteDialog.model.nickname }}?
<v-card-actions class="pt-5 pb-0 pr-0" style="justify-content: flex-end">
<v-btn
:variant="theme.global.name.value === 'LightTheme' ? 'elevated' : 'outlined'"
color="buttonPassive"
@click="confirmDeleteDialog.show = false"
>
Cancel
</v-btn>
<v-btn
:variant="theme.global.name.value === 'LightTheme' ? 'elevated' : 'outlined'"
color="error"
@click="deleteModel(confirmDeleteDialog.model)"
>
Delete
</v-btn>
</v-card-actions>
</v-card-text>
</v-card>
</v-dialog>
<pv-delete-modal
v-model="confirmDeleteDialog.show"
:width="500"
:on-confirm="() => deleteModel(confirmDeleteDialog.model)"
title="Delete Object Detection Model"
:description="`Are you sure you want to delete the model ${confirmDeleteDialog.model.nickname}?`"
delete-text="Delete model"
/>
<v-dialog v-model="showRenameDialog.show" width="600">
<v-card color="surface" dark>
<v-card-title>Rename Object Detection Model</v-card-title>
<v-card-text class="pt-0">
Enter a new name for the model {{ showRenameDialog.model.nickname }}:
Enter a new name for the model "{{ showRenameDialog.model.nickname }}":
<div class="pa-5 pb-0">
<v-text-field v-model="showRenameDialog.newName" hide-details label="New Name" variant="underlined" />
</div>
@@ -462,64 +436,15 @@ const handleBulkImport = () => {
</v-row>
</div>
<v-dialog v-model="showNukeDialog" width="800" dark>
<v-card color="surface" flat>
<v-card-title style="display: flex; justify-content: center">
<span class="open-label">
<v-icon end color="error" class="open-icon ma-1" size="large">mdi-alert-outline</v-icon>
Clear and Reset Object Detection Models
<v-icon end color="error" class="open-icon ma-1" size="large">mdi-alert-outline</v-icon>
</span>
</v-card-title>
<v-card-text class="pt-0 pb-10px">
<v-row class="align-center text-white">
<v-col cols="12" md="6">
<span> This will delete ALL OF YOUR MODELS and re-extract the default models. </span>
</v-col>
<v-col cols="12" md="6">
<v-btn
color="buttonActive"
style="float: right"
:variant="theme.global.name.value === 'LightTheme' ? 'elevated' : 'outlined'"
@click="openExportPrompt"
>
<v-icon start class="open-icon" size="large"> mdi-export </v-icon>
<span class="open-label">Backup Models</span>
<a
ref="exportModels"
style="color: black; text-decoration: none; display: none"
:href="`http://${address}/api/objectdetection/export`"
download="photonvision-object-detection-models-export.zip"
target="_blank"
/>
</v-btn>
</v-col>
</v-row>
</v-card-text>
<v-card-text class="pt-0 pb-0">
<pv-input
v-model="yesDeleteMyModelsText"
:label="'Type &quot;' + expected + '&quot;:'"
:label-cols="6"
:input-cols="6"
/>
</v-card-text>
<v-card-text class="pt-10px">
<v-btn
color="error"
width="100%"
:disabled="yesDeleteMyModelsText.toLowerCase() !== expected.toLowerCase()"
:variant="theme.global.name.value === 'LightTheme' ? 'elevated' : 'outlined'"
@click="nukeModels"
>
<v-icon start class="open-icon" size="large"> mdi-trash-can-outline </v-icon>
<span class="open-label">
{{ $vuetify.display.mdAndUp ? "Delete models, I have backed up what I need" : "Delete Models" }}
</span>
</v-btn>
</v-card-text>
</v-card>
</v-dialog>
<pv-delete-modal
v-model="showNukeDialog"
:on-backup="openExportPrompt"
:on-confirm="nukeModels"
title="Delete and Reset All Object Detection Models"
:description="'This will delete ALL object detection models and re-extract the default object detection models. This action cannot be undone.'"
:expected-confirmation-text="'Delete Models'"
delete-text="Delete all models"
/>
</v-card>
</template>