Skip to content

Commit 275dd04

Browse files
committed
Display search results in a list, with matching terms highlighted
1 parent 6279c5d commit 275dd04

File tree

3 files changed

+124
-76
lines changed

3 files changed

+124
-76
lines changed

api/src/routes/repository.js

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -112,20 +112,24 @@ export async function getRepositoryLookupLanguageHandler(req) {
112112
async function postRepositorySearchHandler(req) {
113113
const bounds = req.body.boundingBox;
114114

115-
let mustMatchQuery = [
116-
esb
117-
.geoShapeQuery("location")
118-
.shape(
119-
esb
120-
.geoShape()
121-
.type("envelope")
122-
.coordinates([
123-
[bounds.topLeft.lng, bounds.topLeft.lat],
124-
[bounds.bottomRight.lng, bounds.bottomRight.lat],
125-
])
126-
)
127-
.relation("intersects"),
128-
];
115+
let mustMatchQuery = [];
116+
if (bounds) {
117+
118+
mustMatchQuery.push(
119+
esb
120+
.geoShapeQuery("location")
121+
.shape(
122+
esb
123+
.geoShape()
124+
.type("envelope")
125+
.coordinates([
126+
[bounds.topLeft.lng, bounds.topLeft.lat],
127+
[bounds.bottomRight.lng, bounds.bottomRight.lat],
128+
])
129+
)
130+
.relation("intersects"),
131+
);
132+
}
129133
if (req.body.language) {
130134
mustMatchQuery.push(
131135
esb
@@ -166,6 +170,12 @@ async function postRepositorySearchHandler(req) {
166170
...esbQuery.toJSON(),
167171
fields: ["name", "description", "identifier", "location", "access"],
168172
_source: false,
173+
highlight: {
174+
fields: {
175+
"text": {},
176+
"phoneticText": {}
177+
}
178+
}
169179
};
170180
let result = await client.search(query);
171181
return result.hits;

ui-repository/src/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="h-screen w-screen bg-slate-100">
2+
<div class="pb-16 w-screen bg-slate-100">
33
<NavbarComponent />
44
<router-view />
55
</div>

ui-repository/src/components/home-page/Search.component.vue

Lines changed: 99 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -58,62 +58,85 @@
5858
{{ data.documentsTotal }} {{ pluralize("manuscript", data.documentsTotal) }}
5959
{{ pluralize("were", data.documentsTotal) }} found matching your search.
6060
</div>
61-
<MapboxMap
62-
class="home-page-map-style m-auto"
63-
:access-token="mapboxToken"
64-
:map-style="mapboxStyle"
65-
:bounds="bounds"
66-
@mb-created="(mapboxInstance) => (map = mapboxInstance)"
67-
>
68-
<div v-for="(feature, idx) of data.features" :key="feature.properties.path + idx">
69-
<MapboxMarker
70-
:lng-lat="feature.geometry.coordinates"
71-
:color="markerColor(feature.properties)"
72-
:popup="{ ...popupOptions, data: feature.properties }"
73-
@mb-open="showDescription"
61+
<el-checkbox
62+
v-model="data.mapFilter"
63+
size="large"
64+
@blur="search"
65+
@change="search">Search map area only</el-checkbox>
66+
<div class="flex flex-row items-start">
67+
<div>
68+
<MapboxMap
69+
class="home-page-map-style m-auto"
70+
:access-token="mapboxToken"
71+
:map-style="mapboxStyle"
72+
:bounds="bounds"
73+
@mb-created="(mapboxInstance) => (map = mapboxInstance)"
7474
>
75-
<template v-slot:popup>
76-
<div
77-
class="flex flex-col space-y-1 p-2 cursor-pointer"
78-
@click="loadItem(feature.properties)"
75+
<div v-for="(feature, idx) of data.features" :key="feature.properties.path + idx">
76+
<MapboxMarker
77+
:lng-lat="feature.geometry.coordinates"
78+
:color="markerColor(feature.properties)"
79+
:popup="{ ...popupOptions, data: feature.properties }"
80+
@mb-open="showDescription"
7981
>
80-
<div class="text-base">
81-
{{ feature.properties.identifier[0] }}
82-
</div>
83-
<div class="text-lg font-medium">
84-
{{ feature.properties.name[0] }}
85-
</div>
86-
<div
87-
class="text-base italic"
88-
:class="{
89-
'text-green-700': feature.properties.access[0].match(/open/i),
90-
'text-red-700': !feature.properties.access[0].match(/open/i),
91-
}"
92-
>
93-
{{ feature.properties.access[0] }}
94-
</div>
95-
</div>
96-
</template>
97-
</MapboxMarker>
82+
<template v-slot:popup>
83+
<div
84+
class="flex flex-col space-y-1 p-2 cursor-pointer"
85+
@click="loadItem(feature.properties)"
86+
>
87+
<div class="text-base">
88+
{{ feature.properties.identifier[0] }}
89+
</div>
90+
<div class="text-lg font-medium">
91+
{{ feature.properties.name[0] }}
92+
</div>
93+
<div
94+
class="text-base italic"
95+
:class="{
96+
'text-green-700': feature.properties.access[0].match(/open/i),
97+
'text-red-700': !feature.properties.access[0].match(/open/i),
98+
}"
99+
>
100+
{{ feature.properties.access[0] }}
101+
</div>
102+
</div>
103+
</template>
104+
</MapboxMarker>
105+
</div>
106+
</MapboxMap>
107+
<div class="flex flex-col space-y-1 p-4 md:p-0">
108+
<div>Legend:</div>
109+
<div>
110+
<i class="fa-solid fa-location-dot text-green-600"></i>&nbsp;The item is open access
111+
subject to agreeing to the terms of use.
112+
</div>
113+
<div>
114+
<i class="fa-solid fa-location-dot text-red-700"></i>&nbsp;The item is restricted
115+
access.
116+
</div>
117+
<div>
118+
<i class="fa-solid fa-location-dot"></i>
119+
&nbsp;The location has been defined as an area so a marker has been placed in the
120+
approximate centre of that area.
121+
</div>
122+
<div class="text-lg text-center font-bold">
123+
Please note that locations are general and not precise points on the map.
124+
</div>
125+
</div>
98126
</div>
99-
</MapboxMap>
100-
<div class="flex flex-col space-y-1 p-4 md:p-0">
101-
<div>Legend:</div>
102-
<div>
103-
<i class="fa-solid fa-location-dot text-green-600"></i>&nbsp;The item is open access
104-
subject to agreeing to the terms of use.
105-
</div>
106-
<div>
107-
<i class="fa-solid fa-location-dot text-red-700"></i>&nbsp;The item is restricted
108-
access.
109-
</div>
110-
<div>
111-
<i class="fa-solid fa-location-dot"></i>
112-
&nbsp;The location has been defined as an area so a marker has been placed in the
113-
approximate centre of that area.
114-
</div>
115-
<div class="text-lg text-center font-bold">
116-
Please note that locations are general and not precise points on the map.
127+
<div v-if="data.showResultsList" v-for="(doc, idx) of data.documents" :key="doc._id + idx" style="display:block;border-bottom:gray 1px solid;padding:1em;cursor:pointer;" @click="loadItem({path: doc._id})">
128+
<div class="text-base">
129+
{{ doc.fields.identifier[0] }}
130+
</div>
131+
<div class="text-lg font-medium">
132+
{{ doc.fields.name[0] }}
133+
</div>
134+
<div v-if="doc.highlight" v-for="(text, idx) of doc.highlight.text" class="text-sm font-medium">
135+
…<span v-html="text"></span>…
136+
</div>
137+
<div v-if="doc.highlight" v-for="(text, idx) of doc.highlight.phoneticText" class="text-sm font-medium">
138+
…<span v-html="text"></span>…
139+
</div>
117140
</div>
118141
</div>
119142
</div>
@@ -148,6 +171,8 @@ const popupOptions = {
148171
149172
const data = reactive({
150173
form: {},
174+
mapFilter: false,
175+
showResultsList: false,
151176
documents: [],
152177
documentsTotal: 0,
153178
debouncedSearch: debounce(search, 400),
@@ -164,23 +189,33 @@ async function init() {
164189
}
165190
166191
function reset() {
167-
map.value.fitBounds(bounds);
168192
data.form = {};
193+
data.showResultsList = false;
169194
search();
170195
}
171196
172197
async function search() {
173198
const bounds = map.value.getBounds();
199+
let boundingBox;
200+
// TODO: replace with value from '[ ] map filter' checkbox
201+
if (data.mapFilter) {
202+
boundingBox = {
203+
topLeft: bounds.getNorthWest().wrap(),
204+
bottomRight: bounds.getSouthEast().wrap(),
205+
}
206+
}
207+
console.log()
174208
let response = await $http.post({
175209
route: "/repository/search",
176210
body: {
177211
...data.form,
178-
boundingBox: {
179-
topLeft: bounds.getNorthWest().wrap(),
180-
bottomRight: bounds.getSouthEast().wrap(),
181-
},
212+
boundingBox: boundingBox,
182213
},
183214
});
215+
// Don't show the search results list until the user has explicitly searched for something
216+
if (Object.keys({...data.form}).length !== 0) {
217+
data.showResultsList = true;
218+
}
184219
if (response.status === 200) {
185220
response = await response.json();
186221
data.documents = response.hits;
@@ -237,14 +272,14 @@ function showDescription(event, data) {
237272
// console.log(event.target._content, data);
238273
}
239274
240-
async function loadItem(item) {
241-
$router.push({ path: item.path });
275+
async function loadItem({ path }) {
276+
$router.push({ path: path });
242277
}
243278
</script>
244279

245280
<style>
246281
.home-page-map-style {
247-
width: calc(100vw - 0.1 * 100vw);
282+
width: 100%;
248283
height: 750px;
249284
}
250285
.mapboxgl-popup-close-button {
@@ -253,4 +288,7 @@ async function loadItem(item) {
253288
.mapboxgl-popup-content {
254289
background-color: #f1f5f9;
255290
}
291+
em {
292+
background-color: yellow;
293+
}
256294
</style>

0 commit comments

Comments
 (0)