import type {
FormSchema,
FormSectionSchema,
SettingsGroup,
SettingsModalSchema,
SettingsTab,
SettingsTabInput,
} from '../types'
import type { AccessControlled } from '../permissions'
import { normalizeItemInput } from '../utils/items'
export const APPEARANCE_TAB_ID = 'appearance'
export const APPEARANCE_TAB: SettingsTab = {
id: APPEARANCE_TAB_ID,
label: 'Appearance',
// Heroicons "swatch" — the built-in tab sits beside plugin tabs that all
// carry icons, so it needs one of its own to keep the rail consistent.
icon: '',
description: 'Theme, color palette, and table density',
}
// Map settings groups onto the form-builder's flat-section shape.
// `title: ''` because the rail/pane header already shows the group name.
export function buildFlatSettingsSchema(schema: SettingsModalSchema): FormSchema {
return {
sections: schema.groups.map((group) => ({
id: group.id,
title: '',
fields: group.fields,
columns: group.columns,
condition: group.condition,
})),
}
}
export function filterSettingsSchemaByAccess(
schema: SettingsModalSchema,
canShow: (item: AccessControlled) => boolean
): SettingsModalSchema {
const groups = schema.groups.flatMap((group) => {
if (!canShow(group)) return []
const fields = group.fields.filter(canShow)
if (fields.length === 0) return []
return [{ ...group, fields }]
})
return { groups }
}
export function settingsGroupToTab(group: SettingsGroup): SettingsTab {
return {
id: group.id,
label: group.label,
icon: group.icon,
description: group.description,
}
}
export function normalizeVisibleSettingsTabs(
tabs: SettingsTabInput[],
canShow: (item: AccessControlled) => boolean
): SettingsTab[] {
return tabs.map(normalizeItemInput).filter(canShow)
}
export function buildSettingsTabs(
baseTabs: SettingsTab[],
showAppearance: boolean,
appearanceFirst = false
): SettingsTab[] {
if (!showAppearance) return baseTabs
return appearanceFirst ? [APPEARANCE_TAB, ...baseTabs] : [...baseTabs, APPEARANCE_TAB]
}