fix(get-user): apply shared khanegi nav sample to all tenants
Keep bottom menu at 4 slots so outdated per-tenant JSON cannot overflow the bar. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { iranDaysUntil } from '../common/iran-time.util';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { applyKhanegiNavSample } from './khanegi-nav-sample';
|
||||
|
||||
type UiSetting = { key: string; value: string };
|
||||
|
||||
@@ -318,10 +319,13 @@ export class GetUserService {
|
||||
}
|
||||
|
||||
const navigation = app.navigation;
|
||||
if (!navigation || typeof navigation !== 'object') return;
|
||||
|
||||
if (navigation.type === 'sidebar+bottom') navigation.type = 'both';
|
||||
if (!navigation || typeof navigation !== 'object') {
|
||||
app.navigation = { type: 'both' };
|
||||
} else if (navigation.type === 'sidebar+bottom') {
|
||||
navigation.type = 'both';
|
||||
}
|
||||
|
||||
const nav = app.navigation;
|
||||
const mapItems = (items: unknown) => {
|
||||
if (!Array.isArray(items)) return items;
|
||||
return items.map((item) => {
|
||||
@@ -331,11 +335,12 @@ export class GetUserService {
|
||||
});
|
||||
};
|
||||
|
||||
navigation.sidebar = mapItems(navigation.sidebar);
|
||||
navigation.bottom = mapItems(navigation.bottom);
|
||||
if (navigation.sidebarReferral?.route === 'products') {
|
||||
navigation.sidebarReferral.route = 'buyProduct';
|
||||
nav.sidebar = mapItems(nav.sidebar);
|
||||
nav.bottom = mapItems(nav.bottom);
|
||||
if (nav.sidebarReferral?.route === 'products') {
|
||||
nav.sidebarReferral.route = 'buyProduct';
|
||||
}
|
||||
applyKhanegiNavSample(nav);
|
||||
}
|
||||
|
||||
private buildHamkarUiSettings(ui: Record<string, any>): UiSetting[] {
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* سمپل منوی خانگی — با controlpanel_user/src/config/defaultKhanegiUiConfig.ts یکی بماند.
|
||||
* آپدیت این لیست روی همهٔ نسخهها از طریق get_user اعمال میشود.
|
||||
*/
|
||||
export const MAX_BOTTOM_NAV_SLOTS = 4
|
||||
|
||||
export type KhanegiNavItem = {
|
||||
id: string
|
||||
label: string
|
||||
icon: string
|
||||
route: string
|
||||
order: number
|
||||
visible: boolean
|
||||
query?: Record<string, string>
|
||||
}
|
||||
|
||||
export const KHANEGI_SAMPLE_SIDEBAR: KhanegiNavItem[] = [
|
||||
{ id: 'home', label: 'داشبورد', icon: 'vuesax-linear:chart', route: 'home', order: 1, visible: true },
|
||||
{ id: 'buy', label: 'خرید طلا', icon: 'vuesax-linear:money-receive', route: 'gold', order: 2, visible: true, query: { state: 'buy' } },
|
||||
{ id: 'sell', label: 'فروش طلا', icon: 'vuesax-linear:money-send', route: 'gold', order: 3, visible: true, query: { state: 'sell' } },
|
||||
{ id: 'wallet', label: 'کیف پول', icon: 'vuesax-linear:wallet-1', route: 'wallet', order: 4, visible: true },
|
||||
{ id: 'transactions', label: 'تراکنشها', icon: 'vuesax-linear:receipt-item', route: 'transactions', order: 5, visible: true },
|
||||
{ id: 'products', label: 'محصولات', icon: 'vuesax-linear:coin', route: 'buyProduct', order: 7, visible: true },
|
||||
{ id: 'user', label: 'تنظیمات', icon: 'vuesax-linear:setting-2', route: 'user', order: 8, visible: true },
|
||||
]
|
||||
|
||||
export const KHANEGI_SAMPLE_BOTTOM: KhanegiNavItem[] = [
|
||||
{ id: 'gold', label: 'خرید و فروش', icon: 'vuesax-linear:coin', route: 'gold', order: 1, visible: true },
|
||||
{ id: 'transactions', label: 'تراکنشها', icon: 'vuesax-linear:receipt-item', route: 'transactions', order: 2, visible: true },
|
||||
{ id: 'wallet', label: 'کیف پول', icon: 'vuesax-linear:wallet-add', route: 'wallet', order: 3, visible: true },
|
||||
{ id: 'user', label: 'تنظیمات', icon: 'vuesax-linear:setting-2', route: 'user', order: 4, visible: true },
|
||||
]
|
||||
|
||||
export function mergeNavItemsFromSample(
|
||||
sample: KhanegiNavItem[],
|
||||
stored: unknown,
|
||||
maxVisible?: number,
|
||||
): KhanegiNavItem[] {
|
||||
const sampleById = new Map(sample.map((item) => [item.id, item]))
|
||||
const storedList = Array.isArray(stored) ? stored : []
|
||||
const kept: KhanegiNavItem[] = []
|
||||
const seen = new Set<string>()
|
||||
|
||||
for (const prev of storedList) {
|
||||
if (!prev || typeof prev !== 'object' || typeof prev.id !== 'string') continue
|
||||
const base = sampleById.get(prev.id)
|
||||
if (!base || seen.has(prev.id)) continue
|
||||
seen.add(prev.id)
|
||||
kept.push({
|
||||
...base,
|
||||
label: prev.label || base.label,
|
||||
icon: prev.icon || base.icon,
|
||||
visible: typeof prev.visible === 'boolean' ? prev.visible : base.visible,
|
||||
query: prev.query ?? base.query,
|
||||
})
|
||||
}
|
||||
|
||||
for (const item of sample) {
|
||||
if (seen.has(item.id)) continue
|
||||
kept.push({ ...item })
|
||||
}
|
||||
|
||||
if (typeof maxVisible === 'number') {
|
||||
let visibleCount = 0
|
||||
for (const item of kept) {
|
||||
if (!item.visible) continue
|
||||
visibleCount += 1
|
||||
if (visibleCount > maxVisible) item.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
return kept.map((item, index) => ({ ...item, order: index + 1 }))
|
||||
}
|
||||
|
||||
export function applyKhanegiNavSample(navigation: Record<string, any>) {
|
||||
navigation.sidebar = mergeNavItemsFromSample(KHANEGI_SAMPLE_SIDEBAR, navigation.sidebar)
|
||||
navigation.bottom = mergeNavItemsFromSample(
|
||||
KHANEGI_SAMPLE_BOTTOM.slice(0, MAX_BOTTOM_NAV_SLOTS),
|
||||
navigation.bottom,
|
||||
MAX_BOTTOM_NAV_SLOTS,
|
||||
).slice(0, MAX_BOTTOM_NAV_SLOTS)
|
||||
}
|
||||
Reference in New Issue
Block a user