) {
- let image: JSX.Element = ; // <== whatever you want here
-
- var ghost = document.createElement("div");
- ghost.style.transform = "translate(-10000px, -10000px)";
- ghost.style.position = "absolute";
- document.body.appendChild(ghost);
- event.dataTransfer.setDragImage(ghost, 0, 0);
- const root = createRoot(ghost);
- root.render(image);
- const flow = getFlowById(data.id);
- if (flow) {
- event.dataTransfer.setData("flow", JSON.stringify(data));
- }
- }
+ const { onDragStart } = useDragStart(data);
return (
<>
@@ -264,7 +197,7 @@ export default function CollectionCardComponent({
- {likes_count ?? 0}
+ {likesCount ?? 0}
@@ -275,7 +208,7 @@ export default function CollectionCardComponent({
className="h-4 w-4"
/>
- {downloads_count ?? 0}
+ {downloadsCount ?? 0}
@@ -324,20 +257,7 @@ export default function CollectionCardComponent({
)}
)}
-
- {/* {data.tags &&
- data.tags.length > 0 &&
- data.tags.map((tag, index) => (
-
- {tag.name}
-
- ))} */}
-
+
@@ -457,7 +377,7 @@ export default function CollectionCardComponent({
name="Heart"
className={cn(
"h-5 w-5",
- liked_by_user
+ likedByUser
? "fill-destructive stroke-destructive"
: "",
!authorized ? "text-ring" : "",
diff --git a/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx b/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx
index c75bf4bec..4dd87fc50 100644
--- a/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx
+++ b/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx
@@ -9,7 +9,10 @@ import useFlowsManagerStore from "../../../stores/flowsManagerStore";
import { useFolderStore } from "../../../stores/foldersStore";
import { addVersionToDuplicates } from "../../../utils/reactflowUtils";
-const useFileDrop = (folderId, folderChangeCallback) => {
+const useFileDrop = (
+ folderId: string,
+ folderChangeCallback: (folderId: string) => void,
+) => {
const setFolderDragging = useFolderStore((state) => state.setFolderDragging);
const setFolderIdDragging = useFolderStore(
(state) => state.setFolderIdDragging,
diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-auto-resize-text-area.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-auto-resize-text-area.tsx
index d4102fe9d..41428e4a4 100644
--- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-auto-resize-text-area.tsx
+++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-auto-resize-text-area.tsx
@@ -1,6 +1,9 @@
import { useEffect } from "react";
-const useAutoResizeTextArea = (value, inputRef) => {
+const useAutoResizeTextArea = (
+ value: string,
+ inputRef: React.RefObject,
+) => {
useEffect(() => {
if (inputRef.current && inputRef.current.scrollHeight! !== 0) {
inputRef.current.style!.height = "inherit"; // Reset the height
diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-drag-and-drop.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-drag-and-drop.tsx
index b1ff9d143..9b30fba41 100644
--- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-drag-and-drop.tsx
+++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-drag-and-drop.tsx
@@ -7,10 +7,10 @@ import {
import useFileUpload from "./use-file-upload";
const useDragAndDrop = (
- setIsDragging,
- setFiles,
- currentFlowId,
- setErrorData,
+ setIsDragging: (value: boolean) => void,
+ setFiles: (value: any) => void,
+ currentFlowId: string,
+ setErrorData: (value: any) => void,
) => {
const dragOver = (e) => {
e.preventDefault();
diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-focus-unlock.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-focus-unlock.tsx
index 15dfe70ae..6e951d80f 100644
--- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-focus-unlock.tsx
+++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-focus-unlock.tsx
@@ -1,6 +1,9 @@
import { useEffect } from "react";
-const useFocusOnUnlock = (lockChat, inputRef) => {
+const useFocusOnUnlock = (
+ lockChat: boolean,
+ inputRef: React.RefObject,
+) => {
useEffect(() => {
if (!lockChat && inputRef.current) {
inputRef.current.focus();
diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-upload.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-upload.tsx
index 5a9e85195..29bc86e6a 100644
--- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-upload.tsx
+++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-upload.tsx
@@ -1,3 +1,4 @@
+import { AxiosResponse } from "axios";
import { useEffect } from "react";
import ShortUniqueId from "short-unique-id";
import {
@@ -6,9 +7,18 @@ import {
SN_ERROR_TEXT,
} from "../../../../../../constants/constants";
import useAlertStore from "../../../../../../stores/alertStore";
+import { UploadFileTypeAPI } from "../../../../../../types/api";
import useFileUpload from "./use-file-upload";
-const useUpload = (uploadFile, currentFlowId, setFiles, lockChat) => {
+const useUpload = (
+ uploadFile: (
+ file: File,
+ id: string,
+ ) => Promise>,
+ currentFlowId: string,
+ setFiles: any,
+ lockChat: boolean,
+) => {
const setErrorData = useAlertStore((state) => state.setErrorData);
useEffect(() => {
const handlePaste = (event: ClipboardEvent): void => {
diff --git a/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx b/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx
index 14263a9c6..71f8566de 100644
--- a/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx
+++ b/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx
@@ -2,9 +2,10 @@ import { ColDef, ValueGetterParams } from "ag-grid-community";
import { useMemo } from "react";
import TableNodeCellRender from "../../../components/tableComponent/components/tableNodeCellRender";
import TableToggleCellRender from "../../../components/tableComponent/components/tableToggleCellRender";
+import { NodeDataType } from "../../../types/flow";
const useColumnDefs = (
- myData: any,
+ myData: NodeDataType,
handleOnNewValue: (newValue: any, name: string) => void,
handleOnChangeDb: (value: boolean, key: string) => void,
changeAdvanced: (n: string) => void,
diff --git a/src/frontend/src/modals/editNodeModal/hooks/use-row-data.tsx b/src/frontend/src/modals/editNodeModal/hooks/use-row-data.tsx
index cafd25c6d..e2cd5a772 100644
--- a/src/frontend/src/modals/editNodeModal/hooks/use-row-data.tsx
+++ b/src/frontend/src/modals/editNodeModal/hooks/use-row-data.tsx
@@ -1,14 +1,12 @@
import { useMemo } from "react";
import { LANGFLOW_SUPPORTED_TYPES } from "../../../constants/constants";
-import { TemplateVariableType } from "../../../types/api";
+import { NodeDataType } from "../../../types/flow";
-const useRowData = (myData, open) => {
+const useRowData = (myData: NodeDataType, open: boolean) => {
const rowData = useMemo(() => {
return Object.keys(myData.node!.template)
.filter((key: string) => {
- const templateParam = myData.node!.template[
- key
- ] as TemplateVariableType;
+ const templateParam = myData.node!.template[key] as any;
return (
key.charAt(0) !== "_" &&
templateParam.show &&
@@ -20,9 +18,7 @@ const useRowData = (myData, open) => {
);
})
.map((key: string) => {
- const templateParam = myData.node!.template[
- key
- ] as TemplateVariableType;
+ const templateParam = myData.node!.template[key] as any;
return {
...templateParam,
key: key,
diff --git a/src/frontend/src/modals/editNodeModal/index.tsx b/src/frontend/src/modals/editNodeModal/index.tsx
index f4a368fa6..2a01e6c0b 100644
--- a/src/frontend/src/modals/editNodeModal/index.tsx
+++ b/src/frontend/src/modals/editNodeModal/index.tsx
@@ -16,13 +16,11 @@ const EditNodeModal = forwardRef(
nodeLength,
open,
setOpen,
- // setOpenWDoubleClick,
data,
}: {
nodeLength: number;
open: boolean;
setOpen: (open: boolean) => void;
- // setOpenWDoubleClick: (open: boolean) => void;
data: NodeDataType;
},
ref,
diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/components/collectionCard/index.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/components/collectionCard/index.tsx
new file mode 100644
index 000000000..1c9c0799e
--- /dev/null
+++ b/src/frontend/src/pages/MainPage/components/componentsComponent/components/collectionCard/index.tsx
@@ -0,0 +1,58 @@
+import React from "react";
+import { Link, useNavigate } from "react-router-dom";
+import CollectionCardComponent from "../../../../../../components/cardComponent";
+import IconComponent from "../../../../../../components/genericIconComponent";
+import { Button } from "../../../../../../components/ui/button";
+const CollectionCard = ({ item, type, isLoading, control }) => {
+ const navigate = useNavigate();
+ const isComponent = item.is_component ?? false;
+ const editFlowLink = `/flow/${item.id}`;
+ const editFlowButtonTestId = `edit-flow-button-${item.id}`;
+
+ const handleClick = () => {
+ if (!isComponent) {
+ navigate(editFlowLink);
+ }
+ };
+
+ const renderButton = () => {
+ if (!isComponent) {
+ return (
+
+
+
+ );
+ }
+ return null;
+ };
+
+ return (
+
+ );
+};
+
+export default CollectionCard;
diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-delete-multiple.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-delete-multiple.tsx
index 395088193..46caecbf1 100644
--- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-delete-multiple.tsx
+++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-delete-multiple.tsx
@@ -1,15 +1,15 @@
import { useCallback } from "react";
const useDeleteMultipleFlows = (
- selectedFlowsComponentsCards,
- removeFlow,
- resetFilter,
- getFoldersApi,
- folderId,
- myCollectionId,
- getFolderById,
- setSuccessData,
- setErrorData,
+ selectedFlowsComponentsCards: string[],
+ removeFlow: (selectedFlowsComponentsCards: string[]) => Promise,
+ resetFilter: () => void,
+ getFoldersApi: (refetch?: boolean) => Promise,
+ folderId: string | undefined,
+ myCollectionId: string,
+ getFolderById: (id: string) => void,
+ setSuccessData: (data: { title: string }) => void,
+ setErrorData: (data: { title: string; list: string[] }) => void,
) => {
const handleDeleteMultiple = useCallback(() => {
removeFlow(selectedFlowsComponentsCards)
diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-description-modal.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-description-modal.tsx
index 6de2ebb6d..2af71e91a 100644
--- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-description-modal.tsx
+++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-description-modal.tsx
@@ -1,6 +1,9 @@
import { useMemo } from "react";
-const useDescriptionModal = (selectedFlowsComponentsCards, type) => {
+const useDescriptionModal = (
+ selectedFlowsComponentsCards: string[] | undefined,
+ type: string | undefined,
+) => {
const getDescriptionModal = useMemo(() => {
const getTypeLabel = (type) => {
const labels = {
diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-filtered-flows.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-filtered-flows.tsx
index 96b1757ff..db8be8c72 100644
--- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-filtered-flows.tsx
+++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-filtered-flows.tsx
@@ -1,10 +1,11 @@
import cloneDeep from "lodash/cloneDeep";
import { useEffect } from "react";
+import { FlowType } from "../../../../../types/flow";
const useFilteredFlows = (
- flowsFromFolder,
- searchFlowsComponents,
- setAllFlows,
+ flowsFromFolder: FlowType[],
+ searchFlowsComponents: string,
+ setAllFlows: (value: any[]) => void,
) => {
useEffect(() => {
const newFlows = cloneDeep(flowsFromFolder || []);
diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-duplicate.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-duplicate.tsx
index fc49fc0d1..d0ae38e4f 100644
--- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-duplicate.tsx
+++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-duplicate.tsx
@@ -1,18 +1,31 @@
import { useCallback } from "react";
+import { XYPosition } from "reactflow";
+import { FlowType } from "../../../../../types/flow";
const useDuplicateFlows = (
- selectedFlowsComponentsCards,
- addFlow,
- allFlows,
- resetFilter,
- getFoldersApi,
- folderId,
- myCollectionId,
- getFolderById,
- setSuccessData,
- setSelectedFlowsComponentsCards,
- handleSelectAll,
- cardTypes,
+ selectedFlowsComponentsCards: string[],
+ addFlow: (
+ newProject: boolean,
+ flow?: FlowType,
+ override?: boolean,
+ position?: XYPosition,
+ fromDragAndDrop?: boolean,
+ ) => Promise,
+ allFlows: any[],
+ resetFilter: () => void,
+ getFoldersApi: (
+ refetch?: boolean,
+ startupApplication?: boolean,
+ ) => Promise,
+ folderId: string,
+ myCollectionId: string,
+ getFolderById: (id: string) => void,
+ setSuccessData: (data: { title: string }) => void,
+ setSelectedFlowsComponentsCards: (
+ selectedFlowsComponentsCards: string[],
+ ) => void,
+ handleSelectAll: (select: boolean) => void,
+ cardTypes: string,
) => {
const handleDuplicate = useCallback(() => {
Promise.all(
diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-export.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-export.tsx
index 8edabc146..4b5e2f925 100644
--- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-export.tsx
+++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-export.tsx
@@ -1,15 +1,18 @@
import { useCallback } from "react";
+import { FlowType } from "../../../../../types/flow";
const useExportFlows = (
- selectedFlowsComponentsCards,
- allFlows,
- downloadFlow,
- removeApiKeys,
- version,
- setSuccessData,
- setSelectedFlowsComponentsCards,
- handleSelectAll,
- cardTypes,
+ selectedFlowsComponentsCards: string[],
+ allFlows: Array,
+ downloadFlow: (flow: any, name: string, description: string) => void,
+ removeApiKeys: (flow: any) => any,
+ version: string,
+ setSuccessData: (data: { title: string }) => void,
+ setSelectedFlowsComponentsCards: (
+ selectedFlowsComponentsCards: string[],
+ ) => void,
+ handleSelectAll: (select: boolean) => void,
+ cardTypes: string,
) => {
const handleExport = useCallback(() => {
selectedFlowsComponentsCards.forEach((selectedFlowId) => {
diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-select-all.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-select-all.tsx
index a81515e0a..4961c73e9 100644
--- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-select-all.tsx
+++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-select-all.tsx
@@ -1,6 +1,11 @@
import { useCallback } from "react";
+import { FlowType } from "../../../../../types/flow";
-const useSelectAll = (flowsFromFolder, getValues, setValue) => {
+const useSelectAll = (
+ flowsFromFolder: FlowType[],
+ getValues: () => Record,
+ setValue: (key: string, value: boolean) => void,
+) => {
const handleSelectAll = useCallback(
(select) => {
const flowsFromFolderIds = flowsFromFolder?.map((f) => f.id);
diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-select-options-change.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-select-options-change.tsx
index 56dc204c7..dc7053600 100644
--- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-select-options-change.tsx
+++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-select-options-change.tsx
@@ -1,15 +1,15 @@
import { useCallback } from "react";
const useSelectOptionsChange = (
- selectedFlowsComponentsCards,
- setErrorData,
- setOpenDelete,
- handleDuplicate,
- handleExport,
+ selectedFlowsComponentsCards: string[] | undefined,
+ setErrorData: (data: { title: string; list: string[] }) => void,
+ setOpenDelete: (value: boolean) => void,
+ handleDuplicate: () => void,
+ handleExport: () => void,
) => {
const handleSelectOptionsChange = useCallback(
(action) => {
- const hasSelected = selectedFlowsComponentsCards?.length > 0;
+ const hasSelected = selectedFlowsComponentsCards?.length! > 0;
if (!hasSelected) {
setErrorData({
title: "No items selected",
diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-selected-flows.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-selected-flows.tsx
index b6f00934e..e5ac9a90d 100644
--- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-selected-flows.tsx
+++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-selected-flows.tsx
@@ -1,8 +1,10 @@
import { useEffect } from "react";
const useSelectedFlows = (
- entireFormValues,
- setSelectedFlowsComponentsCards,
+ entireFormValues: Record | undefined,
+ setSelectedFlowsComponentsCards: (
+ selectedFlowsComponentsCards: string[],
+ ) => void,
) => {
useEffect(() => {
if (!entireFormValues || Object.keys(entireFormValues).length === 0) return;
diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/index.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/index.tsx
index af13e2bb4..7ccd88048 100644
--- a/src/frontend/src/pages/MainPage/components/componentsComponent/index.tsx
+++ b/src/frontend/src/pages/MainPage/components/componentsComponent/index.tsx
@@ -19,6 +19,7 @@ import { getNameByType } from "../../utils/get-name-by-type";
import { sortFlows } from "../../utils/sort-flows";
import EmptyComponent from "../emptyComponent";
import HeaderComponent from "../headerComponent";
+import CollectionCard from "./components/collectionCard";
import useDeleteMultipleFlows from "./hooks/use-delete-multiple";
import useDescriptionModal from "./hooks/use-description-modal";
import useFilteredFlows from "./hooks/use-filtered-flows";
@@ -61,7 +62,6 @@ export default function ComponentsComponent({
const [handleFileDrop] = useFileDrop(uploadFlow, type)!;
const [pageSize, setPageSize] = useState(20);
const [pageIndex, setPageIndex] = useState(1);
- const navigate = useNavigate();
const location = useLocation();
const all: FlowType[] = sortFlows(allFlows, type);
const start = (pageIndex - 1) * pageSize;
@@ -94,7 +94,7 @@ export default function ComponentsComponent({
getFolderById(folderId ? folderId : myCollectionId);
}, [location]);
- useFilteredFlows(flowsFromFolder, searchFlowsComponents, setAllFlows);
+ useFilteredFlows(flowsFromFolder!, searchFlowsComponents, setAllFlows);
const resetFilter = () => {
setPageIndex(1);
@@ -107,7 +107,7 @@ export default function ComponentsComponent({
const methods = useForm();
const { handleSelectAll } = useSelectAll(
- flowsFromFolder,
+ flowsFromFolder!,
getValues,
setValue,
);
@@ -119,7 +119,7 @@ export default function ComponentsComponent({
resetFilter,
getFoldersApi,
folderId,
- myCollectionId,
+ myCollectionId!,
getFolderById,
setSuccessData,
setSelectedFlowsComponentsCards,
@@ -155,7 +155,7 @@ export default function ComponentsComponent({
resetFilter,
getFoldersApi,
folderId,
- myCollectionId,
+ myCollectionId!,
getFolderById,
setSuccessData,
setErrorData,
@@ -205,43 +205,10 @@ export default function ComponentsComponent({
{data?.map((item) => (
diff --git a/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx b/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx
index 0d093bc32..27ccfdc19 100644
--- a/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx
+++ b/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx
@@ -2,7 +2,7 @@ import useAlertStore from "../../../stores/alertStore";
import { useFolderStore } from "../../../stores/foldersStore";
import { deleteFolder, getFolderById } from "../services";
-const useDeleteFolder = ({ navigate }) => {
+const useDeleteFolder = ({ navigate }: { navigate: (url: string) => void }) => {
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setErrorData = useAlertStore((state) => state.setErrorData);
const folderToEdit = useFolderStore((state) => state.folderToEdit);
diff --git a/src/frontend/src/pages/MainPage/hooks/use-dropdown-options.tsx b/src/frontend/src/pages/MainPage/hooks/use-dropdown-options.tsx
index 69e2c2df3..92957d295 100644
--- a/src/frontend/src/pages/MainPage/hooks/use-dropdown-options.tsx
+++ b/src/frontend/src/pages/MainPage/hooks/use-dropdown-options.tsx
@@ -1,7 +1,26 @@
+import { XYPosition } from "reactflow";
import { CONSOLE_ERROR_MSG } from "../../../constants/alerts_constants";
import useAlertStore from "../../../stores/alertStore";
-const useDropdownOptions = ({ uploadFlow, navigate, is_component }) => {
+const useDropdownOptions = ({
+ uploadFlow,
+ navigate,
+ is_component,
+}: {
+ uploadFlow: ({
+ newProject,
+ file,
+ isComponent,
+ position,
+ }: {
+ newProject: boolean;
+ file?: File;
+ isComponent: boolean | null;
+ position?: XYPosition;
+ }) => Promise;
+ navigate: (url: string) => void;
+ is_component: boolean;
+}) => {
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setErrorData = useAlertStore((state) => state.setErrorData);
const handleImportFromJSON = () => {
diff --git a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-api-keys.tsx b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-api-keys.tsx
index 8af9b4a0b..2bdbe33f9 100644
--- a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-api-keys.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-api-keys.tsx
@@ -1,6 +1,12 @@
import { getApiKey } from "../../../../../controllers/API";
+import { Users } from "../../../../../types/api";
-const useApiKeys = (userData, setLoadingKeys, keysList, setUserId) => {
+const useApiKeys = (
+ userData: Users | null,
+ setLoadingKeys: (load: boolean) => void,
+ keysList: React.MutableRefObject,
+ setUserId: (userId: string) => void,
+) => {
const fetchApiKeys = () => {
setLoadingKeys(true);
getApiKey()
diff --git a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-handle-delete-key.tsx b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-handle-delete-key.tsx
index 74d5dae99..0d642dfbf 100644
--- a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-handle-delete-key.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-handle-delete-key.tsx
@@ -7,10 +7,10 @@ import {
import { deleteApiKey } from "../../../../../controllers/API";
const useDeleteApiKeys = (
- selectedRows,
- resetFilter,
- setSuccessData,
- setErrorData,
+ selectedRows: string[],
+ resetFilter: () => void,
+ setSuccessData: (data: { title: string }) => void,
+ setErrorData: (data: { title: string; list: string[] }) => void,
) => {
const handleDeleteKey = () => {
Promise.all(selectedRows.map((selectedRow) => deleteApiKey(selectedRow)))
diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx
index 988af6ea9..abc8587d2 100644
--- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx
@@ -4,7 +4,10 @@ import {
BASE_URL_API,
} from "../../../../../../../../../constants/constants";
-const usePreloadImages = (profilePictures, setImagesLoaded) => {
+const usePreloadImages = (
+ profilePictures: { [key: string]: string[] },
+ setImagesLoaded: (value: boolean) => void,
+) => {
const preloadImages = async (imageUrls) => {
return Promise.all(
imageUrls.map(
diff --git a/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-password.tsx b/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-password.tsx
index c4b452e6b..0003fe4a1 100644
--- a/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-password.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-password.tsx
@@ -5,8 +5,13 @@ import {
SAVE_SUCCESS_ALERT,
} from "../../../../constants/alerts_constants";
import { resetPassword } from "../../../../controllers/API";
+import { Users } from "../../../../types/api";
-const usePatchPassword = (userData, setSuccessData, setErrorData) => {
+const usePatchPassword = (
+ userData: Users | null,
+ setSuccessData: (data: { title: string; list?: string[] }) => void,
+ setErrorData: (data: { title: string; list: string[] }) => void,
+) => {
const handlePatchPassword = async (password, cnfPassword, handleInput) => {
if (password !== cnfPassword) {
setErrorData({
@@ -16,7 +21,7 @@ const usePatchPassword = (userData, setSuccessData, setErrorData) => {
return;
}
try {
- if (password !== "") await resetPassword(userData.id, { password });
+ if (password !== "") await resetPassword(userData!.id, { password });
handleInput({ target: { name: "password", value: "" } });
handleInput({ target: { name: "cnfPassword", value: "" } });
setSuccessData({ title: SAVE_SUCCESS_ALERT });
diff --git a/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-profile-picture.tsx b/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-profile-picture.tsx
index 584300fdf..6ad76f4ff 100644
--- a/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-profile-picture.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-profile-picture.tsx
@@ -4,21 +4,22 @@ import {
SAVE_SUCCESS_ALERT,
} from "../../../../constants/alerts_constants";
import { updateUser } from "../../../../controllers/API";
+import { Users } from "../../../../types/api";
const usePatchProfilePicture = (
- setSuccessData,
- setErrorData,
- currentUserData,
- setUserData,
+ setSuccessData: (data: { title: string; list?: string[] }) => void,
+ setErrorData: (data: { title: string; list: string[] }) => void,
+ currentUserData: Users | null,
+ setUserData: (data: any) => void,
) => {
const handlePatchProfilePicture = async (profile_picture) => {
try {
if (profile_picture !== "") {
- await updateUser(currentUserData.id, {
+ await updateUser(currentUserData!.id, {
profile_image: profile_picture,
});
let newUserData = cloneDeep(currentUserData);
- newUserData.profile_image = profile_picture;
+ newUserData!.profile_image = profile_picture;
setUserData(newUserData);
}
setSuccessData({ title: SAVE_SUCCESS_ALERT });
diff --git a/src/frontend/src/pages/SettingsPage/pages/hooks/use-save-key.tsx b/src/frontend/src/pages/SettingsPage/pages/hooks/use-save-key.tsx
index cf5871a26..4f87405c3 100644
--- a/src/frontend/src/pages/SettingsPage/pages/hooks/use-save-key.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/hooks/use-save-key.tsx
@@ -7,11 +7,11 @@ import { AuthContext } from "../../../../contexts/authContext";
import { addApiKeyStore } from "../../../../controllers/API";
const useSaveKey = (
- setSuccessData,
- setErrorData,
- setHasApiKey,
- setValidApiKey,
- setLoadingApiKey,
+ setSuccessData: (data: { title: string }) => void,
+ setErrorData: (data: { title: string; list: string[] }) => void,
+ setHasApiKey: (hasApiKey: boolean) => void,
+ setValidApiKey: (validApiKey: boolean) => void,
+ setLoadingApiKey: (loadingApiKey: boolean) => void,
) => {
const { storeApiKey } = useContext(AuthContext);
diff --git a/src/frontend/src/pages/SettingsPage/pages/hooks/use-scroll-to-element.tsx b/src/frontend/src/pages/SettingsPage/pages/hooks/use-scroll-to-element.tsx
index a56c2d5d6..faa7408a3 100644
--- a/src/frontend/src/pages/SettingsPage/pages/hooks/use-scroll-to-element.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/hooks/use-scroll-to-element.tsx
@@ -1,6 +1,9 @@
import { useEffect } from "react";
-const useScrollToElement = (scrollId, setCurrentFlowId) => {
+const useScrollToElement = (
+ scrollId: string | null | undefined,
+ setCurrentFlowId: (currentFlowId: string) => void,
+) => {
useEffect(() => {
const element = document.getElementById(scrollId ?? "null");
if (element) {
diff --git a/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-messages-table.tsx b/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-messages-table.tsx
index 7f3a74352..fe344e478 100644
--- a/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-messages-table.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-messages-table.tsx
@@ -1,8 +1,11 @@
+import { ColDef, ColGroupDef } from "ag-grid-community";
import { useEffect } from "react";
import { getMessagesTable } from "../../../../../controllers/API";
import { useMessagesStore } from "../../../../../stores/messagesStore";
-const useMessagesTable = (setColumns) => {
+const useMessagesTable = (
+ setColumns: (data: Array) => void,
+) => {
const setMessages = useMessagesStore((state) => state.setMessages);
useEffect(() => {
const fetchData = async () => {
diff --git a/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-remove-messages.tsx b/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-remove-messages.tsx
index d7f4d5202..f2c8a2a4d 100644
--- a/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-remove-messages.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-remove-messages.tsx
@@ -2,10 +2,10 @@ import { deleteMessagesFn } from "../../../../../controllers/API";
import { useMessagesStore } from "../../../../../stores/messagesStore";
const useRemoveMessages = (
- setSelectedRows,
- setSuccessData,
- setErrorData,
- selectedRows,
+ setSelectedRows: (data: number[]) => void,
+ setSuccessData: (data: { title: string }) => void,
+ setErrorData: (data: { title: string }) => void,
+ selectedRows: number[],
) => {
const deleteMessages = useMessagesStore((state) => state.removeMessages);
diff --git a/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-updateMessage.tsx b/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-updateMessage.tsx
index f199ac489..dc2840b79 100644
--- a/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-updateMessage.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-updateMessage.tsx
@@ -2,7 +2,10 @@ import { updateMessageApi } from "../../../../../controllers/API";
import { useMessagesStore } from "../../../../../stores/messagesStore";
import { Message } from "../../../../../types/messages";
-const useUpdateMessage = (setSuccessData, setErrorData) => {
+const useUpdateMessage = (
+ setSuccessData: (data: { title: string; list?: string[] }) => void,
+ setErrorData: (data: { title: string; list?: string[] }) => void,
+) => {
const updateMessage = useMessagesStore((state) => state.updateMessage);
const handleUpdate = async (data: Message) => {
diff --git a/tests/test_messages_endpoints.py b/tests/test_messages_endpoints.py
new file mode 100644
index 000000000..ee4021784
--- /dev/null
+++ b/tests/test_messages_endpoints.py
@@ -0,0 +1,76 @@
+from uuid import UUID
+
+import pytest
+from fastapi.testclient import TestClient
+
+from langflow.memory import add_messagetables
+
+# Assuming you have these imports available
+from langflow.services.database.models.message import MessageCreate, MessageRead, MessageUpdate
+from langflow.services.database.models.message.model import MessageTable
+from langflow.services.deps import session_scope
+
+
+@pytest.fixture()
+def created_message():
+ with session_scope() as session:
+ message = MessageCreate(text="Test message", sender="User", sender_name="User", session_id="session_id")
+ messagetable = MessageTable.model_validate(message, from_attributes=True)
+ messagetables = add_messagetables([messagetable], session)
+ message_read = MessageRead.model_validate(messagetables[0], from_attributes=True)
+ return message_read
+
+
+@pytest.fixture()
+def created_messages(session):
+ with session_scope() as session:
+ messages = [
+ MessageCreate(text="Test message 1", sender="User", sender_name="User", session_id="session_id2"),
+ MessageCreate(text="Test message 2", sender="User", sender_name="User", session_id="session_id2"),
+ MessageCreate(text="Test message 3", sender="User", sender_name="User", session_id="session_id2"),
+ ]
+ messagetables = [MessageTable.model_validate(message, from_attributes=True) for message in messages]
+ message_list = add_messagetables(messagetables, session)
+
+ return message_list
+
+
+def test_delete_messages(client: TestClient, created_messages, logged_in_headers):
+ response = client.request(
+ "DELETE", "api/v1/monitor/messages", json=[str(msg.id) for msg in created_messages], headers=logged_in_headers
+ )
+ assert response.status_code == 204, response.text
+ assert response.reason_phrase == "No Content"
+
+
+def test_update_message(client: TestClient, logged_in_headers, created_message):
+ message_id = created_message.id
+ message_update = MessageUpdate(text="Updated content")
+ response = client.put(
+ f"api/v1/monitor/messages/{message_id}", json=message_update.model_dump(), headers=logged_in_headers
+ )
+ assert response.status_code == 200, response.text
+ updated_message = MessageRead(**response.json())
+ assert updated_message.text == "Updated content"
+
+
+def test_update_message_not_found(client: TestClient, logged_in_headers):
+ non_existent_id = UUID("00000000-0000-0000-0000-000000000000")
+ message_update = MessageUpdate(text="Updated content")
+ response = client.put(
+ f"api/v1/monitor/messages/{non_existent_id}", json=message_update.model_dump(), headers=logged_in_headers
+ )
+ assert response.status_code == 404, response.text
+ assert response.json()["detail"] == "Message not found"
+
+
+def test_delete_messages_session(client: TestClient, created_messages, logged_in_headers):
+ session_id = "session_id2"
+ response = client.delete(f"api/v1/monitor/messages/session/{session_id}", headers=logged_in_headers)
+ assert response.status_code == 204
+ assert response.reason_phrase == "No Content"
+
+ assert len(created_messages) == 3
+ response = client.get("api/v1/monitor/messages", headers=logged_in_headers)
+ assert response.status_code == 200
+ assert len(response.json()) == 0
diff --git a/tests/unit/test_messages.py b/tests/unit/test_messages.py
new file mode 100644
index 000000000..198387db8
--- /dev/null
+++ b/tests/unit/test_messages.py
@@ -0,0 +1,72 @@
+import pytest
+
+from langflow.memory import add_messages, add_messagetables, delete_messages, get_messages, store_message
+from langflow.schema.message import Message
+
+# Assuming you have these imports available
+from langflow.services.database.models.message import MessageCreate, MessageRead
+from langflow.services.database.models.message.model import MessageTable
+from langflow.services.deps import session_scope
+
+
+@pytest.fixture()
+def created_message():
+ with session_scope() as session:
+ message = MessageCreate(text="Test message", sender="User", sender_name="User", session_id="session_id")
+ messagetable = MessageTable.model_validate(message, from_attributes=True)
+ messagetables = add_messagetables([messagetable], session)
+ message_read = MessageRead.model_validate(messagetables[0], from_attributes=True)
+ return message_read
+
+
+@pytest.fixture()
+def created_messages(session):
+ with session_scope() as session:
+ messages = [
+ MessageCreate(text="Test message 1", sender="User", sender_name="User", session_id="session_id2"),
+ MessageCreate(text="Test message 2", sender="User", sender_name="User", session_id="session_id2"),
+ MessageCreate(text="Test message 3", sender="User", sender_name="User", session_id="session_id2"),
+ ]
+ messagetables = [MessageTable.model_validate(message, from_attributes=True) for message in messages]
+ messagetables = add_messagetables(messagetables, session)
+ messages_read = [
+ MessageRead.model_validate(messagetable, from_attributes=True) for messagetable in messagetables
+ ]
+ return messages_read
+
+
+def test_get_messages(session):
+ add_messages(Message(text="Test message 1", sender="User", sender_name="User", session_id="session_id2"))
+ add_messages(Message(text="Test message 2", sender="User", sender_name="User", session_id="session_id2"))
+ messages = get_messages(sender="User", session_id="session_id2", limit=2)
+ assert len(messages) == 2
+ assert messages[0].text == "Test message 1"
+ assert messages[1].text == "Test message 2"
+
+
+def test_add_messages(session):
+ message = Message(text="New Test message", sender="User", sender_name="User", session_id="new_session_id")
+ messages = add_messages(message)
+ assert len(messages) == 1
+ assert messages[0].text == "New Test message"
+
+
+def test_add_messagetables(session):
+ messages = [MessageTable(text="New Test message", sender="User", sender_name="User", session_id="new_session_id")]
+ added_messages = add_messagetables(messages, session)
+ assert len(added_messages) == 1
+ assert added_messages[0].text == "New Test message"
+
+
+def test_delete_messages(session):
+ session_id = "session_id2"
+ delete_messages(session_id)
+ messages = session.query(MessageTable).filter(MessageTable.session_id == session_id).all()
+ assert len(messages) == 0
+
+
+def test_store_message(session):
+ message = Message(text="Stored message", sender="User", sender_name="User", session_id="stored_session_id")
+ stored_messages = store_message(message)
+ assert len(stored_messages) == 1
+ assert stored_messages[0].text == "Stored message"