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