11import { IJupyterGISModel } from '@jupytergis/schema' ;
2+ import { Dialog } from '@jupyterlab/apputils' ;
3+ import { Widget } from '@lumino/widgets' ;
24import React from 'react' ;
35
6+ import { Button } from '@/src/shared/components/Button' ;
47import {
58 Tabs ,
69 TabsContent ,
710 TabsList ,
811 TabsTrigger ,
912} from '@/src/shared/components/Tabs' ;
13+ import catalogsData from '@/src/stacBrowser/components/catalogs.json' ;
1014import useStacSearch from '@/src/stacBrowser/hooks/useStacSearch' ;
1115import StacPanelFilters from './StacPanelFilters' ;
1216import StacPanelResults from './StacPanelResults' ;
@@ -15,6 +19,8 @@ interface IStacViewProps {
1519 model ?: IJupyterGISModel ;
1620}
1721const StacPanel = ( { model } : IStacViewProps ) => {
22+ const inputRef = React . useRef < HTMLInputElement | null > ( null ) ;
23+
1824 const {
1925 filterState,
2026 filterSetters,
@@ -38,42 +44,158 @@ const StacPanel = ({ model }: IStacViewProps) => {
3844 return null ;
3945 }
4046
47+ const handleOpenDialog = async ( ) => {
48+ const widget = new URLInputWidget ( ) ;
49+ inputRef . current = widget . getInput ( ) ;
50+
51+ const dialog = new Dialog < boolean > ( {
52+ title : 'Add Catalog' ,
53+ body : widget ,
54+ buttons : [ Dialog . cancelButton ( ) , Dialog . okButton ( { label : 'Add' } ) ] ,
55+ } ) ;
56+
57+ const result = await dialog . launch ( ) ;
58+ if ( result . button . accept && inputRef . current ) {
59+ const url = inputRef . current . value ;
60+ console . log ( 'Catalog URL added:' , url ) ;
61+ }
62+ } ;
63+
4164 return (
42- < Tabs defaultValue = "filters" className = "jgis-panel-tabs" >
43- < TabsList style = { { borderRadius : 0 } } >
44- < TabsTrigger className = "jGIS-layer-browser-category" value = "filters" >
45- Filters
46- </ TabsTrigger >
47- < TabsTrigger
48- className = "jGIS-layer-browser-category"
49- value = "results"
50- > { `Results (${ totalResults } )` } </ TabsTrigger >
51- </ TabsList >
52- < TabsContent value = "filters" >
53- < StacPanelFilters
54- filterState = { filterState }
55- filterSetters = { filterSetters }
56- startTime = { startTime }
57- setStartTime = { setStartTime }
58- endTime = { endTime }
59- setEndTime = { setEndTime }
60- useWorldBBox = { useWorldBBox }
61- setUseWorldBBox = { setUseWorldBBox }
62- />
63- </ TabsContent >
64- < TabsContent value = "results" >
65- < StacPanelResults
66- results = { results }
67- currentPage = { currentPage }
68- totalPages = { totalPages }
69- handlePaginationClick = { handlePaginationClick }
70- handleResultClick = { handleResultClick }
71- formatResult = { formatResult }
72- isLoading = { isLoading }
73- />
74- </ TabsContent >
75- </ Tabs >
65+ < div className = "Select Catalog" >
66+ < Button onClick = { handleOpenDialog } > Select a Catalog</ Button >
67+
68+ < Tabs defaultValue = "filters" className = "jgis-panel-tabs" >
69+ < TabsList style = { { borderRadius : 0 } } >
70+ < TabsTrigger className = "jGIS-layer-browser-category" value = "filters" >
71+ Filters
72+ </ TabsTrigger >
73+ < TabsTrigger
74+ className = "jGIS-layer-browser-category"
75+ value = "results"
76+ > { `Results (${ totalResults } )` } </ TabsTrigger >
77+ </ TabsList >
78+ < TabsContent value = "filters" >
79+ < StacPanelFilters
80+ filterState = { filterState }
81+ filterSetters = { filterSetters }
82+ startTime = { startTime }
83+ setStartTime = { setStartTime }
84+ endTime = { endTime }
85+ setEndTime = { setEndTime }
86+ useWorldBBox = { useWorldBBox }
87+ setUseWorldBBox = { setUseWorldBBox }
88+ />
89+ </ TabsContent >
90+ < TabsContent value = "results" >
91+ < StacPanelResults
92+ results = { results }
93+ currentPage = { currentPage }
94+ totalPages = { totalPages }
95+ handlePaginationClick = { handlePaginationClick }
96+ handleResultClick = { handleResultClick }
97+ formatResult = { formatResult }
98+ isLoading = { isLoading }
99+ />
100+ </ TabsContent >
101+ </ Tabs >
102+ </ div >
76103 ) ;
77104} ;
78105
79106export default StacPanel ;
107+
108+ class URLInputWidget extends Widget {
109+ private input : HTMLInputElement ;
110+ private catalogInput : HTMLInputElement ;
111+ private dropdown : HTMLSelectElement ;
112+
113+ constructor ( ) {
114+ const node = document . createElement ( 'div' ) ;
115+ node . style . padding = '10px' ;
116+
117+ // First section: Manual URL entry
118+ const label = document . createElement ( 'label' ) ;
119+ label . textContent = 'Enter Catalog URL:' ;
120+ label . style . display = 'block' ;
121+ label . style . marginBottom = '8px' ;
122+ label . style . fontWeight = 'bold' ;
123+
124+ const input = document . createElement ( 'input' ) ;
125+ input . type = 'url' ;
126+ input . placeholder = 'https://example.com' ;
127+ input . style . width = '100%' ;
128+ input . style . padding = '8px' ;
129+ input . style . boxSizing = 'border-box' ;
130+ input . style . border = '1px solid #ccc' ;
131+ input . style . borderRadius = '4px' ;
132+ input . style . marginBottom = '20px' ;
133+
134+ // Second section: Select from catalog dropdown
135+ const catalogLabel = document . createElement ( 'label' ) ;
136+ catalogLabel . textContent = 'Or select a catalog:' ;
137+ catalogLabel . style . display = 'block' ;
138+ catalogLabel . style . marginBottom = '8px' ;
139+ catalogLabel . style . fontWeight = 'bold' ;
140+
141+ const dropdown = document . createElement ( 'select' ) ;
142+ dropdown . style . width = '100%' ;
143+ dropdown . style . padding = '8px' ;
144+ dropdown . style . boxSizing = 'border-box' ;
145+ dropdown . style . border = '1px solid #ccc' ;
146+ dropdown . style . borderRadius = '4px' ;
147+ dropdown . style . marginBottom = '10px' ;
148+
149+ const defaultOption = document . createElement ( 'option' ) ;
150+ defaultOption . value = '' ;
151+ defaultOption . textContent = 'Select a catalog...' ;
152+ dropdown . appendChild ( defaultOption ) ;
153+
154+ catalogsData . forEach ( ( catalog : any ) => {
155+ const option = document . createElement ( 'option' ) ;
156+ option . value = catalog . url ;
157+ option . textContent = catalog . title ;
158+ dropdown . appendChild ( option ) ;
159+ } ) ;
160+
161+ const catalogInputLabel = document . createElement ( 'label' ) ;
162+ catalogInputLabel . textContent = 'Selected Catalog URL:' ;
163+ catalogInputLabel . style . display = 'block' ;
164+ catalogInputLabel . style . marginBottom = '8px' ;
165+ catalogInputLabel . style . fontWeight = 'normal' ;
166+ catalogInputLabel . style . fontSize = '0.9em' ;
167+ catalogInputLabel . style . color = '#666' ;
168+
169+ const catalogInput = document . createElement ( 'input' ) ;
170+ catalogInput . type = 'url' ;
171+ catalogInput . placeholder = 'Selected catalog URL will appear here' ;
172+ catalogInput . style . width = '100%' ;
173+ catalogInput . style . padding = '8px' ;
174+ catalogInput . style . boxSizing = 'border-box' ;
175+ catalogInput . style . border = '1px solid #ccc' ;
176+ catalogInput . style . borderRadius = '4px' ;
177+ catalogInput . readOnly = true ;
178+ catalogInput . style . backgroundColor = '#f5f5f5' ;
179+
180+ dropdown . addEventListener ( 'change' , e => {
181+ const selectedUrl = ( e . target as HTMLSelectElement ) . value ;
182+ catalogInput . value = selectedUrl ;
183+ } ) ;
184+
185+ node . appendChild ( label ) ;
186+ node . appendChild ( input ) ;
187+ node . appendChild ( catalogLabel ) ;
188+ node . appendChild ( dropdown ) ;
189+ node . appendChild ( catalogInputLabel ) ;
190+ node . appendChild ( catalogInput ) ;
191+
192+ super ( { node } ) ;
193+ this . input = input ;
194+ this . catalogInput = catalogInput ;
195+ this . dropdown = dropdown ;
196+ }
197+
198+ getInput ( ) : HTMLInputElement {
199+ return this . input . value ? this . input : this . catalogInput ;
200+ }
201+ }
0 commit comments