]> git.openstreetmap.org Git - nominatim-ui.git/blob - src/pages/SearchPage.svelte
Merge remote-tracking branch 'upstream/master'
[nominatim-ui.git] / src / pages / SearchPage.svelte
1 <script>
2   import { untrack } from 'svelte';
3   import { update_html_title } from '../lib/api_utils.js';
4   import { appState } from '../state/AppState.svelte.js';
5
6   import Header from '../components/Header.svelte';
7   import SearchSection from '../components/SearchSection.svelte';
8   import ResultsList from '../components/ResultsList.svelte';
9   import Map from '../components/Map.svelte';
10
11   let results = $state();
12   let api_request_params = $state.raw();
13   let bStructuredSearch = $state();
14   let current_result = $state();
15
16   function loaddata(search_params) {
17     update_html_title();
18
19     api_request_params = {
20       q: search_params.get('q'),
21       street: search_params.get('street'),
22       city: search_params.get('city'),
23       county: search_params.get('county'),
24       state: search_params.get('state'),
25       country: search_params.get('country'),
26       postalcode: search_params.get('postalcode'),
27       polygon_geojson: Nominatim_Config.Search_AreaPolygons ? 1 : 0,
28       viewbox: search_params.get('viewbox'),
29       bounded: search_params.get('bounded'),
30       dedupe: (!search_params.has('dedupe') || search_params.get('dedupe') === '1') ? 1 : 0,
31       'accept-language': search_params.get('accept-language'),
32       countrycodes: search_params.get('countrycodes'),
33       layer: search_params.get('layer'),
34       limit: search_params.get('limit'),
35       polygon_threshold: search_params.get('polygon_threshold'),
36       exclude_place_ids: search_params.get('exclude_place_ids'),
37       format: 'jsonv2'
38     };
39
40     let anyStructuredFieldsSet = (api_request_params.street
41                                 || api_request_params.city
42                                 || api_request_params.county
43                                 || api_request_params.state
44                                 || api_request_params.country
45                                 || api_request_params.postalcode);
46
47     if (api_request_params.q || anyStructuredFieldsSet) {
48       appState.fetchFromApi('search', api_request_params, function (data) {
49         results = data;
50
51         if (anyStructuredFieldsSet) {
52           update_html_title('Result for ' + [
53             api_request_params.street,
54             api_request_params.city,
55             api_request_params.county,
56             api_request_params.state,
57             api_request_params.country,
58             api_request_params.postalcode
59           ].filter((text) => text && text.length > 1).join(', '));
60
61           document.querySelector(".nav-tabs a[href='#structured']").click();
62           document.querySelector('input[name=street]').focus();
63         } else {
64           update_html_title('Result for ' + api_request_params.q);
65
66           document.querySelector('input[name=q]').focus();
67         }
68       });
69     } else {
70       results = undefined;
71     }
72   }
73
74   $effect(() => {
75     if (appState.page.tab === 'search') {
76       const params = appState.page.params;
77       untrack(() => loaddata(params));
78     }
79   });
80 </script>
81
82 {#snippet subheader()}
83   <SearchSection api_request_params={api_request_params} bStructuredSearch={bStructuredSearch} />
84 {/snippet}
85 <Header {subheader} />
86
87 <div id="content">
88   <div class="sidebar">
89     <ResultsList {results} bind:current_result reverse_search={false} />
90   </div>
91   <div id="map-wrapper">
92     <Map {current_result} display_minimap={true} />
93   </div>
94 </div>
95
96
97 <style>
98   .sidebar {
99     width: 25%;
100     min-width: 200px;
101     padding: 15px;
102     padding-top: 0;
103     display: block;
104     float: left;
105   }
106
107   #map-wrapper {
108     position: relative;
109     height: calc(100vh - 250pt);
110     min-height: 300px;
111     width: 75%;
112     padding-right: 20px;
113     display: block;
114     float: left;
115   }
116
117   @media (max-width: 768px) {
118     #content {
119       top: 0;
120       position: relative;
121     }
122     .sidebar {
123       width: 100%;
124     }
125     #map-wrapper {
126       width: 100%;
127       height: 300px;
128       padding-left: 20px;
129     }
130   }
131 </style>