Skip to content

Commit 680277f

Browse files
committed
added support for adding files from URLs
1 parent a72d5d1 commit 680277f

File tree

2 files changed

+122
-15
lines changed

2 files changed

+122
-15
lines changed

components/common.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export interface FileInfo {
7070
name: string;
7171
filename?: string;
7272
contents?: string;
73+
url?: string;
7374
}
7475

7576
export interface FileDirective extends BaseDirective {

components/directives/file.tsx

Lines changed: 121 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { ChevronDownIcon, ChevronRightIcon } from "@heroicons/react/24/outline";
1+
import {
2+
ChevronDownIcon,
3+
ChevronRightIcon,
4+
QuestionMarkCircleIcon,
5+
} from "@heroicons/react/24/outline";
26
import { useState, useEffect } from "react";
37
import { FileInfo } from "@/components/common";
48

@@ -10,8 +14,17 @@ export default function FileDirectiveComponent({
1014
onChange: (file: FileInfo) => void;
1115
}) {
1216
const [isExpanded, setIsExpanded] = useState(true);
17+
const [isDocExpanded, setIsDocExpanded] = useState(false);
1318
const [fileContent, setFileContent] = useState(file.contents || "");
14-
const inputType = file.contents !== undefined ? "content" : "filename";
19+
20+
// Determine input type based on file properties
21+
const getInputType = () => {
22+
if (file.contents !== undefined) return "content";
23+
if (file.url !== undefined) return "url";
24+
return "filename";
25+
};
26+
27+
const inputType = getInputType();
1528

1629
useEffect(() => {
1730
// Update local state when file changes externally
@@ -23,21 +36,57 @@ export default function FileDirectiveComponent({
2336
};
2437

2538
const updateFilename = (value: string) => {
26-
onChange({ ...file, filename: value, contents: undefined });
39+
onChange({
40+
...file,
41+
filename: value,
42+
contents: undefined,
43+
url: undefined,
44+
});
2745
};
2846

2947
const updateContents = (value: string) => {
3048
setFileContent(value);
31-
onChange({ ...file, contents: value, filename: undefined });
49+
onChange({
50+
...file,
51+
contents: value,
52+
filename: undefined,
53+
url: undefined,
54+
});
55+
};
56+
57+
const updateUrl = (value: string) => {
58+
onChange({
59+
...file,
60+
url: value,
61+
contents: undefined,
62+
filename: undefined,
63+
});
3264
};
3365

34-
const toggleInputType = (type: "content" | "filename") => {
66+
const toggleInputType = (type: "content" | "filename" | "url") => {
3567
if (type === inputType) return;
3668

3769
if (type === "content") {
38-
onChange({ ...file, contents: fileContent, filename: undefined });
39-
} else {
40-
onChange({ ...file, contents: undefined, filename: file.filename || "" });
70+
onChange({
71+
...file,
72+
contents: fileContent,
73+
filename: undefined,
74+
url: undefined,
75+
});
76+
} else if (type === "filename") {
77+
onChange({
78+
...file,
79+
contents: undefined,
80+
filename: file.filename || "",
81+
url: undefined,
82+
});
83+
} else if (type === "url") {
84+
onChange({
85+
...file,
86+
contents: undefined,
87+
filename: undefined,
88+
url: file.url || "",
89+
});
4190
}
4291
};
4392

@@ -54,11 +103,43 @@ export default function FileDirectiveComponent({
54103
<ChevronRightIcon className="h-5 w-5" />
55104
)}
56105
</button>
57-
<h2 className="text-[#0c0e0a] font-medium">
106+
<h2 className="text-[#0c0e0a] font-medium flex-1">
58107
File: <span className="font-mono">{file.name}</span>
59108
</h2>
109+
<button
110+
onClick={(e) => {
111+
e.stopPropagation();
112+
setIsDocExpanded(!isDocExpanded);
113+
}}
114+
className="ml-2 text-[#4f7b38] hover:text-[#6aa329] transition-colors"
115+
title="Show documentation"
116+
>
117+
<QuestionMarkCircleIcon className="h-5 w-5" />
118+
</button>
60119
</div>
61120

121+
{isDocExpanded && (
122+
<div className="px-4 py-3 bg-blue-50 border-t border-[#e6f1d6] text-sm">
123+
<h3 className="font-medium text-blue-900 mb-2">File Options</h3>
124+
<div className="space-y-2 text-blue-800">
125+
<div>
126+
<strong>Enter Content:</strong> Directly input the file content
127+
into a text area. Use this when you want to provide the exact
128+
content inline.
129+
</div>
130+
<div>
131+
<strong>Provide Filename:</strong> Reference an existing file by
132+
its path. The system will read the file from the specified
133+
location.
134+
</div>
135+
<div>
136+
<strong>Provide URL:</strong> Reference a file by its URL. The
137+
system will fetch the content from the specified web address.
138+
</div>
139+
</div>
140+
</div>
141+
)}
142+
62143
{isExpanded && (
63144
<div className="p-4 border-t border-[#e6f1d6]">
64145
<div className="mb-4">
@@ -81,8 +162,8 @@ export default function FileDirectiveComponent({
81162
type="button"
82163
onClick={() => toggleInputType("content")}
83164
className={`px-4 py-2 text-sm rounded-md transition-colors ${inputType === "content"
84-
? "bg-white shadow-sm text-[#4f7b38] font-medium"
85-
: "text-gray-600 hover:text-[#4f7b38]"
165+
? "bg-white shadow-sm text-[#4f7b38] font-medium"
166+
: "text-gray-600 hover:text-[#4f7b38]"
86167
}`}
87168
>
88169
Enter Content
@@ -91,12 +172,22 @@ export default function FileDirectiveComponent({
91172
type="button"
92173
onClick={() => toggleInputType("filename")}
93174
className={`px-4 py-2 text-sm rounded-md transition-colors ${inputType === "filename"
94-
? "bg-white shadow-sm text-[#4f7b38] font-medium"
95-
: "text-gray-600 hover:text-[#4f7b38]"
175+
? "bg-white shadow-sm text-[#4f7b38] font-medium"
176+
: "text-gray-600 hover:text-[#4f7b38]"
96177
}`}
97178
>
98179
Provide Filename
99180
</button>
181+
<button
182+
type="button"
183+
onClick={() => toggleInputType("url")}
184+
className={`px-4 py-2 text-sm rounded-md transition-colors ${inputType === "url"
185+
? "bg-white shadow-sm text-[#4f7b38] font-medium"
186+
: "text-gray-600 hover:text-[#4f7b38]"
187+
}`}
188+
>
189+
Provide URL
190+
</button>
100191
</div>
101192
</div>
102193

@@ -112,7 +203,7 @@ export default function FileDirectiveComponent({
112203
placeholder="Enter file contents here..."
113204
/>
114205
</div>
115-
) : (
206+
) : inputType === "filename" ? (
116207
<div>
117208
<label className="block mb-1 font-medium text-sm text-[#1e2a16]">
118209
Filename
@@ -127,9 +218,24 @@ export default function FileDirectiveComponent({
127218
Enter the path to an existing file
128219
</p>
129220
</div>
221+
) : (
222+
<div>
223+
<label className="block mb-1 font-medium text-sm text-[#1e2a16]">
224+
URL
225+
</label>
226+
<input
227+
className="w-full px-3 py-2 border border-gray-200 rounded-md text-[#0c0e0a] focus:outline-none focus:ring-1 focus:ring-[#6aa329] focus:border-[#6aa329]"
228+
value={file.url || ""}
229+
onChange={(e) => updateUrl(e.target.value)}
230+
placeholder="https://example.com/file.txt"
231+
/>
232+
<p className="mt-2 text-sm text-gray-500">
233+
Enter a URL to reference a file from the web
234+
</p>
235+
</div>
130236
)}
131237
</div>
132238
)}
133239
</div>
134240
);
135-
}
241+
}

0 commit comments

Comments
 (0)