feat: basic/advanced config split with profile section gate

- FieldSchema gains optional `advanced` boolean flag
- ConfigEditor reads schema at top level and passes sectionSchema as prop
- ConfigSectionForm filters out advanced fields by default; "Show advanced"
  toggle reveals them without entering edit mode
- Profile (Difficulty) section shows an inline banner when
  forced_difficulty is not "Custom", guiding users to the right setting
- All 173 frontend tests pass; tsc clean
This commit is contained in:
Tran G. (Revernomad) Khoa
2026-04-20 10:49:08 +07:00
parent 03ea623536
commit 64b35a7aaf
3 changed files with 319 additions and 22 deletions

View File

@@ -124,10 +124,16 @@ export interface Mod {
path: string;
size_bytes: number;
enabled: boolean;
is_server_mod: boolean;
display_name: string | null;
workshop_id: string | null;
}
export interface EnabledModEntry {
name: string;
is_server_mod: boolean;
}
export interface FieldSchema {
widget: "text" | "number" | "password" | "textarea" | "select" | "toggle" | "tag-list" | "hidden" | "key-value";
label?: string;
@@ -135,6 +141,7 @@ export interface FieldSchema {
min?: number;
max?: number;
options?: string[];
advanced?: boolean;
}
export interface ConfigSchema {
@@ -380,7 +387,7 @@ export function useDeleteMission(serverId: number) {
export function useSetEnabledMods(serverId: number) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (mods: string[]) =>
mutationFn: (mods: EnabledModEntry[]) =>
apiClient.put(`/api/servers/${serverId}/mods/enabled`, { mods }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["mods", serverId] });