From fa41baa8b6bb204f1182155aa266a2bedadf93aa Mon Sep 17 00:00:00 2001 From: seunghyunOh Date: Sun, 4 Dec 2022 09:58:51 +0900 Subject: [PATCH] Update dashboard component --- frontend/components/basic/buttons/Button.tsx | 48 ++++--- ...dInputField.js => DashboardInputField.tsx} | 128 ++++++++++-------- 2 files changed, 103 insertions(+), 73 deletions(-) rename frontend/components/dashboard/{DashboardInputField.js => DashboardInputField.tsx} (57%) diff --git a/frontend/components/basic/buttons/Button.tsx b/frontend/components/basic/buttons/Button.tsx index 40251be93..863dc4b48 100644 --- a/frontend/components/basic/buttons/Button.tsx +++ b/frontend/components/basic/buttons/Button.tsx @@ -1,25 +1,28 @@ import React from "react"; import Image from "next/image"; import { IconProp } from "@fortawesome/fontawesome-svg-core"; -import { FontAwesomeIcon, FontAwesomeIconProps } from "@fortawesome/react-fontawesome"; +import { + FontAwesomeIcon, + FontAwesomeIconProps, +} from "@fortawesome/react-fontawesome"; var classNames = require("classnames"); type ButtonProps = { text: string; onButtonPressed: () => void; - loading: boolean; + loading?: boolean; color: string; size: string; - icon: IconProp; - active: boolean; - iconDisabled: string; - textDisabled: string; -} + icon?: IconProp; + active?: boolean; + iconDisabled?: string; + textDisabled?: string; +}; /** * This is the main butto component in the app. - * @param {object} props + * @param {object} props * @param {string} props.text - text inside the button * @param {function} props.onButtonPressed - the action that happens when the button is clicked * @param {boolean} props.loading - if a button is currently in the laoding state @@ -29,21 +32,28 @@ type ButtonProps = { * @param {boolean} props.active - if the button is active or disabled * @param {FontAwesomeIconProps} props.text - the icon inside the button when it is disabled * @param {string} props.textDisable - text inside the button when it is disabled - * @returns + * @returns */ -export default function Button (props: ButtonProps): JSX.Element { +export default function Button(props: ButtonProps): JSX.Element { // Check if the button show always be 'active' - then true; // or if it should switch between 'active' and 'disabled' - then give the status - const activityStatus = props.active || (props.text != "" && props.textDisabled == undefined) - + const activityStatus = + props.active || (props.text != "" && props.textDisabled == undefined); + let styleButton = classNames( "group m-auto md:m-0 inline-block rounded-md duration-200", // Setting background colors and hover modes - props.color == "mineshaft" && activityStatus && "bg-mineshaft-700 hover:bg-primary", + props.color == "mineshaft" && + activityStatus && + "bg-mineshaft-700 hover:bg-primary", props.color == "mineshaft" && !activityStatus && "bg-mineshaft", - (props.color == "primary" || !props.color) && activityStatus && "bg-primary hover:opacity-80", - (props.color == "primary" || !props.color) && !activityStatus && "bg-primary", + (props.color == "primary" || !props.color) && + activityStatus && + "bg-primary hover:opacity-80", + (props.color == "primary" || !props.color) && + !activityStatus && + "bg-primary", props.color == "red" && "bg-red", // Changing the opacity when active vs when not @@ -73,7 +83,7 @@ export default function Button (props: ButtonProps): JSX.Element { "relative duration-200", // Show the loading sign if the loading indicator is on - props.loading == true ? "opacity-0" : "opacity-100", + Boolean(props.loading) ? "opacity-0" : "opacity-100", props.size == "md" && "text-sm", props.size == "lg" && "text-lg" ); @@ -100,7 +110,7 @@ export default function Button (props: ButtonProps): JSX.Element { {props.icon && ( )} {(props.text || props.textDisabled) && ( -

{activityStatus ? props.text : props.textDisabled}

+

+ {activityStatus ? props.text : props.textDisabled} +

)} diff --git a/frontend/components/dashboard/DashboardInputField.js b/frontend/components/dashboard/DashboardInputField.tsx similarity index 57% rename from frontend/components/dashboard/DashboardInputField.js rename to frontend/components/dashboard/DashboardInputField.tsx index 634591c07..286792784 100644 --- a/frontend/components/dashboard/DashboardInputField.js +++ b/frontend/components/dashboard/DashboardInputField.tsx @@ -1,4 +1,4 @@ -import React, { useRef } from "react"; +import React, { SyntheticEvent, UIEvent, useRef, WheelEvent } from "react"; import { faCircle } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -6,6 +6,15 @@ import guidGenerator from "../utilities/randomId"; const REGEX = /([$]{.*?})/g; +interface DashboardInputFieldProps { + index: number; + onChangeHandler: (value: string, index: number) => void; + value: string; + type: "varName" | "value"; + blurred: boolean; + duplicates: string[]; +} + /** * This component renders the input fields on the dashboard * @param {object} obj - the order number of a keyPair @@ -14,51 +23,60 @@ const REGEX = /([$]{.*?})/g; * @param {string} obj.type - whether the input field is for a Key Name or for a Key Value * @param {string} obj.value - value of the InputField * @param {boolean} obj.blurred - whether the input field should be blurred (behind the gray dots) or not; this can be turned on/off in the dashboard - * @param {string[]} obj.duplicates - list of all the suplicated key names on the dashboard + * @param {string[]} obj.duplicates - list of all the duplicated key names on the dashboard * @returns */ + const DashboardInputField = ({ index, onChangeHandler, type, value, blurred, - duplicates -}) => { - const ref = useRef(null); - const syncScroll = (e) => { - ref.current.scrollTop = e.target.scrollTop; - ref.current.scrollLeft = e.target.scrollLeft; + duplicates, +}: DashboardInputFieldProps) => { + const ref = useRef(null); + const syncScroll = (e: SyntheticEvent) => { + if (ref.current == null) return; + + ref.current.scrollTop = e.currentTarget.scrollTop; + ref.current.scrollLeft = e.currentTarget.scrollLeft; }; - + if (type === "varName") { - const startsWithNumber = !isNaN(value.charAt(0)) && value != ""; + const startsWithNumber = !isNaN(Number(value.charAt(0))) && value != ""; const hasDuplicates = duplicates?.includes(value); const error = startsWithNumber || hasDuplicates; return (
onChangeHandler(e.target.value.toUpperCase(), index)} + onChange={(e) => + onChangeHandler(e.target.value.toUpperCase(), index) + } type={type} value={value} - className={`asolute z-10 peer font-mono ph-no-capture bg-bunker-800 rounded-md caret-white text-gray-400 text-md px-2 py-1.5 w-full min-w-16 outline-none focus:ring-2 ${error ? "focus:ring-red/50" : "focus:ring-primary/50"} duration-200`} + className={`absolute z-10 peer font-mono ph-no-capture bg-bunker-800 rounded-md caret-white text-gray-400 text-md px-2 py-1.5 w-full min-w-16 outline-none focus:ring-2 ${ + error ? "focus:ring-red/50" : "focus:ring-primary/50" + } duration-200`} spellCheck="false" />
- {startsWithNumber && + {startsWithNumber && (

Should not start with a number

- } - {hasDuplicates && !startsWithNumber && + )} + {hasDuplicates && !startsWithNumber && (

Secret names should be unique

- } + )}
); } else if (type === "value") { @@ -78,61 +96,61 @@ const DashboardInputField = ({ } z-10 peer font-mono ph-no-capture bg-transparent rounded-md caret-white text-transparent text-md px-2 py-1.5 w-full min-w-16 outline-none focus:ring-2 focus:ring-primary/50 duration-200 no-scrollbar no-scrollbar::-webkit-scrollbar`} spellCheck="false" /> -
- { - value - .split(REGEX) - .map((word, id) => { - if (word.match(REGEX) !== null) { - return ( - - {word.slice(0, 2)} - - {word.slice(2, word.length - 1)} - - {word.slice(word.length - 1, word.length) == "}" ? ( - - {word.slice(word.length - 1, word.length)} - - ) : ( - - {word.slice(word.length - 1, word.length)} - - )} + {value.split(REGEX).map((word, id) => { + if (word.match(REGEX) !== null) { + return ( + + {word.slice(0, 2)} + + {word.slice(2, word.length - 1)} - ); - } else { - return {word}; - } - }) - } + {word.slice(word.length - 1, word.length) == "}" ? ( + + {word.slice(word.length - 1, word.length)} + + ) : ( + + {word.slice(word.length - 1, word.length)} + + )} + + ); + } else { + return ( + + {word} + + ); + } + })}
{blurred && (
- {value - .split("") - .map(() => ( - - ))} + {value.split("").map(() => ( + + ))}
- )} + )} ); } + + return <>Something Wrong; }; export default React.memo(DashboardInputField);