// GlobalFeedbackHost.jsx — fixed app-level notification stack. (function () { function resolveFeedbackApi() { if (window.Keeper && window.Keeper.feedback) return window.Keeper.feedback; return null; } function i18nText(key, fallback, params) { const i18n = window.Keeper && window.Keeper.i18n ? window.Keeper.i18n : null; if (i18n && typeof i18n.t === "function") return i18n.t(key, params, { fallback }); return fallback; } function GlobalFeedbackHost() { const feedbackApi = resolveFeedbackApi(); const [items, setItems] = React.useState(() => { if (!feedbackApi || typeof feedbackApi.getItems !== "function") return []; return feedbackApi.getItems(); }); const topItemIdRef = React.useRef(null); React.useEffect(() => { const api = resolveFeedbackApi(); if (!api || typeof api.subscribe !== "function") return undefined; return api.subscribe((nextItems) => { setItems(Array.isArray(nextItems) ? nextItems : []); }); }, []); React.useEffect(() => { const top = Array.isArray(items) && items.length > 0 ? items[0] : null; topItemIdRef.current = top ? top.id : null; }, [items]); React.useEffect(() => { function onEscape(event) { if (!event || event.key !== "Escape") return; const topId = topItemIdRef.current; if (!topId) return; const api = resolveFeedbackApi(); if (api && typeof api.dismiss === "function") { api.dismiss(topId); } } window.addEventListener("keydown", onEscape); return () => window.removeEventListener("keydown", onEscape); }, []); if (!items.length) return null; return (
{items.map((item) => (
{ const api = resolveFeedbackApi(); if (api && typeof api.dismiss === "function") api.dismiss(item.id); }} aria-label={i18nText("shell.globalFeedback.closeAria", "Close notification: {message}", { message: item.message || i18nText("shell.globalFeedback.messageFallback", "message"), })} > )} />
))}
); } window.GlobalFeedbackHost = GlobalFeedbackHost; })();