Spaces:
Running
Running
Remove Next.js.
Browse files- web/.eslintrc.json +0 -3
- web/.gitignore +21 -37
- web/README.md +4 -33
- web/app/layout.tsx +0 -23
- web/eslint.config.js +28 -0
- web/index.html +13 -0
- web/next.config.ts +0 -24
- web/package-lock.json +0 -0
- web/package.json +28 -21
- web/postcss.config.js +1 -1
- web/postcss.config.mjs +0 -8
- web/{app/page.tsx β src/Directory.tsx} +41 -37
- web/{app β src/assets}/favicon.ico +0 -0
- web/{public β src/assets}/logo.png +0 -0
- web/{app/globals.css β src/index.css} +20 -5
- web/src/main.tsx +19 -0
- web/src/vite-env.d.ts +1 -0
- web/{app β src}/workspace/EnvironmentSelector.tsx +0 -0
- web/{app β src}/workspace/LynxKiteState.ts +0 -0
- web/{app β src}/workspace/Workspace.tsx +10 -8
- web/{app β src}/workspace/nodes/LynxKiteNode.tsx +0 -0
- web/{app β src}/workspace/nodes/NodeParameter.tsx +0 -0
- web/{app β src}/workspace/nodes/NodeWithParams.tsx +0 -0
- web/{app β src}/workspace/page.tsx +0 -0
- web/tailwind.config.js +2 -2
- web/tailwind.config.ts +0 -18
- web/tsconfig.app.json +26 -0
- web/tsconfig.json +5 -26
- web/tsconfig.node.json +24 -0
- web/vite.config.ts +4 -4
web/.eslintrc.json
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"extends": ["next/core-web-vitals", "next/typescript"]
|
3 |
-
}
|
|
|
|
|
|
|
|
web/.gitignore
CHANGED
@@ -1,40 +1,24 @@
|
|
1 |
-
#
|
2 |
-
|
3 |
-
|
4 |
-
/node_modules
|
5 |
-
/.pnp
|
6 |
-
.pnp.*
|
7 |
-
.yarn/*
|
8 |
-
!.yarn/patches
|
9 |
-
!.yarn/plugins
|
10 |
-
!.yarn/releases
|
11 |
-
!.yarn/versions
|
12 |
-
|
13 |
-
# testing
|
14 |
-
/coverage
|
15 |
-
|
16 |
-
# next.js
|
17 |
-
/.next/
|
18 |
-
/out/
|
19 |
-
|
20 |
-
# production
|
21 |
-
/build
|
22 |
-
|
23 |
-
# misc
|
24 |
-
.DS_Store
|
25 |
-
*.pem
|
26 |
-
|
27 |
-
# debug
|
28 |
npm-debug.log*
|
29 |
yarn-debug.log*
|
30 |
yarn-error.log*
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Logs
|
2 |
+
logs
|
3 |
+
*.log
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
npm-debug.log*
|
5 |
yarn-debug.log*
|
6 |
yarn-error.log*
|
7 |
+
pnpm-debug.log*
|
8 |
+
lerna-debug.log*
|
9 |
+
|
10 |
+
node_modules
|
11 |
+
dist
|
12 |
+
dist-ssr
|
13 |
+
*.local
|
14 |
+
|
15 |
+
# Editor directories and files
|
16 |
+
.vscode/*
|
17 |
+
!.vscode/extensions.json
|
18 |
+
.idea
|
19 |
+
.DS_Store
|
20 |
+
*.suo
|
21 |
+
*.ntvs*
|
22 |
+
*.njsproj
|
23 |
+
*.sln
|
24 |
+
*.sw?
|
web/README.md
CHANGED
@@ -1,36 +1,7 @@
|
|
1 |
-
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
|
7 |
-
|
8 |
-
npm run dev
|
9 |
-
# or
|
10 |
-
yarn dev
|
11 |
-
# or
|
12 |
-
pnpm dev
|
13 |
-
# or
|
14 |
-
bun dev
|
15 |
-
```
|
16 |
-
|
17 |
-
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
18 |
-
|
19 |
-
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
20 |
-
|
21 |
-
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
22 |
-
|
23 |
-
## Learn More
|
24 |
-
|
25 |
-
To learn more about Next.js, take a look at the following resources:
|
26 |
-
|
27 |
-
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
28 |
-
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
29 |
-
|
30 |
-
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
31 |
-
|
32 |
-
## Deploy on Vercel
|
33 |
-
|
34 |
-
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
35 |
-
|
36 |
-
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
|
|
1 |
+
To set up:
|
2 |
|
3 |
+
npm i
|
4 |
|
5 |
+
To start dev server:
|
6 |
|
7 |
+
npm run dev
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/app/layout.tsx
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
import type { Metadata } from "next";
|
2 |
-
import "./globals.css";
|
3 |
-
|
4 |
-
export const metadata: Metadata = {
|
5 |
-
title: "LynxKite MM",
|
6 |
-
description: "From Lynx Analytics",
|
7 |
-
};
|
8 |
-
|
9 |
-
export default function RootLayout({
|
10 |
-
children,
|
11 |
-
}: Readonly<{
|
12 |
-
children: React.ReactNode;
|
13 |
-
}>) {
|
14 |
-
return (
|
15 |
-
<html lang="en">
|
16 |
-
<body
|
17 |
-
className={`antialiased`}
|
18 |
-
>
|
19 |
-
{children}
|
20 |
-
</body>
|
21 |
-
</html>
|
22 |
-
);
|
23 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/eslint.config.js
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import js from '@eslint/js'
|
2 |
+
import globals from 'globals'
|
3 |
+
import reactHooks from 'eslint-plugin-react-hooks'
|
4 |
+
import reactRefresh from 'eslint-plugin-react-refresh'
|
5 |
+
import tseslint from 'typescript-eslint'
|
6 |
+
|
7 |
+
export default tseslint.config(
|
8 |
+
{ ignores: ['dist'] },
|
9 |
+
{
|
10 |
+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
11 |
+
files: ['**/*.{ts,tsx}'],
|
12 |
+
languageOptions: {
|
13 |
+
ecmaVersion: 2020,
|
14 |
+
globals: globals.browser,
|
15 |
+
},
|
16 |
+
plugins: {
|
17 |
+
'react-hooks': reactHooks,
|
18 |
+
'react-refresh': reactRefresh,
|
19 |
+
},
|
20 |
+
rules: {
|
21 |
+
...reactHooks.configs.recommended.rules,
|
22 |
+
'react-refresh/only-export-components': [
|
23 |
+
'warn',
|
24 |
+
{ allowConstantExport: true },
|
25 |
+
],
|
26 |
+
},
|
27 |
+
},
|
28 |
+
)
|
web/index.html
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8" />
|
5 |
+
<link rel="icon" type="image/svg+xml" href="/src/assets/favicon.ico" />
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
7 |
+
<title>LynxKite 2025</title>
|
8 |
+
</head>
|
9 |
+
<body>
|
10 |
+
<div id="root"></div>
|
11 |
+
<script type="module" src="/src/main.tsx"></script>
|
12 |
+
</body>
|
13 |
+
</html>
|
web/next.config.ts
DELETED
@@ -1,24 +0,0 @@
|
|
1 |
-
import type { NextConfig } from "next";
|
2 |
-
import Icons from 'unplugin-icons/webpack'
|
3 |
-
|
4 |
-
const nextConfig: NextConfig = {
|
5 |
-
webpack(config) {
|
6 |
-
config.plugins.push(
|
7 |
-
Icons({
|
8 |
-
compiler: 'jsx',
|
9 |
-
jsx: 'react',
|
10 |
-
})
|
11 |
-
);
|
12 |
-
return config;
|
13 |
-
},
|
14 |
-
async rewrites() {
|
15 |
-
return [
|
16 |
-
{
|
17 |
-
source: '/api/:path*',
|
18 |
-
destination: 'http://127.0.0.1:8000/api/:path*',
|
19 |
-
},
|
20 |
-
]
|
21 |
-
},
|
22 |
-
};
|
23 |
-
|
24 |
-
export default nextConfig;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/package-lock.json
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
web/package.json
CHANGED
@@ -1,40 +1,47 @@
|
|
1 |
{
|
2 |
"name": "lynxkite",
|
3 |
-
"version": "0.1.0",
|
4 |
"private": true,
|
|
|
|
|
5 |
"scripts": {
|
6 |
-
"dev": "
|
7 |
-
"build": "
|
8 |
-
"
|
9 |
-
"
|
10 |
},
|
11 |
"dependencies": {
|
12 |
-
"@iconify-json/tabler": "^1.2.
|
|
|
|
|
13 |
"@syncedstore/core": "^0.6.0",
|
14 |
"@syncedstore/react": "^0.6.0",
|
|
|
15 |
"@xyflow/react": "^12.3.5",
|
|
|
16 |
"echarts": "^5.5.1",
|
17 |
"fuse.js": "^7.0.0",
|
18 |
-
"
|
19 |
-
"react": "
|
20 |
-
"react-dom": "
|
21 |
"swr": "^2.2.5",
|
22 |
-
"unplugin-icons": "^0.
|
23 |
-
"y-websocket": "2.0.4",
|
24 |
"yjs": "^13.6.20"
|
25 |
},
|
26 |
"devDependencies": {
|
27 |
-
"@
|
28 |
-
"@
|
29 |
-
"@types/
|
30 |
-
"@
|
31 |
-
"@types/react-dom": "^18",
|
32 |
"autoprefixer": "^10.4.20",
|
33 |
-
"
|
34 |
-
"eslint": "^
|
35 |
-
"eslint-
|
|
|
36 |
"postcss": "^8.4.49",
|
37 |
-
"tailwindcss": "^3.4.
|
38 |
-
"typescript": "
|
|
|
|
|
39 |
}
|
40 |
}
|
|
|
1 |
{
|
2 |
"name": "lynxkite",
|
|
|
3 |
"private": true,
|
4 |
+
"version": "0.0.0",
|
5 |
+
"type": "module",
|
6 |
"scripts": {
|
7 |
+
"dev": "vite",
|
8 |
+
"build": "tsc -b && vite build",
|
9 |
+
"lint": "eslint .",
|
10 |
+
"preview": "vite preview"
|
11 |
},
|
12 |
"dependencies": {
|
13 |
+
"@iconify-json/tabler": "^1.2.10",
|
14 |
+
"@svgr/core": "^8.1.0",
|
15 |
+
"@svgr/plugin-jsx": "^8.1.0",
|
16 |
"@syncedstore/core": "^0.6.0",
|
17 |
"@syncedstore/react": "^0.6.0",
|
18 |
+
"@types/node": "^22.10.1",
|
19 |
"@xyflow/react": "^12.3.5",
|
20 |
+
"daisyui": "^4.12.20",
|
21 |
"echarts": "^5.5.1",
|
22 |
"fuse.js": "^7.0.0",
|
23 |
+
"react": "^18.3.1",
|
24 |
+
"react-dom": "^18.3.1",
|
25 |
+
"react-router-dom": "^7.0.2",
|
26 |
"swr": "^2.2.5",
|
27 |
+
"unplugin-icons": "^0.21.0",
|
28 |
+
"y-websocket": "^2.0.4",
|
29 |
"yjs": "^13.6.20"
|
30 |
},
|
31 |
"devDependencies": {
|
32 |
+
"@eslint/js": "^9.15.0",
|
33 |
+
"@types/react": "^18.3.14",
|
34 |
+
"@types/react-dom": "^18.3.2",
|
35 |
+
"@vitejs/plugin-react-swc": "^3.5.0",
|
|
|
36 |
"autoprefixer": "^10.4.20",
|
37 |
+
"eslint": "^9.15.0",
|
38 |
+
"eslint-plugin-react-hooks": "^5.0.0",
|
39 |
+
"eslint-plugin-react-refresh": "^0.4.14",
|
40 |
+
"globals": "^15.12.0",
|
41 |
"postcss": "^8.4.49",
|
42 |
+
"tailwindcss": "^3.4.16",
|
43 |
+
"typescript": "~5.6.2",
|
44 |
+
"typescript-eslint": "^8.15.0",
|
45 |
+
"vite": "^6.0.1"
|
46 |
}
|
47 |
}
|
web/postcss.config.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
|
2 |
plugins: {
|
3 |
tailwindcss: {},
|
4 |
autoprefixer: {},
|
|
|
1 |
+
export default {
|
2 |
plugins: {
|
3 |
tailwindcss: {},
|
4 |
autoprefixer: {},
|
web/postcss.config.mjs
DELETED
@@ -1,8 +0,0 @@
|
|
1 |
-
/** @type {import('postcss-load-config').Config} */
|
2 |
-
const config = {
|
3 |
-
plugins: {
|
4 |
-
tailwindcss: {},
|
5 |
-
},
|
6 |
-
};
|
7 |
-
|
8 |
-
export default config;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/{app/page.tsx β src/Directory.tsx}
RENAMED
@@ -1,6 +1,8 @@
|
|
1 |
// The directory browser.
|
2 |
-
import
|
3 |
-
import
|
|
|
|
|
4 |
// @ts-ignore
|
5 |
import Home from '~icons/tabler/home'
|
6 |
// @ts-ignore
|
@@ -12,31 +14,23 @@ import File from '~icons/tabler/file'
|
|
12 |
// @ts-ignore
|
13 |
import FilePlus from '~icons/tabler/file-plus'
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
const encodedPath = encodeURIComponent(path || '');
|
23 |
-
const res = await fetch(`http://localhost:8000/api/dir/list?path=${encodedPath}`);
|
24 |
-
const j = await res.json();
|
25 |
-
return j;
|
26 |
-
}
|
27 |
-
const path = (await searchParams)?.path || '';
|
28 |
-
const list = await fetchList(path);
|
29 |
-
function link(item) {
|
30 |
if (item.type === 'directory') {
|
31 |
-
return `/dir
|
32 |
} else {
|
33 |
-
return `/
|
34 |
}
|
35 |
}
|
36 |
-
function shortName(item) {
|
37 |
return item.name.split('/').pop();
|
38 |
}
|
39 |
-
function newName(list) {
|
40 |
let i = 0;
|
41 |
while (true) {
|
42 |
const name = `Untitled${i ? ` ${i}` : ''}`;
|
@@ -46,11 +40,11 @@ export default async function Home({
|
|
46 |
i++;
|
47 |
}
|
48 |
}
|
49 |
-
function newWorkspaceIn(path, list) {
|
50 |
const pathSlash = path ? `${path}/` : '';
|
51 |
-
return `/
|
52 |
}
|
53 |
-
async function newFolderIn(path, list) {
|
54 |
const pathSlash = path ? `${path}/` : '';
|
55 |
const name = newName(list);
|
56 |
const res = await fetch(`/api/dir/mkdir`, {
|
@@ -60,24 +54,34 @@ export default async function Home({
|
|
60 |
});
|
61 |
list = await res.json();
|
62 |
}
|
|
|
63 |
return (
|
64 |
-
<div className="directory
|
65 |
<div className="logo">
|
66 |
-
<
|
67 |
<div className="tagline">The Complete Graph Data Science Platform</div>
|
68 |
</div>
|
69 |
<div className="entry-list">
|
70 |
-
<
|
71 |
-
|
72 |
-
<
|
73 |
-
|
74 |
-
|
75 |
-
{list.
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
</div>
|
82 |
</div>
|
83 |
);
|
|
|
1 |
// The directory browser.
|
2 |
+
import { useParams } from "react-router";
|
3 |
+
import useSWR from 'swr'
|
4 |
+
|
5 |
+
import logo from './assets/logo.png';
|
6 |
// @ts-ignore
|
7 |
import Home from '~icons/tabler/home'
|
8 |
// @ts-ignore
|
|
|
14 |
// @ts-ignore
|
15 |
import FilePlus from '~icons/tabler/file-plus'
|
16 |
|
17 |
+
const fetcher = (url: string) => fetch(url).then((res) => res.json());
|
18 |
+
|
19 |
+
export default function () {
|
20 |
+
const { path } = useParams();
|
21 |
+
const encodedPath = encodeURIComponent(path || '');
|
22 |
+
const list = useSWR(`/api/dir/list?path=${encodedPath}`, fetcher)
|
23 |
+
function link(item: any) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
if (item.type === 'directory') {
|
25 |
+
return `/dir/${item.name}`;
|
26 |
} else {
|
27 |
+
return `/edit/${item.name}`;
|
28 |
}
|
29 |
}
|
30 |
+
function shortName(item: any) {
|
31 |
return item.name.split('/').pop();
|
32 |
}
|
33 |
+
function newName(list: any[]) {
|
34 |
let i = 0;
|
35 |
while (true) {
|
36 |
const name = `Untitled${i ? ` ${i}` : ''}`;
|
|
|
40 |
i++;
|
41 |
}
|
42 |
}
|
43 |
+
function newWorkspaceIn(path: string, list: any[]) {
|
44 |
const pathSlash = path ? `${path}/` : '';
|
45 |
+
return `/edit/${pathSlash}${newName(list)}`;
|
46 |
}
|
47 |
+
async function newFolderIn(path: string, list: any[]) {
|
48 |
const pathSlash = path ? `${path}/` : '';
|
49 |
const name = newName(list);
|
50 |
const res = await fetch(`/api/dir/mkdir`, {
|
|
|
54 |
});
|
55 |
list = await res.json();
|
56 |
}
|
57 |
+
|
58 |
return (
|
59 |
+
<div className="directory">
|
60 |
<div className="logo">
|
61 |
+
<a href="https://lynxkite.com/"><img src={logo} className="logo-image" alt="LynxKite logo" /></a>
|
62 |
<div className="tagline">The Complete Graph Data Science Platform</div>
|
63 |
</div>
|
64 |
<div className="entry-list">
|
65 |
+
{list.error && <p className="error">{list.error.message}</p>}
|
66 |
+
{list.isLoading &&
|
67 |
+
<div className="loading spinner-border" role="status">
|
68 |
+
<span className="visually-hidden">Loading...</span>
|
69 |
+
</div>}
|
70 |
+
{list.data &&
|
71 |
+
<>
|
72 |
+
<div className="actions">
|
73 |
+
<a href={newWorkspaceIn(path || "", list.data)}><FilePlus /> New workspace</a>
|
74 |
+
<a href="" onClick={() => newFolderIn(path || "", list.data)}><FolderPlus /> New folder</a>
|
75 |
+
</div>
|
76 |
+
{path && <div className="breadcrumbs"><a href="/dir/"><Home /></a> {path} </div>}
|
77 |
+
{list.data.map((item: any) =>
|
78 |
+
<a key={link(item)} className="entry" href={link(item)}>
|
79 |
+
{item.type === 'directory' ? <Folder /> : <File />}
|
80 |
+
{shortName(item)}
|
81 |
+
</a>
|
82 |
+
)}
|
83 |
+
</>
|
84 |
+
}
|
85 |
</div>
|
86 |
</div>
|
87 |
);
|
web/{app β src/assets}/favicon.ico
RENAMED
File without changes
|
web/{public β src/assets}/logo.png
RENAMED
File without changes
|
web/{app/globals.css β src/index.css}
RENAMED
@@ -2,6 +2,23 @@
|
|
2 |
@tailwind components;
|
3 |
@tailwind utilities;
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
body {
|
6 |
color: var(--foreground);
|
7 |
background: var(--background);
|
@@ -9,6 +26,7 @@ body {
|
|
9 |
}
|
10 |
|
11 |
.workspace {
|
|
|
12 |
display: flex;
|
13 |
flex-direction: column;
|
14 |
height: 100vh;
|
@@ -17,6 +35,7 @@ body {
|
|
17 |
display: flex;
|
18 |
justify-content: space-between;
|
19 |
align-items: center;
|
|
|
20 |
|
21 |
.ws-name {
|
22 |
font-size: 1.5em;
|
@@ -35,6 +54,7 @@ body {
|
|
35 |
align-items: center;
|
36 |
|
37 |
a {
|
|
|
38 |
font-size: 1.5em;
|
39 |
padding: 0 10px;
|
40 |
}
|
@@ -229,11 +249,6 @@ body {
|
|
229 |
border-bottom: none;
|
230 |
}
|
231 |
|
232 |
-
.directory-page {
|
233 |
-
background: #002a4c;
|
234 |
-
height: 100vh;
|
235 |
-
}
|
236 |
-
|
237 |
a {
|
238 |
color: black;
|
239 |
text-decoration: none;
|
|
|
2 |
@tailwind components;
|
3 |
@tailwind utilities;
|
4 |
|
5 |
+
:root {
|
6 |
+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
7 |
+
line-height: 1.5;
|
8 |
+
font-weight: 400;
|
9 |
+
|
10 |
+
font-synthesis: none;
|
11 |
+
text-rendering: optimizeLegibility;
|
12 |
+
-webkit-font-smoothing: antialiased;
|
13 |
+
-moz-osx-font-smoothing: grayscale;
|
14 |
+
|
15 |
+
background: #002a4c;
|
16 |
+
}
|
17 |
+
|
18 |
+
img, svg {
|
19 |
+
display: inline-block;
|
20 |
+
}
|
21 |
+
|
22 |
body {
|
23 |
color: var(--foreground);
|
24 |
background: var(--background);
|
|
|
26 |
}
|
27 |
|
28 |
.workspace {
|
29 |
+
background: white;
|
30 |
display: flex;
|
31 |
flex-direction: column;
|
32 |
height: 100vh;
|
|
|
35 |
display: flex;
|
36 |
justify-content: space-between;
|
37 |
align-items: center;
|
38 |
+
background: #002a4c;
|
39 |
|
40 |
.ws-name {
|
41 |
font-size: 1.5em;
|
|
|
54 |
align-items: center;
|
55 |
|
56 |
a {
|
57 |
+
color: oklch(75% 0.13 230);
|
58 |
font-size: 1.5em;
|
59 |
padding: 0 10px;
|
60 |
}
|
|
|
249 |
border-bottom: none;
|
250 |
}
|
251 |
|
|
|
|
|
|
|
|
|
|
|
252 |
a {
|
253 |
color: black;
|
254 |
text-decoration: none;
|
web/src/main.tsx
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { StrictMode } from 'react'
|
2 |
+
import { createRoot } from 'react-dom/client'
|
3 |
+
import './index.css'
|
4 |
+
import Directory from './Directory.tsx'
|
5 |
+
import Workspace from './workspace/Workspace.tsx'
|
6 |
+
import { BrowserRouter, Routes, Route } from "react-router";
|
7 |
+
|
8 |
+
createRoot(document.getElementById('root')!).render(
|
9 |
+
<StrictMode>
|
10 |
+
<BrowserRouter>
|
11 |
+
<Routes>
|
12 |
+
<Route path="/" element={<Directory />} />
|
13 |
+
<Route path="/dir" element={<Directory />} />
|
14 |
+
<Route path="/dir/:path" element={<Directory />} />
|
15 |
+
<Route path="/edit/:path" element={<Workspace />} />
|
16 |
+
</Routes>
|
17 |
+
</BrowserRouter>
|
18 |
+
</StrictMode>,
|
19 |
+
)
|
web/src/vite-env.d.ts
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
/// <reference types="vite/client" />
|
web/{app β src}/workspace/EnvironmentSelector.tsx
RENAMED
File without changes
|
web/{app β src}/workspace/LynxKiteState.ts
RENAMED
File without changes
|
web/{app β src}/workspace/Workspace.tsx
RENAMED
@@ -1,7 +1,8 @@
|
|
1 |
-
|
|
|
2 |
import useSWR from 'swr';
|
3 |
import { useMemo } from "react";
|
4 |
-
import
|
5 |
import {
|
6 |
ReactFlow,
|
7 |
useNodesState,
|
@@ -36,15 +37,15 @@ import EnvironmentSelector from './EnvironmentSelector';
|
|
36 |
import { LynxKiteState } from './LynxKiteState';
|
37 |
import '@xyflow/react/dist/style.css';
|
38 |
|
39 |
-
export default function
|
40 |
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
41 |
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
42 |
-
const
|
43 |
|
44 |
-
let path = searchParams.get('path');
|
45 |
const sstore = syncedStore({ workspace: {} });
|
46 |
const doc = getYjsDoc(sstore);
|
47 |
-
const wsProvider = new WebsocketProvider("ws://localhost:8000/ws/crdt", path
|
|
|
48 |
const state = useSyncedStore(sstore);
|
49 |
|
50 |
const fetcher = (resource: string, init?: RequestInit) => fetch(resource, init).then(res => res.json());
|
@@ -54,10 +55,11 @@ export default function Workspace() {
|
|
54 |
basic: NodeWithParams,
|
55 |
table_view: NodeWithParams,
|
56 |
}), []);
|
|
|
57 |
return (
|
58 |
<div className="workspace">
|
59 |
<div className="top-bar bg-neutral">
|
60 |
-
<a className="logo" href=""><img src=
|
61 |
<div className="ws-name">
|
62 |
{path}
|
63 |
</div>
|
@@ -69,7 +71,7 @@ export default function Workspace() {
|
|
69 |
<div className="tools text-secondary">
|
70 |
<a href=""><Atom /></a>
|
71 |
<a href=""><Backspace /></a>
|
72 |
-
<a href=
|
73 |
</div>
|
74 |
</div>
|
75 |
<div style={{ height: "100%", width: '100vw' }}>
|
|
|
1 |
+
// The LynxKite workspace editor.
|
2 |
+
import { useParams } from "react-router";
|
3 |
import useSWR from 'swr';
|
4 |
import { useMemo } from "react";
|
5 |
+
import favicon from '../assets/favicon.ico';
|
6 |
import {
|
7 |
ReactFlow,
|
8 |
useNodesState,
|
|
|
37 |
import { LynxKiteState } from './LynxKiteState';
|
38 |
import '@xyflow/react/dist/style.css';
|
39 |
|
40 |
+
export default function () {
|
41 |
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
42 |
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
43 |
+
const { path } = useParams();
|
44 |
|
|
|
45 |
const sstore = syncedStore({ workspace: {} });
|
46 |
const doc = getYjsDoc(sstore);
|
47 |
+
const wsProvider = new WebsocketProvider("ws://localhost:8000/ws/crdt", path!, doc);
|
48 |
+
wsProvider; // Just to disable the lint warning. The life cycle of this object is a mystery.
|
49 |
const state = useSyncedStore(sstore);
|
50 |
|
51 |
const fetcher = (resource: string, init?: RequestInit) => fetch(resource, init).then(res => res.json());
|
|
|
55 |
basic: NodeWithParams,
|
56 |
table_view: NodeWithParams,
|
57 |
}), []);
|
58 |
+
const parentDir = path!.split('/').slice(0, -1).join('/');
|
59 |
return (
|
60 |
<div className="workspace">
|
61 |
<div className="top-bar bg-neutral">
|
62 |
+
<a className="logo" href=""><img src={favicon} /></a>
|
63 |
<div className="ws-name">
|
64 |
{path}
|
65 |
</div>
|
|
|
71 |
<div className="tools text-secondary">
|
72 |
<a href=""><Atom /></a>
|
73 |
<a href=""><Backspace /></a>
|
74 |
+
<a href={'/dir/' + parentDir}><ArrowBack /></a>
|
75 |
</div>
|
76 |
</div>
|
77 |
<div style={{ height: "100%", width: '100vw' }}>
|
web/{app β src}/workspace/nodes/LynxKiteNode.tsx
RENAMED
File without changes
|
web/{app β src}/workspace/nodes/NodeParameter.tsx
RENAMED
File without changes
|
web/{app β src}/workspace/nodes/NodeWithParams.tsx
RENAMED
File without changes
|
web/{app β src}/workspace/page.tsx
RENAMED
File without changes
|
web/tailwind.config.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
/** @type {import('tailwindcss').Config} */
|
2 |
-
|
3 |
darkMode: 'selector',
|
4 |
-
content: ['./
|
5 |
theme: {
|
6 |
extend: {},
|
7 |
},
|
|
|
1 |
/** @type {import('tailwindcss').Config} */
|
2 |
+
export default {
|
3 |
darkMode: 'selector',
|
4 |
+
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
|
5 |
theme: {
|
6 |
extend: {},
|
7 |
},
|
web/tailwind.config.ts
DELETED
@@ -1,18 +0,0 @@
|
|
1 |
-
import type { Config } from "tailwindcss";
|
2 |
-
|
3 |
-
export default {
|
4 |
-
content: [
|
5 |
-
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
6 |
-
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
7 |
-
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
8 |
-
],
|
9 |
-
theme: {
|
10 |
-
extend: {
|
11 |
-
colors: {
|
12 |
-
background: "var(--background)",
|
13 |
-
foreground: "var(--foreground)",
|
14 |
-
},
|
15 |
-
},
|
16 |
-
},
|
17 |
-
plugins: [],
|
18 |
-
} satisfies Config;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/tsconfig.app.json
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"compilerOptions": {
|
3 |
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
4 |
+
"target": "ES2020",
|
5 |
+
"useDefineForClassFields": true,
|
6 |
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
7 |
+
"module": "ESNext",
|
8 |
+
"skipLibCheck": true,
|
9 |
+
|
10 |
+
/* Bundler mode */
|
11 |
+
"moduleResolution": "bundler",
|
12 |
+
"allowImportingTsExtensions": true,
|
13 |
+
"isolatedModules": true,
|
14 |
+
"moduleDetection": "force",
|
15 |
+
"noEmit": true,
|
16 |
+
"jsx": "react-jsx",
|
17 |
+
|
18 |
+
/* Linting */
|
19 |
+
"strict": true,
|
20 |
+
"noUnusedLocals": true,
|
21 |
+
"noUnusedParameters": true,
|
22 |
+
"noFallthroughCasesInSwitch": true,
|
23 |
+
"noUncheckedSideEffectImports": true
|
24 |
+
},
|
25 |
+
"include": ["src"]
|
26 |
+
}
|
web/tsconfig.json
CHANGED
@@ -1,28 +1,7 @@
|
|
1 |
{
|
2 |
-
"
|
3 |
-
|
4 |
-
"
|
5 |
-
"
|
6 |
-
|
7 |
-
"strict": true,
|
8 |
-
"noEmit": true,
|
9 |
-
"esModuleInterop": true,
|
10 |
-
"module": "esnext",
|
11 |
-
"moduleResolution": "bundler",
|
12 |
-
"resolveJsonModule": true,
|
13 |
-
"isolatedModules": true,
|
14 |
-
"jsx": "preserve",
|
15 |
-
"incremental": true,
|
16 |
-
"noImplicitAny": false,
|
17 |
-
"plugins": [
|
18 |
-
{
|
19 |
-
"name": "next"
|
20 |
-
}
|
21 |
-
],
|
22 |
-
"paths": {
|
23 |
-
"@/*": ["./*"]
|
24 |
-
}
|
25 |
-
},
|
26 |
-
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
27 |
-
"exclude": ["node_modules"]
|
28 |
}
|
|
|
1 |
{
|
2 |
+
"files": [],
|
3 |
+
"references": [
|
4 |
+
{ "path": "./tsconfig.app.json" },
|
5 |
+
{ "path": "./tsconfig.node.json" }
|
6 |
+
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
}
|
web/tsconfig.node.json
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"compilerOptions": {
|
3 |
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
4 |
+
"target": "ES2022",
|
5 |
+
"lib": ["ES2023"],
|
6 |
+
"module": "ESNext",
|
7 |
+
"skipLibCheck": true,
|
8 |
+
|
9 |
+
/* Bundler mode */
|
10 |
+
"moduleResolution": "bundler",
|
11 |
+
"allowImportingTsExtensions": true,
|
12 |
+
"isolatedModules": true,
|
13 |
+
"moduleDetection": "force",
|
14 |
+
"noEmit": true,
|
15 |
+
|
16 |
+
/* Linting */
|
17 |
+
"strict": true,
|
18 |
+
"noUnusedLocals": true,
|
19 |
+
"noUnusedParameters": true,
|
20 |
+
"noFallthroughCasesInSwitch": true,
|
21 |
+
"noUncheckedSideEffectImports": true
|
22 |
+
},
|
23 |
+
"include": ["vite.config.ts"]
|
24 |
+
}
|
web/vite.config.ts
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
import { defineConfig } from 'vite'
|
2 |
-
import
|
3 |
import Icons from 'unplugin-icons/vite'
|
4 |
|
5 |
-
// https://
|
6 |
export default defineConfig({
|
7 |
plugins: [
|
8 |
-
|
9 |
-
Icons({ compiler: '
|
10 |
],
|
11 |
server: {
|
12 |
proxy: {
|
|
|
1 |
import { defineConfig } from 'vite'
|
2 |
+
import react from '@vitejs/plugin-react-swc'
|
3 |
import Icons from 'unplugin-icons/vite'
|
4 |
|
5 |
+
// https://vite.dev/config/
|
6 |
export default defineConfig({
|
7 |
plugins: [
|
8 |
+
react(),
|
9 |
+
Icons({ compiler: 'jsx', jsx: 'react' }),
|
10 |
],
|
11 |
server: {
|
12 |
proxy: {
|