Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,41 @@ import { TextField, Select, MenuItem, FormControl } from "@mui/material";
import { useTheme } from "@mui/material/styles";
import { useTranslation } from "react-i18next";

export const renderInputField = (
function InputField({
handleChange,
rowIndex,
col,
typeInfo,
value,
placeholder,
) => {
}) {
const { dtype, type, categories } = typeInfo || {};
const effectiveType = type || dtype || "string";
const theme = useTheme();
const { t } = useTranslation(["prediction"]);

const commonStyles = {
"& .MuiOutlinedInput-root": {
fontSize: "0.875rem",
backgroundColor: theme.palette.background.paper,
"& fieldset": {
borderColor: theme.palette.divider,
borderWidth: "1px",
},
"&:hover fieldset": {
borderColor: theme.palette.primary.main,
},
"&.Mui-focused fieldset": {
borderColor: theme.palette.primary.main,
borderWidth: "2px",
},
},
"& .MuiInputBase-input": {
padding: "6px 10px",
color: theme.palette.text.primary,
},
};

if (effectiveType === "Categorical" && categories && categories.length > 0) {
return (
<FormControl fullWidth size="small">
Expand All @@ -24,19 +46,33 @@ export const renderInputField = (
onChange={(e) => handleChange(rowIndex, col, e.target.value)}
displayEmpty
sx={{
color: theme.palette.text.primary,
".MuiOutlinedInput-notchedOutline": {
fontSize: "0.875rem",
backgroundColor: theme.palette.background.paper,
"& .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.divider,
borderWidth: "1px",
},
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.primary.main,
},
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.primary.main,
borderWidth: "2px",
},
"& .MuiSelect-select": {
padding: "6px 10px",
color: theme.palette.text.primary,
},
"& .MuiSvgIcon-root": {
color: theme.palette.text.secondary,
},
"&:hover .MuiOutlinedInput-notchedOutline": { borderColor: "#888" },
".MuiSvgIcon-root": { color: theme.palette.text.primary },
}}
>
<MenuItem value="" disabled>
<MenuItem value="" disabled sx={{ fontSize: "0.875rem" }}>
{t("prediction:label.selectCategory")}
</MenuItem>
{categories.map((cat, idx) => (
<MenuItem key={idx} value={cat}>
<MenuItem key={idx} value={cat} sx={{ fontSize: "0.875rem" }}>
{cat}
</MenuItem>
))}
Expand All @@ -55,6 +91,7 @@ export const renderInputField = (

return (
<TextField
fullWidth
size="small"
type="number"
value={value}
Expand All @@ -71,13 +108,7 @@ export const renderInputField = (
: parseFloat(e.target.value);
handleChange(rowIndex, col, val);
}}
sx={{
input: { color: theme.palette.text.primary },
"& .MuiOutlinedInput-root": {
"& fieldset": { borderColor: theme.palette.divider },
"&:hover fieldset": { borderColor: "#888" },
},
}}
sx={commonStyles}
/>
);
}
Expand All @@ -89,45 +120,49 @@ export const renderInputField = (
) {
return (
<TextField
fullWidth
size="small"
value={value}
placeholder={placeholder}
onChange={(e) => handleChange(rowIndex, col, e.target.value)}
sx={{
input: { color: theme.palette.text.primary },
"& .MuiOutlinedInput-root": {
"& fieldset": { borderColor: theme.palette.divider },
"&:hover fieldset": { borderColor: "#888" },
},
}}
sx={commonStyles}
/>
);
}

if (effectiveType === "Image" || dtype === "image") {
return (
<input
type="file"
accept="image/*"
onChange={(e) => handleChange(rowIndex, col, e.target.files?.[0])}
style={{ color: theme.palette.text.primary }}
/>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: 1,
}}
>
<input
type="file"
accept="image/*"
onChange={(e) => handleChange(rowIndex, col, e.target.files?.[0])}
style={{
fontSize: "0.875rem",
color: theme.palette.text.primary,
padding: "4px 0",
}}
/>
</Box>
);
}

