diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx
index 28db741e6..385d441d3 100644
--- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx
+++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx
@@ -17,10 +17,10 @@ import TextAreaComponent from "../../../../components/textAreaComponent";
import ToggleShadComponent from "../../../../components/toggleShadComponent";
import { Button } from "../../../../components/ui/button";
import {
+ INPUT_HANDLER_HOVER,
LANGFLOW_SUPPORTED_TYPES,
+ OUTPUT_HANDLER_HOVER,
TOOLTIP_EMPTY,
- inputHandleHover,
- outputHandleHover,
} from "../../../../constants/constants";
import { postCustomComponentUpdate } from "../../../../controllers/API";
import useAlertStore from "../../../../stores/alertStore";
@@ -182,7 +182,7 @@ export default function ParameterComponent({
return (
{index === 0 && (
-
{left ? inputHandleHover : outputHandleHover}
+
{left ? INPUT_HANDLER_HOVER : OUTPUT_HANDLER_HOVER}
)}
<>
diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx
index 1c27ed847..a7126fff7 100644
--- a/src/frontend/src/CustomNodes/GenericNode/index.tsx
+++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx
@@ -9,9 +9,9 @@ import Loading from "../../components/ui/loading";
import { Textarea } from "../../components/ui/textarea";
import Xmark from "../../components/ui/xmark";
import {
+ STATUS_BUILD,
+ STATUS_BUILDING,
priorityFields,
- statusBuild,
- statusBuilding,
} from "../../constants/constants";
import { BuildStatus } from "../../constants/enums";
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
@@ -49,7 +49,12 @@ export default function GenericNode({
const [nodeDescription, setNodeDescription] = useState(
data.node?.description!
);
- const buildStatus = useFlowStore((state) => state.flowBuildStatus[data.id]);
+ const buildStatus = useFlowStore(
+ (state) => state.flowBuildStatus[data.id]?.status
+ );
+ const lastRunTime = useFlowStore(
+ (state) => state.flowBuildStatus[data.id]?.timestamp
+ );
const [validationStatus, setValidationStatus] =
useState(null);
const [handles, setHandles] = useState(0);
@@ -100,10 +105,7 @@ export default function GenericNode({
if (duration === undefined) {
return "";
} else {
- const nowTimestamp = new Date(Date.now());
- // readable last run time like YYYY-MM-DD HH:MM:SS
- const last_run_datetime = nowTimestamp.toLocaleString();
- return `Last run: ${last_run_datetime}\nDuration: ${duration}`;
+ return `Duration: ${duration}`;
}
};
const durationString = getDurationString(validationStatus?.data.duration);
@@ -487,9 +489,9 @@ export default function GenericNode({
{statusBuilding}
+
{STATUS_BUILDING}
) : !validationStatus ? (
-
{statusBuild}
+
{STATUS_BUILD}
) : (
{typeof validationStatus.params === "string"
@@ -723,6 +725,15 @@ export default function GenericNode({
showNode={showNode}
/>
)}
+
+ {lastRunTime && (
+
+ {lastRunTime.split("\n").map((line, index) => (
+
{line}
+ ))}
+
+ )}
+
>
)}
diff --git a/src/frontend/src/alerts/alertDropDown/index.tsx b/src/frontend/src/alerts/alertDropDown/index.tsx
index 617ba3e29..3577a5de6 100644
--- a/src/frontend/src/alerts/alertDropDown/index.tsx
+++ b/src/frontend/src/alerts/alertDropDown/index.tsx
@@ -6,7 +6,7 @@ import {
PopoverContent,
PopoverTrigger,
} from "../../components/ui/popover";
-import { zeroNotifications } from "../../constants/constants";
+import { ZERO_NOTIFICATIONS } from "../../constants/constants";
import useAlertStore from "../../stores/alertStore";
import { AlertDropdownType } from "../../types/alerts";
import SingleAlert from "./components/singleAlertComponent";
@@ -70,7 +70,7 @@ export default function AlertDropdown({
))
) : (
- {zeroNotifications}
+ {ZERO_NOTIFICATIONS}
)}
diff --git a/src/frontend/src/components/IOview/index.tsx b/src/frontend/src/components/IOview/index.tsx
index 3500160a0..73f0a068e 100644
--- a/src/frontend/src/components/IOview/index.tsx
+++ b/src/frontend/src/components/IOview/index.tsx
@@ -1,12 +1,13 @@
import { useEffect, useState } from "react";
import {
CHAT_FORM_DIALOG_SUBTITLE,
- outputsModalTitle,
- textInputModalTitle,
+ OUTPUTS_MODAL_TITLE,
+ TEXT_INPUT_MODAL_TITLE,
} from "../../constants/constants";
import BaseModal from "../../modals/baseModal";
import useFlowStore from "../../stores/flowStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
+import { NodeType } from "../../types/flow";
import { updateVerticesOrder } from "../../utils/buildUtils";
import { cn } from "../../utils/utils";
import AccordionComponent from "../AccordionComponent";
@@ -18,7 +19,6 @@ import NewChatView from "../newChatView";
import { Badge } from "../ui/badge";
import { Button } from "../ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs";
-import { NodeType } from "../../types/flow";
export default function IOView({ children, open, setOpen }): JSX.Element {
const inputs = useFlowStore((state) => state.inputs).filter(
@@ -79,10 +79,9 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
});
}
setLockChat(false);
- if(chatInput) {
- setNode(chatInput.id, (node:NodeType)=>{
-
- const newNode = {...node}
+ if (chatInput) {
+ setNode(chatInput.id, (node: NodeType) => {
+ const newNode = { ...node };
newNode.data.node!.template["input_value"].value = chatValue;
return newNode;
});
@@ -148,7 +147,7 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
>
- {textInputModalTitle}
+ {TEXT_INPUT_MODAL_TITLE}
{nodes
.filter((node) =>
@@ -209,7 +208,7 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
>
- {outputsModalTitle}
+ {OUTPUTS_MODAL_TITLE}
{nodes
.filter((node) =>
diff --git a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx
index ed15bdede..9bff70924 100644
--- a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx
+++ b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx
@@ -9,7 +9,7 @@ import {
import { useNavigate } from "react-router-dom";
import { Node } from "reactflow";
-import { savedHover } from "../../../../constants/constants";
+import { SAVED_HOVER } from "../../../../constants/constants";
import FlowSettingsModal from "../../../../modals/flowSettingsModal";
import useAlertStore from "../../../../stores/alertStore";
import useFlowStore from "../../../../stores/flowStore";
@@ -128,7 +128,7 @@ export const MenuBar = ({
diff --git a/src/frontend/src/components/newChatView/index.tsx b/src/frontend/src/components/newChatView/index.tsx
index c4be0bcc7..da811d376 100644
--- a/src/frontend/src/components/newChatView/index.tsx
+++ b/src/frontend/src/components/newChatView/index.tsx
@@ -2,8 +2,8 @@ import { useEffect, useRef, useState } from "react";
import IconComponent from "../../components/genericIconComponent";
import { NOCHATOUTPUT_NOTICE_ALERT } from "../../constants/alerts_constants";
import {
- chatFirstInitialText,
- chatSecondInitialText,
+ CHAT_FIRST_INITIAL_TEXT,
+ CHAT_SECOND_INITIAL_TEXT,
} from "../../constants/constants";
import { deleteFlowPool } from "../../controllers/API";
import useAlertStore from "../../stores/alertStore";
@@ -182,14 +182,14 @@ export default function NewChatView({
- {chatFirstInitialText}{" "}
+ {CHAT_FIRST_INITIAL_TEXT}{" "}
{" "}
- {chatSecondInitialText}
+ {CHAT_SECOND_INITIAL_TEXT}
diff --git a/src/frontend/src/components/textAreaComponent/index.tsx b/src/frontend/src/components/textAreaComponent/index.tsx
index 3c7c5c0ab..813f1c672 100644
--- a/src/frontend/src/components/textAreaComponent/index.tsx
+++ b/src/frontend/src/components/textAreaComponent/index.tsx
@@ -1,5 +1,5 @@
import { useEffect } from "react";
-import { editTextModalTitle } from "../../constants/constants";
+import { EDIT_TEXT_MODAL_TITLE } from "../../constants/constants";
import { TypeModal } from "../../constants/enums";
import GenericModal from "../../modals/genericModal";
import { TextAreaComponentType } from "../../types/components";
@@ -38,7 +38,7 @@ export default function TextAreaComponent({
{
onChange(value);
diff --git a/src/frontend/src/constants/alerts_constants.tsx b/src/frontend/src/constants/alerts_constants.tsx
index 6ac4efae9..205933b4b 100644
--- a/src/frontend/src/constants/alerts_constants.tsx
+++ b/src/frontend/src/constants/alerts_constants.tsx
@@ -56,3 +56,6 @@ export const USER_ADD_SUCCESS_ALERT = "Success! New user added!";
export const DEL_KEY_SUCCESS_ALERT = "Success! Key deleted!";
export const FLOW_BUILD_SUCCESS_ALERT = `Flow built successfully`;
export const SAVE_SUCCESS_ALERT = "Changes saved successfully!";
+
+// Generic Node
+
diff --git a/src/frontend/src/constants/constants.ts b/src/frontend/src/constants/constants.ts
index 49a012a84..3f4584102 100644
--- a/src/frontend/src/constants/constants.ts
+++ b/src/frontend/src/constants/constants.ts
@@ -691,38 +691,39 @@ export const priorityFields = new Set(["code", "template"]);
export const INPUT_TYPES = new Set(["ChatInput", "TextInput"]);
export const OUTPUT_TYPES = new Set(["ChatOutput", "TextOutput"]);
-export const chatFirstInitialText =
+export const CHAT_FIRST_INITIAL_TEXT =
"Start a conversation and click the agent's thoughts";
-export const chatSecondInitialText = "to inspect the chaining process.";
+export const CHAT_SECOND_INITIAL_TEXT = "to inspect the chaining process.";
-export const zeroNotifications = "No new notifications";
+export const ZERO_NOTIFICATIONS = "No new notifications";
-export const successBuild = "Built sucessfully ✨";
+export const SUCCESS_BUILD = "Built sucessfully ✨";
-export const alertSaveWApi =
+export const ALERT_SAVE_WITH_API =
"Caution: Uncheck this box only removes API keys from fields specifically designated for API keys.";
-export const saveWApiCheckbox = "Save with my API keys";
-export const editTextModalTitle = "Edit Text";
-export const editTextPlaceholder = "Type message here.";
-export const inputHandleHover = "Avaliable input components:";
-export const outputHandleHover = "Avaliable output components:";
-export const textInputModalTitle = "Text Inputs";
-export const outputsModalTitle = "Text Outputs";
-export const langflowChatTitle = "Langflow Chat";
-export const chatInputPlaceholder =
+export const SAVE_WITH_API_CHECKBOX = "Save with my API keys";
+export const EDIT_TEXT_MODAL_TITLE = "Edit Text";
+export const EDIT_TEXT_PLACEHOLDER = "Type message here.";
+export const INPUT_HANDLER_HOVER = "Avaliable input components:";
+export const OUTPUT_HANDLER_HOVER = "Avaliable output components:";
+export const TEXT_INPUT_MODAL_TITLE = "Text Inputs";
+export const OUTPUTS_MODAL_TITLE = "Text Outputs";
+export const LANGFLOW_CHAT_TITLE = "Langflow Chat";
+export const CHAT_INPUT_PLACEHOLDER =
"No chat input variables found. Click to run your flow.";
-export const chatInputPlaceholderSend = "Send a message...";
-export const editCodeTitle = "Edit Code";
-export const myCollectionDesc =
+export const CHAT_INPUT_PLACEHOLDER_SEND = "Send a message...";
+export const EDIT_CODE_TITLE = "Edit Code";
+export const MY_COLLECTION_DESC =
"Manage your personal projects. Download and upload entire collections.";
-export const storeDesc = "Explore community-shared flows and components.";
-export const storeTitle = "Langflow Store";
-export const noApi = "You don't have an API key. ";
-export const insertApi = "Insert your Langflow API key.";
-export const invalidApi = "Your API key is not valid. ";
-export const createApi = `Don’t have an API key? Sign up at`;
-export const statusBuild = "Build to validate status.";
-export const statusBuilding = "Building...";
-export const savedHover = "Last saved at ";
+export const STORE_DESC = "Explore community-shared flows and components.";
+export const STORE_TITLE = "Langflow Store";
+export const NO_API_KEY = "You don't have an API key. ";
+export const INSERT_API_KEY = "Insert your Langflow API key.";
+export const INVALID_API_KEY = "Your API key is not valid. ";
+export const CREATE_API_KEY = `Don’t have an API key? Sign up at`;
+export const STATUS_BUILD = "Build to validate status.";
+export const STATUS_BUILDING = "Building...";
+export const SAVED_HOVER = "Last saved at ";
+export const RUN_TIMESTAMP_PREFIX = "Last Run: ";
diff --git a/src/frontend/src/modals/StoreApiKeyModal/index.tsx b/src/frontend/src/modals/StoreApiKeyModal/index.tsx
index fca6a36ee..1b5d78a2f 100644
--- a/src/frontend/src/modals/StoreApiKeyModal/index.tsx
+++ b/src/frontend/src/modals/StoreApiKeyModal/index.tsx
@@ -8,10 +8,10 @@ import {
API_SUCCESS_ALERT,
} from "../../constants/alerts_constants";
import {
- createApi,
- insertApi,
- invalidApi,
- noApi,
+ CREATE_API_KEY,
+ INSERT_API_KEY,
+ INVALID_API_KEY,
+ NO_API_KEY,
} from "../../constants/constants";
import { AuthContext } from "../../contexts/authContext";
import { addApiKeyStore } from "../../controllers/API";
@@ -68,8 +68,11 @@ export default function StoreApiKeyModal({
{children}
API Key
@@ -104,7 +107,7 @@ export default function StoreApiKeyModal({
- {alertSaveWApi}
+
+ {ALERT_SAVE_WITH_API}
+
diff --git a/src/frontend/src/modals/formModal/chatInput/index.tsx b/src/frontend/src/modals/formModal/chatInput/index.tsx
index b3a126b7e..9cf675b9e 100644
--- a/src/frontend/src/modals/formModal/chatInput/index.tsx
+++ b/src/frontend/src/modals/formModal/chatInput/index.tsx
@@ -2,8 +2,8 @@ import { useEffect } from "react";
import IconComponent from "../../../components/genericIconComponent";
import { Textarea } from "../../../components/ui/textarea";
import {
- chatInputPlaceholder,
- chatInputPlaceholderSend,
+ CHAT_INPUT_PLACEHOLDER,
+ CHAT_INPUT_PLACEHOLDER_SEND,
} from "../../../constants/constants";
import { chatInputType } from "../../../types/components";
import { classNames } from "../../../utils/utils";
@@ -55,7 +55,7 @@ export default function ChatInput({
? "Thinking..."
: typeof chatValue === "object" &&
Object.keys(chatValue)?.length === 0
- ? chatInputPlaceholder
+ ? CHAT_INPUT_PLACEHOLDER
: chatValue
}
onChange={(event): void => {
@@ -70,7 +70,9 @@ export default function ChatInput({
"form-modal-lockchat"
)}
- placeholder={noInput ? chatInputPlaceholder : chatInputPlaceholderSend}
+ placeholder={
+ noInput ? CHAT_INPUT_PLACEHOLDER : CHAT_INPUT_PLACEHOLDER_SEND
+ }
/>
diff --git a/src/frontend/src/modals/genericModal/index.tsx b/src/frontend/src/modals/genericModal/index.tsx
index 5ad9d7b07..e00462218 100644
--- a/src/frontend/src/modals/genericModal/index.tsx
+++ b/src/frontend/src/modals/genericModal/index.tsx
@@ -12,11 +12,11 @@ import {
TEMP_NOTICE_ALERT,
} from "../../constants/alerts_constants";
import {
+ EDIT_TEXT_PLACEHOLDER,
INVALID_CHARACTERS,
MAX_WORDS_HIGHLIGHT,
PROMPT_DIALOG_SUBTITLE,
TEXT_DIALOG_SUBTITLE,
- editTextPlaceholder,
regexHighlight,
} from "../../constants/constants";
import { TypeModal } from "../../constants/enums";
@@ -227,7 +227,7 @@ export default function GenericModal({
setInputValue(event.target.value);
checkVariables(event.target.value);
}}
- placeholder={editTextPlaceholder}
+ placeholder={EDIT_TEXT_PLACEHOLDER}
onKeyDown={(e) => {
handleKeyDown(e, inputValue, "");
}}
@@ -249,7 +249,7 @@ export default function GenericModal({
onChange={(event) => {
setInputValue(event.target.value);
}}
- placeholder={editTextPlaceholder}
+ placeholder={EDIT_TEXT_PLACEHOLDER}
onKeyDown={(e) => {
handleKeyDown(e, value, "");
}}
diff --git a/src/frontend/src/pages/MainPage/index.tsx b/src/frontend/src/pages/MainPage/index.tsx
index 2cddf4273..cc4115e7e 100644
--- a/src/frontend/src/pages/MainPage/index.tsx
+++ b/src/frontend/src/pages/MainPage/index.tsx
@@ -8,8 +8,8 @@ import SidebarNav from "../../components/sidebarComponent";
import { Button } from "../../components/ui/button";
import { CONSOLE_ERROR_MSG } from "../../constants/alerts_constants";
import {
+ MY_COLLECTION_DESC,
USER_PROJECTS_HEADER,
- myCollectionDesc,
} from "../../constants/constants";
import useAlertStore from "../../stores/alertStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
@@ -75,7 +75,7 @@ export default function HomePage(): JSX.Element {
return (