feat: allow merging of adjacent search results
This commit is contained in:
@@ -243,3 +243,48 @@ h2 {
|
||||
align-items: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.search-result-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.merge-button-wrapper {
|
||||
flex-shrink: 0;
|
||||
width: 2em;
|
||||
position: relative;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.merge-button {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 50%);
|
||||
z-index: 10;
|
||||
background-color: #888;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 50%;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-size: 0.8rem;
|
||||
line-height: 1;
|
||||
height: 1.5em;
|
||||
width: 1.5em;
|
||||
padding: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.merge-button:hover {
|
||||
background-color: #999;
|
||||
}
|
||||
|
||||
.search-result-button-wrapper {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.search-result-button-wrapper button {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -515,7 +515,8 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
||||
);
|
||||
|
||||
setActiveSearchResult(null);
|
||||
setSearchResults(res.data);
|
||||
const sortedData = res.data.sort((a, b) => b.start - a.start);
|
||||
setSearchResults(sortedData);
|
||||
} catch (error) {
|
||||
console.error('Error during area search:', error);
|
||||
alert('An error occurred during the search.');
|
||||
@@ -554,6 +555,20 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
||||
setSubmenu(false);
|
||||
};
|
||||
|
||||
const mergeSearchResults = (index) => {
|
||||
const newResults = [...searchResults];
|
||||
const item1 = newResults[index];
|
||||
const item2 = newResults[index + 1];
|
||||
|
||||
const mergedItem = {
|
||||
start: item2.start,
|
||||
end: item1.end,
|
||||
};
|
||||
|
||||
newResults.splice(index, 2, mergedItem);
|
||||
setSearchResults(newResults);
|
||||
};
|
||||
|
||||
const range = parseSlider(end, duration, slider);
|
||||
const startDate = moment(end).subtract(...duration.delta);
|
||||
|
||||
@@ -722,9 +737,7 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
||||
<div ref={scrollContainerRef} className="search-results-container">
|
||||
{searchResults.length > 0 ? (
|
||||
(() => {
|
||||
const sortedResults = [...searchResults].sort((a, b) => b.start - a.start);
|
||||
|
||||
const groupedResults = sortedResults.reduce((acc, result) => {
|
||||
const groupedResults = searchResults.reduce((acc, result) => {
|
||||
const groupKey = moment.unix(result.start).format('YYYY');
|
||||
if (!acc[groupKey]) {
|
||||
acc[groupKey] = [];
|
||||
@@ -747,15 +760,34 @@ function Menu({data, duration, setDuration, end, setEnd, slider, setSlider, subm
|
||||
.map(([groupKey, results]) => (
|
||||
<div key={groupKey}>
|
||||
<h3 className="search-results-group-header">{groupKey}</h3>
|
||||
{results.map((result, index) => (
|
||||
{results.map((result, indexInYear) => {
|
||||
const absoluteIndex = searchResults.findIndex(r => r.start === result.start && r.end === result.end);
|
||||
const isLastResultOverall = absoluteIndex === searchResults.length - 1;
|
||||
|
||||
return (
|
||||
<div className="search-result-row" key={`${result.start}-${result.end}`}>
|
||||
<div className="merge-button-wrapper">
|
||||
{!isLastResultOverall && (
|
||||
<button
|
||||
className="merge-button"
|
||||
title="Merge with next item"
|
||||
onClick={() => mergeSearchResults(absoluteIndex)}
|
||||
>
|
||||
↓↑
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div className="search-result-button-wrapper">
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => selectSearchResult(result)}
|
||||
className={activeSearchResult && activeSearchResult.start === result.start && activeSearchResult.end === result.end ? 'active' : ''}
|
||||
>
|
||||
{formatShortTime(result.start)} - {formatShortTime(result.end)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
));
|
||||
})()
|
||||
|
||||
Reference in New Issue
Block a user