fix(admin): apply SuperAdmin flags on بروزرسانی and fix overlay card keys
Pull live program-settings, set menu flags from the response, and key setting cards by setting key so id-null overlay rows no longer share one toggle state. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -80,7 +80,7 @@
|
|||||||
<a-row :gutter="[16, 16]" class="settings-grid">
|
<a-row :gutter="[16, 16]" class="settings-grid">
|
||||||
<a-col
|
<a-col
|
||||||
v-for="row in block.rows"
|
v-for="row in block.rows"
|
||||||
:key="row.id"
|
:key="row.key || `id-${row.id}`"
|
||||||
:xs="24"
|
:xs="24"
|
||||||
:sm="12"
|
:sm="12"
|
||||||
:lg="rowColSpan(row)"
|
:lg="rowColSpan(row)"
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
<a-row v-else :gutter="[16, 16]" class="settings-grid">
|
<a-row v-else :gutter="[16, 16]" class="settings-grid">
|
||||||
<a-col
|
<a-col
|
||||||
v-for="row in groupedFiltered[group.id]"
|
v-for="row in groupedFiltered[group.id]"
|
||||||
:key="row.id"
|
:key="row.key || `id-${row.id}`"
|
||||||
:xs="24"
|
:xs="24"
|
||||||
:sm="12"
|
:sm="12"
|
||||||
:lg="rowColSpan(row)"
|
:lg="rowColSpan(row)"
|
||||||
@@ -209,7 +209,7 @@ import SettingValueField from './SettingValueField.vue'
|
|||||||
import SettingCard from './SettingCard.vue'
|
import SettingCard from './SettingCard.vue'
|
||||||
import { refreshAppModeMenu } from '@/router'
|
import { refreshAppModeMenu } from '@/router'
|
||||||
import { useUserStore } from '@/store/userStore'
|
import { useUserStore } from '@/store/userStore'
|
||||||
import { applyBannerEnabledFromRows, applyTrackingSystemsEnabledFromRows, applyConditionalOrderEnabledFromRows, applyAutomationEnabledFromRows, applyProductFundsEnabledFromRows, applyPriceTriggerEnabledFromRows, applyAppNotificationEnabledFromRows, applyPriceProviderFromRows, applyPriceChannelAccessFromRows, applySupportChatMenuEnabledFromRows, applyGroupSmsFromRows, applyCustomerSpecialPricingFromRows, applyCustomerDirectSmsFromRows, applyCustomerLevelProfitEnabledFromRows, setBannerEnabledFromSettings, setConditionalOrderEnabledFromSettings, setAutomationEnabledFromSettings, setProductFundsEnabledFromSettings, setPriceTriggerEnabledFromSettings, setAppNotificationEnabledFromSettings, setPriceProviderFromSettings, setPriceChannelAccessFromSettings, setStoreModeFromSettings, setTrackingSystemsEnabledFromSettings, setGroupSmsEnabledFromSettings, setCustomerSpecialPricingEnabledFromSettings } from '@/utils/config'
|
import { applyBannerEnabledFromRows, applyTrackingSystemsEnabledFromRows, applyConditionalOrderEnabledFromRows, applyAutomationEnabledFromRows, applyProductFundsEnabledFromRows, applyPriceTriggerEnabledFromRows, applyAppNotificationEnabledFromRows, applyPriceProviderFromRows, applyPriceChannelAccessFromRows, applySupportChatMenuEnabledFromRows, applyGroupSmsFromRows, applyCustomerSpecialPricingFromRows, applyCustomerDirectSmsFromRows, applyCustomerLevelProfitEnabledFromRows, applySuperAdminAccessFlagsFromItems, invalidateSettingsBootstrap, setBannerEnabledFromSettings, setConditionalOrderEnabledFromSettings, setAutomationEnabledFromSettings, setProductFundsEnabledFromSettings, setPriceTriggerEnabledFromSettings, setAppNotificationEnabledFromSettings, setPriceProviderFromSettings, setPriceChannelAccessFromSettings, setStoreModeFromSettings, setTrackingSystemsEnabledFromSettings, setGroupSmsEnabledFromSettings, setCustomerSpecialPricingEnabledFromSettings } from '@/utils/config'
|
||||||
import {
|
import {
|
||||||
EDITABLE_SETTING_GROUPS,
|
EDITABLE_SETTING_GROUPS,
|
||||||
SYSTEM_SETTING_GROUPS,
|
SYSTEM_SETTING_GROUPS,
|
||||||
@@ -256,7 +256,8 @@ const typeSelectOptions = SETTING_TYPE_OPTIONS.map((t) => ({
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
const baseData = ref<Array<Const>>([])
|
const baseData = ref<Array<Const>>([])
|
||||||
const drafts = ref<Record<number, string>>({})
|
/** draft بر اساس id یا key — ردیفهای overlay سوپرادمین id=null دارند */
|
||||||
|
const drafts = ref<Record<string, string>>({})
|
||||||
const addConfigVisible = ref(false)
|
const addConfigVisible = ref(false)
|
||||||
const search = ref('')
|
const search = ref('')
|
||||||
const filterType = ref<string | undefined>()
|
const filterType = ref<string | undefined>()
|
||||||
@@ -266,6 +267,11 @@ const savedFlashIds = ref<Set<number>>(new Set())
|
|||||||
const saveTimers = new Map<number, ReturnType<typeof setTimeout>>()
|
const saveTimers = new Map<number, ReturnType<typeof setTimeout>>()
|
||||||
const debouncedSave = new Map<number, ReturnType<typeof debounce>>()
|
const debouncedSave = new Map<number, ReturnType<typeof debounce>>()
|
||||||
|
|
||||||
|
function rowDraftKey(row: Const): string {
|
||||||
|
if (row.id != null) return `id:${row.id}`
|
||||||
|
return `key:${row.key || ''}`
|
||||||
|
}
|
||||||
|
|
||||||
const form = ref<Const>({
|
const form = ref<Const>({
|
||||||
key: '',
|
key: '',
|
||||||
value: '',
|
value: '',
|
||||||
@@ -311,7 +317,7 @@ function matchesFilter(row: Const): boolean {
|
|||||||
(row.key || '').toLowerCase().includes(q) ||
|
(row.key || '').toLowerCase().includes(q) ||
|
||||||
(row.title_fa || '').toLowerCase().includes(q) ||
|
(row.title_fa || '').toLowerCase().includes(q) ||
|
||||||
(row.value || '').toLowerCase().includes(q) ||
|
(row.value || '').toLowerCase().includes(q) ||
|
||||||
(drafts.value[row.id!] || '').toLowerCase().includes(q)
|
(drafts.value[rowDraftKey(row)] || '').toLowerCase().includes(q)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,8 +459,8 @@ function isReadonly(row: Const): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function draftValue(row: Const): string {
|
function draftValue(row: Const): string {
|
||||||
const id = row.id!
|
const k = rowDraftKey(row)
|
||||||
if (drafts.value[id] !== undefined) return drafts.value[id]
|
if (drafts.value[k] !== undefined) return drafts.value[k]
|
||||||
return row.value ?? ''
|
return row.value ?? ''
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,9 +473,9 @@ function isSavedFlash(id?: number): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function syncDraftsFromBase() {
|
function syncDraftsFromBase() {
|
||||||
const next: Record<number, string> = {}
|
const next: Record<string, string> = {}
|
||||||
for (const row of baseData.value || []) {
|
for (const row of baseData.value || []) {
|
||||||
if (row.id != null) next[row.id] = row.value ?? ''
|
next[rowDraftKey(row)] = row.value ?? ''
|
||||||
}
|
}
|
||||||
drafts.value = next
|
drafts.value = next
|
||||||
}
|
}
|
||||||
@@ -488,11 +494,39 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async function pullSuperAdminAndApplyFlags(): Promise<{
|
||||||
|
ok: boolean
|
||||||
|
message?: string
|
||||||
|
count?: number
|
||||||
|
}> {
|
||||||
|
invalidateSettingsBootstrap()
|
||||||
|
const res = await refreshSuperAdminSettings()
|
||||||
|
if (res?.items && typeof res.items === 'object') {
|
||||||
|
applySuperAdminAccessFlagsFromItems(res.items)
|
||||||
|
}
|
||||||
|
// get_settings کامل — فلگ منو و کارتها با مقدار زنده همتراز شوند
|
||||||
|
try {
|
||||||
|
const { getConfiguration } = await import('@/api/configuration')
|
||||||
|
const all = await getConfiguration()
|
||||||
|
const rows = Array.isArray(all) ? all : []
|
||||||
|
applySuperAdminAccessFlagsFromItems(rows)
|
||||||
|
applyPriceProviderFromRows(rows)
|
||||||
|
applyPriceChannelAccessFromRows(rows)
|
||||||
|
} catch {
|
||||||
|
/* فلگ از items میماند */
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
ok: res?.ok !== false,
|
||||||
|
message: res?.message,
|
||||||
|
count: res?.count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function refreshFromSuperAdmin() {
|
async function refreshFromSuperAdmin() {
|
||||||
if (refreshingSuperAdmin.value) return
|
if (refreshingSuperAdmin.value) return
|
||||||
refreshingSuperAdmin.value = true
|
refreshingSuperAdmin.value = true
|
||||||
try {
|
try {
|
||||||
const res = await refreshSuperAdminSettings()
|
const res = await pullSuperAdminAndApplyFlags()
|
||||||
await initConfig()
|
await initConfig()
|
||||||
refreshMenuAfterStoreChange()
|
refreshMenuAfterStoreChange()
|
||||||
message.success(res?.message || `همگام شد (${res?.count ?? 0} کلید دسترسی از سوپرادمین)`)
|
message.success(res?.message || `همگام شد (${res?.count ?? 0} کلید دسترسی از سوپرادمین)`)
|
||||||
@@ -505,21 +539,23 @@ async function refreshFromSuperAdmin() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** بروزرسانی: اول از سوپرادمین زنده بخوان، بعد لیست تنظیمات را دوباره بگیر */
|
/** بروزرسانی: زنده از سوپرادمین بگیر → فلگ منو اعمال شود → لیست تنظیمات رفرش */
|
||||||
async function onRefreshClick() {
|
async function onRefreshClick() {
|
||||||
if (refreshingSuperAdmin.value || loading.value) return
|
if (refreshingSuperAdmin.value || loading.value) return
|
||||||
refreshingSuperAdmin.value = true
|
refreshingSuperAdmin.value = true
|
||||||
try {
|
try {
|
||||||
await refreshSuperAdminSettings()
|
const res = await pullSuperAdminAndApplyFlags()
|
||||||
|
await initConfig()
|
||||||
|
refreshMenuAfterStoreChange()
|
||||||
|
message.success(res?.message || 'بروزرسانی شد')
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
const msg = e?.response?.data?.message || e?.message || 'همگامسازی از سوپرادمین ناموفق بود'
|
const msg = e?.response?.data?.message || e?.message || 'همگامسازی از سوپرادمین ناموفق بود'
|
||||||
message.error(Array.isArray(msg) ? msg.join('، ') : msg)
|
message.error(Array.isArray(msg) ? msg.join('، ') : msg)
|
||||||
|
await initConfig()
|
||||||
} finally {
|
} finally {
|
||||||
refreshingSuperAdmin.value = false
|
refreshingSuperAdmin.value = false
|
||||||
}
|
}
|
||||||
await initConfig()
|
|
||||||
refreshMenuAfterStoreChange()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initConfig() {
|
async function initConfig() {
|
||||||
@@ -644,13 +680,15 @@ function syncMenuFlagsFromSetting(key: string | undefined, value: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onValueChange(row: Const, value: string) {
|
function onValueChange(row: Const, value: string) {
|
||||||
if (row.id == null || isReadonly(row)) return
|
if (isReadonly(row)) return
|
||||||
|
|
||||||
drafts.value[row.id] = value
|
drafts.value[rowDraftKey(row)] = value
|
||||||
|
|
||||||
// منو و UI وابسته را همان لحظه با سوئیچ همگام کن
|
// منو و UI وابسته را همان لحظه با سوئیچ همگام کن
|
||||||
syncMenuFlagsFromSetting(row.key, value)
|
syncMenuFlagsFromSetting(row.key, value)
|
||||||
|
|
||||||
|
if (row.id == null) return
|
||||||
|
|
||||||
// longtext هم باید ذخیره شود، فقط با delay بیشتر
|
// longtext هم باید ذخیره شود، فقط با delay بیشتر
|
||||||
scheduleSave(row)
|
scheduleSave(row)
|
||||||
}
|
}
|
||||||
@@ -699,9 +737,10 @@ async function persistRow(row: Const) {
|
|||||||
async function saveSettingRow(row: Const) {
|
async function saveSettingRow(row: Const) {
|
||||||
if (row.id == null) return
|
if (row.id == null) return
|
||||||
const id = row.id
|
const id = row.id
|
||||||
|
const draftKey = rowDraftKey(row)
|
||||||
|
|
||||||
const type = resolveSettingFieldType(row)
|
const type = resolveSettingFieldType(row)
|
||||||
const raw = drafts.value[id] ?? row.value ?? ''
|
const raw = drafts.value[draftKey] ?? row.value ?? ''
|
||||||
const value = formatValueForSave(raw, type, row.key)
|
const value = formatValueForSave(raw, type, row.key)
|
||||||
if (value === (row.value ?? '')) return
|
if (value === (row.value ?? '')) return
|
||||||
|
|
||||||
@@ -723,9 +762,9 @@ async function saveSettingRow(row: Const) {
|
|||||||
})
|
})
|
||||||
row.value = value
|
row.value = value
|
||||||
row.is_active = true
|
row.is_active = true
|
||||||
const currentDraft = drafts.value[id] ?? ''
|
const currentDraft = drafts.value[draftKey] ?? ''
|
||||||
if (currentDraft === draftSnapshot) {
|
if (currentDraft === draftSnapshot) {
|
||||||
drafts.value[id] = value
|
drafts.value[draftKey] = value
|
||||||
} else {
|
} else {
|
||||||
scheduleSave(row)
|
scheduleSave(row)
|
||||||
}
|
}
|
||||||
@@ -745,8 +784,8 @@ async function saveSettingRow(row: Const) {
|
|||||||
)
|
)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
if ((drafts.value[id] ?? '') === draftSnapshot) {
|
if ((drafts.value[draftKey] ?? '') === draftSnapshot) {
|
||||||
drafts.value[id] = row.value ?? ''
|
drafts.value[draftKey] = row.value ?? ''
|
||||||
}
|
}
|
||||||
// برگرداندن فلگ منو به مقدار ذخیرهشده قبلی
|
// برگرداندن فلگ منو به مقدار ذخیرهشده قبلی
|
||||||
syncMenuFlagsFromSetting(row.key, row.value ?? '')
|
syncMenuFlagsFromSetting(row.key, row.value ?? '')
|
||||||
|
|||||||
@@ -283,6 +283,33 @@ export function applyCustomerSpecialPricingFromRows(
|
|||||||
if (row) setCustomerSpecialPricingEnabledFromSettings(isSwitchOn(row.value))
|
if (row) setCustomerSpecialPricingEnabledFromSettings(isSwitchOn(row.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** بعد از همگامسازی سوپرادمین — bootstrap بعدی دوباره از API میخواند */
|
||||||
|
export function invalidateSettingsBootstrap(): void {
|
||||||
|
settingsBootstrapped = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* اعمال مستقیم ۱۴ دسترسی سوپرادمین روی فلگهای منو/UI
|
||||||
|
* (پاسخ refresh-superadmin.items یا ردیفهای get_settings).
|
||||||
|
*/
|
||||||
|
export function applySuperAdminAccessFlagsFromItems(
|
||||||
|
items: Record<string, string> | Array<{ key?: string; value?: string | null }>
|
||||||
|
): void {
|
||||||
|
const rows = Array.isArray(items)
|
||||||
|
? items
|
||||||
|
: Object.entries(items).map(([key, value]) => ({ key, value }))
|
||||||
|
applyCustomerDirectSmsFromRows(rows)
|
||||||
|
applyGroupSmsFromRows(rows)
|
||||||
|
applyCustomerSpecialPricingFromRows(rows)
|
||||||
|
applyConditionalOrderEnabledFromRows(rows)
|
||||||
|
applyAutomationEnabledFromRows(rows)
|
||||||
|
applyProductFundsEnabledFromRows(rows)
|
||||||
|
applyCustomerLevelProfitEnabledFromRows(rows)
|
||||||
|
applyPriceTriggerEnabledFromRows(rows)
|
||||||
|
applyAppNotificationEnabledFromRows(rows)
|
||||||
|
applySupportChatMenuEnabledFromRows(rows)
|
||||||
|
}
|
||||||
|
|
||||||
export function applyConditionalOrderEnabledFromRows(
|
export function applyConditionalOrderEnabledFromRows(
|
||||||
rows: Array<{ key?: string; value?: string | null }>
|
rows: Array<{ key?: string; value?: string | null }>
|
||||||
) {
|
) {
|
||||||
|
|||||||
Reference in New Issue
Block a user