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 handleProxmoxSubmit = async (e) => {
18
  e.preventDefault();
19
- const requestData = { vmid, node };
20
- fetch("http://localhost:2000/api/proxmox/vnc", {
21
- method: "POST",
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
- <div className='w-full shadow-lg rounded-lg'>
47
- <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">
48
- <li className="" onClick={()=>{
49
- setTab("gradio")
50
- props.catch ? props.handelError(false) : props.handelError(props.catch) }}>
51
- <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>
52
- </li>
53
- <li className="" onClick={()=>{
54
- setTab("streamlit")
55
- props.catch ? props.handelError(false) : props.handelError(props.catch) }}>
56
- <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>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  </li>
58
- <li className="" onClick={()=>{
59
- setTab("proxmox")
60
- props.catch ? props.handelError(false) : props.handelError(props.catch) }}>
61
- <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>
 
62
  </li>
63
  </ul>
64
- <div className='absolute right-5 top-5 z-20 mr-5'
65
- onClick={()=>{
66
- props.quitHandeler(false)
67
- props.catch ? props.handelError(false) : props.handelError(props.catch) }}>
68
- <button type="button"
69
- className=" bg-neutral-300 rounded-2xl p-2 inline-flex items-center justify-center dark:bg-neutral-700 hover:opacity-70 focus:outline-none">
70
- <Exit className=" w-[20px] h-[20px] text-gray-400 dark:text-white"/>
71
- </button>
72
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  </div>
74
- { tab === "gradio" &&
75
- <div className='w-full bg-white'>
76
- <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">
77
- <li className="" onClick={()=>{
78
- setSubTab(0)
79
- props.catch ? props.handelError(false) : props.handelError(props.catch) }}>
80
- <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>
81
- </li>
82
- <li className="" onClick={()=>{
83
- setSubTab(1)
84
- props.catch ? props.handelError(false) : props.handelError(props.catch) }}>
85
- <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>
86
- </li>
87
- </ul>
88
- {subTab === 0 && <Local/>}
89
- {subTab === 1 && <Shared type="gradio" textHandler={props.textHandler} appendHandler={props.appendHandler} handelError={props.handelError} catch={props.catch}/>}
 
 
90
 
91
- {props.catch && <div className='p-5'>
92
- <Message floating negative>
93
- <Message.Header className=" text-lg text-center">🚫 Something went wrong...</Message.Header>
94
- <br/>
95
- <h1 className=" underline pb-3 font-bold text-lg">πŸ€” Possible Things That could of happen <br/></h1>
96
- <ul className="font-bold">
97
- <li key={"error_1"}>- The input was empty</li>
98
- <li key={"error_2"}>- The connection was forbidden</li>
99
- <li key={"error_3"}>- The name was already taken</li>
100
- <li key={"error_4"}>- The link you gave did not pass the regex</li>
101
- <ul className="px-6">
102
- <li key={"error_5"}>- http://localhost:xxxx</li>
103
- <li key={"error_6"}>- http://xxxxx.gradio.app</li>
104
- <li key={"error_7"}>- https://hf.space/embed/$user/$space_name/+</li>
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="Embed URL"
154
  className="input input-bordered input-primary w-full max-w-xs"
155
- value={embedUrl}
156
- onChange={(e) => setEmbedUrl(e.target.value)}
 
 
 
 
 
 
 
157
  />
158
- <button className="btn btn-primary mt-2" onClick={() => props.onAddEmbed({ url: embedUrl, type: 'embed' })}>
159
- Add Embed
160
  </button>
161
- </div>
162
- </Modal>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  </div>)
164
  }
165
 
166
- function Local(props){
167
  return (
168
  <div className='p-5'>
169
- <Message floating>
170
-
171
- <Message.Header>πŸ—οΈ Comming soon...</Message.Header>
172
- <Message.Content className='p-5'>
173
- This tab will allow you grab your function from a given directory and build
174
- your own tabular module gradio functions
175
- </Message.Content>
176
 
177
- </Message>
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 : new RegExp("^https?:\\/\\/([0-9a-zA-Z-]+)\\.gradio\\.live\\/?"),
189
- hugginFace : new RegExp("^https?:\\/\\/([a-zA-Z0-9-]+)-gradio\\.hf\\.space\\/?$")
190
- }
191
 
192
  if (!pattern.share.test(url) &&
193
- !pattern.hugginFace.test(url)){
194
- setFetch(false)
195
- return
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
- }).catch((err)=>{
209
  setFetch(false)
210
- })
211
- setFetch(false)
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
- <Message floating>
220
- <div className={`flex items-center rounded-md bg-light-white mt-6 border-dashed`}>
221
- <label className="relative block w-full p-5 focus:shadow-xl">
222
- <span className={`absolute inset-y-0 left-0 flex items-center pl-8`}>
223
- <BsSearch className="block float-left cursor-pointer text-gray-500"/>
224
- </span>
225
- <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`}
226
- placeholder={`URL`}
227
- type="text" name="search"
228
- onChange={(e) => {
229
- props.textHandler(e, "text")
230
- setPreview(e.target.value)
231
- setFetch(isFetchable(e.target.value))
232
- }}
233
- />
234
- </label>
235
- </div>
236
- { fetchable === true && <div className=' w-full'>
237
- <h1 className=' text-xl font-sans font-bold text-center text-black mb-2'> Preview </h1>
238
- <div className='p-3 px-1 w-3/4 h-80 bg-gray-200 mr-auto ml-auto rounded-xl'>
239
- <div className='w-full h-full overflow-hidden relative -ml-[5px]'>
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
- <div className={`flex items-center rounded-md bg-light-white dark:bg-[#1b1c1d] mt-6 border-dashed`}>
245
- <label className="relative block p-5 w-full focus:shadow-xl">
246
- <span className={`absolute inset-y-0 left-0 flex items-center pl-7`}>
247
- <Icon className=" text-gray-500 block float-left cursor-pointer mr-2" name="address card"/>
248
- </span>
249
- <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`}
250
- placeholder={`Name ( > 20 Characters)` }
251
- type="text" name="search"
252
- autoComplete='off'
253
- onChange={(e) => {
254
- props.textHandler(e, "name")
255
- }}
 
256
  />
257
- </label>
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
- onClick={()=>{props.appendHandler(props.type)}}>
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
- </div>
269
- </div>
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
+