diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4294bde --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +package-lock.json + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..922e683 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM node:20 + +# Create and set the working directory +WORKDIR /app + +# Copy all files to the container +COPY . . + +# Install dependencies +RUN npm install + +RUN npm run build + +# Expose the port the app runs on +EXPOSE 3000 + +# Start the application +CMD ["npm", "run", "preview", "--", "--host", "0.0.0.0", "--port", "3000"] \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..870a1b4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 HomunMage + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b2b7d07 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# reactflow-ts + +## Dev +* compile + * ```npm run tsc``` +* lint + * ```npm run lint``` +* hold + * ```npm run dev``` +* vitest + * ```npm run test``` + +## Serve +``` bash +npm run build +npm run preview -- --host 0.0.0.0 --port 3000 +``` \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..6277d3d --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,31 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + 'indent': ['error', 4], + // Disable the no-explicit-any rule + '@typescript-eslint/no-explicit-any': 'off', + }, + }, +) \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..4c6d616 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + LangGraph-GUI + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..8b7fcee --- /dev/null +++ b/package.json @@ -0,0 +1,45 @@ +{ + "name": "langgraph-gui", + "private": true, + "version": "1.3.0", + "type": "module", + "scripts": { + "dev": "NODE_ENV=DEBUG vite", + "build": "tsc -b && vite build", + "lint": "eslint --fix .", + "preview": "vite preview", + "tsc": "tsc -p tsconfig.app.json", + "test": "vitest" + }, + "dependencies": { + "@redux-devtools/extension": "^3.3.0", + "@reduxjs/toolkit": "^2.5.0", + "@xyflow/react": "^12.3.6", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-redux": "^9.2.0", + "react-router-dom": "^7.1.1", + "uuid": "^11.0.5" + }, + "devDependencies": { + "@eslint/js": "^9.17.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.2.0", + "@types/node": "^22.10.10", + "@types/react": "^18.3.18", + "@types/react-dom": "^18.3.5", + "@vitejs/plugin-react": "^4.3.4", + "autoprefixer": "^10.4.20", + "eslint": "^9.17.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.16", + "globals": "^15.14.0", + "jsdom": "^26.0.0", + "postcss": "^8.4.49", + "tailwindcss": "^3.4.17", + "typescript": "~5.6.2", + "typescript-eslint": "^8.18.2", + "vite": "^6.0.5", + "vitest": "^3.0.2" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/setupTests.ts b/setupTests.ts new file mode 100644 index 0000000..2eee530 --- /dev/null +++ b/setupTests.ts @@ -0,0 +1,17 @@ +// setupTests.ts + +import "@testing-library/jest-dom"; // important to import this for rendering react components + +if (typeof ResizeObserver === 'undefined') { + global.ResizeObserver = class ResizeObserver { + observe() { + // do nothing + } + unobserve() { + // do nothing + } + disconnect() { + // do nothing + } + }; +} \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..73579a5 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,12 @@ +// App.tsx + +import React from 'react'; +import AppRoutes from './routes/AppRoutes'; + +const App: React.FC = () => { + return ( + + ); +}; + +export default App; \ No newline at end of file diff --git a/src/Doc/DocPage.tsx b/src/Doc/DocPage.tsx new file mode 100644 index 0000000..6f4bd7d --- /dev/null +++ b/src/Doc/DocPage.tsx @@ -0,0 +1,15 @@ +// Graph/Doc.tsx + +import React from 'react'; + +const DocPage: React.FC = () => { + return ( +