Internalize accordion state in ServerSettingsForm
Move expandedSections/onExpandedSectionsChange from props to internal useState. The accordion open/close is local display logic, not parent state. Add optional defaultExpandedSections prop for initial state. Simplify UnconnectedView WithSettingsModal story — no longer needs external state management for accordion sections. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cc9be5e930
commit
adb909daf6
3 changed files with 11 additions and 38 deletions
|
|
@ -15,8 +15,6 @@ const meta: Meta<typeof ServerSettingsForm> = {
|
||||||
title: "Groups/ServerSettingsForm",
|
title: "Groups/ServerSettingsForm",
|
||||||
component: ServerSettingsForm,
|
component: ServerSettingsForm,
|
||||||
args: {
|
args: {
|
||||||
expandedSections: ["connectionMode"],
|
|
||||||
onExpandedSectionsChange: fn(),
|
|
||||||
onConnectionModeChange: fn(),
|
onConnectionModeChange: fn(),
|
||||||
onAddHeader: fn(),
|
onAddHeader: fn(),
|
||||||
onRemoveHeader: fn(),
|
onRemoveHeader: fn(),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { useState } from "react";
|
||||||
import {
|
import {
|
||||||
Accordion,
|
Accordion,
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
|
|
@ -20,8 +21,7 @@ export type ServerSettingsSection =
|
||||||
|
|
||||||
export interface ServerSettingsFormProps {
|
export interface ServerSettingsFormProps {
|
||||||
settings: InspectorServerSettings;
|
settings: InspectorServerSettings;
|
||||||
expandedSections: ServerSettingsSection[];
|
defaultExpandedSections?: ServerSettingsSection[];
|
||||||
onExpandedSectionsChange: (sections: ServerSettingsSection[]) => void;
|
|
||||||
onConnectionModeChange: (mode: "proxy" | "direct") => void;
|
onConnectionModeChange: (mode: "proxy" | "direct") => void;
|
||||||
onAddHeader: () => void;
|
onAddHeader: () => void;
|
||||||
onRemoveHeader: (index: number) => void;
|
onRemoveHeader: (index: number) => void;
|
||||||
|
|
@ -95,8 +95,7 @@ function KeyValueRows({
|
||||||
|
|
||||||
export function ServerSettingsForm({
|
export function ServerSettingsForm({
|
||||||
settings,
|
settings,
|
||||||
expandedSections,
|
defaultExpandedSections = ["connectionMode"],
|
||||||
onExpandedSectionsChange,
|
|
||||||
onConnectionModeChange,
|
onConnectionModeChange,
|
||||||
onAddHeader,
|
onAddHeader,
|
||||||
onRemoveHeader,
|
onRemoveHeader,
|
||||||
|
|
@ -107,6 +106,10 @@ export function ServerSettingsForm({
|
||||||
onTimeoutChange,
|
onTimeoutChange,
|
||||||
onOAuthChange,
|
onOAuthChange,
|
||||||
}: ServerSettingsFormProps) {
|
}: ServerSettingsFormProps) {
|
||||||
|
const [expandedSections, setExpandedSections] = useState<
|
||||||
|
ServerSettingsSection[]
|
||||||
|
>(defaultExpandedSections);
|
||||||
|
|
||||||
const handleTimeoutChange = (field: string) => (value: number | string) => {
|
const handleTimeoutChange = (field: string) => (value: number | string) => {
|
||||||
const numValue =
|
const numValue =
|
||||||
typeof value === "string" ? parseInt(value, 10) || 0 : value;
|
typeof value === "string" ? parseInt(value, 10) || 0 : value;
|
||||||
|
|
@ -118,7 +121,7 @@ export function ServerSettingsForm({
|
||||||
multiple
|
multiple
|
||||||
value={expandedSections}
|
value={expandedSections}
|
||||||
onChange={(value) =>
|
onChange={(value) =>
|
||||||
onExpandedSectionsChange(value as ServerSettingsSection[])
|
setExpandedSections(value as ServerSettingsSection[])
|
||||||
}
|
}
|
||||||
variant="separated"
|
variant="separated"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,9 @@
|
||||||
import { useState } from "react";
|
|
||||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||||
import { Box, CloseButton, Group, Modal, Title } from "@mantine/core";
|
import { CloseButton, Group, Modal, Title } from "@mantine/core";
|
||||||
import { fn } from "storybook/test";
|
import { fn } from "storybook/test";
|
||||||
import { UnconnectedView } from "./UnconnectedView.js";
|
import { UnconnectedView } from "./UnconnectedView.js";
|
||||||
import { ServerListScreen } from "../../screens/ServerListScreen/ServerListScreen";
|
import { ServerListScreen } from "../../screens/ServerListScreen/ServerListScreen";
|
||||||
import {
|
import { ServerSettingsForm } from "../../groups/ServerSettingsForm/ServerSettingsForm";
|
||||||
ServerSettingsForm,
|
|
||||||
type ServerSettingsSection,
|
|
||||||
} from "../../groups/ServerSettingsForm/ServerSettingsForm";
|
|
||||||
|
|
||||||
const ALL_SETTINGS_SECTIONS: ServerSettingsSection[] = [
|
|
||||||
"connectionMode",
|
|
||||||
"headers",
|
|
||||||
"metadata",
|
|
||||||
"timeouts",
|
|
||||||
"oauth",
|
|
||||||
];
|
|
||||||
import { ListToggle } from "../../elements/ListToggle/ListToggle";
|
|
||||||
import type { ServerCardProps } from "../../groups/ServerCard/ServerCard";
|
import type { ServerCardProps } from "../../groups/ServerCard/ServerCard";
|
||||||
|
|
||||||
const meta: Meta<typeof UnconnectedView> = {
|
const meta: Meta<typeof UnconnectedView> = {
|
||||||
|
|
@ -125,10 +112,6 @@ export const WithServers: Story = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function SettingsModalStory() {
|
function SettingsModalStory() {
|
||||||
const [expandedSections, setExpandedSections] = useState<
|
|
||||||
ServerSettingsSection[]
|
|
||||||
>(["connectionMode"]);
|
|
||||||
const allExpanded = expandedSections.length === ALL_SETTINGS_SECTIONS.length;
|
|
||||||
return (
|
return (
|
||||||
<UnconnectedView onToggleTheme={fn()}>
|
<UnconnectedView onToggleTheme={fn()}>
|
||||||
<ServerListScreen
|
<ServerListScreen
|
||||||
|
|
@ -149,19 +132,10 @@ function SettingsModalStory() {
|
||||||
withCloseButton={false}
|
withCloseButton={false}
|
||||||
title={
|
title={
|
||||||
<Group justify="space-between" wrap="nowrap" w="100%">
|
<Group justify="space-between" wrap="nowrap" w="100%">
|
||||||
<ListToggle
|
|
||||||
compact={allExpanded}
|
|
||||||
variant="subtle"
|
|
||||||
onToggle={() =>
|
|
||||||
setExpandedSections(allExpanded ? [] : ALL_SETTINGS_SECTIONS)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Title order={4} ta="center" style={{ flex: 1 }}>
|
<Title order={4} ta="center" style={{ flex: 1 }}>
|
||||||
Server Settings
|
Server Settings
|
||||||
</Title>
|
</Title>
|
||||||
<Box>
|
<CloseButton onClick={fn()} />
|
||||||
<CloseButton onClick={fn()} />
|
|
||||||
</Box>
|
|
||||||
</Group>
|
</Group>
|
||||||
}
|
}
|
||||||
size="lg"
|
size="lg"
|
||||||
|
|
@ -182,8 +156,6 @@ function SettingsModalStory() {
|
||||||
oauthClientSecret: "super-secret-value",
|
oauthClientSecret: "super-secret-value",
|
||||||
oauthScopes: "read write",
|
oauthScopes: "read write",
|
||||||
}}
|
}}
|
||||||
expandedSections={expandedSections}
|
|
||||||
onExpandedSectionsChange={setExpandedSections}
|
|
||||||
onConnectionModeChange={fn()}
|
onConnectionModeChange={fn()}
|
||||||
onAddHeader={fn()}
|
onAddHeader={fn()}
|
||||||
onRemoveHeader={fn()}
|
onRemoveHeader={fn()}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue