Remove asks in the page, not in a dialog the browser may refuse to show
Removing a charger was gated behind window.confirm(). A browser that suppresses native dialogs — an embedded webview, a blocked-dialogs setting — does not show it and hands back false, so the click answered "no" on the user's behalf: no request, no error, nothing. The button looked broken and the endpoint was never reached. It always had been fine; a delete with an unknown id still answers 404 and the ownership path still resolves. The prompt is part of the row now — the warning, Cancel, Remove — the way the charger reset in the same view already asks. Remove disables while the delete is in flight, and a failure lands in the error line the list already has. Fifteen other confirm() call sites share the flaw and are left for their own change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
21a54c4cfa
commit
749f42f481
@@ -232,14 +232,34 @@ function onChargerImported(charger) {
|
||||
loadChargerLive(true);
|
||||
}
|
||||
|
||||
async function removeHomeCharger(c) {
|
||||
if (!confirm(t("charging.home.removeConfirm", { name: c.name }))) return;
|
||||
// Removing asks first, inline. A window.confirm() would be shorter, but a
|
||||
// browser that suppresses dialogs — an embedded webview, a blocked-popups
|
||||
// setting — hands back false, and the button then does nothing at all with
|
||||
// nothing said about why. The prompt is part of the page instead, the way the
|
||||
// charger reset above already asks.
|
||||
const pendingRemoval = ref(""); // charger id awaiting a yes
|
||||
const removing = ref("");
|
||||
|
||||
function askRemoveHomeCharger(c) {
|
||||
homeChargersError.value = "";
|
||||
pendingRemoval.value = c.id;
|
||||
}
|
||||
|
||||
function cancelRemoveHomeCharger() {
|
||||
pendingRemoval.value = "";
|
||||
}
|
||||
|
||||
async function removeHomeCharger(c) {
|
||||
homeChargersError.value = "";
|
||||
removing.value = c.id;
|
||||
try {
|
||||
await api.deleteHomeCharger(c.id);
|
||||
homeChargers.value = homeChargers.value.filter((x) => x.id !== c.id);
|
||||
pendingRemoval.value = "";
|
||||
} catch (e) {
|
||||
homeChargersError.value = e.message;
|
||||
} finally {
|
||||
removing.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,9 +674,8 @@ onMounted(async () => {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-for="c in homeChargers" :key="c.id">
|
||||
<div
|
||||
v-for="c in homeChargers"
|
||||
:key="c.id"
|
||||
class="flex w-full items-center gap-3 rounded-control p-3 text-left transition-colors"
|
||||
:class="selected === c.id ? 'bg-brand-100' : 'hover:bg-sunken'"
|
||||
>
|
||||
@@ -677,12 +696,36 @@ onMounted(async () => {
|
||||
type="button"
|
||||
class="shrink-0 text-xs font-medium text-muted hover:text-danger"
|
||||
:title="t('charging.home.remove')"
|
||||
@click="removeHomeCharger(c)"
|
||||
@click="askRemoveHomeCharger(c)"
|
||||
>
|
||||
{{ t("charging.home.remove") }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Asked here rather than in a dialog the browser may never show. -->
|
||||
<div
|
||||
v-if="pendingRemoval === c.id"
|
||||
class="mx-3 mb-2 rounded-control border border-danger/40 bg-danger-soft p-3"
|
||||
>
|
||||
<p class="text-xs font-medium text-danger">
|
||||
{{ t("charging.home.removeConfirm", { name: c.name }) }}
|
||||
</p>
|
||||
<div class="mt-2 flex gap-2">
|
||||
<button type="button" class="dh-btn dh-btn-ghost grow" @click="cancelRemoveHomeCharger">
|
||||
{{ t("common.cancel") }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="dh-btn dh-btn-danger grow"
|
||||
:disabled="removing === c.id"
|
||||
@click="removeHomeCharger(c)"
|
||||
>
|
||||
{{ t("charging.home.remove") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Nothing imported yet: say what this list is for and offer the import. -->
|
||||
<div v-if="homeChargers.length === 0" class="px-3 pb-3 pt-1">
|
||||
<p class="text-sm text-muted">{{ t("charging.home.empty") }}</p>
|
||||
|
||||
Reference in New Issue
Block a user