return (
<TextField1
<TextField
fullWidth
size="small"
value={value}
placeholder={placeholder}
onChange={(e) => handleChange(rowIndex, col, e.target.value)}
sx={{
input: { color: theme.palette.text.primary },
"& .MuiOutlinedInput-root": {
"& fieldset": { borderColor: theme.palette.divider },
"&:hover fieldset": { borderColor: "#888" },
},
}}
sx={commonStyles}
/>
);
};
}

export default InputField;
106 changes: 84 additions & 22 deletions DashAI/front/src/components/predictions/ManualInputForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
} from "@mui/material";
import { useTheme } from "@mui/material/styles";
import { AddCircleOutline, DeleteOutline } from "@mui/icons-material";
import { renderInputField } from "./renderInputField";
import InputField from "./InputField";
import { useTranslation } from "react-i18next";

export default function ManualInputForm({
Expand Down Expand Up @@ -106,47 +106,106 @@ export default function ManualInputForm({

<TableContainer
component={Paper}
sx={{ p: 1, bgcolor: theme.palette.background.box }}
sx={{
border: `1px solid ${theme.palette.divider}`,
borderRadius: 1,
overflow: "hidden",
boxShadow: "0 1px 3px rgba(0,0,0,0.08)",
}}
>
<Table size="small">
<Table
size="small"
sx={{
"& .MuiTableCell-root": {
borderBottom: `1px solid ${theme.palette.divider}`,
padding: "8px 12px",
},
}}
>
<TableHead>
<TableRow>
<TableRow
sx={{
backgroundColor:
theme.palette.mode === "dark"
? "rgba(255, 255, 255, 0.05)"
: "rgba(0, 0, 0, 0.02)",
}}
>
{inputColumns.map((col) => (
<TableCell key={col} sx={{ fontWeight: 600 }}>
<TableCell
key={col}
sx={{
fontWeight: 600,
fontSize: "0.875rem",
color: theme.palette.text.primary,
textTransform: "none",
whiteSpace: "nowrap",
}}
>
{col}
</TableCell>
))}
<TableCell sx={{ fontWeight: 600 }}>
<TableCell
sx={{
fontWeight: 600,
fontSize: "0.875rem",
color: theme.palette.text.primary,
width: "60px",
textAlign: "center",
}}
>
{t("common:remove")}
</TableCell>
</TableRow>
</TableHead>

<TableBody>
{rows.map((row, rowIndex) => (
<TableRow key={rowIndex}>
<TableRow
key={rowIndex}
sx={{
"&:hover": {
backgroundColor:
theme.palette.mode === "dark"
? "rgba(255, 255, 255, 0.03)"
: "rgba(0, 0, 0, 0.01)",
},
"&:last-child .MuiTableCell-root": {
borderBottom: "none",
},
}}
>
{inputColumns.map((col) => (
<TableCell
key={col}
sx={{ color: theme.palette.text.primary }}
sx={{
color: theme.palette.text.primary,
padding: "6px 12px",
}}
>
{renderInputField(
handleChange,
rowIndex,
col,
types[col],
row[col],
sample[col][0],
)}
<InputField
handleChange={handleChange}
rowIndex={rowIndex}
col={col}
typeInfo={types[col]}
value={row[col]}
placeholder={sample[col][0]}
/>
</TableCell>
))}
<TableCell>
<TableCell sx={{ padding: "6px 12px", textAlign: "center" }}>
<IconButton
sx={{ color: theme.palette.error.main }}
size="small"
sx={{
color: theme.palette.error.main,
"&:hover": {
backgroundColor: theme.palette.error.light + "20",
},
}}
onClick={() => handleDeleteRow(rowIndex)}
disabled={rows.length === 1}
>
<DeleteOutline />
<DeleteOutline fontSize="small" />
</IconButton>
</TableCell>
</TableRow>
Expand All @@ -155,12 +214,15 @@ export default function ManualInputForm({
</Table>
</TableContainer>

<Box sx={{ display: "flex", justifyContent: "flex-end", mt: 2 }}>
<Box sx={{ display: "flex", justifyContent: "flex-end", mt: 2, gap: 1 }}>
<Button
startIcon={<AddCircleOutline />}
variant="contained"
color="primary"
variant="outlined"
onClick={handleAddRow}
sx={{
textTransform: "none",
fontWeight: 500,
}}
>
{t("common:addRow")}
</Button>
Expand Down