Spaces:
Configuration error
Configuration error
zack
commited on
Commit
·
e6949ce
1
Parent(s):
61accb8
🔧 Fix conditional rendering and iframeSrc handling
Browse files
frontend/src/components/Modal/importer.js
CHANGED
@@ -1,272 +1,309 @@
|
|
1 |
-
import { Modal, Icon, Message} from 'semantic-ui-react'
|
2 |
-
import {ReactComponent as Gradio} from '../../images/gradio.svg'
|
3 |
-
import {ReactComponent as Streamlit} from '../../images/streamlit.svg'
|
4 |
-
import {ReactComponent as Exit} from '../../images/exit.svg'
|
5 |
-
import {ReactComponent as Proxmox} from '../../images/proxmox.svg'
|
6 |
import { useState } from 'react'
|
7 |
-
import {BsSearch} from 'react-icons/bs';
|
8 |
|
9 |
-
export default function Import(props){
|
10 |
const [tab, setTab] = useState("gradio")
|
11 |
const [subTab, setSubTab] = useState(0)
|
12 |
-
const [embedUrl, setEmbedUrl] = useState("");
|
13 |
-
const [vmid, setVmid] = useState('');
|
14 |
-
const [node, setNode] = useState('');
|
15 |
-
const [iframeSrc, setIframeSrc] = useState("");
|
16 |
|
17 |
-
const
|
18 |
e.preventDefault();
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
headers: { 'Content-Type': 'application/json' },
|
23 |
-
body: JSON.stringify(requestData)
|
24 |
-
})
|
25 |
-
.then(response => response.json())
|
26 |
-
.then(data => {
|
27 |
-
if(data.iframe_src) {
|
28 |
-
setIframeSrc(data.iframe_src);
|
29 |
-
props.onAddEmbed({ url: data.iframe_src, type: 'embed' });
|
30 |
-
} else {
|
31 |
-
console.error("Failed to get iframe source URL");
|
32 |
-
}
|
33 |
-
})
|
34 |
-
.catch(error => {
|
35 |
-
console.error("Error fetching iframe source URL:", error);
|
36 |
-
});
|
37 |
};
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
return (<div>
|
40 |
<Modal
|
41 |
basic
|
42 |
className=''
|
43 |
open={props.open}
|
44 |
size='fullscreen'
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
</li>
|
58 |
-
<li className="" onClick={()=>{
|
59 |
-
|
60 |
-
props.catch ? props.handelError(false) : props.handelError(props.catch)
|
61 |
-
|
|
|
62 |
</li>
|
63 |
</ul>
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
<
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
</div>
|
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 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
</ul>
|
106 |
-
<li>- link already exist within the menu</li>
|
107 |
-
</ul>
|
108 |
-
|
109 |
-
</Message>
|
110 |
-
</div>}
|
111 |
-
</div>
|
112 |
-
}
|
113 |
-
{ tab === "streamlit" &&
|
114 |
-
<div className='w-full bg-white'>
|
115 |
-
<Shared type="streamlit" textHandler={props.textHandler} appendHandler={props.appendHandler} handelError={props.handelError} catch={props.catch}/>
|
116 |
-
</div>
|
117 |
-
}
|
118 |
-
{ tab === "proxmox" &&
|
119 |
-
<div className='w-full bg-white'>
|
120 |
-
<form onSubmit={handleProxmoxSubmit} className="p-5">
|
121 |
-
<input
|
122 |
-
type="text"
|
123 |
-
placeholder="VM ID"
|
124 |
-
className="input input-bordered input-primary w-full max-w-xs"
|
125 |
-
value={vmid}
|
126 |
-
onChange={(e) => setVmid(e.target.value)}
|
127 |
-
/>
|
128 |
-
<input
|
129 |
-
type="text"
|
130 |
-
placeholder="Node"
|
131 |
-
className="input input-bordered input-primary w-full max-w-xs mt-2"
|
132 |
-
value={node}
|
133 |
-
onChange={(e) => setNode(e.target.value)}
|
134 |
-
/>
|
135 |
-
<button className="btn btn-primary mt-2" type="submit">
|
136 |
-
Generate Proxmox noVNC Session
|
137 |
-
</button>
|
138 |
-
</form>
|
139 |
-
{iframeSrc &&
|
140 |
-
<div className='p-5 flex flex-col items-start'>
|
141 |
-
<a href={iframeSrc} target="_blank" rel="noopener noreferrer" className="mb-2 underline text-blue-600 hover:text-blue-800 visited:text-purple-600">Access Proxmox noVNC Session</a>
|
142 |
-
<button onClick={() => navigator.clipboard.writeText(iframeSrc)} className="btn btn-primary">
|
143 |
-
Copy Session Link
|
144 |
-
</button>
|
145 |
-
</div>
|
146 |
-
}
|
147 |
-
</div>
|
148 |
-
}
|
149 |
-
|
150 |
-
<div className='embed-form p-5'>
|
151 |
<input
|
152 |
type="text"
|
153 |
-
placeholder="
|
154 |
className="input input-bordered input-primary w-full max-w-xs"
|
155 |
-
value={
|
156 |
-
onChange={(e) =>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
/>
|
158 |
-
<button className="btn btn-primary mt-2"
|
159 |
-
|
160 |
</button>
|
161 |
-
</
|
162 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
</div>)
|
164 |
}
|
165 |
|
166 |
-
function Local(props){
|
167 |
return (
|
168 |
<div className='p-5'>
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
|
177 |
-
|
178 |
</div>
|
179 |
)
|
180 |
}
|
181 |
|
182 |
-
function Shared(props){
|
183 |
const [preview, setPreview] = useState("")
|
184 |
const [fetchable, setFetch] = useState(false)
|
185 |
|
186 |
const isFetchable = async (url) => {
|
187 |
const pattern = {
|
188 |
-
share
|
189 |
-
hugginFace
|
190 |
-
}
|
191 |
|
192 |
if (!pattern.share.test(url) &&
|
193 |
-
!pattern.hugginFace.test(url)){
|
194 |
-
|
195 |
-
|
196 |
-
|
|
|
197 |
|
198 |
-
|
199 |
-
fetch(url, {mode : "no-cors"}).then((re) => {
|
200 |
console.log(re)
|
201 |
-
if(re.url.includes("http://localhost:3000")){
|
202 |
-
setFetch(false)
|
203 |
-
} else {
|
204 |
setFetch(true)
|
205 |
-
props.catch ? props.handelError(false) : props.handelError(props.catch)
|
206 |
}
|
207 |
-
|
208 |
-
|
209 |
setFetch(false)
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
return (
|
215 |
-
<div className='w-full shadow-lg' onKeyPress={(e)=>{
|
216 |
if (e.key.includes("Enter")) props.appendHandler(props.type)
|
217 |
}}>
|
218 |
<div className='p-5'>
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
<iframe title='Preview' src={preview} className=' absolute top-0 bottom-0 left-0 -right-[25px] overflow-y-scroll w-full h-full mr-auto ml-auto'/>
|
241 |
-
</div>
|
242 |
</div>
|
243 |
-
</div>
|
244 |
-
|
245 |
-
<
|
246 |
-
<
|
247 |
-
<
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
|
|
256 |
/>
|
257 |
-
|
258 |
-
</div>
|
259 |
<div className=' right-0 ml-5'>
|
260 |
<button className="relative inline-flex justify-center p-0.5 mb-2 mr-2 overflow-hidden text-sm font-sans font-bold text-gray-900 rounded-lg group bg-gradient-to-br from-purple-600 to-blue-500 group-hover:from-purple-600 group-hover:to-blue-500 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800"
|
261 |
-
|
262 |
<span className="relative px-5 py-2.5 transition-all ease-in duration-75 bg-white dark:bg-[#1b1c1d] rounded-md group-hover:bg-opacity-0">
|
263 |
Enter
|
264 |
</span>
|
265 |
</button>
|
266 |
</div>
|
267 |
</Message>
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
)
|
272 |
-
}
|
|
|
1 |
+
import { Modal, Icon, Message } from 'semantic-ui-react'
|
2 |
+
import { ReactComponent as Gradio } from '../../images/gradio.svg'
|
3 |
+
import { ReactComponent as Streamlit } from '../../images/streamlit.svg'
|
4 |
+
import { ReactComponent as Exit } from '../../images/exit.svg'
|
5 |
+
import { ReactComponent as Proxmox } from '../../images/proxmox.svg'
|
6 |
import { useState } from 'react'
|
7 |
+
import { BsSearch } from 'react-icons/bs';
|
8 |
|
9 |
+
export default function Import(props) {
|
10 |
const [tab, setTab] = useState("gradio")
|
11 |
const [subTab, setSubTab] = useState(0)
|
12 |
+
const [embedUrl, setEmbedUrl] = useState("");
|
13 |
+
const [vmid, setVmid] = useState('');
|
14 |
+
const [node, setNode] = useState('');
|
15 |
+
const [iframeSrc, setIframeSrc] = useState("");
|
16 |
|
17 |
+
const handleSubmit = async (e) => {
|
18 |
e.preventDefault();
|
19 |
+
// Assuming iframeSrc is already bound to an input field where users can paste any iframe link
|
20 |
+
console.debug("Embed submit:", iframeSrc);
|
21 |
+
props.onAddEmbed({ url: iframeSrc, type: 'embed' });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
};
|
23 |
|
24 |
+
// const handleProxmoxSubmit = async (e) => {
|
25 |
+
// e.preventDefault();
|
26 |
+
// const requestData = { vmid, node };
|
27 |
+
// fetch("http://localhost:2000/api/proxmox/vnc", {
|
28 |
+
// method: "POST",
|
29 |
+
// headers: { 'Content-Type': 'application/json' },
|
30 |
+
// body: JSON.stringify(requestData)
|
31 |
+
// })
|
32 |
+
// .then(response => response.json())
|
33 |
+
// .then(data => {
|
34 |
+
// if(data.iframe_src) {
|
35 |
+
// setIframeSrc(data.iframe_src);
|
36 |
+
// props.onAddEmbed({ url: data.iframe_src, type: 'embed' });
|
37 |
+
// } else {
|
38 |
+
// console.error("Failed to get iframe source URL");
|
39 |
+
// }
|
40 |
+
// })
|
41 |
+
// .catch(error => {
|
42 |
+
// console.error("Error fetching iframe source URL:", error);
|
43 |
+
// });
|
44 |
+
// };
|
45 |
+
|
46 |
return (<div>
|
47 |
<Modal
|
48 |
basic
|
49 |
className=''
|
50 |
open={props.open}
|
51 |
size='fullscreen'
|
52 |
+
>
|
53 |
+
<div className='w-full shadow-lg rounded-lg'>
|
54 |
+
<ul className="flex flex-wrap text-sm font-medium text-center text-gray-500 bg-gray-100 rounded-t-lg border-gray-200 dark:border-gray-700 dark:text-gray-400 dark:bg-gray-800" id="defaultTab" data-tabs-toggle="#defaultTabContent" role="tablist">
|
55 |
+
<li className="" onClick={() => {
|
56 |
+
setTab("gradio")
|
57 |
+
props.catch ? props.handelError(false) : props.handelError(props.catch)
|
58 |
+
}}>
|
59 |
+
<button id="gradio-tab" data-tabs-target="#Gradio" type="button" role="tab" aria-controls="gradio" aria-selected={tab === "gradio" ? "true" : "false"} className={`inline-block p-4 rounded-tl-lg ${tab === "gradio" ? 'bg-gray-200' : 'hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 focus:bg-gray-700'}`}><Gradio className=" w-20 h-10" /></button>
|
60 |
+
</li>
|
61 |
+
<li className="" onClick={() => {
|
62 |
+
setTab("streamlit")
|
63 |
+
props.catch ? props.handelError(false) : props.handelError(props.catch)
|
64 |
+
}}>
|
65 |
+
<button id="services-tab" data-tabs-target="#Streamlit" type="button" role="tab" aria-controls="services" aria-selected="false" className={`inline-block p-4 rounded-tl-lg ${tab === "streamlit" ? 'bg-gray-200' : 'hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 focus:bg-gray-700'}`}><Streamlit className=" w-20 h-10" /></button>
|
66 |
+
</li>
|
67 |
+
<li className="" onClick={() => {
|
68 |
+
setTab("proxmox")
|
69 |
+
props.catch ? props.handelError(false) : props.handelError(props.catch)
|
70 |
+
}}>
|
71 |
+
<button id="proxmox-tab" data-tabs-target="#Proxmox" type="button" role="tab" aria-controls="proxmox" aria-selected={tab === "proxmox" ? "true" : "false"} className={`inline-block p-4 rounded-tl-lg ${tab === "proxmox" ? 'bg-gray-200' : 'hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 focus:bg-gray-700'}`}><Proxmox className=" w-20 h-10" /></button>
|
72 |
+
</li>
|
73 |
+
</ul>
|
74 |
+
<div className='absolute right-5 top-5 z-20 mr-5'
|
75 |
+
onClick={() => {
|
76 |
+
props.quitHandeler(false)
|
77 |
+
props.catch ? props.handelError(false) : props.handelError(props.catch)
|
78 |
+
}}>
|
79 |
+
<button type="button"
|
80 |
+
className=" bg-neutral-300 rounded-2xl p-2 inline-flex items-center justify-center dark:bg-neutral-700 hover:opacity-70 focus:outline-none">
|
81 |
+
<Exit className=" w-[20px] h-[20px] text-gray-400 dark:text-white" />
|
82 |
+
</button>
|
83 |
+
</div>
|
84 |
+
</div>
|
85 |
+
{tab === "gradio" &&
|
86 |
+
<div className='w-full bg-white'>
|
87 |
+
<ul className="flex flex-wrap text-sm font-medium text-center text-gray-500 bg-gray-200 border-gray-200 dark:border-gray-700 dark:text-gray-400 dark:bg-gray-800" id="defaultTab" data-tabs-toggle="#defaultTabContent" role="tablist">
|
88 |
+
<li className="" onClick={() => {
|
89 |
+
setSubTab(0)
|
90 |
+
props.catch ? props.handelError(false) : props.handelError(props.catch)
|
91 |
+
}}>
|
92 |
+
<button id="local-sub-tab" data-tabs-target="#local" type="button" role="tab" aria-controls="local-gradio" aria-selected={tab === "gradio" ? "true" : "false"} className={`inline-block p-4 px-6 text-base font-sans font-bold ${subTab === 0 ? 'bg-gray-300' : ''} hover:bg-gray-300 `}>Local</button>
|
93 |
</li>
|
94 |
+
<li className="" onClick={() => {
|
95 |
+
setSubTab(1)
|
96 |
+
props.catch ? props.handelError(false) : props.handelError(props.catch)
|
97 |
+
}}>
|
98 |
+
<button id="shared-sub-tab" data-tabs-target="#Gradio" type="button" role="tab" aria-controls="shared-gradio" aria-selected={tab === "gradio" ? "true" : "false"} className={`inline-block p-4 px-6 text-base font-sans font-bold ${subTab === 1 ? 'bg-gray-300' : ''} hover:bg-gray-300 `}>Shared</button>
|
99 |
</li>
|
100 |
</ul>
|
101 |
+
{subTab === 0 && <Local />}
|
102 |
+
{subTab === 1 && <Shared type="gradio" textHandler={props.textHandler} appendHandler={props.appendHandler} handelError={props.handelError} catch={props.catch} />}
|
103 |
+
|
104 |
+
{props.catch && <div className='p-5'>
|
105 |
+
<Message floating negative>
|
106 |
+
<Message.Header className=" text-lg text-center">🚫 Something went wrong...</Message.Header>
|
107 |
+
<br />
|
108 |
+
<h1 className=" underline pb-3 font-bold text-lg">🤔 Possible Things That could of happen <br /></h1>
|
109 |
+
<ul className="font-bold">
|
110 |
+
<li key={"error_1"}>- The input was empty</li>
|
111 |
+
<li key={"error_2"}>- The connection was forbidden</li>
|
112 |
+
<li key={"error_3"}>- The name was already taken</li>
|
113 |
+
<li key={"error_4"}>- The link you gave did not pass the regex</li>
|
114 |
+
<ul className="px-6">
|
115 |
+
<li key={"error_5"}>- http://localhost:xxxx</li>
|
116 |
+
<li key={"error_6"}>- http://xxxxx.gradio.app</li>
|
117 |
+
<li key={"error_7"}>- https://hf.space/embed/$user/$space_name/+</li>
|
118 |
+
</ul>
|
119 |
+
<li>- link already exist within the menu</li>
|
120 |
+
</ul>
|
121 |
+
|
122 |
+
</Message>
|
123 |
+
</div>}
|
124 |
</div>
|
125 |
+
}
|
126 |
+
{tab === "streamlit" &&
|
127 |
+
<div className='w-full bg-white'>
|
128 |
+
<Shared type="streamlit" textHandler={props.textHandler} appendHandler={props.appendHandler} handelError={props.handelError} catch={props.catch} />
|
129 |
+
</div>
|
130 |
+
}
|
131 |
+
{tab === "IframeURL" && (
|
132 |
+
<form onSubmit={handleSubmit}>
|
133 |
+
<input
|
134 |
+
type="text"
|
135 |
+
placeholder="Enter iframe link here..."
|
136 |
+
value={iframeSrc}
|
137 |
+
onChange={(e) => setIframeSrc(e.target.value)}
|
138 |
+
className="input"
|
139 |
+
/>
|
140 |
+
<button type="submit" className="button">Embed</button>
|
141 |
+
</form>
|
142 |
+
)}
|
143 |
|
144 |
+
// Ensure this conditional rendering block is correctly placed within your component's return statement
|
145 |
+
{iframeSrc && (
|
146 |
+
<div className='p-5 flex flex-col items-start'>
|
147 |
+
<iframe src={iframeSrc} frameBorder="0" style={{ width: "100%", height: "400px" }} allowFullScreen></iframe>
|
148 |
+
</div>
|
149 |
+
)}
|
150 |
+
{iframeSrc &&
|
151 |
+
<div className='p-5 flex flex-col items-start'>
|
152 |
+
<iframe src={iframeSrc} frameBorder="0" style={{ width: "100%", height: "400px" }} allowFullScreen></iframe>
|
153 |
+
</div>
|
154 |
+
}
|
155 |
+
{tab === "proxmox" &&
|
156 |
+
<div className='w-full bg-white'>
|
157 |
+
<form onSubmit={handleProxmoxSubmit} className="p-5">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
<input
|
159 |
type="text"
|
160 |
+
placeholder="VM ID"
|
161 |
className="input input-bordered input-primary w-full max-w-xs"
|
162 |
+
value={vmid}
|
163 |
+
onChange={(e) => setVmid(e.target.value)}
|
164 |
+
/>
|
165 |
+
<input
|
166 |
+
type="text"
|
167 |
+
placeholder="Node"
|
168 |
+
className="input input-bordered input-primary w-full max-w-xs mt-2"
|
169 |
+
value={node}
|
170 |
+
onChange={(e) => setNode(e.target.value)}
|
171 |
/>
|
172 |
+
<button className="btn btn-primary mt-2" type="submit">
|
173 |
+
Generate Proxmox noVNC Session
|
174 |
</button>
|
175 |
+
</form>
|
176 |
+
{iframeSrc &&
|
177 |
+
<div className='p-5 flex flex-col items-start'>
|
178 |
+
<a href={iframeSrc} target="_blank" rel="noopener noreferrer" className="mb-2 underline text-blue-600 hover:text-blue-800 visited:text-purple-600">Access Proxmox noVNC Session</a>
|
179 |
+
<button onClick={() => navigator.clipboard.writeText(iframeSrc)} className="btn btn-primary">
|
180 |
+
Copy Session Link
|
181 |
+
</button>
|
182 |
+
</div>
|
183 |
+
}
|
184 |
+
</div>
|
185 |
+
}
|
186 |
+
|
187 |
+
<div className='embed-form p-5'>
|
188 |
+
<input
|
189 |
+
type="text"
|
190 |
+
placeholder="Embed URL"
|
191 |
+
className="input input-bordered input-primary w-full max-w-xs"
|
192 |
+
value={embedUrl}
|
193 |
+
onChange={(e) => setEmbedUrl(e.target.value)}
|
194 |
+
/>
|
195 |
+
<button className="btn btn-primary mt-2" onClick={() => props.onAddEmbed({ url: embedUrl, type: 'embed' })}>
|
196 |
+
Add Embed
|
197 |
+
</button>
|
198 |
+
</div>
|
199 |
+
</Modal>
|
200 |
</div>)
|
201 |
}
|
202 |
|
203 |
+
function Local(props) {
|
204 |
return (
|
205 |
<div className='p-5'>
|
206 |
+
<Message floating>
|
207 |
+
|
208 |
+
<Message.Header>🏗️ Comming soon...</Message.Header>
|
209 |
+
<Message.Content className='p-5'>
|
210 |
+
This tab will allow you grab your function from a given directory and build
|
211 |
+
your own tabular module gradio functions
|
212 |
+
</Message.Content>
|
213 |
|
214 |
+
</Message>
|
215 |
</div>
|
216 |
)
|
217 |
}
|
218 |
|
219 |
+
function Shared(props) {
|
220 |
const [preview, setPreview] = useState("")
|
221 |
const [fetchable, setFetch] = useState(false)
|
222 |
|
223 |
const isFetchable = async (url) => {
|
224 |
const pattern = {
|
225 |
+
share: new RegExp("^https?:\\/\\/([0-9a-zA-Z-]+)\\.gradio\\.live\\/?"),
|
226 |
+
hugginFace: new RegExp("^https?:\\/\\/([a-zA-Z0-9-]+)-gradio\\.hf\\.space\\/?$")
|
227 |
+
}
|
228 |
|
229 |
if (!pattern.share.test(url) &&
|
230 |
+
!pattern.hugginFace.test(url)) {
|
231 |
+
setFetch(false)
|
232 |
+
return
|
233 |
+
}
|
234 |
+
|
235 |
|
236 |
+
fetch(url, { mode: "no-cors" }).then((re) => {
|
|
|
237 |
console.log(re)
|
238 |
+
if (re.url.includes("http://localhost:3000")) {
|
239 |
+
setFetch(false)
|
240 |
+
} else {
|
241 |
setFetch(true)
|
242 |
+
props.catch ? props.handelError(false) : props.handelError(props.catch)
|
243 |
}
|
244 |
+
|
245 |
+
}).catch((err) => {
|
246 |
setFetch(false)
|
247 |
+
})
|
248 |
+
setFetch(false)
|
249 |
+
}
|
250 |
+
|
251 |
return (
|
252 |
+
<div className='w-full shadow-lg' onKeyPress={(e) => {
|
253 |
if (e.key.includes("Enter")) props.appendHandler(props.type)
|
254 |
}}>
|
255 |
<div className='p-5'>
|
256 |
+
<Message floating>
|
257 |
+
<div className={`flex items-center rounded-md bg-light-white mt-6 border-dashed`}>
|
258 |
+
<label className="relative block w-full p-5 focus:shadow-xl">
|
259 |
+
<span className={`absolute inset-y-0 left-0 flex items-center pl-8`}>
|
260 |
+
<BsSearch className="block float-left cursor-pointer text-gray-500" />
|
261 |
+
</span>
|
262 |
+
<input className={`placeholder:italic placeholder:text-slate-400 text-black dark:text-white block w-full border border-slate-300 border-dashed rounded-md py-2 pl-9 pr-3 focus:shadow-xl focus:outline-none focus:border-sky-500 focus:ring-sky-500 focus:ring-1 sm:text-sm bg-transparent`}
|
263 |
+
placeholder={`URL`}
|
264 |
+
type="text" name="search"
|
265 |
+
onChange={(e) => {
|
266 |
+
props.textHandler(e, "text")
|
267 |
+
setPreview(e.target.value)
|
268 |
+
setFetch(isFetchable(e.target.value))
|
269 |
+
}}
|
270 |
+
/>
|
271 |
+
</label>
|
272 |
+
</div>
|
273 |
+
{fetchable === true && <div className=' w-full'>
|
274 |
+
<h1 className=' text-xl font-sans font-bold text-center text-black mb-2'> Preview </h1>
|
275 |
+
<div className='p-3 px-1 w-3/4 h-80 bg-gray-200 mr-auto ml-auto rounded-xl'>
|
276 |
+
<div className='w-full h-full overflow-hidden relative -ml-[5px]'>
|
277 |
+
<iframe title='Preview' src={preview} className=' absolute top-0 bottom-0 left-0 -right-[25px] overflow-y-scroll w-full h-full mr-auto ml-auto' />
|
|
|
278 |
</div>
|
279 |
+
</div>
|
280 |
+
</div>}
|
281 |
+
<div className={`flex items-center rounded-md bg-light-white dark:bg-[#1b1c1d] mt-6 border-dashed`}>
|
282 |
+
<label className="relative block p-5 w-full focus:shadow-xl">
|
283 |
+
<span className={`absolute inset-y-0 left-0 flex items-center pl-7`}>
|
284 |
+
<Icon className=" text-gray-500 block float-left cursor-pointer mr-2" name="address card" />
|
285 |
+
</span>
|
286 |
+
<input className={`placeholder:italic placeholder:text-slate-400 text-black dark:text-white block bg-transparent w-full border border-slate-300 border-dashed rounded-md py-2 pl-9 pr-3 focus:shadow-xl focus:outline-none focus:border-sky-500 focus:ring-sky-500 focus:ring-1 sm:text-sm`}
|
287 |
+
placeholder={`Name ( > 20 Characters)`}
|
288 |
+
type="text" name="search"
|
289 |
+
autoComplete='off'
|
290 |
+
onChange={(e) => {
|
291 |
+
props.textHandler(e, "name")
|
292 |
+
}}
|
293 |
/>
|
294 |
+
</label>
|
295 |
+
</div>
|
296 |
<div className=' right-0 ml-5'>
|
297 |
<button className="relative inline-flex justify-center p-0.5 mb-2 mr-2 overflow-hidden text-sm font-sans font-bold text-gray-900 rounded-lg group bg-gradient-to-br from-purple-600 to-blue-500 group-hover:from-purple-600 group-hover:to-blue-500 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800"
|
298 |
+
onClick={() => { props.appendHandler(props.type) }}>
|
299 |
<span className="relative px-5 py-2.5 transition-all ease-in duration-75 bg-white dark:bg-[#1b1c1d] rounded-md group-hover:bg-opacity-0">
|
300 |
Enter
|
301 |
</span>
|
302 |
</button>
|
303 |
</div>
|
304 |
</Message>
|
305 |
+
</div>
|
306 |
+
</div>
|
307 |
+
|
308 |
)
|
309 |
+
}
|
frontend/src/components/ReactFlow/ReactFlowEnv.js
CHANGED
@@ -231,3 +231,4 @@ export default function ReactEnviorment() {
|
|
231 |
);
|
232 |
}
|
233 |
|
|
|
|
231 |
);
|
232 |
}
|
233 |
|
234 |
+
|