fix: HA-Event-Update URL-Encoding und Popup-Überlappung bei Lösch-Dialog
- HA Update/Delete: UID wird URL-encoded (@ → %40), Delete mit Fallback auf Service-Call API für ältere HA-Versionen - Lösch-Dialog: Event-Popup wird geschlossen BEVOR der Bestätigungsdialog erscheint, kein Überlappen mehr
This commit is contained in:
@@ -110,7 +110,11 @@ def _ha_get_events(url: str, token: str, entity_id: str, start_dt: datetime, end
|
|||||||
|
|
||||||
|
|
||||||
def _ha_update_event(url: str, token: str, entity_id: str, uid: str, data: dict):
|
def _ha_update_event(url: str, token: str, entity_id: str, uid: str, data: dict):
|
||||||
"""Update an event via HA REST API."""
|
"""Update an event via HA REST API (HA 2023.11+)."""
|
||||||
|
from urllib.parse import quote
|
||||||
|
base = url.rstrip("/")
|
||||||
|
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
|
||||||
|
encoded_uid = quote(uid, safe="")
|
||||||
body = {}
|
body = {}
|
||||||
if "title" in data:
|
if "title" in data:
|
||||||
body["summary"] = data["title"]
|
body["summary"] = data["title"]
|
||||||
@@ -126,26 +130,35 @@ def _ha_update_event(url: str, token: str, entity_id: str, uid: str, data: dict)
|
|||||||
body["start"] = {"dateTime": data["start"]}
|
body["start"] = {"dateTime": data["start"]}
|
||||||
body["end"] = {"dateTime": data["end"]}
|
body["end"] = {"dateTime": data["end"]}
|
||||||
resp = http_requests.put(
|
resp = http_requests.put(
|
||||||
f"{url.rstrip('/')}/api/calendars/{entity_id}/{uid}",
|
f"{base}/api/calendars/{entity_id}/{encoded_uid}",
|
||||||
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
|
headers=headers, json=body, timeout=15, verify=False,
|
||||||
json=body,
|
|
||||||
timeout=15,
|
|
||||||
verify=False,
|
|
||||||
)
|
)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
|
||||||
def _ha_delete_event(url: str, token: str, entity_id: str, uid: str):
|
def _ha_delete_event(url: str, token: str, entity_id: str, uid: str):
|
||||||
"""Delete an event via HA REST API."""
|
"""Delete an event via HA REST API with fallback to service call."""
|
||||||
|
base = url.rstrip("/")
|
||||||
|
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
|
||||||
|
# Try REST API first (HA 2023.11+)
|
||||||
|
from urllib.parse import quote
|
||||||
|
encoded_uid = quote(uid, safe="")
|
||||||
resp = http_requests.delete(
|
resp = http_requests.delete(
|
||||||
f"{url.rstrip('/')}/api/calendars/{entity_id}/{uid}",
|
f"{base}/api/calendars/{entity_id}/{encoded_uid}",
|
||||||
headers={"Authorization": f"Bearer {token}"},
|
headers=headers, timeout=15, verify=False,
|
||||||
timeout=15,
|
|
||||||
verify=False,
|
|
||||||
)
|
)
|
||||||
resp.raise_for_status()
|
if resp.status_code < 400:
|
||||||
return resp
|
return resp
|
||||||
|
# Fallback: service call
|
||||||
|
resp2 = http_requests.post(
|
||||||
|
f"{base}/api/services/calendar/delete_event",
|
||||||
|
headers=headers,
|
||||||
|
json={"entity_id": entity_id, "uid": uid},
|
||||||
|
timeout=15, verify=False,
|
||||||
|
)
|
||||||
|
resp2.raise_for_status()
|
||||||
|
return resp2
|
||||||
|
|
||||||
|
|
||||||
def _parse_ha_event(ev: dict, cal_db_id: int, cal_name: str, cal_color: str) -> dict:
|
def _parse_ha_event(ev: dict, cal_db_id: int, cal_name: str, cal_color: str) -> dict:
|
||||||
|
|||||||
@@ -1034,9 +1034,9 @@ function showEventPopup(ev, anchor) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
document.getElementById('popup-delete').onclick = async () => {
|
document.getElementById('popup-delete').onclick = async () => {
|
||||||
|
popup.classList.add('hidden');
|
||||||
const scope = await showDeleteConfirm(ev);
|
const scope = await showDeleteConfirm(ev);
|
||||||
if (!scope) return;
|
if (!scope) return;
|
||||||
popup.classList.add('hidden');
|
|
||||||
try {
|
try {
|
||||||
await deleteEventByScope(ev, scope);
|
await deleteEventByScope(ev, scope);
|
||||||
showToast(t('event_deleted'));
|
showToast(t('event_deleted'));
|
||||||
|
|||||||
Reference in New Issue
Block a user