diff --git a/frontend/components/basic/buttons/Button.tsx b/frontend/components/basic/buttons/Button.tsx
index 40251be932..863dc4b48a 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 634591c073..cc70daa0ac 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, useRef } 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);
diff --git a/frontend/components/dashboard/DropZone.js b/frontend/components/dashboard/DropZone.tsx
similarity index 69%
rename from frontend/components/dashboard/DropZone.js
rename to frontend/components/dashboard/DropZone.tsx
index 6171e682f3..7519bca10b 100644
--- a/frontend/components/dashboard/DropZone.js
+++ b/frontend/components/dashboard/DropZone.tsx
@@ -1,4 +1,4 @@
-import { useState } from "react";
+import { type ChangeEvent, type DragEvent, useState } from "react";
import Image from "next/image";
import { faUpload } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -8,27 +8,37 @@ import Error from "../basic/Error";
import parse from "../utilities/file";
import guidGenerator from "../utilities/randomId";
+interface DropZoneProps {
+ // TODO: change Data type from any
+ setData: (data: any) => void;
+ setErrorDragAndDrop: (hasError: boolean) => void;
+ createNewFile: () => void;
+ errorDragAndDrop: boolean;
+ setButtonReady: (isReady: boolean) => void;
+ keysExist: boolean;
+ numCurrentRows: number;
+}
+
const DropZone = ({
setData,
setErrorDragAndDrop,
createNewFile,
errorDragAndDrop,
- addPresetRow,
setButtonReady,
keysExist,
numCurrentRows,
-}) => {
- const handleDragEnter = (e) => {
+}: DropZoneProps) => {
+ const handleDragEnter = (e: DragEvent) => {
e.preventDefault();
e.stopPropagation();
};
- const handleDragLeave = (e) => {
+ const handleDragLeave = (e: DragEvent) => {
e.preventDefault();
e.stopPropagation();
};
- const handleDragOver = (e) => {
+ const handleDragOver = (e: DragEvent) => {
e.preventDefault();
e.stopPropagation();
@@ -39,22 +49,25 @@ const DropZone = ({
const [loading, setLoading] = useState(false);
// This function function immediately parses the file after it is dropped
- const handleDrop = async (e) => {
+ const handleDrop = async (e: DragEvent) => {
setLoading(true);
setTimeout(() => setLoading(false), 5000);
e.preventDefault();
e.stopPropagation();
e.dataTransfer.dropEffect = "copy";
- var file = e.dataTransfer.files[0],
- reader = new FileReader();
- reader.onload = function (event) {
- const keyPairs = parse(event.target.result);
+ const file = e.dataTransfer.files[0];
+ const reader = new FileReader();
+
+ reader.onload = (event) => {
+ if (event.target === null || event.target.result === null) return;
+ // parse function's argument looks like to be ArrayBuffer
+ const keyPairs = parse(event.target.result as Buffer);
const newData = Object.keys(keyPairs).map((key, index) => [
guidGenerator(),
numCurrentRows + index,
key,
- keyPairs[key],
+ keyPairs[key as keyof typeof keyPairs],
"shared",
]);
setData(newData);
@@ -72,23 +85,28 @@ const DropZone = ({
};
// This function is used when the user manually selects a file from the in-browser dircetory (not drag and drop)
- const handleFileSelect = (e) => {
+ const handleFileSelect = (e: ChangeEvent) => {
setLoading(true);
setTimeout(() => setLoading(false), 5000);
- var file = e.target.files[0],
- reader = new FileReader();
- reader.onload = function (event) {
- const newData = event.target.result
- .split("\n")
- .map((line, index) => [
- guidGenerator(),
- numCurrentRows + index,
- line.split("=")[0],
- line.split("=").slice(1, line.split("=").length).join("="),
- "shared",
- ]);
- setData(newData);
- setButtonReady(true);
+ if (e.currentTarget.files === null) return;
+ const file = e.currentTarget.files[0];
+ const reader = new FileReader();
+ reader.onload = (event) => {
+ if (event.target === null || event.target.result === null) return;
+ const { result } = event.target;
+ if (typeof result === "string") {
+ const newData = result
+ .split("\n")
+ .map((line: string, index: number) => [
+ guidGenerator(),
+ numCurrentRows + index,
+ line.split("=")[0],
+ line.split("=").slice(1, line.split("=").length).join("="),
+ "shared",
+ ]);
+ setData(newData);
+ setButtonReady(true);
+ }
};
reader.readAsText(file);
};
@@ -105,17 +123,17 @@ const DropZone = ({
) : keysExist ? (
handleDragEnter(e)}
- onDragOver={(e) => handleDragOver(e)}
- onDragLeave={(e) => handleDragLeave(e)}
- onDrop={(e) => handleDrop(e)}
+ onDragEnter={handleDragEnter}
+ onDragOver={handleDragOver}
+ onDragLeave={handleDragLeave}
+ onDrop={handleDrop}
>
handleFileSelect(e)}
+ onChange={handleFileSelect}
/>
{errorDragAndDrop ? (
@@ -142,10 +160,10 @@ const DropZone = ({
) : (
handleDragEnter(e)}
- onDragOver={(e) => handleDragOver(e)}
- onDragLeave={(e) => handleDragLeave(e)}
- onDrop={(e) => handleDrop(e)}
+ onDragEnter={handleDragEnter}
+ onDragOver={handleDragOver}
+ onDragLeave={handleDragLeave}
+ onDrop={handleDrop}
>
Drag and drop your .env file here.
@@ -154,7 +172,7 @@ const DropZone = ({
type="file"
className="opacity-0 absolute w-full h-full"
accept=".txt,.env"
- onChange={(e) => handleFileSelect(e)}
+ onChange={handleFileSelect}
/>