-
-
-
- 🛡️ ВЫ В РЕЖИМЕ СУПЕР-АДМИНА — ОРГАНИЗАЦИЯ «{ov.name}» — ТОЛЬКО ПРОСМОТР
-
+ <>
+
+
+
+
+ 🛡️ ВЫ В РЕЖИМЕ СУПЕР-АДМИНА — ОРГАНИЗАЦИЯ «{ov.name}»
+ {edit
+ ? <> — EDIT-MODE ({minutesLeft} мин), мутации пишутся в журнал>
+ : <> — ТОЛЬКО ПРОСМОТР>}
+
+
+
+ {!edit ? (
+
+ ) : (
+
+ )}
+
+
-
-
+
+ {askReason && (
+
setAskReason(false)}>
+
e.stopPropagation()}>
+
Включить редактирование на 30 минут
+
+ Каждое изменение будет записано в журнал супер-админа с этой причиной.
+ Минимум 10 символов.
+
+
+
+ )}
+ >
)
}
diff --git a/src/food-market.web/src/lib/api.ts b/src/food-market.web/src/lib/api.ts
index d47d4bf..5117022 100644
--- a/src/food-market.web/src/lib/api.ts
+++ b/src/food-market.web/src/lib/api.ts
@@ -16,6 +16,10 @@ api.interceptors.request.use((config: InternalAxiosRequestConfig) => {
const asOrg = getOrgOverride()
if (asOrg && !(config.url ?? '').startsWith('/api/super-admin/')) {
config.headers.set('X-Org-Override', asOrg.id)
+ const edit = getEditMode()
+ if (edit && edit.expiresAt > Date.now()) {
+ config.headers.set('X-Org-Override-Reason', edit.reason)
+ }
}
return config
})
@@ -30,12 +34,35 @@ export function getOrgOverride(): OrgOverride | null {
}
export function setOrgOverride(value: OrgOverride | null) {
if (value) localStorage.setItem(ORG_OVERRIDE_KEY, JSON.stringify(value))
- else localStorage.removeItem(ORG_OVERRIDE_KEY)
+ else { localStorage.removeItem(ORG_OVERRIDE_KEY); localStorage.removeItem(EDIT_MODE_KEY) }
// Силой обновляем все вкладки/страницы — кэш TanStack Query построен по
// tenant'у, нужен hard reload чтобы снять старые данные.
if (typeof window !== 'undefined') window.location.reload()
}
+const EDIT_MODE_KEY = 'superAdminEditMode'
+export interface EditMode { reason: string; expiresAt: number }
+export function getEditMode(): EditMode | null {
+ try {
+ const raw = localStorage.getItem(EDIT_MODE_KEY)
+ if (!raw) return null
+ const v = JSON.parse(raw) as EditMode
+ if (v.expiresAt < Date.now()) { localStorage.removeItem(EDIT_MODE_KEY); return null }
+ return v
+ } catch { return null }
+}
+/** Включает edit-mode на 30 минут (по таймеру localStorage). После
+ * истечения axios перестаёт слать reason, мутации снова блокируются. */
+export function enableEditMode(reason: string) {
+ const v: EditMode = { reason: reason.trim(), expiresAt: Date.now() + 30 * 60 * 1000 }
+ localStorage.setItem(EDIT_MODE_KEY, JSON.stringify(v))
+ if (typeof window !== 'undefined') window.location.reload()
+}
+export function disableEditMode() {
+ localStorage.removeItem(EDIT_MODE_KEY)
+ if (typeof window !== 'undefined') window.location.reload()
+}
+
let refreshing: Promise
| null = null
api.interceptors.response.use(