separate out the config name modal and prevent it from flashing error when closing after a save

This commit is contained in:
lone-cloud 2025-08-23 14:31:41 -07:00
parent 5cc2f42568
commit a6b3351548
3 changed files with 82 additions and 52 deletions

View file

@ -1,13 +1,4 @@
import { import { Stack, Text, Group, Button, Select, Badge } from '@mantine/core';
Stack,
Text,
Group,
Button,
Select,
Modal,
TextInput,
Badge,
} from '@mantine/core';
import { import {
useState, useState,
useCallback, useCallback,
@ -17,6 +8,7 @@ import {
import { Save, File, Plus, Check } from 'lucide-react'; import { Save, File, Plus, Check } from 'lucide-react';
import type { ConfigFile } from '@/types'; import type { ConfigFile } from '@/types';
import styles from '@/styles/layout.module.css'; import styles from '@/styles/layout.module.css';
import { CreateConfigModal } from './CreateConfigModal';
interface ConfigFileManagerProps { interface ConfigFileManagerProps {
configFiles: ConfigFile[]; configFiles: ConfigFile[];
@ -68,7 +60,6 @@ export const ConfigFileManager = ({
onSaveConfig, onSaveConfig,
}: ConfigFileManagerProps) => { }: ConfigFileManagerProps) => {
const [configModalOpened, setConfigModalOpened] = useState(false); const [configModalOpened, setConfigModalOpened] = useState(false);
const [newConfigName, setNewConfigName] = useState('');
const [saveSuccess, setSaveSuccess] = useState(false); const [saveSuccess, setSaveSuccess] = useState(false);
const existingConfigNames = configFiles.map((file) => { const existingConfigNames = configFiles.map((file) => {
@ -76,25 +67,14 @@ export const ConfigFileManager = ({
return file.name.replace(`.${extension}`, '').toLowerCase(); return file.name.replace(`.${extension}`, '').toLowerCase();
}); });
const trimmedConfigName = newConfigName.trim();
const configNameExists =
trimmedConfigName &&
existingConfigNames.includes(trimmedConfigName.toLowerCase());
const handleOpenConfigModal = () => { const handleOpenConfigModal = () => {
setConfigModalOpened(true); setConfigModalOpened(true);
}; };
const handleCloseConfigModal = useCallback(() => { const handleCloseConfigModal = useCallback(() => {
setConfigModalOpened(false); setConfigModalOpened(false);
setNewConfigName('');
}, []); }, []);
const handleConfigSubmit = async () => {
await onCreateNewConfig(trimmedConfigName);
handleCloseConfigModal();
};
const handleSaveClick = async () => { const handleSaveClick = async () => {
if (selectedFile) { if (selectedFile) {
const success = await onSaveConfig(); const success = await onSaveConfig();
@ -174,38 +154,12 @@ export const ConfigFileManager = ({
</Group> </Group>
</Stack> </Stack>
<Modal <CreateConfigModal
opened={configModalOpened} opened={configModalOpened}
onClose={handleCloseConfigModal} onClose={handleCloseConfigModal}
title="Create New Configuration" onCreateConfig={onCreateNewConfig}
size="sm" existingConfigNames={existingConfigNames}
> />
<Stack gap="md">
<TextInput
label="Name"
placeholder="Enter a name for the new configuration"
value={newConfigName}
onChange={(event) => setNewConfigName(event.currentTarget.value)}
data-autofocus
error={
configNameExists
? 'A configuration with this name already exists'
: undefined
}
/>
<Group justify="flex-end" gap="sm">
<Button variant="outline" onClick={handleCloseConfigModal}>
Cancel
</Button>
<Button
disabled={!trimmedConfigName || !!configNameExists}
onClick={handleConfigSubmit}
>
Create
</Button>
</Group>
</Stack>
</Modal>
</> </>
); );
}; };

View file

@ -0,0 +1,76 @@
import { Modal, TextInput, Group, Button, Stack } from '@mantine/core';
import { useState, useEffect } from 'react';
interface CreateConfigModalProps {
opened: boolean;
onClose: () => void;
onCreateConfig: (configName: string) => Promise<void>;
existingConfigNames: string[];
}
export const CreateConfigModal = ({
opened,
onClose,
onCreateConfig,
existingConfigNames,
}: CreateConfigModalProps) => {
const [newConfigName, setNewConfigName] = useState('');
const trimmedConfigName = newConfigName.trim();
const configNameExists =
trimmedConfigName &&
existingConfigNames.includes(trimmedConfigName.toLowerCase());
const handleClose = () => {
setNewConfigName('');
onClose();
};
const handleSubmit = async () => {
const configName = trimmedConfigName;
setNewConfigName('');
await onCreateConfig(configName);
onClose();
};
useEffect(() => {
if (opened) {
setNewConfigName('');
}
}, [opened]);
return (
<Modal
opened={opened}
onClose={handleClose}
title="Create New Configuration"
size="sm"
>
<Stack gap="md">
<TextInput
label="Name"
placeholder="Enter a name for the new configuration"
value={newConfigName}
onChange={(event) => setNewConfigName(event.currentTarget.value)}
data-autofocus
error={
configNameExists
? 'A configuration with this name already exists'
: undefined
}
/>
<Group justify="flex-end" gap="sm">
<Button variant="outline" onClick={handleClose}>
Cancel
</Button>
<Button
disabled={!trimmedConfigName || !!configNameExists}
onClick={handleSubmit}
>
Create
</Button>
</Group>
</Stack>
</Modal>
);
};