David Headrick 4180e50c9c Refactor authentication and implement target management
- Updated `AuthenticationController` to return user data instead of token.
- Added `ITargetService` and `ITargetRepository` to `Program.cs`.
- Enhanced `appsettings.json` with connection timeout and security notes.
- Modified `IAuthService` to reflect new authentication response structure.
- Implemented connection retry mechanism in `DataAccess.cs`.
- Refactored UI components to use MUI styling in `Layout.tsx`, `App.tsx`, and others.
- Created new files for target management, including `TargetsController`, `TargetUpdateDto`, and related services.
- Added `TargetEdit` modal for editing target details and `LineChartSample` for data visualization.
- Updated package dependencies in `package-lock.json` and project file.
2025-02-26 17:42:40 -06:00

128 lines
4.2 KiB
TypeScript

import { useState } from "react";
import {
Dialog,
DialogTitle,
DialogContent,
TextField,
DialogActions,
Button,
Switch,
FormControlLabel,
} from "@mui/material";
import { Target } from "@/types/target";
type TargetEditProps = {
open: boolean;
target: Target;
onClose: () => void;
onSave: (updatedTarget: Target) => void;
};
const TargetEdit = ({ open, target, onClose, onSave }: TargetEditProps) => {
const [formData, setFormData] = useState<Target>({ ...target });
const [loading, setLoading] = useState(false);
const handleChange = (field: keyof Target, value: string | boolean) => {
setFormData((prev) => ({ ...prev, [field]: value }));
};
const handleSave = async () => {
setLoading(true);
try {
const response = await fetch(`/api/targets/${formData.id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(formData),
});
if (!response.ok) throw new Error("Failed to update");
const updatedTarget = await response.json();
onSave(updatedTarget); // Update UI optimistically
onClose();
} catch (error) {
console.error("Update error:", error);
} finally {
setLoading(false);
}
};
return (
<Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
<DialogTitle>Edit Target</DialogTitle>
<DialogContent>
<TextField
label="Target Key"
fullWidth
value={formData.id}
onChange={(e) => handleChange("id", e.target.value)}
margin="dense"
/>
<TextField
label="Server Key"
fullWidth
value={formData.serverId}
onChange={(e) => handleChange("serverId", e.target.value)}
margin="dense"
/>
<TextField
label="Name"
fullWidth
value={formData.name}
onChange={(e) => handleChange("name", e.target.value)}
margin="dense"
/>
<TextField
label="Database Name"
fullWidth
value={formData.databaseName}
onChange={(e) => handleChange("databaseName", e.target.value)}
margin="dense"
/>
<TextField
label="View Name"
fullWidth
value={formData.viewName}
onChange={(e) => handleChange("viewName", e.target.value)}
margin="dense"
/>
<TextField
label="Filter Query"
fullWidth
value={formData.filterQuery}
onChange={(e) => handleChange("filterQuery", e.target.value)}
margin="dense"
/>
<FormControlLabel
control={
<Switch
checked={formData.allowWriteBack}
onChange={(e) => handleChange("allowWriteBack", e.target.checked)}
/>
}
label="Allow Write Back"
/>
<FormControlLabel
control={
<Switch
checked={formData.isActive}
onChange={(e) => handleChange("isActive", e.target.checked)}
/>
}
label="Active"
/>
</DialogContent>
<DialogActions>
<Button onClick={onClose} disabled={loading}>Cancel</Button>
<Button onClick={handleSave} color="primary" disabled={loading}>
{loading ? "Saving..." : "Save"}
</Button>
</DialogActions>
</Dialog>
);
};
export default TargetEdit;