Skip to content

Commit 5f94aaf

Browse files
committed
Initial commit
1 parent 3d303d2 commit 5f94aaf

File tree

4 files changed

+1540
-37
lines changed

4 files changed

+1540
-37
lines changed
Lines changed: 156 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { IJupyterGISModel } from '@jupytergis/schema';
2+
import { Dialog } from '@jupyterlab/apputils';
3+
import { Widget } from '@lumino/widgets';
24
import React from 'react';
35

6+
import { Button } from '@/src/shared/components/Button';
47
import {
58
Tabs,
69
TabsContent,
710
TabsList,
811
TabsTrigger,
912
} from '@/src/shared/components/Tabs';
13+
import catalogsData from '@/src/stacBrowser/components/catalogs.json';
1014
import useStacSearch from '@/src/stacBrowser/hooks/useStacSearch';
1115
import StacPanelFilters from './StacPanelFilters';
1216
import StacPanelResults from './StacPanelResults';
@@ -15,6 +19,8 @@ interface IStacViewProps {
1519
model?: IJupyterGISModel;
1620
}
1721
const 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

79106
export 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

Comments
 (0)