From a46d0e0eac0b7e75d965238731da09b18ee969ca Mon Sep 17 00:00:00 2001 From: IK Date: Mon, 21 Sep 2026 20:41:35 +0700 Subject: [PATCH] fix: constrain admin media role choices --- apps/web/src/pages/admin/media.astro | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/web/src/pages/admin/media.astro b/apps/web/src/pages/admin/media.astro index 4cbba02..5fb475b 100644 --- a/apps/web/src/pages/admin/media.astro +++ b/apps/web/src/pages/admin/media.astro @@ -30,6 +30,10 @@ const apiUrl = import.meta.env.PUBLIC_API_URL || "http://localhost:8000"; const next = document.querySelector("[data-next]"); const refresh = document.querySelector("[data-refresh]"); const pageNumber = document.querySelector("[data-page-number]"); + const entityFilter = filters?.querySelector('[name="entity_type"]'); + const roleFilter = filters?.querySelector('[name="media_role"]'); + const rolesByEntity: Record> = { waterbody: new Set(["waterbody_cover", "waterbody_map", "waterbody_depth_map", "waterbody_screenshot"]), tackle: new Set(["tackle_card", "tackle_detail", "rig_diagram", "tackle_screenshot"]) }; + const syncRoleFilter = () => { const allowed = rolesByEntity[entityFilter?.value ?? ""] ?? new Set(); if (roleFilter) { [...roleFilter.options].forEach(option => { if (!option.value) return; option.hidden = !allowed.has(option.value); option.disabled = !allowed.has(option.value); }); if (roleFilter.value && !allowed.has(roleFilter.value)) roleFilter.value = ""; roleFilter.disabled = allowed.size === 0; } }; let token = ""; let offset = 0; let timer: ReturnType | undefined; const esc = (value: unknown) => String(value ?? "—").replace(/[&<>'"]/g, char => ({"&":"&","<":"<",">":">","'":"'",'"':"""}[char] ?? char)); const url = (value: unknown) => { try { const parsed = new URL(String(value), root?.dataset.apiUrl); return (parsed.protocol === "http:" || parsed.protocol === "https:") && !parsed.username && !parsed.password && parsed.hostname ? esc(parsed.href) : ""; } catch { return ""; } }; @@ -57,5 +61,7 @@ const apiUrl = import.meta.env.PUBLIC_API_URL || "http://localhost:8000"; const move = async (delta: number) => { offset = Math.max(0, offset + delta); try { await load(); } catch (cause) { fail(cause instanceof Error ? cause.message : "Ошибка загрузки страницы."); } }; previous?.addEventListener("click", () => move(-50)); next?.addEventListener("click", () => move(50)); refresh?.addEventListener("click", async () => { refresh.disabled = true; try { await load(); succeed("Медиатека обновлена."); } catch (cause) { fail(cause instanceof Error ? cause.message : "Не удалось обновить медиатеку."); } finally { refresh.disabled = false; } }); logout?.addEventListener("click", () => endSession("Вы вышли из административной панели.")); + entityFilter?.addEventListener("change", syncRoleFilter); + syncRoleFilter();