ToolkitEditor.svelte 3.77 KB
Newer Older
Timothy J. Baek's avatar
Timothy J. Baek committed
1
<script>
Timothy J. Baek's avatar
Timothy J. Baek committed
2
	import { getContext, createEventDispatcher, onMount } from 'svelte';
Timothy J. Baek's avatar
Timothy J. Baek committed
3
4
5
6
7
8

	const i18n = getContext('i18n');

	import CodeEditor from './CodeEditor.svelte';
	import { goto } from '$app/navigation';

Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
9
10
	const dispatch = createEventDispatcher();

Timothy J. Baek's avatar
Timothy J. Baek committed
11
	let formElement = null;
Timothy J. Baek's avatar
Timothy J. Baek committed
12
13
	let loading = false;

Timothy J. Baek's avatar
Timothy J. Baek committed
14
	export let edit = false;
Timothy J. Baek's avatar
Timothy J. Baek committed
15
	export let clone = false;
Timothy J. Baek's avatar
Timothy J. Baek committed
16
17
18
19

	export let id = '';
	export let name = '';
	export let meta = {
Timothy J. Baek's avatar
Timothy J. Baek committed
20
21
		description: ''
	};
Timothy J. Baek's avatar
Timothy J. Baek committed
22
	export let content = '';
Timothy J. Baek's avatar
Timothy J. Baek committed
23

Timothy J. Baek's avatar
Timothy J. Baek committed
24
	$: if (name && !edit && !clone) {
Timothy J. Baek's avatar
Timothy J. Baek committed
25
26
27
28
29
30
31
		id = name.replace(/\s+/g, '_').toLowerCase();
	}

	let codeEditor;

	const saveHandler = async () => {
		loading = true;
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
32
33
34
35
36
37
		dispatch('save', {
			id,
			name,
			meta,
			content
		});
Timothy J. Baek's avatar
Timothy J. Baek committed
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
	};

	const submitHandler = async () => {
		if (codeEditor) {
			const res = await codeEditor.formatHandler();

			if (res) {
				console.log('Code formatted successfully');
				saveHandler();
			}
		}
	};
</script>

<div class=" flex flex-col justify-between w-full overflow-y-auto h-full">
	<div class="mx-auto w-full md:px-0 h-full">
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
54
		<form
Timothy J. Baek's avatar
Timothy J. Baek committed
55
			bind:this={formElement}
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
56
57
58
59
60
			class=" flex flex-col max-h-[100dvh] h-full"
			on:submit|preventDefault={() => {
				submitHandler();
			}}
		>
Timothy J. Baek's avatar
Timothy J. Baek committed
61
62
63
64
65
66
			<div class="mb-2.5">
				<button
					class="flex space-x-1"
					on:click={() => {
						goto('/workspace/tools');
					}}
Timothy J. Baek's avatar
Timothy J. Baek committed
67
					type="button"
Timothy J. Baek's avatar
Timothy J. Baek committed
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
				>
					<div class=" self-center">
						<svg
							xmlns="http://www.w3.org/2000/svg"
							viewBox="0 0 20 20"
							fill="currentColor"
							class="w-4 h-4"
						>
							<path
								fill-rule="evenodd"
								d="M17 10a.75.75 0 01-.75.75H5.612l4.158 3.96a.75.75 0 11-1.04 1.08l-5.5-5.25a.75.75 0 010-1.08l5.5-5.25a.75.75 0 111.04 1.08L5.612 9.25H16.25A.75.75 0 0117 10z"
								clip-rule="evenodd"
							/>
						</svg>
					</div>
					<div class=" self-center font-medium text-sm">{$i18n.t('Back')}</div>
				</button>
			</div>

			<div class="flex flex-col flex-1 overflow-auto h-0 rounded-lg">
				<div class="w-full mb-2 flex flex-col gap-1.5">
					<div class="flex gap-2 w-full">
						<input
							class="w-full px-3 py-2 text-sm font-medium bg-gray-50 dark:bg-gray-850 dark:text-gray-200 rounded-lg outline-none"
							type="text"
							placeholder="Toolkit Name (e.g. My ToolKit)"
							bind:value={name}
							required
						/>

						<input
Timothy J. Baek's avatar
Timothy J. Baek committed
99
							class="w-full px-3 py-2 text-sm font-medium disabled:text-gray-300 dark:disabled:text-gray-700 bg-gray-50 dark:bg-gray-850 dark:text-gray-200 rounded-lg outline-none"
Timothy J. Baek's avatar
Timothy J. Baek committed
100
101
102
103
							type="text"
							placeholder="Toolkit ID (e.g. my_toolkit)"
							bind:value={id}
							required
Timothy J. Baek's avatar
Timothy J. Baek committed
104
							disabled={edit}
Timothy J. Baek's avatar
Timothy J. Baek committed
105
106
107
108
109
110
111
112
113
114
115
116
						/>
					</div>
					<input
						class="w-full px-3 py-2 text-sm font-medium bg-gray-50 dark:bg-gray-850 dark:text-gray-200 rounded-lg outline-none"
						type="text"
						placeholder="Toolkit Description (e.g. A toolkit for performing various operations)"
						bind:value={meta.description}
						required
					/>
				</div>

				<div class="mb-2 flex-1 overflow-auto h-0 rounded-lg">
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
117
118
119
120
					<CodeEditor
						bind:value={content}
						bind:this={codeEditor}
						on:save={() => {
Timothy J. Baek's avatar
Timothy J. Baek committed
121
122
123
							if (formElement) {
								formElement.requestSubmit();
							}
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
124
125
						}}
					/>
Timothy J. Baek's avatar
Timothy J. Baek committed
126
127
				</div>

Timothy J. Baek's avatar
Timothy J. Baek committed
128
129
130
131
132
133
134
135
136
137
				<div class="pb-3 flex justify-between">
					<div class="flex-1 pr-3">
						<div class="text-xs text-gray-500 line-clamp-2">
							<span class=" font-semibold dark:text-gray-200">Warning:</span> Tools are a function
							calling system with arbitrary code execution <br />—
							<span class=" font-medium dark:text-gray-400"
								>don't install random tools from sources you don't trust.</span
							>
						</div>
					</div>
Timothy J. Baek's avatar
Timothy J. Baek committed
138
139
140
141
142
143
144
					<button
						class="px-3 py-1.5 text-sm font-medium bg-emerald-600 hover:bg-emerald-700 text-gray-50 transition rounded-lg"
					>
						{$i18n.t('Save')}
					</button>
				</div>
			</div>
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
145
		</form>
Timothy J. Baek's avatar
Timothy J. Baek committed
146
147
	</div>
</div>