@@ -5,9 +5,10 @@ import copy from 'copy-to-clipboard';
55import CopyThis from '../assets/images/copy-this.png' ;
66import LeftPane from '../assets/images/left-pane-instructions.png' ;
77
8+ import { BsFillPencilFill } from 'react-icons/bs' ;
89import { AiFillCheckCircle } from "react-icons/ai" ;
910import { BiLinkExternal } from 'react-icons/bi' ;
10- import { IoMdClose } from "react-icons/io" ;
11+ import { IoMdClose , IoMdCloseCircle } from "react-icons/io" ;
1112import { IoAddCircleOutline } from "react-icons/io5" ;
1213import { RxCopy } from 'react-icons/rx' ;
1314import { ClipLoader } from "react-spinners" ;
@@ -28,6 +29,7 @@ export interface DataSourcePanelState {
2829 isAdding : boolean
2930 selectedDataSource : SelectOption
3031 isAddingLoading : boolean
32+ editMode : boolean
3133}
3234
3335export interface DataSourcePanelProps {
@@ -68,6 +70,9 @@ const slackManifest = {
6870 }
6971}
7072
73+ // let editMode = false;
74+ let addOrRemoveIcon = < AiFillCheckCircle className = "ml-6 text-[#9875d4] text-2xl" /> ;
75+
7176export default class DataSourcePanel extends React . Component < DataSourcePanelProps , DataSourcePanelState > {
7277
7378 constructor ( props ) {
@@ -76,7 +81,8 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
7681 selectOptions : [ ] ,
7782 isAdding : false ,
7883 isAddingLoading : false ,
79- selectedDataSource : { value : 'unknown' , label : 'unknown' , imageBase64 : '' , configFields : [ ] }
84+ selectedDataSource : { value : 'unknown' , label : 'unknown' , imageBase64 : '' , configFields : [ ] } ,
85+ editMode : false
8086 }
8187 }
8288
@@ -88,7 +94,8 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
8894 label : data_source . display_name ,
8995 imageBase64 : data_source . image_base64 ,
9096 configFields : data_source . config_fields
91- } }
97+ }
98+ }
9299 ) ;
93100
94101 this . setState ( {
@@ -116,24 +123,32 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
116123
117124 render ( ) {
118125 return (
119- < div className = "relative flex flex-col bg-[#221f2e] items-start px-8 pt-0 pb-4 min-h-[300px]" >
126+ < div className = "relative flex flex-col bg-[#221f2e] items-start px-8 pt-0 pb-4 min-h-[300px]" > 1
120127 {
121128 ! this . state . isAdding && < h1 className = "mt-4 relative self-center text-white block text-4xl mb-8 font-poppins" > Data Source Panel</ h1 >
122129 }
123- < IoMdClose onClick = { this . props . onClose } className = 'absolute right-4 top-3 text-2xl text-white hover:text-[#9875d4] hover:cursor-pointer' > </ IoMdClose >
130+
131+ { /* X and Edit in top right */ }
132+ < div className = "absolute flex flex-col items-center right-4 top-3 text-2xl text-white gap-4" >
133+ < IoMdClose onClick = { this . props . onClose } className = 'hover:text-[#9875d4] hover:cursor-pointer' />
134+ { this . state . isAdding === false && < BsFillPencilFill key = "pencil" onClick = { this . swithcMode } className = 'text-base hover:text-[#9875d4] hover:cursor-pointer' /> }
135+ </ div >
124136 {
125137 ! this . state . isAdding && (
126138 < div >
127139 < h1 className = "text-2xl block text-white mb-4" >
140+ { /* h1 tag specifies whether there are active data sources */ }
128141 { this . props . connectedDataSources . length > 0 ? 'Active data sources:' : 'No Active Data Sources. Add Now!' }
129142 </ h1 >
130143 < div className = "flex flex-row w-[100%] flex-wrap" >
131144 { this . props . connectedDataSources . map ( ( data_source ) => {
132145 return (
146+ // connected data source
133147 < div className = "flex py-2 pl-5 pr-3 m-2 flex-row items-center justify-center bg-[#352C45] hover:shadow-inner shadow-blue-500/50 rounded-lg font-poppins leading-[28px] border-b-[#916CCD] border-b-2" >
134148 < img alt = "data-source" className = { "mr-2 h-[20px]" } src = { this . props . dataSourceTypesDict [ data_source ] . image_base64 } > </ img >
135149 < h1 className = "text-white" > { this . props . dataSourceTypesDict [ data_source ] . display_name } </ h1 >
136- < AiFillCheckCircle className = "ml-6 text-[#9875d4] text-2xl" > </ AiFillCheckCircle >
150+ { addOrRemoveIcon }
151+
137152 </ div >
138153 )
139154 } )
@@ -143,6 +158,7 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
143158 let dataSource = this . props . dataSourceTypesDict [ key ] ;
144159 if ( ! this . props . connectedDataSources . includes ( dataSource . name ) ) {
145160 return (
161+ // unconnected data source
146162 < div onClick = { ( ) => this . dataSourceToAddSelected ( dataSource ) } className = "flex hover:text-[#9875d4] py-2 pl-5 pr-3 m-2 flex-row items-center justify-center bg-[#36323b] hover:border-[#9875d4] rounded-lg font-poppins leading-[28px] border-[#777777] border-b-[.5px] transition duration-300 ease-in-out" >
147163 < img alt = "" className = { "mr-2 h-[20px]" } src = { dataSource . image_base64 } > </ img >
148164 { /* <h1 className="text-white">Add</h1> */ }
@@ -160,7 +176,8 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
160176 < IoAddCircleOutline className = "ml-4 text-white text-2xl hover:text-[#9875d4] hover:cursor-pointer transition duration-200 ease-in-out" > </ IoAddCircleOutline >
161177 </ div >
162178 </ div >
163- </ div > )
179+ </ div >
180+ )
164181 }
165182 {
166183 this . state . isAdding && (
@@ -197,6 +214,7 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
197214 } } />
198215 </ div >
199216 {
217+ // instructions
200218 < div className = "flex flex-col " >
201219 < div className = "bg-[#352C45] py-[26px] px-10 rounded-xl border-[1px] border-[#4e326b]" >
202220 {
@@ -228,6 +246,7 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
228246 )
229247 }
230248 { this . state . selectedDataSource . value === 'slack' && (
249+ // slack instructions
231250 < span className = " flex flex-col leading-9 text-lg text-white" >
232251 < span className = "flex flex-row items-center" > 1.
233252 < button onClick = { this . copyManifest } className = "flex py-3 pl-3 pr-2 m-2 w-[110px] h-10 text-lg flex-row items-center justify-center bg-[#584971] active:transform active:translate-y-4 hover:bg-[#9875d4] rounded-lg font-poppins border-[#ffffff] border-b-[.5px] transition duration-300 ease-in-out" >
@@ -276,6 +295,7 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
276295 }
277296
278297 { this . state . selectedDataSource . value === 'google_drive' && (
298+ // Google Drive instructions
279299 < span className = "leading-9 text-lg text-white" >
280300 Follow < a href = 'https://github.com/GerevAI/gerev/blob/main/docs/data-sources/google-drive/google-drive.md' rel = "noreferrer" className = "inline underline" target = "_blank" > these instructions</ a >
281301 </ span >
@@ -308,11 +328,11 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
308328 { /* for each field */ }
309329 {
310330 this . state . selectedDataSource . configFields . map ( ( field , index ) => {
311- if ( field . input_type === 'text' || field . input_type === 'password' ) {
331+ if ( field . input_type === 'text' || field . input_type === 'password' ) {
312332 return (
313333 < div className = "flex flex-col mr-10 mt-4" >
314334 < h1 className = "text-lg block text-white mb-4" > { field . label } </ h1 >
315- < input value = { field . value } onChange = { ( event ) => { field . value = event . target . value } }
335+ < input value = { field . value } onChange = { ( event ) => { field . value = event . target . value } }
316336 className = "w-96 h-10 rounded-lg bg-[#352C45] text-white p-2"
317337 placeholder = { field . placeholder } > </ input >
318338 </ div >
@@ -321,10 +341,11 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
321341 return (
322342 < div className = "flex flex-col w-full mt-4" >
323343 < h1 className = "text-lg block text-white mb-4" > { field . label } </ h1 >
324- < textarea value = { field . value } onChange = { ( event ) => { field . value = event . target . value } }
344+ < textarea value = { field . value } onChange = { ( event ) => { field . value = event . target . value } }
325345 className = "w-full h-80 rounded-lg bg-[#352C45] text-white p-2 mb-5" placeholder = { field . placeholder } > </ textarea >
326346 </ div >
327- ) }
347+ )
348+ }
328349 return null ;
329350 } )
330351 }
@@ -352,7 +373,7 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
352373
353374 copyManifest = ( ) => {
354375 let manifestText = JSON . stringify ( slackManifest ) ;
355- if ( ! copy ( manifestText ) ) {
376+ if ( ! copy ( manifestText ) ) {
356377 toast . error ( "Error copying manifest" ) ;
357378 } else {
358379 toast . success ( "Manifest copied to clipboard" , { autoClose : 2000 } ) ;
@@ -382,7 +403,7 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
382403 } ) ;
383404 this . setState ( { selectedDataSource : selectedDataSource } ) ;
384405 this . props . onAdded ( this . state . selectedDataSource . value ) ;
385- this . setState ( { isAddingLoading : false , isAdding : false , selectedDataSource : this . state . selectOptions [ 0 ] } ) ;
406+ this . setState ( { isAddingLoading : false , isAdding : false , selectedDataSource : this . state . selectOptions [ 0 ] } ) ;
386407 } ) . catch ( error => {
387408 toast . error ( "Error adding data source: " + error . response . data , { autoClose : 10000 } ) ;
388409 this . setState ( { isAddingLoading : false } ) ;
@@ -392,4 +413,23 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
392413 onSelectChange = ( event ) => {
393414 this . setState ( { selectedDataSource : event } )
394415 }
395- }
416+
417+ removeDataSource = ( ) => {
418+ let connected = this . props . connectedDataSources ;
419+ let index = connected . indexOf ( this . state . selectedDataSource . value ) ;
420+ connected . splice ( index , 1 ) ;
421+ }
422+
423+
424+ swithcMode = ( ) => {
425+ if ( this . state . editMode === true ) {
426+ this . setState ( { editMode : false } )
427+ addOrRemoveIcon = < AiFillCheckCircle className = "ml-6 text-[#9875d4] text-2xl" /> ;
428+ } else {
429+ this . setState ( { editMode : true } )
430+ addOrRemoveIcon = < IoMdCloseCircle onClick = { this . removeDataSource } className = "ml-6 text-[#df335e] text-2xl" /> ;
431+ }
432+ console . log ( this . state . editMode ) ;
433+ }
434+ }
435+
0 commit comments