Migrate workspace settings to ts

This commit is contained in:
2025-05-18 12:21:18 +02:00
parent 7044e42e94
commit 9125cbdad3
8 changed files with 118 additions and 48 deletions

View File

@@ -1,12 +1,21 @@
import React from 'react';
import { Text, Switch, Group, Box, Title } from '@mantine/core';
import { Text, Switch, Group, Box } from '@mantine/core';
import { useWorkspace } from '../../../contexts/WorkspaceContext';
import { Theme } from '@/types/theme';
const AppearanceSettings = ({ themeSettings, onThemeChange }) => {
interface AppearanceSettingsProps {
themeSettings?: Theme;
onThemeChange: (newTheme: Theme) => void;
}
const AppearanceSettings: React.FC<AppearanceSettingsProps> = ({
themeSettings,
onThemeChange,
}) => {
const { colorScheme, updateColorScheme } = useWorkspace();
const handleThemeChange = () => {
const newTheme = colorScheme === 'dark' ? 'light' : 'dark';
const handleThemeChange = (): void => {
const newTheme = colorScheme === 'dark' ? Theme.Light : Theme.Dark;
updateColorScheme(newTheme);
onThemeChange(newTheme);
};

View File

@@ -4,13 +4,13 @@ import DeleteWorkspaceModal from '../../modals/workspace/DeleteWorkspaceModal';
import { useWorkspace } from '../../../contexts/WorkspaceContext';
import { useModalContext } from '../../../contexts/ModalContext';
const DangerZoneSettings = () => {
const DangerZoneSettings: React.FC = () => {
const { currentWorkspace, workspaces, deleteCurrentWorkspace } =
useWorkspace();
const { setSettingsModalVisible } = useModalContext();
const [deleteModalOpened, setDeleteModalOpened] = useState(false);
const [deleteModalOpened, setDeleteModalOpened] = useState<boolean>(false);
const handleDelete = async () => {
const handleDelete = async (): Promise<void> => {
await deleteCurrentWorkspace();
setDeleteModalOpened(false);
setSettingsModalVisible(false);

View File

@@ -1,7 +1,14 @@
import React from 'react';
import { Text, Switch, Tooltip, Group, Box } from '@mantine/core';
const EditorSettings = ({
interface EditorSettingsProps {
autoSave: boolean;
showHiddenFiles: boolean;
onAutoSaveChange: (value: boolean) => void;
onShowHiddenFilesChange: (value: boolean) => void;
}
const EditorSettings: React.FC<EditorSettingsProps> = ({
autoSave,
showHiddenFiles,
onAutoSaveChange,

View File

@@ -1,7 +1,16 @@
import React from 'react';
import { Title, Box, TextInput, Text, Grid } from '@mantine/core';
import { Box, TextInput, Text, Grid } from '@mantine/core';
import { Workspace } from '@/types/workspace';
const GeneralSettings = ({ name, onInputChange }) => {
interface GeneralSettingsProps {
name: string;
onInputChange: (key: keyof Workspace, value: string) => void;
}
const GeneralSettings: React.FC<GeneralSettingsProps> = ({
name,
onInputChange,
}) => {
return (
<Box mb="md">
<Grid gutter="md" align="center">
@@ -10,7 +19,7 @@ const GeneralSettings = ({ name, onInputChange }) => {
</Grid.Col>
<Grid.Col span={6}>
<TextInput
value={name || ''}
value={name}
onChange={(event) =>
onInputChange('name', event.currentTarget.value)
}

View File

@@ -8,8 +8,21 @@ import {
Group,
Grid,
} from '@mantine/core';
import { Workspace } from '@/types/workspace';
const GitSettings = ({
interface GitSettingsProps {
gitEnabled: boolean;
gitUrl: string;
gitUser: string;
gitToken: string;
gitAutoCommit: boolean;
gitCommitMsgTemplate: string;
gitCommitName: string;
gitCommitEmail: string;
onInputChange: (key: keyof Workspace, value: any) => void;
}
const GitSettings: React.FC<GitSettingsProps> = ({
gitEnabled,
gitUrl,
gitUser,
@@ -21,7 +34,7 @@ const GitSettings = ({
onInputChange,
}) => {
return (
<Stack spacing="md">
<Stack gap="md">
<Grid gutter="md" align="center">
<Grid.Col span={6}>
<Text size="sm">Enable Git Repository</Text>

View File

@@ -17,23 +17,35 @@ import GeneralSettings from './GeneralSettings';
import { useModalContext } from '../../../contexts/ModalContext';
import DangerZoneSettings from './DangerZoneSettings';
import AccordionControl from '../AccordionControl';
import { SettingsActionType, SettingsAction } from '../../../types/settings';
import { Workspace } from '../../../types/workspace';
const initialState = {
// State and reducer for workspace settings
interface WorkspaceSettingsState {
localSettings: Partial<Workspace>;
initialSettings: Partial<Workspace>;
hasUnsavedChanges: boolean;
}
const initialState: WorkspaceSettingsState = {
localSettings: {},
initialSettings: {},
hasUnsavedChanges: false,
};
function settingsReducer(state, action) {
function settingsReducer(
state: WorkspaceSettingsState,
action: SettingsAction<Partial<Workspace>>
): WorkspaceSettingsState {
switch (action.type) {
case 'INIT_SETTINGS':
case SettingsActionType.INIT_SETTINGS:
return {
...state,
localSettings: action.payload,
initialSettings: action.payload,
localSettings: action.payload || {},
initialSettings: action.payload || {},
hasUnsavedChanges: false,
};
case 'UPDATE_LOCAL_SETTINGS':
case SettingsActionType.UPDATE_LOCAL_SETTINGS:
const newLocalSettings = { ...state.localSettings, ...action.payload };
const hasChanges =
JSON.stringify(newLocalSettings) !==
@@ -43,7 +55,7 @@ function settingsReducer(state, action) {
localSettings: newLocalSettings,
hasUnsavedChanges: hasChanges,
};
case 'MARK_SAVED':
case SettingsActionType.MARK_SAVED:
return {
...state,
initialSettings: state.localSettings,
@@ -54,16 +66,16 @@ function settingsReducer(state, action) {
}
}
const WorkspaceSettings = () => {
const WorkspaceSettings: React.FC = () => {
const { currentWorkspace, updateSettings } = useWorkspace();
const { settingsModalVisible, setSettingsModalVisible } = useModalContext();
const [state, dispatch] = useReducer(settingsReducer, initialState);
const isInitialMount = useRef(true);
const isInitialMount = useRef<boolean>(true);
useEffect(() => {
if (isInitialMount.current) {
if (isInitialMount.current && currentWorkspace) {
isInitialMount.current = false;
const settings = {
const settings: Partial<Workspace> = {
name: currentWorkspace.name,
theme: currentWorkspace.theme,
autoSave: currentWorkspace.autoSave,
@@ -77,15 +89,21 @@ const WorkspaceSettings = () => {
gitCommitName: currentWorkspace.gitCommitName,
gitCommitEmail: currentWorkspace.gitCommitEmail,
};
dispatch({ type: 'INIT_SETTINGS', payload: settings });
dispatch({ type: SettingsActionType.INIT_SETTINGS, payload: settings });
}
}, [currentWorkspace]);
const handleInputChange = useCallback((key, value) => {
dispatch({ type: 'UPDATE_LOCAL_SETTINGS', payload: { [key]: value } });
}, []);
const handleInputChange = useCallback(
(key: keyof Workspace, value: any): void => {
dispatch({
type: SettingsActionType.UPDATE_LOCAL_SETTINGS,
payload: { [key]: value } as Partial<Workspace>,
});
},
[]
);
const handleSubmit = async () => {
const handleSubmit = async (): Promise<void> => {
try {
if (!state.localSettings.name?.trim()) {
notifications.show({
@@ -96,7 +114,7 @@ const WorkspaceSettings = () => {
}
await updateSettings(state.localSettings);
dispatch({ type: 'MARK_SAVED' });
dispatch({ type: SettingsActionType.MARK_SAVED });
notifications.show({
message: 'Settings saved successfully',
color: 'green',
@@ -105,7 +123,9 @@ const WorkspaceSettings = () => {
} catch (error) {
console.error('Failed to save settings:', error);
notifications.show({
message: 'Failed to save settings: ' + error.message,
message:
'Failed to save settings: ' +
(error instanceof Error ? error.message : String(error)),
color: 'red',
});
}
@@ -123,7 +143,7 @@ const WorkspaceSettings = () => {
centered
size="lg"
>
<Stack spacing="xl">
<Stack gap="xl">
{state.hasUnsavedChanges && (
<Badge color="yellow" variant="light">
Unsaved Changes
@@ -133,7 +153,7 @@ const WorkspaceSettings = () => {
<Accordion
defaultValue={['general', 'appearance', 'editor', 'git', 'danger']}
multiple
styles={(theme) => ({
styles={(theme: any) => ({
control: {
paddingTop: theme.spacing.md,
paddingBottom: theme.spacing.md,
@@ -162,7 +182,7 @@ const WorkspaceSettings = () => {
<AccordionControl>General</AccordionControl>
<Accordion.Panel>
<GeneralSettings
name={state.localSettings.name}
name={state.localSettings.name || ''}
onInputChange={handleInputChange}
/>
</Accordion.Panel>
@@ -173,7 +193,7 @@ const WorkspaceSettings = () => {
<Accordion.Panel>
<AppearanceSettings
themeSettings={state.localSettings.theme}
onThemeChange={(newTheme) =>
onThemeChange={(newTheme: string) =>
handleInputChange('theme', newTheme)
}
/>
@@ -184,12 +204,12 @@ const WorkspaceSettings = () => {
<AccordionControl>Editor</AccordionControl>
<Accordion.Panel>
<EditorSettings
autoSave={state.localSettings.autoSave}
onAutoSaveChange={(value) =>
autoSave={state.localSettings.autoSave || false}
onAutoSaveChange={(value: boolean) =>
handleInputChange('autoSave', value)
}
showHiddenFiles={state.localSettings.showHiddenFiles}
onShowHiddenFilesChange={(value) =>
showHiddenFiles={state.localSettings.showHiddenFiles || false}
onShowHiddenFilesChange={(value: boolean) =>
handleInputChange('showHiddenFiles', value)
}
/>
@@ -200,14 +220,16 @@ const WorkspaceSettings = () => {
<AccordionControl>Git Integration</AccordionControl>
<Accordion.Panel>
<GitSettings
gitEnabled={state.localSettings.gitEnabled}
gitUrl={state.localSettings.gitUrl}
gitUser={state.localSettings.gitUser}
gitToken={state.localSettings.gitToken}
gitAutoCommit={state.localSettings.gitAutoCommit}
gitCommitMsgTemplate={state.localSettings.gitCommitMsgTemplate}
gitCommitName={state.localSettings.gitCommitName}
gitCommitEmail={state.localSettings.gitCommitEmail}
gitEnabled={state.localSettings.gitEnabled || false}
gitUrl={state.localSettings.gitUrl || ''}
gitUser={state.localSettings.gitUser || ''}
gitToken={state.localSettings.gitToken || ''}
gitAutoCommit={state.localSettings.gitAutoCommit || false}
gitCommitMsgTemplate={
state.localSettings.gitCommitMsgTemplate || ''
}
gitCommitName={state.localSettings.gitCommitName || ''}
gitCommitEmail={state.localSettings.gitCommitEmail || ''}
onInputChange={handleInputChange}
/>
</Accordion.Panel>