diff --git a/src/pages/Schedule/index.jsx b/src/pages/Schedule/index.jsx index a328779..a237f0b 100644 --- a/src/pages/Schedule/index.jsx +++ b/src/pages/Schedule/index.jsx @@ -1,125 +1,160 @@ -import React, { useState, useEffect } from "react"; -import Typography from "@mui/material/Typography"; +import { useEffect, useState } from 'react'; import { Helmet } from "react-helmet"; +import { useLocalStorage } from "usehooks-ts"; +import Typography from "@mui/material/Typography"; import Button from "@mui/material/Button"; +import Fab from '@mui/material/Fab'; +import AddIcon from '@mui/icons-material/Add'; import DeleteIcon from "@mui/icons-material/Delete"; import LockIcon from "@mui/icons-material/Lock"; import LockOpenIcon from "@mui/icons-material/LockOpen"; -import { useLocalStorage } from "usehooks-ts"; +import Paper from '@mui/material/Paper'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import TableCell from '@mui/material/TableCell'; +import TableBody from '@mui/material/TableBody'; +import Table from '@mui/material/Table'; +import TextField from '@mui/material/TextField'; +import Select from '@mui/material/Select'; +import MenuItem from '@mui/material/MenuItem'; +import Checkbox from '@mui/material/Checkbox'; +import Tooltip from '@mui/material/Tooltip'; +import InfoIcon from '@mui/icons-material/Info'; export default function Schedule() { - const predefinedKeyOptions = [ - "--ceph-repo", "--suite-repo", "--subset", - "--suite-branch", "--suite", "--limit", - "--repo", "--ceph-branch", "subset" - ]; + const keyOptions = + [ + "--ceph", + "--ceph-repo", + "--suite-repo", + "--suite-branch", + "--suite", + "--subset", + "--machine", + "--filter", + "--distro", + "--rerun", + "--rerun-statuses", + "--limit", + "--priority", + ]; + const OptionsInfo = { + "--ceph": "The ceph branch to run against [default: main]", + "--ceph-repo": "Query this repository for Ceph branch and \ + SHA1 values [default: https://github.com/ceph/ceph-ci.git]", + "--suite-repo": "Use tasks and suite definition in this \ + repository [default: https://github.com/ceph/ceph-ci.git]", + "--suite-branch": "Use this suite branch instead of the ceph branch", + "--suite": "The suite to schedule", + "--subset": "Instead of scheduling the entire suite, break the \ + set of jobs into pieces (each of which will \ + contain each facet at least once) and schedule \ + piece . Scheduling 0/, 1/, \ + 2/ ... -1/ will schedule all \ + jobs in the suite (many more than once). If specified, \ + this value can be found in results.log.", + "--machine": "Machine type e.g., smithi, mira, gibba.", + "--filter": "Only run jobs whose description contains at least one \ + of the keywords in the comma separated keyword string specified.", + "--distro": "Distribution to run against", + "--rerun": "Attempt to reschedule a run, selecting only those \ + jobs whose status are mentioned by --rerun-status. \ + Note that this is implemented by scheduling an \ + entirely new suite and including only jobs whose \ + descriptions match the selected ones. It does so \ + using the same logic as --filter. \ + Of all the flags that were passed when scheduling \ + the original run, the resulting one will only \ + inherit the --suite value. Any other arguments \ + must be passed again while scheduling. By default, \ + 'seed' and 'subset' will be taken from results.log, \ + but can be overide if passed again. \ + This is important for tests involving random facet \ + (path ends with '$' operator).", + "--rerun-statuses": "A comma-separated list of statuses to be used \ + with --rerun. Supported statuses are: 'dead', \ + 'fail', 'pass', 'queued', 'running', 'waiting' \ + [default: fail,dead]", + "--limit": "Queue at most this many jobs [default: 0]", + "--priority": "Job priority (lower is sooner) 0 - 1000", + } - const [inputValue, setInputValue] = useLocalStorage("inputValue", ""); - const [selectedKeyIndices, setSelectedKeyIndices] = useLocalStorage("selectedKeyIndices", []); - const [valueData, setValueData] = useLocalStorage("valueData", []); - const [hoveredRowIndex, setHoveredRowIndex] = useState(null); - const [checkedRows, setCheckedRows] = useLocalStorage("checkedRows", []); - const [rowLocks, setRowLocks] = useLocalStorage("rowLocks", Array(selectedKeyIndices.length).fill(false)); - const [keyLocks, setKeyLocks] = useLocalStorage("keyLocks", Array(selectedKeyIndices.length).fill(false)); + const [rowData, setRowData] = useLocalStorage("rowData", []); + const [rowIndex, setRowIndex] = useLocalStorage("rowIndex", -1); + const [commandBarValue, setCommandBarValue] = useState([]); - const handleInputChange = (event) => { - setInputValue(event.target.value); - }; + useEffect(() => { + setCommandBarValue(rowData); + }, [rowData]) const handleRun = () => { - updateCommand(checkedRows); + return false; }; const handleDryRun = () => { - updateCommand(checkedRows); + return false; }; - useEffect(() => { - updateCommand(checkedRows); - }, [selectedKeyIndices, valueData, checkedRows]); + const handleForcePriority = () => { + return false; + }; const addNewRow = () => { - setSelectedKeyIndices([...selectedKeyIndices, 0]); - setValueData([...valueData, ""]); - setRowLocks([...rowLocks, false]); - setKeyLocks([...keyLocks, false]); + console.log("addNewRow"); + const updatedRowIndex = rowIndex + 1; + setRowIndex(updatedRowIndex); + const index = (updatedRowIndex % keyOptions.length); + const object = { + key: keyOptions[index], + value: "", + lock: false, + checked: true, + } + const updatedRowData = [...rowData]; + updatedRowData.push(object); + setRowData(updatedRowData); }; const handleCheckboxChange = (index, event) => { - const newCheckedRows = [...checkedRows]; - + console.log("handleCheckboxChange"); + const newRowData = [...rowData]; if (event.target.checked) { - newCheckedRows.push(index); + newRowData[index].checked = true; } else { - const indexToRemove = newCheckedRows.indexOf(index); - if (indexToRemove !== -1) { - newCheckedRows.splice(indexToRemove, 1); - } + newRowData[index].checked = false; } - - setCheckedRows(newCheckedRows); - updateCommand(newCheckedRows); + setRowData(newRowData); }; const handleKeySelectChange = (index, event) => { - const updatedSelectedKeyIndices = [...selectedKeyIndices]; - updatedSelectedKeyIndices[index] = event.target.value; - setSelectedKeyIndices(updatedSelectedKeyIndices); - updateCommand(checkedRows); + console.log("handleKeySelectChange"); + const newRowData = [...rowData]; + newRowData[index].key = event.target.value; + setRowData(newRowData); }; const handleValueChange = (index, event) => { - const updatedValueData = [...valueData]; - updatedValueData[index] = event.target.value; - setValueData(updatedValueData); - updateCommand(checkedRows); + console.log("handleValueChange"); + const newRowData = [...rowData]; + newRowData[index].value = event.target.value; + setRowData(newRowData); }; const handleDeleteRow = (index) => { - const updatedSelectedKeyIndices = [...selectedKeyIndices]; - updatedSelectedKeyIndices.splice(index, 1); - setSelectedKeyIndices(updatedSelectedKeyIndices); - - const updatedValueData = [...valueData]; - updatedValueData.splice(index, 1); - setValueData(updatedValueData); - - const newCheckedRows = checkedRows.filter((checkedIndex) => checkedIndex !== index); - setCheckedRows(newCheckedRows); - - const updatedRowLocks = [...rowLocks]; - updatedRowLocks.splice(index, 1); - setRowLocks(updatedRowLocks); - - const updatedKeyLocks = [...keyLocks]; - updatedKeyLocks.splice(index, 1); - setKeyLocks(updatedKeyLocks); - - updateCommand(newCheckedRows); + console.log("handleDeleteRow"); + let newRowData = [...rowData]; + newRowData.splice(index, 1) + setRowData(newRowData); + const updatedRowIndex = rowIndex - 1; + setRowIndex(updatedRowIndex); }; const toggleRowLock = (index) => { - const updatedRowLocks = [...rowLocks]; - updatedRowLocks[index] = !updatedRowLocks[index]; - setRowLocks(updatedRowLocks); - - const updatedKeyLocks = [...keyLocks]; - updatedKeyLocks[index] = !updatedKeyLocks[index]; - setKeyLocks(updatedKeyLocks); - }; - - const updateCommand = (checkedRows) => { - const commandArgs = checkedRows - .map((index) => { - const selectedKeyIndex = selectedKeyIndices[index]; - const selectedKey = predefinedKeyOptions[selectedKeyIndex]; - const selectedValue = valueData[index]; - return `${selectedKey} ${selectedValue}`; - }) - .join(" "); - const teuthologySuiteCommand = `teuthology suite ${commandArgs}`; - - setInputValue(teuthologySuiteCommand); + console.log("toggleRowLock"); + const newRowData = [...rowData]; + newRowData[index].lock = !newRowData[index].lock; + setRowData(newRowData); }; return ( @@ -127,105 +162,156 @@ export default function Schedule() { Schedule - Pulpito - + Schedule a run -
- -
- - +
+ + { + if (data.checked) { + return `${data.key} ${data.value}`; + } + }) + .join(" ")}`} + placeholder="teuthology-suite" + disabled={true} + /> + +
+ + + + + + + + +
- - - - - - - - - - {selectedKeyIndices.map((selectedKeyIndex, index) => ( - setHoveredRowIndex(index)} - onMouseLeave={() => setHoveredRowIndex(null)} - style={{ - background: hoveredRowIndex === index ? "#f5f5f5" : "transparent", - }} - > - -
KeyValue
-
- handleCheckboxChange(index, event)} - /> -
toggleRowLock(index)} - > - {rowLocks[index] ? : } -
-
-
- + + + + Key + Value + + + + { + {rowData.map((data, index) => ( + - {predefinedKeyOptions.map((option, optionIndex) => ( - - ))} - - - - - ))} - -
-
- handleValueChange(index, event)} - disabled={rowLocks[index]} - /> -
handleDeleteRow(index)} - > - {hoveredRowIndex === index && } -
-
-
- - + + handleCheckboxChange(index, event)} /> + + +
+ + + + +
+
+ + handleValueChange(index, event)} + disabled={data.lock} + /> + + +
+ +
toggleRowLock(index)} + > + {data.lock ? : } +
+
+ +
{ + handleDeleteRow(index); + }} + > + +
+
+
+
+ + ))} + } +
+ +
+ + + + + + +
); }