Multiple tags can be selected. Restoring TagsDropdown functionality for Videos and Archives search.

This commit is contained in:
Roland 2023-04-05 14:37:14 -06:00
parent 023e6c771e
commit e9f820d483
No known key found for this signature in database
GPG key ID: 9D6DBD3ACF11AB93
5 changed files with 61 additions and 38 deletions

View file

@ -75,7 +75,7 @@ export function Dashboard() {
// Only show dashboard parts if not searching.
let body;
if (searchStr || activeTags) {
if (searchStr || (activeTags && activeTags.length > 0)) {
body = <FilesSearchView showLimit={true} showSelectButton={true}/>;
} else {
body = <>

View file

@ -4,7 +4,7 @@ import {
Button as SButton,
Confirm,
Dimmer,
Divider,
Divider, Dropdown,
Form,
FormInput,
Grid,
@ -356,6 +356,40 @@ const Dashboard = () => {
</Segment>
}
export const TagsDropdown = ({value = [], onChange, ...props}) => {
const {tagNames} = React.useContext(TagsContext);
const [activeTags, setActiveTags] = React.useState(value);
const handleChange = (e, {value}) => {
if (e) {
e.preventDefault();
}
if (!value) {
setActiveTags([]);
onChange([]);
} else {
setActiveTags(value);
onChange(value);
}
}
let options = [{key: null, text: '', value: ''}];
if (tagNames && tagNames.length > 0) {
const tagOptions = tagNames.map(i => {
return {key: i, text: i, value: i}
})
options = [...options, ...tagOptions];
}
return <Dropdown multiple selection clearable
options={options}
placeholder='Tags'
onChange={handleChange}
value={activeTags}
{...props}
/>
}
export const TagsDashboard = () => {
return <TagsProvider>
<Dashboard/>

View file

@ -103,7 +103,7 @@ export async function getChannel(id) {
return (await response.json())['channel'];
}
export async function searchVideos(offset, limit, channelId, searchStr, order_by, tags) {
export async function searchVideos(offset, limit, channelId, searchStr, order_by, tagNames) {
// Build a search query to retrieve a list of videos from the API
offset = parseInt(offset || 0);
limit = parseInt(limit || DEFAULT_LIMIT);
@ -115,8 +115,8 @@ export async function searchVideos(offset, limit, channelId, searchStr, order_by
if (channelId) {
body['channel_id'] = parseInt(channelId);
}
if (tags) {
body['tag_names'] = tags.split(',');
if (tagNames) {
body['tag_names'] = tagNames;
}
console.debug('searching videos', body);
@ -350,7 +350,7 @@ export async function deleteArchives(archiveIds) {
}
}
export async function searchArchives(offset, limit, domain, searchStr, order, tags) {
export async function searchArchives(offset, limit, domain, searchStr, order, tagNames) {
// Build a search query to retrieve a list of videos from the API
offset = parseInt(offset || 0);
limit = parseInt(limit || DEFAULT_LIMIT);
@ -364,8 +364,8 @@ export async function searchArchives(offset, limit, domain, searchStr, order, ta
if (order) {
body['order_by'] = order;
}
if (tags) {
body['tag_names'] = tags.split(',');
if (tagNames) {
body['tag_names'] = tagNames;
}
console.debug('searching archives', body);
@ -479,7 +479,7 @@ export async function deleteDownload(downloadId) {
}
}
export async function filesSearch(offset, limit, searchStr, mimetypes, model, tags) {
export async function filesSearch(offset, limit, searchStr, mimetypes, model, tagNames) {
const body = {search_str: searchStr, offset: parseInt(offset), limit: parseInt(limit)};
if (mimetypes) {
body['mimetypes'] = mimetypes;
@ -487,8 +487,8 @@ export async function filesSearch(offset, limit, searchStr, mimetypes, model, ta
if (model) {
body['model'] = model;
}
if (tags) {
body['tag_names'] = tags.split(',');
if (tagNames) {
body['tag_names'] = tagNames;
}
console.debug('searching files', body);
const response = await apiPost(`${API_URI}/files/search`, body);

View file

@ -42,7 +42,7 @@ import _ from 'lodash';
import {FileBrowser} from "./FileBrowser";
import {refreshDirectoryFiles, refreshFiles} from "../api";
import {useSubscribeEventName} from "../Events";
import {TagsContext} from "../Tags";
import {TagsContext, TagsDropdown, TagsProvider} from "../Tags";
function EbookCard({file}) {
const {s} = useContext(ThemeContext);
@ -347,7 +347,9 @@ export function FilesView({
{selectButton}
{viewButton}
{limitDropdown}
<TagsFilesGroupDropdown/>
<TagsProvider>
<TagsFilesGroupDropdown/>
</TagsProvider>
{filterOptions && filtersDropdown}
</Grid.Column>
{menuColumns}
@ -360,8 +362,7 @@ export function FilesView({
export function TagsFilesGroupDropdown({onChange}) {
// Creates dropdown that the User can use to manipulate the tag query.
const {searchParams, updateQuery} = useQuery();
const activeTag = searchParams.get('tag');
const {tags} = React.useContext(TagsContext);
const activeTags = searchParams.getAll('tag');
const localOnChange = (name) => {
updateQuery({'tag': name});
@ -370,23 +371,11 @@ export function TagsFilesGroupDropdown({onChange}) {
}
}
let tagOptions = [];
if (tags && tags.length) {
for (let i = 0; i < tags.length; i++) {
const {name} = tags[i];
tagOptions = [...tagOptions, {key: name, text: name, value: name}];
}
return <Dropdown selection clearable search
options={tagOptions || []}
placeholder={'Tags'}
onChange={(e, {value}) => localOnChange(value)}
style={{marginLeft: '0.3em', marginTop: '0.3em'}}
value={activeTag}
/>;
} else {
return <React.Fragment/>
}
return <TagsDropdown
value={activeTags}
onChange={localOnChange}
style={{marginLeft: '0.3em', marginTop: '0.3em'}}
/>
}
export function FilesSearchView({

View file

@ -153,7 +153,7 @@ export const useSearchArchives = (defaultLimit, domain, order_by) => {
const {searchParams, updateQuery} = useQuery();
const searchStr = searchParams.get('q') || '';
const order = searchParams.get('order') || order_by;
const activeTags = searchParams.get('tag');
const activeTags = searchParams.getAll('tag');
const [archives, setArchives] = useState(null);
const [totalPages, setTotalPages] = useState(0);
@ -179,7 +179,7 @@ export const useSearchArchives = (defaultLimit, domain, order_by) => {
useEffect(() => {
localSearchArchives();
}, [searchStr, limit, domain, order, activePage, activeTags]);
}, [searchStr, limit, domain, order, activePage, JSON.stringify(activeTags)]);
const setSearchStr = (value) => {
updateQuery({q: value, o: 0, order: undefined});
@ -211,7 +211,7 @@ export const useSearchVideos = (defaultLimit, channelId, order_by) => {
const {offset, limit, setLimit, activePage, setPage} = usePages(defaultLimit)
const searchStr = searchParams.get('q') || '';
const order = searchParams.get('order') || order_by;
const activeTags = searchParams.get('tag');
const activeTags = searchParams.getAll('tag');
const [videos, setVideos] = useState();
const [totalPages, setTotalPages] = useState(0);
@ -237,7 +237,7 @@ export const useSearchVideos = (defaultLimit, channelId, order_by) => {
useEffect(() => {
localSearchVideos();
}, [searchStr, limit, channelId, offset, order_by, activeTags]);
}, [searchStr, limit, channelId, offset, order_by, JSON.stringify(activeTags)]);
const setSearchStr = (value) => {
updateQuery({q: value, o: 0, order: undefined});
@ -385,7 +385,7 @@ export const useSearchFiles = (defaultLimit = 48, emptySearch = false, model) =>
const searchStr = searchParams.get('q');
const filter = searchParams.get('filter');
const model_ = searchParams.get('model');
const activeTags = searchParams.get('tag');
const activeTags = searchParams.getAll('tag');
const [searchFiles, setSearchFiles] = useState(null);
const [totalPages, setTotalPages] = useState(0);
@ -416,7 +416,7 @@ export const useSearchFiles = (defaultLimit = 48, emptySearch = false, model) =>
useEffect(() => {
localSearchFiles();
}, [searchStr, limit, offset, activePage, filter, model, model_, activeTags]);
}, [searchStr, limit, offset, activePage, filter, model, model_, JSON.stringify(activeTags)]);
const setPage = (i) => {
i = parseInt(i);