feat: Move to Biome for linting and formatting (#8997)

* init biome

* lint

* format

* unused vars

* more unused vars

* error fixes

* import ordering

* test precommit hook

* add precommit hook

* [autofix.ci] apply automated fixes

* remove prettier and eslint and update gh actions

* pre-commit update

*  (Makefile): add new targets 'biome' and 'biome_check' to run biome check and format on frontend code.

* 🔧 (Makefile): rename 'biome' target to 'format_frontend' for clarity and consistency
🔧 (Makefile): rename 'biome_check' target to 'format_frontend_check' for clarity and consistency

* 📝 (biome.json): Update a11y rule in biome.json to turn off 'noStaticElementInteractions' warning
🔧 (apiModal/code-tabs.tsx): Remove unused 'autologin' variable in APITabsComponent
♻️ (global-variable-modal.tsx): Simplify GeneralGlobalVariableModal component by removing unused props definition

* 📝 (biome.json): Remove 'debug' from allowed console methods to improve code quality
🔧 (index.tsx): Replace console.debug with console.log for better logging consistency
♻️ (index.tsx): Refactor UpdateAllComponents function signature to remove unnecessary empty object parameter

* fix console rules

* 📝 (biome.json): update a11y rule to warn for noStaticElementInteractions to improve accessibility compliance.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: cristhianzl <cristhian.lousa@gmail.com>
This commit is contained in:
Mike Fortman 2025-07-15 13:46:51 -05:00 committed by GitHub
commit 0f89e39da1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
680 changed files with 2232 additions and 2671 deletions

View file

@ -37,7 +37,7 @@ jobs:
cd src/frontend
npm ci
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
- name: Run Prettier
- name: Run Biome
run: |
cd src/frontend
npm run format

View file

@ -15,7 +15,7 @@ env:
jobs:
run-linters:
name: Run Prettier
name: Run Biome
runs-on: ubuntu-latest
permissions:
contents: write
@ -47,7 +47,7 @@ jobs:
npm install
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
- name: Run Prettier
- name: Run Biome
run: |
cd src/frontend
npm run check-format
npx @biomejs/biome check --changed

View file

@ -25,3 +25,11 @@ repos:
language: system
types_or: [python, pyi]
args: [--config, pyproject.toml]
- repo: local
hooks:
- id: local-biome-check
name: biome check
entry: bash -c 'cd src/frontend && npx @biomejs/biome check --write --files-ignore-unknown=true --no-errors-on-unmatched'
language: system
types: [text]
files: "\\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$"

View file

@ -177,6 +177,14 @@ format_backend: ## backend code formatters
format: format_backend format_frontend ## run code formatters
format_frontend: ## run biome check and format on frontend code
@echo 'Running Biome check and format on frontend...'
@cd src/frontend && npx @biomejs/biome check --write
format_frontend_check: ## run biome check without formatting
@echo 'Running Biome check on frontend...'
@cd src/frontend && npx @biomejs/biome check
unsafe_fix:
@uv run ruff check . --fix --unsafe-fixes

View file

13
src/frontend/.biomeignore Normal file
View file

@ -0,0 +1,13 @@
# Build outputs
build/
dist/
# Dependencies
node_modules/
# Test outputs
coverage/
test-results/
playwright-report/
blob-report/
playwright/.cache/

View file

@ -1,47 +0,0 @@
{
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:prettier/recommended"
],
"plugins": ["react", "import-helpers", "prettier"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": ["./tsconfig.node.json", "./tsconfig.json"],
"extraFileExtensions:": [".mdx"],
"extensions:": [".mdx"]
},
"env": {
"browser": true,
"es2021": true
},
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"no-console": "warn",
"no-self-assign": "warn",
"no-self-compare": "warn",
"complexity": ["error", { "max": 15 }],
"indent": ["error", 2, { "SwitchCase": 1 }],
"no-dupe-keys": "error",
"no-invalid-regexp": "error",
"no-undef": "error",
"no-return-assign": "error",
"no-redeclare": "error",
"no-empty": "error",
"no-await-in-loop": "error",
"react/react-in-jsx-scope": 0,
"node/exports-style": ["error", "module.exports"],
"node/file-extension-in-import": ["error", "always"],
"node/prefer-global/buffer": ["error", "always"],
"node/prefer-global/console": ["error", "always"],
"node/prefer-global/process": ["error", "always"],
"node/prefer-global/url-search-params": ["error", "always"],
"node/prefer-global/url": ["error", "always"],
"node/prefer-promises/dns": "error",
"node/prefer-promises/fs": "error"
}
}

View file

@ -0,0 +1 @@
npm test

View file

