added main page config
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { applyKhanegiLayoutVariants, createDefaultKhanegiLayoutVariants } from '@/config/khanegiLayoutVariants'
|
||||
|
||||
export type ThemeColors = {
|
||||
primary: string
|
||||
secondary: string
|
||||
@@ -112,6 +114,7 @@ export function createDefaultKhanegiUiConfig() {
|
||||
showProfile: true,
|
||||
brandSubtitle: 'پنل کاربری',
|
||||
},
|
||||
layoutVariants: createDefaultKhanegiLayoutVariants(),
|
||||
},
|
||||
pages: {} as Record<string, unknown>,
|
||||
}
|
||||
@@ -303,6 +306,7 @@ export function normalizeKhanegiUiConfigForClient<T extends Record<string, any>>
|
||||
if (app.header && typeof app.header === 'object') {
|
||||
app.header.variant = 'default'
|
||||
}
|
||||
applyKhanegiLayoutVariants(app)
|
||||
if (app.navigation && typeof app.navigation === 'object') {
|
||||
if (app.navigation.type === 'sidebar+bottom') app.navigation.type = 'both'
|
||||
app.navigation.sidebar = mapLegacyNavItems(app.navigation.sidebar)
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* چیدمان المانهای تم جدید.
|
||||
* با controlpanel_server/src/get-user/khanegi-layout-variants.ts یکی بماند.
|
||||
* variant شناسهٔ themeN است. جزئیات المان داخل options میماند.
|
||||
*/
|
||||
|
||||
export const LAYOUT_VARIANT_ID = /^theme[1-9]\d*$/
|
||||
export const LAYOUT_OPTION_KEY = /^[a-zA-Z][a-zA-Z0-9_]*$/
|
||||
|
||||
export type LayoutThemeDef = {
|
||||
id: string
|
||||
label: string
|
||||
}
|
||||
|
||||
export type LayoutElementConfig = {
|
||||
id: string
|
||||
variant: string
|
||||
options: Record<string, unknown>
|
||||
}
|
||||
|
||||
export type KhanegiLayoutVariants = {
|
||||
schemaId: 'layout-variants'
|
||||
version: '1.0.0'
|
||||
themes: LayoutThemeDef[]
|
||||
header: LayoutElementConfig
|
||||
footer: LayoutElementConfig
|
||||
home: {
|
||||
assets: LayoutElementConfig
|
||||
livePrice: LayoutElementConfig
|
||||
quickAccess: LayoutElementConfig
|
||||
recentTransactions: LayoutElementConfig
|
||||
[elementId: string]: LayoutElementConfig
|
||||
}
|
||||
}
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
|
||||
}
|
||||
|
||||
export function isLayoutVariantId(value: unknown): value is string {
|
||||
return typeof value === 'string' && LAYOUT_VARIANT_ID.test(value)
|
||||
}
|
||||
|
||||
export function nextLayoutThemeId(ids: string[]): string {
|
||||
let n = 1
|
||||
const used = new Set(ids)
|
||||
while (used.has(`theme${n}`)) n += 1
|
||||
return `theme${n}`
|
||||
}
|
||||
|
||||
function defaultThemes(): LayoutThemeDef[] {
|
||||
return [
|
||||
{ id: 'theme1', label: 'تم ۱' },
|
||||
{ id: 'theme2', label: 'تم ۲' },
|
||||
]
|
||||
}
|
||||
|
||||
function element(id: string): LayoutElementConfig {
|
||||
return { id, variant: 'theme1', options: {} }
|
||||
}
|
||||
|
||||
export function mergeLayoutThemes(stored: unknown, usedIds: string[] = []): LayoutThemeDef[] {
|
||||
const parsed: LayoutThemeDef[] = []
|
||||
const seen = new Set<string>()
|
||||
if (Array.isArray(stored)) {
|
||||
for (const row of stored) {
|
||||
if (!isRecord(row) || !isLayoutVariantId(row.id) || seen.has(row.id)) continue
|
||||
seen.add(row.id)
|
||||
const label = typeof row.label === 'string' && row.label.trim()
|
||||
? row.label.trim().slice(0, 40)
|
||||
: row.id
|
||||
parsed.push({ id: row.id, label })
|
||||
}
|
||||
}
|
||||
const list = parsed.length ? parsed : defaultThemes()
|
||||
for (const id of usedIds) {
|
||||
if (!isLayoutVariantId(id) || list.some((theme) => theme.id === id)) continue
|
||||
list.push({ id, label: id })
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
export function createDefaultKhanegiLayoutVariants(): KhanegiLayoutVariants {
|
||||
return {
|
||||
schemaId: 'layout-variants',
|
||||
version: '1.0.0',
|
||||
themes: defaultThemes(),
|
||||
header: element('header'),
|
||||
footer: element('footer'),
|
||||
home: {
|
||||
assets: element('assets'),
|
||||
livePrice: element('livePrice'),
|
||||
quickAccess: element('quickAccess'),
|
||||
recentTransactions: element('recentTransactions'),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function mergeLayoutElement(id: string, stored: unknown): LayoutElementConfig {
|
||||
const base = element(id)
|
||||
if (!isRecord(stored)) return base
|
||||
const options = isRecord(stored.options) ? { ...stored.options } : {}
|
||||
return {
|
||||
...stored,
|
||||
id,
|
||||
variant: isLayoutVariantId(stored.variant) ? stored.variant : 'theme1',
|
||||
options,
|
||||
}
|
||||
}
|
||||
|
||||
/** تم انتخابشده و کلید options پاک نمیشود. فهرست تم خالی به تم ۱ و ۲ برمیگردد. */
|
||||
export function mergeKhanegiLayoutVariants(stored: unknown): KhanegiLayoutVariants {
|
||||
const defaults = createDefaultKhanegiLayoutVariants()
|
||||
const src = isRecord(stored) ? stored : {}
|
||||
const homeSrc = isRecord(src.home) ? src.home : {}
|
||||
const knownHome = Object.keys(defaults.home)
|
||||
const home: KhanegiLayoutVariants['home'] = { ...defaults.home }
|
||||
|
||||
for (const key of Object.keys(homeSrc)) {
|
||||
if (knownHome.includes(key)) continue
|
||||
home[key] = mergeLayoutElement(key, homeSrc[key])
|
||||
}
|
||||
for (const key of knownHome) {
|
||||
home[key] = mergeLayoutElement(key, homeSrc[key])
|
||||
}
|
||||
|
||||
const header = mergeLayoutElement('header', src.header)
|
||||
const footer = mergeLayoutElement('footer', src.footer)
|
||||
const usedIds = [header.variant, footer.variant, ...Object.values(home).map((item) => item.variant)]
|
||||
|
||||
return {
|
||||
...src,
|
||||
schemaId: 'layout-variants',
|
||||
version: '1.0.0',
|
||||
themes: mergeLayoutThemes(src.themes, usedIds),
|
||||
header,
|
||||
footer,
|
||||
home,
|
||||
}
|
||||
}
|
||||
|
||||
export function applyKhanegiLayoutVariants(app: { layoutVariants?: unknown } | null | undefined) {
|
||||
if (!app || typeof app !== 'object') return
|
||||
app.layoutVariants = mergeKhanegiLayoutVariants(app.layoutVariants)
|
||||
}
|
||||
Reference in New Issue
Block a user