Skip to content

Commit

Permalink
some modifications
Browse files Browse the repository at this point in the history
  • Loading branch information
shubhamraj-git committed Oct 24, 2024
1 parent 2a5248a commit a9806ab
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 142 deletions.
6 changes: 5 additions & 1 deletion airflow/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@
},
"dependencies": {
"@chakra-ui/anatomy": "^2.2.2",
"@chakra-ui/react": "^2.8.2",
"@chakra-ui/react": "^2.8.2",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/theme-one-dark": "^6.0.0",
"@codemirror/autocomplete": "^6.1.1",
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@tanstack/react-query": "^5.52.1",
"@tanstack/react-table": "^8.20.1",
"@uiw/react-codemirror": "^4.23.5",
"axios": "^1.7.7",
"chakra-react-select": "^4.9.2",
"dayjs": "^1.11.13",
Expand Down
291 changes: 150 additions & 141 deletions airflow/ui/src/components/DataTable/TriggerDAGForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,154 +17,163 @@
* under the License.
*/
import {
FormControl,
FormLabel,
Input,
Textarea,
VStack,
ModalCloseButton,
Button,
ModalFooter,
Checkbox,
Box,
Text,
Spacer,
HStack,
} from "@chakra-ui/react";
import React, { useState, useEffect } from "react";

type DagParams = {
configJson: string;
dagId: string;
logicalDate: string;
runId?: string;
};

type TriggerDAGFormProps = {
dagParams: DagParams;
onClose: () => void;
onTrigger: () => void;
setDagParams: React.Dispatch<React.SetStateAction<DagParams>>;
};

const TriggerDAGForm: React.FC<TriggerDAGFormProps> = ({
dagParams,
onClose,
onTrigger,
setDagParams,
}) => {
const [validateJson, setValidateJson] = useState(false); // State to track checkbox

// Format the JSON in a pretty way whenever the configJson changes
useEffect(() => {
if (validateJson && dagParams.configJson) {
FormControl,
FormLabel,
Input,
VStack,
ModalCloseButton,
Button,
ModalFooter,
Box,
Text,
Spacer,
HStack,
Collapse,
} from "@chakra-ui/react";
import React, { useState, useEffect } from "react";
import CodeMirror from "@uiw/react-codemirror";
import { json } from "@codemirror/lang-json";
import { autocompletion } from "@codemirror/autocomplete";
import { oneDark } from "@codemirror/theme-one-dark";

type DagParams = {
configJson: string;
dagId: string;
logicalDate: string;
runId?: string;
};

type TriggerDAGFormProps = {
dagParams: DagParams;
onClose: () => void;
onTrigger: () => void;
setDagParams: React.Dispatch<React.SetStateAction<DagParams>>;
};

const TriggerDAGForm: React.FC<TriggerDAGFormProps> = ({
dagParams,
onClose,
onTrigger,
setDagParams,
}) => {
const [showDetails, setShowDetails] = useState(false); // State to show/hide all details

// Automatically format JSON whenever the configJson changes
useEffect(() => {
try {
const prettyJson = JSON.stringify(
JSON.parse(dagParams.configJson),
null,
2,
); // Pretty JSON formatting

2
);
setDagParams((prev) => ({ ...prev, configJson: prettyJson }));
} catch {
// Do nothing if it's invalid; handle validation separately
// Invalid JSON handling can go here (e.g., highlight or notification)
}
}
}, [dagParams.configJson, validateJson, setDagParams]);

const handleChange = (
ele: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => {
const { name, value } = ele.target;

setDagParams((prev) => ({ ...prev, [name]: value }));
};

const handleCheckboxChange = (ele: React.ChangeEvent<HTMLInputElement>) => {
setValidateJson(ele.target.checked);
};

const isValidJson = () => {
try {
JSON.parse(dagParams.configJson);

return true;
} catch {
return false;
}
};

return (
<>
<ModalCloseButton />

<VStack align="stretch" p={4} spacing={4}>
<FormControl isRequired>
<FormLabel>Logical date</FormLabel>
<Input
boxShadow="md" // Shadow effect on input
name="logicalDate"
onChange={handleChange}
placeholder="mm / dd / yyyy"
type="date"
value={dagParams.logicalDate}
/>
</FormControl>

<FormControl>
<FormLabel>Run ID (Optional)</FormLabel>
<Input
boxShadow="md" // Shadow effect on input
name="runId"
onChange={handleChange}
opacity={0.7} // Slightly faded to indicate it's optional
placeholder="Run ID (Optional - autogenerated if left empty)"
value={dagParams.runId}
/>
</FormControl>

<FormControl>
<FormLabel>Configuration JSON</FormLabel>
<Textarea
boxShadow="md" // Shadow effect on input
name="configJson"
onChange={handleChange}
rows={6}
value={dagParams.configJson}
whiteSpace="pre-wrap" // Preserve whitespace to show pretty JSON formatting
/>
{validateJson && !isValidJson() ? (
<Box color="red.500" mt={2}>
<Text fontSize="sm">Invalid JSON format</Text>
</Box>
) : null}
</FormControl>

{/* Checkbox for JSON validation */}
<Checkbox isChecked={validateJson} onChange={handleCheckboxChange}>
Validate JSON
</Checkbox>
</VStack>

<ModalFooter>
<HStack w="full">
{/* Cancel button in red */}
<Button colorScheme="red" onClick={onClose}>
Cancel
</Button>
<Spacer />
{/* Trigger button in green */}
}, [dagParams.configJson, setDagParams]);

const handleChange = (
ele: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
const { name, value } = ele.target;
setDagParams((prev) => ({ ...prev, [name]: value }));
};

const handleJsonChange = (value: string) => {
setDagParams((prev) => ({ ...prev, configJson: value }));
};

const isValidJson = () => {
try {
JSON.parse(dagParams.configJson);
return true;
} catch {
return false;
}
};

return (
<>
<ModalCloseButton />

{/* Toggle show/hide for all details */}
<VStack align="stretch" p={4} spacing={4}>
<Button
colorScheme="green" // Green color for trigger button
isDisabled={validateJson ? !isValidJson() : undefined} // Disable if JSON is invalid
onClick={onTrigger}
variant="outline"
onClick={() => setShowDetails(!showDetails)}
width="full"
>
Trigger
{showDetails ? "Hide Details" : "Show Details"}
</Button>
</HStack>
</ModalFooter>
</>
);
};

export default TriggerDAGForm;

<Collapse in={showDetails}>
<VStack align="stretch" spacing={4}>
{/* Logical date/time input with timezone */}
<FormControl>
<FormLabel>Logical date (with time)</FormLabel>
<Input
boxShadow="md"
name="logicalDate"
onChange={handleChange}
placeholder="yyyy-mm-ddThh:mm"
type="datetime-local" // Allows date and time selection
value={dagParams.logicalDate}
/>
</FormControl>

{/* Run ID input */}
<FormControl>
<FormLabel>Run ID (Optional)</FormLabel>
<Input
boxShadow="md"
name="runId"
onChange={handleChange}
placeholder="Run ID (Optional - autogenerated if left empty)"
value={dagParams.runId}
/>
</FormControl>

{/* JSON Configuration with CodeMirror */}
<FormControl>
<FormLabel>Configuration JSON</FormLabel>
<Box border="1px" borderColor="gray.300" borderRadius="md">
<CodeMirror
value={dagParams.configJson}
height="200px"
extensions={[json(), autocompletion()]}
theme={oneDark}
onChange={handleJsonChange}
/>
</Box>
{!isValidJson() ? (
<Box color="red.500" mt={2}>
<Text fontSize="sm">Invalid JSON format</Text>
</Box>
) : null}
</FormControl>
</VStack>
</Collapse>
</VStack>

<ModalFooter>
<HStack w="full">
{/* Cancel button in red */}
<Button colorScheme="red" onClick={onClose}>
Cancel
</Button>
<Spacer />
{/* Trigger button in green */}
<Button
colorScheme="green"
isDisabled={!isValidJson()} // Disable if JSON is invalid
onClick={onTrigger}
>
Trigger
</Button>
</HStack>
</ModalFooter>
</>
);
};

export default TriggerDAGForm;

0 comments on commit a9806ab

Please sign in to comment.