@ -1 +0,0 @@
build/*

View file

@ -1,7 +0,0 @@
const config = {
plugins: ["prettier-plugin-organize-imports", "prettier-plugin-tailwindcss"],
tailwindConfig: "./tailwind.config.mjs",
organizeImportsSkipDestructiveCodeActions: true,
};
export default config;

90
src/frontend/biome.json Normal file
View file

@ -0,0 +1,90 @@
{
"$schema": "https://biomejs.dev/schemas/2.1.1/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true,
"defaultBranch": "main"
},
"files": { "ignoreUnknown": false },
"formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
"linter": {
"domains": {
"test": "recommended"
},
"enabled": true,
"rules": {
"recommended": false,
"a11y": { "noStaticElementInteractions": "warn" },
"complexity": {
"noAdjacentSpacesInRegex": "error",
"noExtraBooleanCast": "error",
"noUselessEscapeInRegex": "error"
},
"correctness": {
"noConstAssign": "error",
"noConstantCondition": "error",
"noEmptyCharacterClassInRegex": "error",
"noEmptyPattern": "warn",
"noGlobalObjectCalls": "error",
"noInvalidBuiltinInstantiation": "error",
"noInvalidConstructorSuper": "error",
"noNonoctalDecimalEscape": "error",
"noPrecisionLoss": "error",
"noSelfAssign": "warn",
"noSetterReturn": "error",
"noSwitchDeclarations": "error",
"noUnreachable": "error",
"noUnreachableSuper": "error",
"noUnsafeFinally": "error",
"noUnusedLabels": "error",
"noUnusedPrivateClassMembers": "error",
"noUnusedVariables": "warn",
"useExhaustiveDependencies": "off",
"useIsNan": "error",
"useValidForDirection": "error",
"useValidTypeof": "error",
"useYield": "error"
},
"suspicious": {
"noAssignInExpressions": "error",
"noAsyncPromiseExecutor": "warn",
"noCatchAssign": "error",
"noClassAssign": "error",
"noCompareNegZero": "error",
"noConsole": {
"level": "warn",
"options": {
"allow": ["error", "warn"]
}
},
"noControlCharactersInRegex": "error",
"noDebugger": "error",
"noDuplicateCase": "error",
"noDuplicateClassMembers": "error",
"noDuplicateElseIf": "error",
"noDuplicateObjectKeys": "error",
"noDuplicateParameters": "error",
"noFallthroughSwitchClause": "error",
"noFunctionAssign": "error",
"noGlobalAssign": "error",
"noImportAssign": "error",
"noIrregularWhitespace": "error",
"noMisleadingCharacterClass": "error",
"noPrototypeBuiltins": "error",
"noRedeclare": "error",
"noSelfCompare": "warn",
"noShadowRestrictedNames": "error",
"noSparseArray": "error",
"noUnsafeNegation": "error",
"noWith": "error",
"useGetterReturn": "error"
}
}
},
"javascript": { "formatter": { "quoteStyle": "double" } },
"assist": {
"enabled": true,
"actions": { "source": { "organizeImports": "on" } }
}
}

File diff suppressed because it is too large Load diff

View file

@ -96,16 +96,10 @@
"test": "jest",
"test:watch": "jest --watch",
"serve": "vite preview",
"format": "npx prettier --write \"{tests,src}/**/*.{js,jsx,ts,tsx,json,md}\" --ignore-path .prettierignore",
"check-format": "npx prettier --check \"{tests,src}/**/*.{js,jsx,ts,tsx,json,md}\" --ignore-path .prettierignore",
"format": "npx @biomejs/biome check --write",
"check-format": "npx @biomejs/biome check",
"type-check": "tsc --noEmit --pretty --project tsconfig.json && vite"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
@ -120,6 +114,7 @@
},
"proxy": "http://localhost:7860",
"devDependencies": {
"@biomejs/biome": "2.1.1",
"@jest/types": "^30.0.1",
"@playwright/test": "^1.52.0",
"@swc/cli": "^0.5.2",
@ -137,15 +132,10 @@
"@types/uuid": "^9.0.8",
"@vitejs/plugin-react-swc": "^3.7.0",
"autoprefixer": "^10.4.19",
"eslint": "^9.5.0",
"jest": "^30.0.3",
"jest-environment-jsdom": "^30.0.2",
"jest-junit": "^16.0.0",
"postcss": "^8.4.38",
"prettier": "^3.3.2",
"prettier-plugin-organize-imports": "^3.2.4",
"prettier-plugin-tailwindcss": "^0.6.5",
"simple-git-hooks": "^2.11.1",
"tailwindcss": "^3.4.4",
"tailwindcss-dotted-background": "^1.1.0",
"ts-jest": "^29.4.0",

View file

@ -2,6 +2,7 @@ import { defineConfig, devices } from "@playwright/test";
import * as dotenv from "dotenv";
import path from "path";
import { PORT } from "./src/customization/config-constants";
dotenv.config();
dotenv.config({ path: path.resolve(__dirname, "../../.env") });

View file

@ -112,12 +112,7 @@ body {
}
.custom-hover:hover {
background-color: rgba(
99,
102,
241,
0.1
); /* Medium indigo color with 20% opacity */
background-color: rgba(99, 102, 241, 0.1); /* Medium indigo color with 20% opacity */
}
/* This CSS is to not apply the border for the column having 'no-border' class */

View file

@ -1,6 +1,11 @@
import {
BaseEdge,
type EdgeProps,
getBezierPath,
Position,
} from "@xyflow/react";
import useFlowStore from "@/stores/flowStore";
import { scapeJSONParse } from "@/utils/reactflowUtils";
import { BaseEdge, EdgeProps, getBezierPath, Position } from "@xyflow/react";
export function DefaultEdge({
sourceHandleId,
@ -56,16 +61,7 @@ export function DefaultEdge({
targetY: targetYNew,
});
const {
animated,
selectable,
deletable,
sourcePosition,
targetPosition,
pathOptions,
selected,
...domSafeProps
} = props;
const { animated, selectable, deletable, selected, ...domSafeProps } = props;
return (
<BaseEdge

View file

@ -1,5 +1,5 @@
import { Button } from "@/components/ui/button";
import { useState } from "react";
import { Button } from "@/components/ui/button";
interface ComboBoxItemProps {
item: any;

View file

@ -1,7 +1,7 @@
import { useEffect, useRef, useState } from "react";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import { cn } from "@/utils/utils";
import { useEffect, useRef, useState } from "react";
const ListItem = ({
item,

View file

@ -1,12 +1,12 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import SearchBarComponent from "@/components/core/parameterRenderComponent/components/searchBarComponent";
import { InputProps } from "@/components/core/parameterRenderComponent/types";
import type { InputProps } from "@/components/core/parameterRenderComponent/types";
import { Button } from "@/components/ui/button";
import { DialogFooter, DialogHeader } from "@/components/ui/dialog";
import { Dialog, DialogContent } from "@/components/ui/dialog-with-no-close";
import { Input } from "@/components/ui/input";
import { cn, testIdCase } from "@/utils/utils";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import ListItem from "./ListItem";
// Update interface with better types

View file

@ -1,10 +1,10 @@
import { Textarea } from "@/components/ui/textarea";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import useFlowStore from "@/stores/flowStore";
import { handleKeyDown } from "@/utils/reactflowUtils";
import { cn } from "@/utils/utils";
import { memo, useEffect, useMemo, useRef, useState } from "react";
import Markdown from "react-markdown";
import { Textarea } from "@/components/ui/textarea";
import useFlowStore from "@/stores/flowStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { handleKeyDown } from "@/utils/reactflowUtils";
import { cn } from "@/utils/utils";
export default function NodeDescription({
description,

View file

@ -1,3 +1,5 @@
import { useState } from "react";
import { mutateTemplate } from "@/CustomNodes/helpers/mutate-template";
import { ParameterRenderComponent } from "@/components/core/parameterRenderComponent";
import { Button } from "@/components/ui/button";
import {
@ -11,11 +13,9 @@ import {
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
import { getCustomParameterTitle } from "@/customization/components/custom-parameter";
import { track } from "@/customization/utils/analytics";
import { mutateTemplate } from "@/CustomNodes/helpers/mutate-template";
import useAlertStore from "@/stores/alertStore";
import useFlowStore from "@/stores/flowStore";
import { APIClassType, InputFieldType } from "@/types/api";
import { useState } from "react";
import type { APIClassType, InputFieldType } from "@/types/api";
interface NodeDialogProps {
open: boolean;

View file

@ -1,5 +1,7 @@
import { useEffect, useMemo, useRef } from "react";
import { useShallow } from "zustand/react/shallow";
import useHandleNodeClass from "@/CustomNodes/hooks/use-handle-node-class";
import { NodeInfoType } from "@/components/core/parameterRenderComponent/types";
import type { NodeInfoType } from "@/components/core/parameterRenderComponent/types";
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
import {
CustomParameterComponent,
@ -9,8 +11,6 @@ import {
import { useIsAutoLogin } from "@/hooks/use-is-auto-login";
import useAuthStore from "@/stores/authStore";
import { cn } from "@/utils/utils";
import { useEffect, useMemo, useRef } from "react";
import { useShallow } from "zustand/react/shallow";
import { default as IconComponent } from "../../../../components/common/genericIconComponent";
import ShadTooltip from "../../../../components/common/shadTooltipComponent";
import {
@ -22,11 +22,11 @@ import {
} from "../../../../constants/constants";
import useFlowStore from "../../../../stores/flowStore";
import { useTypesStore } from "../../../../stores/typesStore";
import { NodeInputFieldComponentType } from "../../../../types/components";
import type { NodeInputFieldComponentType } from "../../../../types/components";
import useFetchDataOnMount from "../../../hooks/use-fetch-data-on-mount";
import useHandleOnNewValue from "../../../hooks/use-handle-new-value";
import NodeInputInfo from "../NodeInputInfo";
import HandleRenderComponent from "../handleRenderComponent";
import NodeInputInfo from "../NodeInputInfo";
export default function NodeInputField({
id,

View file

@ -1,10 +1,10 @@
import { useEffect, useState } from "react";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { Input } from "@/components/ui/input";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import useFlowStore from "@/stores/flowStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { cn } from "@/utils/utils";
import { useEffect, useState } from "react";
export default function NodeName({
display_name,

View file

@ -1,4 +1,4 @@
import { NodeDataType } from "@/types/flow";
import type { NodeDataType } from "@/types/flow";
import { OutputParameter } from ".";
export default function NodeOutputs({

View file

@ -1,7 +1,3 @@
import { Badge } from "@/components/ui/badge";
import { ICON_STROKE_WIDTH } from "@/constants/constants";
import { useShortcutsStore } from "@/stores/shortcuts";
import { targetHandleType } from "@/types/flow";
import { useUpdateNodeInternals } from "@xyflow/react";
import { cloneDeep } from "lodash";
import {
@ -14,6 +10,10 @@ import {
useState,
} from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { Badge } from "@/components/ui/badge";
import { ICON_STROKE_WIDTH } from "@/constants/constants";
import { useShortcutsStore } from "@/stores/shortcuts";
import type { targetHandleType } from "@/types/flow";
import ForwardedIconComponent, {
default as IconComponent,
} from "../../../../components/common/genericIconComponent";
@ -21,7 +21,7 @@ import ShadTooltip from "../../../../components/common/shadTooltipComponent";
import { Button } from "../../../../components/ui/button";
import useFlowStore from "../../../../stores/flowStore";
import { useTypesStore } from "../../../../stores/typesStore";
import { NodeOutputFieldComponentType } from "../../../../types/components";
import type { NodeOutputFieldComponentType } from "../../../../types/components";
import {
getGroupOutputNodeId,
scapedJSONStringfy,
@ -34,11 +34,11 @@ import {
logTypeIsError,
logTypeIsUnknown,
} from "../../../../utils/utils";
import OutputComponent from "../OutputComponent";
import HandleRenderComponent from "../handleRenderComponent";
import OutputComponent from "../OutputComponent";
import OutputModal from "../outputModal";
const EyeIcon = memo(
const _EyeIcon = memo(
({ hidden, className }: { hidden: boolean; className: string }) => (
<IconComponent
className={className}
@ -195,7 +195,7 @@ function NodeOutputField({
(value?: boolean) => {
setNode(data.id, (oldNode) => {
if (oldNode.type !== "genericNode") return oldNode;
let newNode = cloneDeep(oldNode);
const newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
node: {

View file

@ -1,3 +1,10 @@
import { useEffect, useRef, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { getSpecificClassFromBuildStatus } from "@/CustomNodes/helpers/get-class-from-build-status";
import { mutateTemplate } from "@/CustomNodes/helpers/mutate-template";
import useIconStatus from "@/CustomNodes/hooks/use-icons-status";
import useUpdateValidationStatus from "@/CustomNodes/hooks/use-update-validation-status";
import useValidationStatusString from "@/CustomNodes/hooks/use-validation-status-string";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { Button } from "@/components/ui/button";
import { ICON_STROKE_WIDTH } from "@/constants/constants";
@ -5,25 +12,19 @@ import { BuildStatus } from "@/constants/enums";
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
import { track } from "@/customization/utils/analytics";
import { customOpenNewTab } from "@/customization/utils/custom-open-new-tab";
import { getSpecificClassFromBuildStatus } from "@/CustomNodes/helpers/get-class-from-build-status";
import { mutateTemplate } from "@/CustomNodes/helpers/mutate-template";
import useIconStatus from "@/CustomNodes/hooks/use-icons-status";
import useUpdateValidationStatus from "@/CustomNodes/hooks/use-update-validation-status";
import useValidationStatusString from "@/CustomNodes/hooks/use-validation-status-string";
import useAlertStore from "@/stores/alertStore";
import { useDarkStore } from "@/stores/darkStore";
import useFlowStore from "@/stores/flowStore";
import { useShortcutsStore } from "@/stores/shortcuts";
import { useUtilityStore } from "@/stores/utilityStore";
import { VertexBuildTypeAPI } from "@/types/api";
import { NodeDataType } from "@/types/flow";
import type { VertexBuildTypeAPI } from "@/types/api";
import type { NodeDataType } from "@/types/flow";
import { findLastNode } from "@/utils/reactflowUtils";
import { classNames, cn } from "@/utils/utils";
import { useEffect, useRef, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import IconComponent from "../../../../components/common/genericIconComponent";
import BuildStatusDisplay from "./components/build-status-display";
import { normalizeTimeString } from "./utils/format-run-time";
const POLLING_TIMEOUT = 21000;
const POLLING_INTERVAL = 3000;
@ -188,12 +189,12 @@ export default function NodeStatus({
);
const getBaseBorderClass = (selected) => {
let className =
const className =
selected && !isBuilding
? " border ring-[0.75px] ring-muted-foreground border-muted-foreground hover:shadow-node"
: "border ring-[0.5px] hover:shadow-node ring-border";
let frozenClass = selected ? "border-ring-frozen" : "border-frozen";
let updateClass =
const frozenClass = selected ? "border-ring-frozen" : "border-frozen";
const updateClass =
isOutdated && !isUserEdited && !dismissAll && isBreakingChange
? "border-warning"
: "";

View file

@ -1,3 +1,4 @@
import { useRef } from "react";
import { ForwardedIconComponent } from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import {
@ -6,16 +7,14 @@ import {
CommandItem,
CommandList,
} from "@/components/ui/command";
import {
Popover,
PopoverContentWithoutPortal,
PopoverTrigger,
} from "@/components/ui/popover";
import useFlowStore from "@/stores/flowStore";
import { useRef } from "react";
import ShadTooltip from "../../../../components/common/shadTooltipComponent";
import { outputComponentType } from "../../../../types/components";
import type { outputComponentType } from "../../../../types/components";
import { cn } from "../../../../utils/utils";
export default function OutputComponent({

View file

@ -1,9 +1,9 @@
import { useMemo } from "react";
import { getNodeInputColors } from "@/CustomNodes/helpers/get-node-input-colors";
import { getNodeInputColorsName } from "@/CustomNodes/helpers/get-node-input-colors-name";
import { sortToolModeFields } from "@/CustomNodes/helpers/sort-tool-mode-field";
import getFieldTitle from "@/CustomNodes/utils/get-field-title";
import { scapedJSONStringfy } from "@/utils/reactflowUtils";
import { useMemo } from "react";
import NodeInputField from "../NodeInputField";
const RenderInputParameters = ({

View file

@ -1,9 +1,9 @@
import { type Connection, Handle, Position } from "@xyflow/react";
import { memo, useCallback, useEffect, useMemo, useState } from "react";
import { useShallow } from "zustand/react/shallow";
import { useDarkStore } from "@/stores/darkStore";
import useFlowStore from "@/stores/flowStore";
import { nodeColorsName } from "@/utils/styleUtils";
import { Connection, Handle, Position } from "@xyflow/react";
import { memo, useCallback, useEffect, useMemo, useState } from "react";
import { useShallow } from "zustand/react/shallow";
import ShadTooltip from "../../../../components/common/shadTooltipComponent";
import {
isValidConnection,

View file

@ -1,10 +1,9 @@
import { useTypesStore } from "@/stores/typesStore";
import { iconExists, nodeColors } from "@/utils/styleUtils";
import emojiRegex from "emoji-regex";
import { useEffect, useState } from "react";
import { ICON_STROKE_WIDTH } from "@/constants/constants";
import { checkLucideIcons } from "@/CustomNodes/helpers/check-lucide-icons";
import { ICON_STROKE_WIDTH } from "@/constants/constants";
import { useTypesStore } from "@/stores/typesStore";
import { iconExists, nodeColors } from "@/utils/styleUtils";
import IconComponent from "../../../../components/common/genericIconComponent";
export function NodeIcon({

View file

@ -1,7 +1,7 @@
import { useMemo } from "react";
import JsonOutputViewComponent from "@/components/core/jsonOutputComponent/json-output-view";
import { MAX_TEXT_LENGTH } from "@/constants/constants";
import { LogsLogType, OutputLogType } from "@/types/api";
import { useMemo } from "react";
import type { LogsLogType, OutputLogType } from "@/types/api";
import ForwardedIconComponent from "../../../../../../components/common/genericIconComponent";
import DataOutputComponent from "../../../../../../components/core/dataOutputComponent";
import {
@ -13,6 +13,7 @@ import { Case } from "../../../../../../shared/components/caseComponent";
import TextOutputView from "../../../../../../shared/components/textOutputView";
import useFlowStore from "../../../../../../stores/flowStore";
import ErrorOutput from "./components";
// Define the props type
interface SwitchOutputViewProps {
nodeId: string;
@ -31,7 +32,7 @@ const SwitchOutputView: React.FC<SwitchOutputViewProps> = ({
(flowPool[nodeId]?.length ?? 1) - 1
];
let results: OutputLogType | LogsLogType =
const results: OutputLogType | LogsLogType =
(type === "Outputs"
? flowPoolNode?.data?.outputs?.[outputName]
: flowPoolNode?.data?.logs?.[outputName]) ?? {};

View file

@ -1,5 +1,5 @@
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { useState } from "react";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import BaseModal from "../../../../modals/baseModal";
import SwitchOutputView from "./components/switchOutputView";

View file

@ -1,6 +1,6 @@
import { BuildStatus } from "@/constants/enums";
import useFlowStore from "@/stores/flowStore";
import { NodeDataType } from "@/types/flow";
import type { NodeDataType } from "@/types/flow";
export const useBuildStatus = (data: NodeDataType, nodeId: string) => {
return useFlowStore((state) => {

View file

@ -1,15 +1,15 @@
import { useUpdateNodeInternals } from "@xyflow/react";
import { cloneDeep } from "lodash";
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { useShallow } from "zustand/react/shallow";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { usePostValidateComponentCode } from "@/controllers/API/queries/nodes/use-post-validate-component-code";
import { CustomNodeStatus } from "@/customization/components/custom-NodeStatus";
import UpdateComponentModal from "@/modals/updateComponentModal";
import { useAlternate } from "@/shared/hooks/use-alternate";
import { FlowStoreType } from "@/types/zustand/flow";
import { useUpdateNodeInternals } from "@xyflow/react";
import { cloneDeep } from "lodash";
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { useShallow } from "zustand/react/shallow";
import type { FlowStoreType } from "@/types/zustand/flow";
import { Button } from "../../components/ui/button";
import {
ICON_STROKE_WIDTH,
@ -23,8 +23,8 @@ import useFlowStore from "../../stores/flowStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { useShortcutsStore } from "../../stores/shortcuts";
import { useTypesStore } from "../../stores/typesStore";
import { OutputFieldType, VertexBuildTypeAPI } from "../../types/api";
import { NodeDataType } from "../../types/flow";
import type { OutputFieldType, VertexBuildTypeAPI } from "../../types/api";
import type { NodeDataType } from "../../types/flow";
import { scapedJSONStringfy } from "../../utils/reactflowUtils";
import { classNames, cn } from "../../utils/utils";
import { processNodeAdvancedFields } from "../helpers/process-node-advanced-fields";
@ -33,8 +33,8 @@ import NodeDescription from "./components/NodeDescription";
import NodeName from "./components/NodeName";
import NodeOutputs from "./components/NodeOutputParameter/NodeOutputs";
import NodeUpdateComponent from "./components/NodeUpdateComponent";
import RenderInputParameters from "./components/RenderInputParameters";
import { NodeIcon } from "./components/nodeIcon";
import RenderInputParameters from "./components/RenderInputParameters";
import { useBuildStatus } from "./hooks/use-get-build-status";
const MemoizedRenderInputParameters = memo(RenderInputParameters);
@ -44,7 +44,7 @@ const MemoizedNodeStatus = memo(CustomNodeStatus);
const MemoizedNodeDescription = memo(NodeDescription);
const MemoizedNodeOutputs = memo(NodeOutputs);
const HiddenOutputsButton = memo(
const _HiddenOutputsButton = memo(
({
showHiddenOutputs,
onClick,
@ -77,7 +77,7 @@ function GenericNode({
const [borderColor, setBorderColor] = useState<string>("");
const [loadingUpdate, setLoadingUpdate] = useState(false);
const [showHiddenOutputs, setShowHiddenOutputs] = useState(false);
const [validationStatus, setValidationStatus] =
const [_validationStatus, setValidationStatus] =
useState<VertexBuildTypeAPI | null>(null);
const [openUpdateModal, setOpenUpdateModal] = useState(false);

View file

@ -1,3 +1,5 @@
import { cloneDeep } from "lodash";
import { memo, useCallback, useMemo } from "react";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import {
Popover,
@ -11,10 +13,8 @@ import useAlertStore from "@/stores/alertStore";
import useFlowStore from "@/stores/flowStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { useShortcutsStore } from "@/stores/shortcuts";
import { NoteDataType } from "@/types/flow";
import type { NoteDataType } from "@/types/flow";
import { classNames, cn } from "@/utils/utils";
import { cloneDeep } from "lodash";
import { memo, useCallback, useMemo } from "react";
import IconComponent from "../../../components/common/genericIconComponent";
import { ColorPickerButtons } from "../components/color-picker-buttons";
import { SelectItems } from "../components/select-items";
@ -65,10 +65,11 @@ const NoteToolbarComponent = memo(function NoteToolbarComponent({
takeSnapshot();
deleteNode(data.id);
break;
case "copy":
case "copy": {
const node = nodes.filter((node) => node.id === data.id);
setLastCopiedSelection({ nodes: cloneDeep(node), edges: [] });
break;
}
case "duplicate":
paste(
{

View file

@ -1,10 +1,9 @@
import { memo } from "react";
import { Button } from "@/components/ui/button";
import { COLOR_OPTIONS } from "@/constants/constants";
import { noteDataType } from "@/types/flow";
import type { noteDataType } from "@/types/flow";
import { cn } from "@/utils/utils";
import { memo } from "react";
export const ColorPickerButtons = memo(
({
bgColor,

View file

@ -1,12 +1,11 @@
import { memo } from "react";
import { ForwardedIconComponent } from "@/components/common/genericIconComponent";
import {
SelectContentWithoutPortal,
SelectItem,
} from "@/components/ui/select-custom";
import ToolbarSelectItem from "@/pages/FlowPage/components/nodeToolbarComponent/toolbarSelectItem";
import { NoteDataType } from "@/types/flow";
import { memo } from "react";
import type { NoteDataType } from "@/types/flow";
export const SelectItems = memo(
({ shortcuts, data }: { shortcuts: any[]; data: NoteDataType }) => (

View file

@ -1,3 +1,6 @@
import { NodeResizer } from "@xyflow/react";
import { debounce } from "lodash";
import { useMemo, useRef, useState } from "react";
import {
COLOR_OPTIONS,
NOTE_NODE_MAX_HEIGHT,
@ -7,15 +10,11 @@ import {
} from "@/constants/constants";
import { useAlternate } from "@/shared/hooks/use-alternate";
import useFlowStore from "@/stores/flowStore";
import { NoteDataType } from "@/types/flow";
import type { NoteDataType } from "@/types/flow";
import { cn } from "@/utils/utils";
import { NodeResizer } from "@xyflow/react";
import { debounce } from "lodash";
import { useEffect, useMemo, useRef, useState } from "react";
import NodeDescription from "../GenericNode/components/NodeDescription";
import NoteToolbarComponent from "./NoteToolbarComponent";
const NOTE_NODE_PADDING = 25;
const CHAR_LIMIT = 2500;
const DEFAULT_WIDTH = 324;
const DEFAULT_HEIGHT = 324;
@ -32,7 +31,7 @@ function NoteNode({
(key) => key === data.node?.template.backgroundColor,
) ?? Object.keys(COLOR_OPTIONS)[0];
const nodeDiv = useRef<HTMLDivElement>(null);
const [resizedNote, setResizedNote] = useState(false);
const [_resizedNote, setResizedNote] = useState(false);
const currentFlow = useFlowStore((state) => state.currentFlow);
const setNode = useFlowStore((state) => state.setNode);
const [isResizing, setIsResizing] = useState(false);

View file

@ -1,6 +1,6 @@
import { componentsToIgnoreUpdate } from "@/constants/constants";
import { OutputFieldType } from "@/types/api";
import { NodeDataType } from "../../types/flow";
import type { OutputFieldType } from "@/types/api";
import type { NodeDataType } from "../../types/flow";
// Returns true if the code is outdated (code string changed and not ignored)
const codeIsOutdated = (

View file

@ -1,6 +1,6 @@
import { categoryIcons } from "@/utils/styleUtils";
import * as lucideIcons from "lucide-react";
import dynamicIconImports from "lucide-react/dynamicIconImports";
import { categoryIcons } from "@/utils/styleUtils";
export const checkLucideIcons = (iconName: string): boolean => {
return (

View file

@ -1,7 +1,7 @@
import { NodeDataType } from "../../types/flow";
import type { NodeDataType } from "../../types/flow";
export function countHandlesFn(data: NodeDataType): number {
let count = Object.keys(data.node!.template)
const count = Object.keys(data.node!.template)
.filter(
(templateField) =>
templateField.charAt(0) !== "_" &&

View file

@ -1,12 +1,12 @@
import { BuildStatus } from "../../constants/enums";
import { VertexBuildTypeAPI } from "../../types/api";
import type { VertexBuildTypeAPI } from "../../types/api";
export const getSpecificClassFromBuildStatus = (
buildStatus: BuildStatus | undefined,
validationStatus: VertexBuildTypeAPI | null,
isBuilding: boolean,
): string => {
let isInvalid = validationStatus && !validationStatus.valid;
const isInvalid = validationStatus && !validationStatus.valid;
if (BuildStatus.BUILDING === buildStatus) {
return "border-foreground border-[1px] ring-[0.75px] ring-foreground";

View file

@ -1,5 +1,5 @@
import { OutputFieldType } from "../../types/api";
import { NodeDataType } from "../../types/flow";
import type { OutputFieldType } from "../../types/api";
import type { NodeDataType } from "../../types/flow";
import { nodeColorsName } from "../../utils/styleUtils";
export function getNodeOutputColorsName(

View file

@ -1,5 +1,5 @@
import { OutputFieldType } from "../../types/api";
import { NodeDataType } from "../../types/flow";
import type { OutputFieldType } from "../../types/api";
import type { NodeDataType } from "../../types/flow";
import { nodeColors } from "../../utils/styleUtils";
export function getNodeOutputColors(

View file

@ -1,11 +1,11 @@
import type { UseMutationResult } from "@tanstack/react-query";
import { cloneDeep, debounce } from "lodash";
import {
ERROR_UPDATING_COMPONENT,
SAVE_DEBOUNCE_TIME,
TITLE_ERROR_UPDATING_COMPONENT,
} from "@/constants/constants";
import { APIClassType, ResponseErrorDetailAPI } from "@/types/api";
import { UseMutationResult } from "@tanstack/react-query";
import { cloneDeep, debounce } from "lodash";
import type { APIClassType, ResponseErrorDetailAPI } from "@/types/api";
import { updateHiddenOutputs } from "./update-hidden-outputs";
// Map to store debounced functions for each node ID
@ -64,7 +64,7 @@ export const mutateTemplate = async (
setNodeClass(newNode);
} catch (e) {
if (e instanceof Error && e.message === "Node not found") {
console.log("Node not found");
console.error("Node not found");
} else {
throw e;
}

View file

@ -1,13 +1,13 @@
import { APIClassType } from "@/types/api";
import { EdgeType } from "@/types/flow";
import { cloneDeep } from "lodash";
import type { APIClassType } from "@/types/api";
import type { EdgeType } from "@/types/flow";
export function processNodeAdvancedFields(
resData: APIClassType,
edges: EdgeType[],
nodeId: string,
) {
let newNode = cloneDeep(resData);
const newNode = cloneDeep(resData);
const relevantEdges = edges.filter(
(edge) => edge.source !== nodeId || edge.target !== nodeId,

View file

@ -1,4 +1,4 @@
import { OutputFieldType } from "@/types/api";
import type { OutputFieldType } from "@/types/api";
export const updateHiddenOutputs = (
outputs: OutputFieldType[],

View file

@ -1,6 +1,6 @@
import { APIClassType, ResponseErrorDetailAPI } from "@/types/api";
import { UseMutationResult } from "@tanstack/react-query";
import type { UseMutationResult } from "@tanstack/react-query";
import { useEffect } from "react";
import type { APIClassType, ResponseErrorDetailAPI } from "@/types/api";
import useAlertStore from "../../stores/alertStore";
import { mutateTemplate } from "../helpers/mutate-template";

View file

@ -1,14 +1,14 @@
import { useUpdateNodeInternals } from "@xyflow/react";
import { cloneDeep, debounce } from "lodash";
import { useCallback, useMemo, useRef } from "react";
import { DEBOUNCE_FIELD_LIST } from "@/constants/constants";
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
import { track } from "@/customization/utils/analytics";
import useAlertStore from "@/stores/alertStore";
import useFlowStore from "@/stores/flowStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { APIClassType, InputFieldType } from "@/types/api";
import { AllNodeType } from "@/types/flow";
import { useUpdateNodeInternals } from "@xyflow/react";
import { cloneDeep, debounce } from "lodash";
import { useCallback, useMemo, useRef } from "react";
import type { APIClassType, InputFieldType } from "@/types/api";
import type { AllNodeType } from "@/types/flow";
import { mutateTemplate } from "../helpers/mutate-template";
const DEBOUNCE_TIME_1_SECOND = 1000;

View file

@ -1,7 +1,7 @@
import useFlowStore from "@/stores/flowStore";
import { AllNodeType } from "@/types/flow";
import { useUpdateNodeInternals } from "@xyflow/react";
import { cloneDeep } from "lodash";
import useFlowStore from "@/stores/flowStore";
import type { AllNodeType } from "@/types/flow";
const useHandleNodeClass = (
nodeId: string,
@ -15,7 +15,7 @@ const useHandleNodeClass = (
const handleNodeClass = (newNodeClass, type?: string) => {
setNode(nodeId, (oldNode) => {
let newNode = cloneDeep(oldNode);
const newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,

View file

@ -1,4 +1,4 @@
import { MutableRefObject, useEffect, useRef } from "react";
import { type MutableRefObject, useEffect, useRef } from "react";
type Ref<T> = MutableRefObject<T | null> | ((instance: T | null) => void);

View file

@ -1,7 +1,7 @@
import { AllNodeType } from "@/types/flow";
import { cloneDeep } from "lodash";
import { useCallback } from "react";
import { APIClassType, OutputFieldType } from "../../types/api";
import type { AllNodeType } from "@/types/flow";
import { type APIClassType, OutputFieldType } from "../../types/api";
import { updateHiddenOutputs } from "../helpers/update-hidden-outputs";
export type UpdateNodesType = {

View file

@ -1,7 +1,7 @@
import useFlowStore from "@/stores/flowStore";
import { cloneDeep } from "lodash"; // or any other deep cloning library you prefer
import { useCallback } from "react";
import { APIClassType } from "../../types/api";
import useFlowStore from "@/stores/flowStore";
import type { APIClassType } from "../../types/api";
import { updateHiddenOutputs } from "../helpers/update-hidden-outputs";
const useUpdateNodeCode = (
@ -15,7 +15,7 @@ const useUpdateNodeCode = (
const updateNodeCode = useCallback(
(newNodeClass: APIClassType, code: string, name: string, type: string) => {
setNode(dataId, (oldNode) => {
let newNode = cloneDeep(oldNode);
const newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,

View file

@ -1,6 +1,6 @@
import { VertexBuildTypeAPI } from "@/types/api";
import { useEffect } from "react";
import { FlowPoolType } from "../../types/zustand/flow";
import type { VertexBuildTypeAPI } from "@/types/api";
import type { FlowPoolType } from "../../types/zustand/flow";
const useUpdateValidationStatus = (
dataId: string,

View file

@ -1,5 +1,5 @@
import { useEffect } from "react";
import { VertexBuildTypeAPI } from "../../types/api";
import type { VertexBuildTypeAPI } from "../../types/api";
import { isErrorLog } from "../../types/utils/typeCheckingUtils";
const useValidationStatusString = (

View file

@ -1,4 +1,4 @@
import { APITemplateType } from "../../types/api";
import type { APITemplateType } from "../../types/api";
export default function getFieldTitle(
template: APITemplateType,

View file

@ -1,4 +1,4 @@
import { sourceHandleType, targetHandleType } from "@/types/flow";
import type { sourceHandleType, targetHandleType } from "@/types/flow";
import { scapedJSONStringfy } from "@/utils/reactflowUtils";
export function getRightHandleId({

View file

@ -1,15 +1,15 @@
import { CustomLink } from "@/customization/components/custom-link";
import { useState } from "react";
import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { CustomLink } from "@/customization/components/custom-link";
import IconComponent from "../../../../components/common/genericIconComponent";
import { SingleAlertComponentType } from "../../../../types/alerts";
import type { SingleAlertComponentType } from "../../../../types/alerts";
export default function SingleAlert({
dropItem,
removeAlert,
}: SingleAlertComponentType): JSX.Element {
const [show, setShow] = useState(true);
const [_show, setShow] = useState(true);
const type = dropItem.type;
return type === "error" ? (

View file

@ -8,7 +8,7 @@ import {
} from "../../components/ui/popover";
import { ZERO_NOTIFICATIONS } from "../../constants/constants";
import useAlertStore from "../../stores/alertStore";
import { AlertDropdownType } from "../../types/alerts";
import type { AlertDropdownType } from "../../types/alerts";
import SingleAlert from "./components/singleAlertComponent";
const AlertDropdown = forwardRef<HTMLDivElement, AlertDropdownType>(

View file

@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
import IconComponent from "../../components/common/genericIconComponent";
import { ErrorAlertType } from "../../types/alerts";
import type { ErrorAlertType } from "../../types/alerts";
export default function ErrorAlert({
title,

View file

@ -1,10 +1,10 @@
import { CustomLink } from "@/customization/components/custom-link";
import { Transition } from "@headlessui/react";
import { useEffect, useState } from "react";
import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { CustomLink } from "@/customization/components/custom-link";
import IconComponent from "../../components/common/genericIconComponent";
import { NoticeAlertType } from "../../types/alerts";
import type { NoticeAlertType } from "../../types/alerts";
export default function NoticeAlert({
title,

View file

@ -1,7 +1,7 @@
import { Transition } from "@headlessui/react";
import { useEffect, useState } from "react";
import IconComponent from "../../components/common/genericIconComponent";
import { SuccessAlertType } from "../../types/alerts";
import type { SuccessAlertType } from "../../types/alerts";
export default function SuccessAlert({
title,

View file

@ -1,9 +0,0 @@
type RawComponentProps = {};
const RawComponent = ({}: RawComponentProps) => {
return (
<>
<div>RawComponent</div>
</>
);
};
export default RawComponent;

View file

@ -1,8 +1,8 @@
import { useContext } from "react";
import { AuthContext } from "@/contexts/authContext";
import { CustomNavigate } from "@/customization/components/custom-navigate";
import { LoadingPage } from "@/pages/LoadingPage";
import useAuthStore from "@/stores/authStore";
import { useContext } from "react";
export const ProtectedAdminRoute = ({ children }) => {
const { userData } = useContext(AuthContext);

View file

@ -1,3 +1,4 @@
import { useEffect } from "react";
import {
IS_AUTO_LOGIN,
LANGFLOW_ACCESS_TOKEN_EXPIRE_SECONDS,
@ -6,7 +7,6 @@ import {
import { useRefreshAccessToken } from "@/controllers/API/queries/auth";
import { CustomNavigate } from "@/customization/components/custom-navigate";
import useAuthStore from "@/stores/authStore";
import { useEffect } from "react";
export const ProtectedRoute = ({ children }) => {
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);

View file

@ -1,4 +1,4 @@
import { ReactNode } from "react";
import type { ReactNode } from "react";
export function GradientWrapper({ children }: { children: ReactNode }) {
return (

View file

@ -11,9 +11,9 @@ import ForwardedIconComponent from "../genericIconComponent";
export default function ImageViewer({ image }: { image: string }) {
const viewerRef = useRef(null);
const [errorDownloading, setErrordownloading] = useState(false);
const [_errorDownloading, _setErrordownloading] = useState(false);
const setErrorList = useAlertStore((state) => state.setErrorData);
const [initialMsg, setInicialMsg] = useState("Please build your flow");
const [_initialMsg, _setInicialMsg] = useState("Please build your flow");
useEffect(() => {
try {

View file

@ -1,12 +1,12 @@
import { useState } from "react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
import { AccordionComponentType } from "@/types/components";
import type { AccordionComponentType } from "@/types/components";
import { cn } from "@/utils/utils";
import { useState } from "react";
export default function AccordionComponent({
trigger,

View file

@ -1,6 +1,11 @@
import { cn } from "@/utils/utils";
import { motion, SpringOptions, useSpring, useTransform } from "framer-motion";
import {
motion,
type SpringOptions,
useSpring,
useTransform,
} from "framer-motion";
import { useEffect, useState } from "react";
import { cn } from "@/utils/utils";
type AnimatedNumberProps = {
value: number;

View file

@ -1,5 +1,5 @@
import { XCircle } from "lucide-react";
import { crashComponentPropsType } from "../../../types/components";
import type { crashComponentPropsType } from "../../../types/components";
import { Button } from "../../ui/button";
import { Card, CardContent, CardFooter, CardHeader } from "../../ui/card";

View file

@ -1,5 +1,5 @@
import BaseModal from "../../../modals/baseModal";
import { fetchErrorComponentType } from "../../../types/components";
import type { fetchErrorComponentType } from "../../../types/components";
import IconComponent from "../genericIconComponent";
export default function FetchErrorComponent({

View file

@ -1,11 +1,16 @@
import React, { Suspense, forwardRef, memo } from "react";
import { IconComponentProps } from "../../../types/components";
import React, {
forwardRef,
memo,
Suspense,
useCallback,
useEffect,
useState,
} from "react";
import { Skeleton } from "@/components/ui/skeleton";
import type { IconComponentProps } from "../../../types/components";
import { getCachedIcon, getNodeIcon } from "../../../utils/styleUtils";
import { cn } from "../../../utils/utils";
import { Skeleton } from "@/components/ui/skeleton";
import { useCallback, useEffect, useState } from "react";
export const ForwardedIconComponent = memo(
forwardRef(
(

View file

@ -1,4 +1,4 @@
import { LoadingComponentProps } from "../../../types/components";
import type { LoadingComponentProps } from "../../../types/components";
export default function LoadingComponent({
remSize,

View file

@ -11,11 +11,11 @@ export default function ObjectRender({
if (typeof object === "string") {
try {
newObject = JSON.parse(object);
} catch (e) {
} catch (_e) {
newObject = object;
}
}
let preview =
const preview =
newObject === null || newObject === undefined
? ""
: JSON.stringify(newObject);

View file

@ -1,6 +1,6 @@
import type { To } from "react-router-dom";
import { CustomBanner } from "@/customization/components/custom-banner";
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
import { To } from "react-router-dom";
import { Button } from "../../ui/button";
import { Separator } from "../../ui/separator";
import ForwardedIconComponent from "../genericIconComponent";

View file

@ -1,10 +1,10 @@
import { useEffect, useState } from "react";
import {
PAGINATION_PAGE,
PAGINATION_ROWS_COUNT,
PAGINATION_SIZE,
} from "@/constants/constants";
import { useEffect, useState } from "react";
import { PaginatorComponentType } from "../../../types/components";
import type { PaginatorComponentType } from "../../../types/components";
import IconComponent from "../../common/genericIconComponent";
import { Button } from "../../ui/button";
import {
@ -36,7 +36,7 @@ export default function PaginatorComponent({
const disableFirstPage = pageIndex <= 1;
const disableLastPage = pageIndex === maxIndex;
const handleValueChange = (pageSize: string) => {
const _handleValueChange = (pageSize: string) => {
setPageSize(Number(pageSize));
setMaxPageIndex(pages ?? Math.ceil(totalRowsCount / Number(pageSize)));
paginate(1, Number(pageSize));

View file

@ -1,7 +1,7 @@
import { cn } from "@/utils/utils";
import DOMPurify from "dompurify";
import { forwardRef } from "react";
import { SanitizedHTMLWrapperType } from "../../../types/components";
import { cn } from "@/utils/utils";
import type { SanitizedHTMLWrapperType } from "../../../types/components";
const SanitizedHTMLWrapper = forwardRef<
HTMLDivElement,

View file

@ -1,5 +1,6 @@
import React, { forwardRef, memo, useMemo } from "react";
import { ShadToolTipType } from "../../../types/components";
import type React from "react";
import { forwardRef, memo, useMemo } from "react";
import type { ShadToolTipType } from "../../../types/components";
import { cn } from "../../../utils/utils";
import { Tooltip, TooltipContent, TooltipTrigger } from "../../ui/tooltip";

View file

@ -1,5 +1,5 @@
import { useEffect } from "react";
import { storeComponent } from "../../../../types/store";
import type { storeComponent } from "../../../../types/store";
const useDataEffect = (
data: storeComponent,

View file

@ -1,6 +1,6 @@
import useAddFlow from "@/hooks/flows/use-add-flow";
import { getComponent } from "../../../../controllers/API";
import { storeComponent } from "../../../../types/store";
import type { storeComponent } from "../../../../types/store";
import cloneFlowWithParent from "../../../../utils/storeUtils";
const useInstallComponent = (

View file

@ -1,10 +1,10 @@
import { usePostLikeComponent } from "@/controllers/API/queries/store";
import { useState } from "react";
import { usePostLikeComponent } from "@/controllers/API/queries/store";
import { getComponent } from "../../../controllers/API";
import useAlertStore from "../../../stores/alertStore";
import { useStoreStore } from "../../../stores/storeStore";
import { FlowType } from "../../../types/flow";
import { storeComponent } from "../../../types/store";
import type { FlowType } from "../../../types/flow";
import type { storeComponent } from "../../../types/store";
import cloneFLowWithParent, {
getInputsAndOutputs,
} from "../../../utils/storeUtils";
@ -44,13 +44,13 @@ export default function StoreCardComponent({
const name = data.is_component ? "Component" : "Flow";
async function getFlowData() {
async function _getFlowData() {
const res = await getComponent(data.id);
const newFlow = cloneFLowWithParent(res, res.id, data.is_component, true);
return newFlow;
}
function hasPlayground(flow?: FlowType) {
function _hasPlayground(flow?: FlowType) {
if (!flow) {
return false;
}

View file

@ -17,7 +17,7 @@ export function TagsSelector({
}) {
const updateTags = (tagName: string) => {
const index = selectedTags.indexOf(tagName);
let newArray =
const newArray =
index === -1
? [...selectedTags, tagName]
: selectedTags.filter((_, i) => i !== index);

View file

@ -1,5 +1,5 @@
import BaseModal from "../../../modals/baseModal";
import { fetchErrorComponentType } from "../../../types/components";
import type { fetchErrorComponentType } from "../../../types/components";
import Loading from "../../ui/loading";
export default function TimeoutErrorComponent({

View file

@ -1,21 +1,20 @@
import {
useGetGlobalVariables,
usePatchGlobalVariables,
usePostGlobalVariables,
} from "@/controllers/API/queries/variables";
import getUnavailableFields from "@/stores/globalVariablesStore/utils/get-unavailable-fields";
import { GlobalVariable } from "@/types/global_variables";
import { useEffect, useState } from "react";
import { ForwardedIconComponent } from "@/components/common/genericIconComponent";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs-button";
import { useGetTypes } from "@/controllers/API/queries/flows/use-get-types";
import {
useGetGlobalVariables,
usePatchGlobalVariables,
usePostGlobalVariables,
} from "@/controllers/API/queries/variables";
import BaseModal from "@/modals/baseModal";
import useAlertStore from "@/stores/alertStore";
import getUnavailableFields from "@/stores/globalVariablesStore/utils/get-unavailable-fields";
import { useTypesStore } from "@/stores/typesStore";
import { ResponseErrorDetailAPI } from "@/types/api";
import type { ResponseErrorDetailAPI } from "@/types/api";
import type { GlobalVariable } from "@/types/global_variables";
import InputComponent from "../parameterRenderComponent/components/inputComponent";
import sortByName from "./utils/sort-by-name";
@ -60,7 +59,7 @@ export default function GlobalVariableModal({
if (globalVariables && componentFields.size > 0) {
const unavailableFields = getUnavailableFields(globalVariables);
const fields = Array.from(componentFields).filter(
(field) => !unavailableFields.hasOwnProperty(field.trim()),
(field) => !Object.hasOwn(unavailableFields, field.trim()),
);
setAvailableFields(
sortByName(fields.concat(initialData?.default_fields ?? [])),
@ -76,7 +75,7 @@ export default function GlobalVariableModal({
const setSuccessData = useAlertStore((state) => state.setSuccessData);
function handleSaveVariable() {
let data: {
const data: {
name: string;
value: string;
type?: string;
@ -102,7 +101,7 @@ export default function GlobalVariableModal({
});
},
onError: (error) => {
let responseError = error as ResponseErrorDetailAPI;
const responseError = error as ResponseErrorDetailAPI;
setErrorData({
title: `Error ${initialData ? "updating" : "creating"} variable`,
list: [

View file

@ -1,3 +1,4 @@
import { FaDiscord, FaGithub } from "react-icons/fa";
import { ForwardedIconComponent } from "@/components/common/genericIconComponent";
import {
DATASTAX_DOCS_URL,
@ -13,8 +14,6 @@ import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
import useAuthStore from "@/stores/authStore";
import { useDarkStore } from "@/stores/darkStore";
import { cn } from "@/utils/utils";
import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa";
import { useParams } from "react-router-dom";
import {
HeaderMenu,
HeaderMenuItemButton,
@ -22,11 +21,9 @@ import {
HeaderMenuItems,
HeaderMenuToggle,
} from "../HeaderMenu";
import { ProfileIcon } from "../ProfileIcon";
import ThemeButtons from "../ThemeButtons";
export const AccountMenu = () => {
const { customParam: id } = useParams();
const version = useDarkStore((state) => state.version);
const latestVersion = useDarkStore((state) => state.latestVersion);
const navigate = useCustomNavigate();
@ -44,136 +41,134 @@ export const AccountMenu = () => {
const isLatestVersion = version === latestVersion;
return (
<>
<HeaderMenu>
<HeaderMenuToggle>
<div
className="h-6 w-6 rounded-lg focus-visible:outline-0"
data-testid="user-profile-settings"
>
<CustomProfileIcon />
<HeaderMenu>
<HeaderMenuToggle>
<div
className="h-6 w-6 rounded-lg focus-visible:outline-0"
data-testid="user-profile-settings"
>
<CustomProfileIcon />
</div>
</HeaderMenuToggle>
<HeaderMenuItems position="right" classNameSize="w-[272px]">
<div className="divide-y divide-foreground/10">
<div>
<div className="h-[44px] items-center px-4 pt-3">
<div className="flex items-center justify-between">
<span
data-testid="menu_version_button"
id="menu_version_button"
className="text-sm"
>
Version
</span>
<div
className={cn(
"float-right text-xs",
isLatestVersion && "text-accent-emerald-foreground",
!isLatestVersion && "text-accent-amber-foreground",
)}
>
{version}{" "}
{isLatestVersion ? "(latest)" : "(update available)"}
</div>
</div>
</div>
</div>
</HeaderMenuToggle>
<HeaderMenuItems position="right" classNameSize="w-[272px]">
<div className="divide-y divide-foreground/10">
<div>
<div className="h-[44px] items-center px-4 pt-3">
<div className="flex items-center justify-between">
<span
data-testid="menu_version_button"
id="menu_version_button"
className="text-sm"
>
Version
</span>
<div
className={cn(
"float-right text-xs",
isLatestVersion && "text-accent-emerald-foreground",
!isLatestVersion && "text-accent-amber-foreground",
)}
>
{version}{" "}
{isLatestVersion ? "(latest)" : "(update available)"}
</div>
</div>
</div>
</div>
<div>
<HeaderMenuItemButton
onClick={() => {
navigate("/settings");
}}
<div>
<HeaderMenuItemButton
onClick={() => {
navigate("/settings");
}}
>
<span
data-testid="menu_settings_button"
id="menu_settings_button"
>
<span
data-testid="menu_settings_button"
id="menu_settings_button"
>
Settings
</span>
</HeaderMenuItemButton>
Settings
</span>
</HeaderMenuItemButton>
{isAdmin && !autoLogin && (
<div>
<HeaderMenuItemButton
onClick={() => {
navigate("/admin");
}}
>
<span
data-testid="menu_admin_page_button"
id="menu_admin_page_button"
>
Admin Page
</span>
</HeaderMenuItemButton>
</div>
)}
<HeaderMenuItemLink
newPage
href={ENABLE_DATASTAX_LANGFLOW ? DATASTAX_DOCS_URL : DOCS_URL}
>
<span data-testid="menu_docs_button" id="menu_docs_button">
Docs
</span>
</HeaderMenuItemLink>
</div>
<div>
<HeaderMenuItemLink newPage href={GITHUB_URL}>
<span
data-testid="menu_github_button"
id="menu_github_button"
className="flex items-center gap-2"
>
<FaGithub className="h-4 w-4" />
GitHub
</span>
</HeaderMenuItemLink>
<HeaderMenuItemLink newPage href={DISCORD_URL}>
<span
data-testid="menu_discord_button"
id="menu_discord_button"
className="flex items-center gap-2"
>
<FaDiscord className="h-4 w-4 text-[#5865F2]" />
Discord
</span>
</HeaderMenuItemLink>
<HeaderMenuItemLink newPage href={TWITTER_URL}>
<span
data-testid="menu_twitter_button"
id="menu_twitter_button"
className="flex items-center gap-2"
>
<ForwardedIconComponent
strokeWidth={2}
name="TwitterX"
className="h-4 w-4"
/>
X
</span>
</HeaderMenuItemLink>
</div>
<div className="flex items-center justify-between px-4 py-[6.5px] text-sm">
<span className="">Theme</span>
<div className="relative top-[1px] float-right">
<ThemeButtons />
</div>
</div>
{!autoLogin && (
{isAdmin && !autoLogin && (
<div>
<HeaderMenuItemButton onClick={handleLogout} icon="log-out">
Logout
<HeaderMenuItemButton
onClick={() => {
navigate("/admin");
}}
>
<span
data-testid="menu_admin_page_button"
id="menu_admin_page_button"
>
Admin Page
</span>
</HeaderMenuItemButton>
</div>
)}
<HeaderMenuItemLink
newPage
href={ENABLE_DATASTAX_LANGFLOW ? DATASTAX_DOCS_URL : DOCS_URL}
>
<span data-testid="menu_docs_button" id="menu_docs_button">
Docs
</span>
</HeaderMenuItemLink>
</div>
</HeaderMenuItems>
</HeaderMenu>
</>
<div>
<HeaderMenuItemLink newPage href={GITHUB_URL}>
<span
data-testid="menu_github_button"
id="menu_github_button"
className="flex items-center gap-2"
>
<FaGithub className="h-4 w-4" />
GitHub
</span>
</HeaderMenuItemLink>
<HeaderMenuItemLink newPage href={DISCORD_URL}>
<span
data-testid="menu_discord_button"
id="menu_discord_button"
className="flex items-center gap-2"
>
<FaDiscord className="h-4 w-4 text-[#5865F2]" />
Discord
</span>
</HeaderMenuItemLink>
<HeaderMenuItemLink newPage href={TWITTER_URL}>
<span
data-testid="menu_twitter_button"
id="menu_twitter_button"
className="flex items-center gap-2"
>
<ForwardedIconComponent
strokeWidth={2}
name="TwitterX"
className="h-4 w-4"
/>
X
</span>
</HeaderMenuItemLink>
</div>
<div className="flex items-center justify-between px-4 py-[6.5px] text-sm">
<span className="">Theme</span>
<div className="relative top-[1px] float-right">
<ThemeButtons />
</div>
</div>
{!autoLogin && (
<div>
<HeaderMenuItemButton onClick={handleLogout} icon="log-out">
Logout
</HeaderMenuItemButton>
</div>
)}
</div>
</HeaderMenuItems>
</HeaderMenu>
);
};

View file

@ -1,5 +1,6 @@
import { memo, useMemo, useRef, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { useShallow } from "zustand/react/shallow";
import IconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import FlowSettingsComponent from "@/components/core/flowSettingsComponent";
@ -17,13 +18,11 @@ import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
import useSaveFlow from "@/hooks/flows/use-save-flow";
import { useUnsavedChanges } from "@/hooks/use-unsaved-changes";
import useAlertStore from "@/stores/alertStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import useFlowStore from "@/stores/flowStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { useShortcutsStore } from "@/stores/shortcuts";
import { swatchColors } from "@/utils/styleUtils";
import { cn, getNumberFromString } from "@/utils/utils";
import { useHotkeys } from "react-hotkeys-hook";
import { useShallow } from "zustand/react/shallow";
export const MenuBar = memo((): JSX.Element => {
const setSuccessData = useAlertStore((state) => state.setSuccessData);

View file

@ -1,3 +1,5 @@
import { ChevronsUpDown } from "lucide-react";
import type React from "react";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import {
DropdownMenu,
@ -7,8 +9,6 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { cn } from "@/utils/utils";
import { ChevronsUpDown } from "lucide-react";
import React from "react";
export const HeaderMenu = ({ children }) => (
<DropdownMenu>{children}</DropdownMenu>

View file

@ -1,6 +1,6 @@
import { useContext } from "react";
import { AuthContext } from "@/contexts/authContext";
import { BASE_URL_API } from "@/customization/config-constants";
import { useContext } from "react";
export function ProfileIcon() {
const { userData } = useContext(AuthContext);

View file

@ -1,7 +1,7 @@
import { useEffect, useState } from "react";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import useTheme from "@/customization/hooks/use-custom-theme";
import { useEffect, useState } from "react";
export const ThemeButtons = () => {
const { systemTheme, dark, setThemePreference } = useTheme();

View file

@ -1,8 +1,8 @@
import { FaDiscord, FaGithub } from "react-icons/fa";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { DISCORD_URL, GITHUB_URL } from "@/constants/constants";
import { useDarkStore } from "@/stores/darkStore";
import { formatNumber } from "@/utils/utils";
import { FaDiscord, FaGithub } from "react-icons/fa";
export const LangflowCounts = () => {
const stars: number | undefined = useDarkStore((state) => state.stars);

View file

@ -1,3 +1,4 @@
import { useEffect, useRef, useState } from "react";
import AlertDropdown from "@/alerts/alertDropDown";
import DataStaxLogo from "@/assets/DataStaxLogo.svg?react";
import LangflowLogo from "@/assets/LangflowLogo.svg?react";
@ -13,7 +14,6 @@ import { ENABLE_DATASTAX_LANGFLOW } from "@/customization/feature-flags";
import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
import useTheme from "@/customization/hooks/use-custom-theme";
import useAlertStore from "@/stores/alertStore";
import { useEffect, useRef, useState } from "react";
import FlowMenu from "./components/FlowMenu";
export default function AppHeader(): JSX.Element {

View file

@ -1,5 +1,5 @@
import { motion, type Transition } from "framer-motion";
import { cn } from "@/utils/utils";
import { motion, Transition } from "framer-motion";
type BorderTrailProps = {
className?: string;

View file

@ -1,21 +1,21 @@
import IconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import useSaveFlow from "@/hooks/flows/use-save-flow";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import useFlowStore from "@/stores/flowStore";
import { cn } from "@/utils/utils";
import {
ControlButton,
Panel,
type ReactFlowState,
useReactFlow,
useStore,
useStoreApi,
type ReactFlowState,
} from "@xyflow/react";
import { cloneDeep } from "lodash";
import { useCallback, useEffect } from "react";
import { useShallow } from "zustand/react/shallow";
import { shallow } from "zustand/shallow";
import IconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import useSaveFlow from "@/hooks/flows/use-save-flow";
import useFlowStore from "@/stores/flowStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { cn } from "@/utils/utils";
type CustomControlButtonProps = {
iconName: string;

View file

@ -1,4 +1,4 @@
import { FlowType } from "@/types/flow";
import type { FlowType } from "@/types/flow";
import { cn } from "../../../../../utils/utils";
import ForwardedIconComponent from "../../../../common/genericIconComponent";
import { Card, CardHeader, CardTitle } from "../../../../ui/card";

View file

@ -1,6 +1,6 @@
import { FlowType } from "@/types/flow";
import { useCallback } from "react";
import { createRoot } from "react-dom/client";
import type { FlowType } from "@/types/flow";
import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
import DragCardComponent from "../components/dragCardComponent";
@ -9,7 +9,7 @@ const useDragStart = (data: FlowType) => {
const onDragStart = useCallback(
(event) => {
let image = <DragCardComponent data={data} />; // Replace with whatever you want here
const image = <DragCardComponent data={data} />; // Replace with whatever you want here
const ghost = document.createElement("div");
ghost.style.transform = "translate(-10000px, -10000px)";

View file

@ -1,5 +1,5 @@
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { useEffect, useState } from "react";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { cn } from "../../../utils/utils";
import IconComponent from "../../common/genericIconComponent";

View file

@ -1,13 +1,13 @@
"use client";
import { BorderTrail } from "@/components/core/border-trail";
import { ContentBlock } from "@/types/chat";
import { cn } from "@/utils/utils";
import { AnimatePresence, motion } from "framer-motion";
import { ChevronDown } from "lucide-react";
import { useState } from "react";
import Markdown from "react-markdown";
import rehypeMathjax from "rehype-mathjax";
import remarkGfm from "remark-gfm";
import { BorderTrail } from "@/components/core/border-trail";
import type { ContentBlock } from "@/types/chat";
import { cn } from "@/utils/utils";
import ForwardedIconComponent from "../../common/genericIconComponent";
import { Separator } from "../../ui/separator";
import ContentDisplay from "./ContentDisplay";

View file

@ -1,8 +1,8 @@
import { ContentType } from "@/types/chat";
import { ReactNode } from "react";
import type { ReactNode } from "react";
import Markdown from "react-markdown";
import rehypeMathjax from "rehype-mathjax";
import remarkGfm from "remark-gfm";
import type { ContentType } from "@/types/chat";
import ForwardedIconComponent from "../../common/genericIconComponent";
import SimplifiedCodeTabComponent from "../codeTabsComponent";
import DurationDisplay from "./DurationDisplay";
@ -144,7 +144,7 @@ export default function ContentDisplay({
);
break;
case "tool_use":
case "tool_use": {
const formatToolOutput = (output: any) => {
if (output === null || output === undefined) return "";
@ -241,6 +241,7 @@ export default function ContentDisplay({
</div>
);
break;
}
case "media":
contentData = (

View file

@ -1,5 +1,5 @@
import { useDurationStore } from "@/stores/durationStore";
import { useEffect } from "react";
import { useDurationStore } from "@/stores/durationStore";
import { AnimatedNumber } from "../../common/animatedNumbers";
import ForwardedIconComponent from "../../common/genericIconComponent";
import Loading from "../../ui/loading";

View file

@ -1,10 +1,10 @@
import { useEffect, useState } from "react";
import AccordionComponent from "@/components/common/accordionComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { EditNodeComponent } from "@/modals/editNodeModal/components/editNodeComponent";
import { APIClassType } from "@/types/api";
import { AllNodeType } from "@/types/flow";
import type { APIClassType } from "@/types/api";
import type { AllNodeType } from "@/types/flow";
import { customStringify } from "@/utils/reactflowUtils";
import { useEffect, useState } from "react";
export function TweakComponent({
open,

Some files were not shown because too many files have changed in this diff Show more