mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
Removing result categories when no results exist in those categories.
This commit is contained in:
parent
eefc4d4d79
commit
c628af4f49
5 changed files with 106 additions and 29 deletions
|
|
@ -1024,10 +1024,15 @@ export async function searchSuggestions(search_str) {
|
|||
const response = await apiPost(`${API_URI}/search_suggestions`, body);
|
||||
if (response.ok) {
|
||||
const content = await response.json();
|
||||
|
||||
const fileGroups = content['file_groups'];
|
||||
const zimsEstimates = content['zims_estimates'];
|
||||
const channels = content['channels'];
|
||||
const domains = content['domains'];
|
||||
const tags = content['tags'];
|
||||
return {
|
||||
fileGroups,
|
||||
zimsEstimates,
|
||||
channels,
|
||||
domains,
|
||||
tags,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ const suggestedApps = [
|
|||
{location: '/more/vin', title: 'Vin Decoder', description: 'Decode and analyze vehicle VIN numbers'},
|
||||
{location: '/admin', title: 'Downloads', description: 'View your downloads'},
|
||||
{location: '/admin/settings', title: 'Settings', description: 'View and modify your settings'},
|
||||
{location: '/admin/status', title: 'Status', description: 'View the status of this WROLPi'},
|
||||
{location: '/admin/wrol', title: 'WROL Mode', description: 'Enable or disable WROL Mode'},
|
||||
];
|
||||
|
||||
|
|
@ -31,29 +32,55 @@ export function useSearchSuggestions() {
|
|||
if (searchStr && searchStr.length > 0) {
|
||||
const lowerSearchStr = searchStr.toLowerCase();
|
||||
try {
|
||||
const i = await searchSuggestions(searchStr);
|
||||
const newSuggestions = await searchSuggestions(searchStr);
|
||||
const matchingApps = suggestedApps.filter(i =>
|
||||
i.title.toLowerCase().includes(lowerSearchStr)
|
||||
|| fuzzyMatch(i.title.toLowerCase(), lowerSearchStr));
|
||||
const matchingSuggestions = {
|
||||
channels: {
|
||||
name: 'Channels', results: i.channels.map(i => {
|
||||
return {title: i['name'], id: i['id'], type: 'channel'}
|
||||
|
||||
const zimSum = newSuggestions.zimsEstimates.reduce((i, j) => i + j['estimate'], 0);
|
||||
|
||||
// Suggested results are ordered.
|
||||
let matchingSuggestions = {};
|
||||
if (newSuggestions.fileGroups > 0) {
|
||||
matchingSuggestions.fileGroups = {
|
||||
name: 'Files', results: [
|
||||
{description: newSuggestions.fileGroups, type: 'files'}
|
||||
]
|
||||
};
|
||||
}
|
||||
if (zimSum > 0) {
|
||||
matchingSuggestions.zimsSum = {
|
||||
name: 'Zims', results: [
|
||||
{description: zimSum, type: 'zims'}
|
||||
],
|
||||
}
|
||||
}
|
||||
if (newSuggestions.channels && newSuggestions.channels.length > 0) {
|
||||
matchingSuggestions.channels = {
|
||||
name: 'Channels', results: newSuggestions.channels.map(i => {
|
||||
return {type: 'channel', description: i['name'], id: i['id']}
|
||||
})
|
||||
},
|
||||
domains: {
|
||||
name: 'Domains', results: i.domains.map(i => {
|
||||
return {title: i['domain'], id: i['id'], type: 'domain'}
|
||||
}
|
||||
}
|
||||
if (newSuggestions.domains && newSuggestions.domains.length > 0) {
|
||||
matchingSuggestions.domains = {
|
||||
name: 'Domains', results: newSuggestions.domains.map(i => {
|
||||
return {type: 'domain', description: i.domain, id: i['id'], domain: i.domain}
|
||||
})
|
||||
},
|
||||
tags: {
|
||||
name: 'Tags', results: i.tags.map(i => {
|
||||
return {title: i['name'], type: 'tag'}
|
||||
}
|
||||
}
|
||||
if (newSuggestions.tags && newSuggestions.tags.length > 0) {
|
||||
matchingSuggestions.tags = {
|
||||
name: 'Tags', results: newSuggestions.tags.map(i => {
|
||||
return {type: 'tag', description: i['name']}
|
||||
})
|
||||
},
|
||||
apps: {name: 'Apps', results: matchingApps},
|
||||
};
|
||||
console.debug('newSuggestions', matchingSuggestions);
|
||||
}
|
||||
}
|
||||
if (matchingApps && matchingApps.length > 0) {
|
||||
matchingSuggestions.apps = {name: 'Apps', results: matchingApps};
|
||||
}
|
||||
|
||||
console.debug('matchingSuggestions', matchingSuggestions);
|
||||
setSuggestions(matchingSuggestions);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
|
@ -75,14 +102,19 @@ export function useSearchSuggestions() {
|
|||
}
|
||||
|
||||
if (result.location) {
|
||||
navigate(result.location);
|
||||
return navigate(result.location);
|
||||
} else if (result['type'] === 'channel') {
|
||||
navigate(`/videos/channel/${result['id']}/video`);
|
||||
return navigate(`/videos/channel/${result['id']}/video`);
|
||||
} else if (result['type'] === 'domain') {
|
||||
navigate(`/archive?domain=${result['domain']}`);
|
||||
return navigate(`/archive?domain=${result['domain']}`);
|
||||
} else if (result['type'] === 'tag') {
|
||||
navigate(`/search?tag=${encodeURIComponent(result['title'])}`);
|
||||
return navigate(`/search?tag=${encodeURIComponent(result['title'])}`);
|
||||
} else if (result['type'] === 'files') {
|
||||
return navigate(`/search?q=${encodeURIComponent(searchStr)}`);
|
||||
} else if (result['type'] === 'zims') {
|
||||
return navigate(`/search/zim?q=${encodeURIComponent(searchStr)}`);
|
||||
}
|
||||
console.error('No handleResultSelect defined:', result);
|
||||
};
|
||||
|
||||
const resultRenderer = ({type, title, description}) => {
|
||||
|
|
@ -92,10 +124,13 @@ export function useSearchSuggestions() {
|
|||
}
|
||||
|
||||
// No specific renderer, use the generic.
|
||||
return <>
|
||||
<SHeader as='h4'>{title}</SHeader>
|
||||
{description}
|
||||
</>
|
||||
if (title) {
|
||||
return <>
|
||||
<SHeader as='h4'>{title}</SHeader>
|
||||
{description}
|
||||
</>
|
||||
}
|
||||
return <span>{description}</span>
|
||||
};
|
||||
|
||||
return {suggestions, searchStr, handleResultSelect, resultRenderer}
|
||||
|
|
|
|||
|
|
@ -551,13 +551,40 @@ async def post_search_suggestions(_: Request, body: schema.SearchSuggestionsRequ
|
|||
"""Used by the Global search to suggest links to the user."""
|
||||
from modules.videos.channel.lib import search_channels_by_name
|
||||
from modules.archive.lib import search_domains_by_name
|
||||
from modules.zim.models import Zims
|
||||
|
||||
channels, domains, tags_ = await asyncio.gather(
|
||||
if not body.search_str and not body.tag_names:
|
||||
return response.empty(HTTPStatus.BAD_REQUEST)
|
||||
|
||||
file_groups, channels, domains, tags_ = await asyncio.gather(
|
||||
estimate_search(body.search_str, body.tag_names),
|
||||
search_channels_by_name(body.search_str),
|
||||
search_domains_by_name(body.search_str),
|
||||
tags.search_tags_by_name(body.search_str),
|
||||
)
|
||||
|
||||
if body.tag_names:
|
||||
# Get actual count of entries tagged with the tag names.
|
||||
zims_estimates = list()
|
||||
for zim, count in Zims.entries_with_tags(body.tag_names).items():
|
||||
d = dict(
|
||||
estimate=count,
|
||||
**zim.__json__(),
|
||||
)
|
||||
zims_estimates.append(d)
|
||||
else:
|
||||
# Get estimates using libzim.
|
||||
zims_estimates = list()
|
||||
for zim, estimate in Zims.estimate(body.search_str).items():
|
||||
d = dict(
|
||||
estimate=estimate,
|
||||
**zim.__json__(),
|
||||
)
|
||||
zims_estimates.append(d)
|
||||
|
||||
ret = dict(
|
||||
file_groups=file_groups,
|
||||
zims_estimates=zims_estimates,
|
||||
channels=channels,
|
||||
domains=domains,
|
||||
tags=tags_,
|
||||
|
|
|
|||
|
|
@ -146,3 +146,4 @@ class SearchEstimateRequest:
|
|||
@dataclass
|
||||
class SearchSuggestionsRequest:
|
||||
search_str: Optional[str] = None
|
||||
tag_names: List[str] = field(default_factory=lambda: list())
|
||||
|
|
|
|||
|
|
@ -488,12 +488,14 @@ def test_search_str_estimate(test_session, test_client, test_directory, test_zim
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_search_suggestions(test_session, test_async_client, channel_factory, archive_factory, tag_factory):
|
||||
async def test_search_suggestions(test_session, test_async_client, channel_factory, archive_factory, tag_factory,
|
||||
zim_factory):
|
||||
channel_factory(name='Foo')
|
||||
channel_factory(name='Fool')
|
||||
channel_factory(name='Bar')
|
||||
archive_factory(domain='foo.com')
|
||||
archive_factory(domain='bar.com')
|
||||
archive_factory(domain='foo.com', contents='contents of foo')
|
||||
archive_factory(domain='bar.com', contents='contents of bar')
|
||||
zim_factory('test zim')
|
||||
tag_factory()
|
||||
test_session.commit()
|
||||
|
||||
|
|
@ -506,12 +508,17 @@ async def test_search_suggestions(test_session, test_async_client, channel_facto
|
|||
'name': 'Fool',
|
||||
'url': 'https://example.com/Fool'}]
|
||||
assert response.json['domains'] == [{'directory': 'archive/foo.com', 'domain': 'foo.com', 'id': 1}]
|
||||
assert response.json['file_groups'] == 1
|
||||
assert 'zims_estimates' in response.json and len(response.json['zims_estimates']) == 1
|
||||
assert response.json['zims_estimates'][0]['estimate'] == 0
|
||||
|
||||
body = dict(search_str='bar')
|
||||
request, response = await test_async_client.post('/api/search_suggestions', json=body)
|
||||
assert response.status_code == HTTPStatus.OK
|
||||
assert response.json['channels'] == [{'directory': 'Bar', 'id': 3, 'name': 'Bar', 'url': 'https://example.com/Bar'}]
|
||||
assert response.json['domains'] == [{'directory': 'archive/bar.com', 'domain': 'bar.com', 'id': 2}]
|
||||
assert response.json['file_groups'] == 1
|
||||
assert response.json['zims_estimates'][0]['estimate'] == 0
|
||||
|
||||
body = dict(search_str='one')
|
||||
request, response = await test_async_client.post('/api/search_suggestions', json=body)
|
||||
|
|
@ -519,6 +526,8 @@ async def test_search_suggestions(test_session, test_async_client, channel_facto
|
|||
assert response.json['channels'] == []
|
||||
assert response.json['domains'] == []
|
||||
assert response.json['tags'] == [{'color': '#111111', 'id': 1, 'name': 'one'}]
|
||||
assert response.json['file_groups'] == 0
|
||||
assert response.json['zims_estimates'][0]['estimate'] == 2
|
||||
|
||||
|
||||
def test_recursive_errors():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue