瀏覽代碼

feat: tools page

Timothy J. Baek 11 月之前
父節點
當前提交
5a3736f1ee

+ 60 - 0
package-lock.json

@@ -8,6 +8,9 @@
 			"name": "open-webui",
 			"version": "0.3.2",
 			"dependencies": {
+				"@codemirror/lang-javascript": "^6.2.2",
+				"@codemirror/lang-python": "^6.1.6",
+				"@codemirror/theme-one-dark": "^6.1.2",
 				"@pyscript/core": "^0.4.32",
 				"@sveltejs/adapter-node": "^1.3.1",
 				"async": "^3.2.5",
@@ -137,6 +140,32 @@
 				"@lezer/common": "^1.1.0"
 			}
 		},
+		"node_modules/@codemirror/lang-javascript": {
+			"version": "6.2.2",
+			"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz",
+			"integrity": "sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==",
+			"dependencies": {
+				"@codemirror/autocomplete": "^6.0.0",
+				"@codemirror/language": "^6.6.0",
+				"@codemirror/lint": "^6.0.0",
+				"@codemirror/state": "^6.0.0",
+				"@codemirror/view": "^6.17.0",
+				"@lezer/common": "^1.0.0",
+				"@lezer/javascript": "^1.0.0"
+			}
+		},
+		"node_modules/@codemirror/lang-python": {
+			"version": "6.1.6",
+			"resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.6.tgz",
+			"integrity": "sha512-ai+01WfZhWqM92UqjnvorkxosZ2aq2u28kHvr+N3gu012XqY2CThD67JPMHnGceRfXPDBmn1HnyqowdpF57bNg==",
+			"dependencies": {
+				"@codemirror/autocomplete": "^6.3.2",
+				"@codemirror/language": "^6.8.0",
+				"@codemirror/state": "^6.0.0",
+				"@lezer/common": "^1.2.1",
+				"@lezer/python": "^1.1.4"
+			}
+		},
 		"node_modules/@codemirror/language": {
 			"version": "6.10.2",
 			"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.2.tgz",
@@ -175,6 +204,17 @@
 			"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
 			"integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
 		},
+		"node_modules/@codemirror/theme-one-dark": {
+			"version": "6.1.2",
+			"resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz",
+			"integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==",
+			"dependencies": {
+				"@codemirror/language": "^6.0.0",
+				"@codemirror/state": "^6.0.0",
+				"@codemirror/view": "^6.0.0",
+				"@lezer/highlight": "^1.0.0"
+			}
+		},
 		"node_modules/@codemirror/view": {
 			"version": "6.28.0",
 			"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.28.0.tgz",
@@ -915,6 +955,16 @@
 				"@lezer/common": "^1.0.0"
 			}
 		},
+		"node_modules/@lezer/javascript": {
+			"version": "1.4.16",
+			"resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.16.tgz",
+			"integrity": "sha512-84UXR3N7s11MPQHWgMnjb9571fr19MmXnr5zTv2XX0gHXXUvW3uPJ8GCjKrfTXmSdfktjRK0ayKklw+A13rk4g==",
+			"dependencies": {
+				"@lezer/common": "^1.2.0",
+				"@lezer/highlight": "^1.1.3",
+				"@lezer/lr": "^1.3.0"
+			}
+		},
 		"node_modules/@lezer/lr": {
 			"version": "1.4.1",
 			"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.1.tgz",
@@ -923,6 +973,16 @@
 				"@lezer/common": "^1.0.0"
 			}
 		},
+		"node_modules/@lezer/python": {
+			"version": "1.1.14",
+			"resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.14.tgz",
+			"integrity": "sha512-ykDOb2Ti24n76PJsSa4ZoDF0zH12BSw1LGfQXCYJhJyOGiFTfGaX0Du66Ze72R+u/P35U+O6I9m8TFXov1JzsA==",
+			"dependencies": {
+				"@lezer/common": "^1.2.0",
+				"@lezer/highlight": "^1.0.0",
+				"@lezer/lr": "^1.0.0"
+			}
+		},
 		"node_modules/@melt-ui/svelte": {
 			"version": "0.76.0",
 			"resolved": "https://registry.npmjs.org/@melt-ui/svelte/-/svelte-0.76.0.tgz",

+ 3 - 0
package.json

@@ -48,6 +48,9 @@
 	},
 	"type": "module",
 	"dependencies": {
+		"@codemirror/lang-javascript": "^6.2.2",
+		"@codemirror/lang-python": "^6.1.6",
+		"@codemirror/theme-one-dark": "^6.1.2",
 		"@pyscript/core": "^0.4.32",
 		"@sveltejs/adapter-node": "^1.3.1",
 		"async": "^3.2.5",

+ 34 - 0
src/lib/components/common/CodeEditor.svelte

@@ -0,0 +1,34 @@
+<script lang="ts">
+	import { basicSetup, EditorView } from 'codemirror';
+	import { keymap, placeholder } from '@codemirror/view';
+	import { EditorState } from '@codemirror/state';
+
+	import { acceptCompletion } from '@codemirror/autocomplete';
+	import { indentWithTab } from '@codemirror/commands';
+
+	import { python } from '@codemirror/lang-python';
+	import { oneDark } from '@codemirror/theme-one-dark';
+
+	import { onMount } from 'svelte';
+
+	export let value = '';
+
+	onMount(() => {
+		// python code editor, highlight python code
+		const codeEditor = new EditorView({
+			state: EditorState.create({
+				doc: value,
+				extensions: [
+					basicSetup,
+					keymap.of([{ key: 'Tab', run: acceptCompletion }, indentWithTab]),
+					python(),
+					oneDark,
+					placeholder('Enter your code here...')
+				]
+			}),
+			parent: document.getElementById('code-textarea')
+		});
+	});
+</script>
+
+<div id="code-textarea" />

+ 9 - 0
src/routes/(app)/workspace/+layout.svelte

@@ -61,6 +61,15 @@
 				{$i18n.t('Documents')}
 			</a>
 
+			<a
+				class="min-w-fit rounded-lg p-1.5 px-3 {$page.url.pathname.includes('/workspace/tools')
+					? 'bg-gray-50 dark:bg-gray-850'
+					: ''} transition"
+				href="/workspace/tools"
+			>
+				{$i18n.t('Tools')}
+			</a>
+
 			<a
 				class="min-w-fit rounded-lg p-1.5 px-3 {$page.url.pathname.includes('/workspace/playground')
 					? 'bg-gray-50 dark:bg-gray-850'

+ 5 - 0
src/routes/(app)/workspace/tools/+page.svelte

@@ -0,0 +1,5 @@
+<script>
+	import CodeEditor from '$lib/components/common/CodeEditor.svelte';
+</script>
+
+<CodeEditor />