You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

175 lines
5.5 KiB

import React, { useState, useEffect } from 'react';
import { Menu, MenuItem } from '@material-ui/core';
import NestedMenuItem from "material-ui-nested-menu-item";
import { QueryElem, QueryLeafBy, QueryLeafOp, TagQueryInfo } from '../../lib/query/Query';
import QBSelectWithRequest from './QBSelectWithRequest';
import { Requests, TagItem } from './QueryBuilder';
export interface MenuProps {
anchorEl: null | HTMLElement,
onClose: () => void,
onCreateQuery: (q: QueryElem) => void,
requestFunctions: Requests,
}
export function createTagInfo(tag: any, allTags: any[]): TagQueryInfo {
const resolveName: (t: any) => string[] = (t: any) => {
if (t.parentId) {
const parent = allTags.filter((o: any) => o.tagId === t.parentId)[0];
return [resolveName(parent), t.name];
}
return [t.name];
}
const resolveChildren: (t: any) => Set<number> = (t: any) => {
if (t.childIds.length > 0) {
const childSets: Set<number>[] = allTags.filter((o: any) => t.childIds.includes(o.tagId))
.map((child: any) => resolveChildren(child));
var r = new Set<number>();
childSets.forEach((c: any) => {
r = new Set([...r, ...c]);
});
return r;
}
return new Set([t.tagId]);
}
return {
matchIds: [...resolveChildren(tag)],
fullName: resolveName(tag),
}
}
export function QBAddElemMenu(props: MenuProps) {
let anchorEl = props.anchorEl;
let onClose = props.onClose;
interface TagItemProps {
tag: any,
allTags: any[],
}
const TagItem = (_props: TagItemProps) => {
if (_props.tag.childIds.length > 0) {
const children = _props.allTags.filter(
(tag: any) => _props.tag.childIds.includes(tag.tagId)
);
return <NestedMenuItem
label={_props.tag.name}
parentMenuOpen={Boolean(anchorEl)}
onClick={() => {
onClose();
props.onCreateQuery({
a: QueryLeafBy.TagInfo,
leafOp: QueryLeafOp.Equals,
b: createTagInfo(_props.tag, _props.allTags),
});
}}
>
{children.map((child: any) => <TagItem tag={child} allTags={_props.allTags} />)}
</NestedMenuItem>
}
return <MenuItem
onClick={() => {
onClose();
props.onCreateQuery({
a: QueryLeafBy.TagInfo,
leafOp: QueryLeafOp.Equals,
b: createTagInfo(_props.tag, _props.allTags),
});
}}
>
{_props.tag.name}
</MenuItem>
}
const BaseTagsItem = (_props: any) => {
const [tags, setTags] = useState<any[] | null>(null);
useEffect(() => {
(async () => {
setTags(await props.requestFunctions.getTags());
})()
}, []);
return tags ?
<>
{tags.filter((tag: any) => !tag.parentId).map((tag: any) => {
return <TagItem tag={tag} allTags={tags} />
})}
</>
: <>...</>
}
return <Menu
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={onClose}
>
<MenuItem disabled={true}>New query element</MenuItem>
<NestedMenuItem
label="Song"
parentMenuOpen={Boolean(anchorEl)}
>
<QBSelectWithRequest
label="Title"
getNewOptions={props.requestFunctions.getSongTitles}
onSubmit={(s: string, exact: boolean) => {
onClose();
props.onCreateQuery({
a: QueryLeafBy.SongTitle,
leafOp: exact ? QueryLeafOp.Equals : QueryLeafOp.Like,
b: s
});
}}
style={{ width: 300 }}
/>
</NestedMenuItem>
<NestedMenuItem
label="Artist"
parentMenuOpen={Boolean(anchorEl)}
>
<QBSelectWithRequest
label="Name"
getNewOptions={props.requestFunctions.getArtists}
onSubmit={(s: string, exact: boolean) => {
onClose();
props.onCreateQuery({
a: QueryLeafBy.ArtistName,
leafOp: exact ? QueryLeafOp.Equals : QueryLeafOp.Like,
b: s
});
}}
style={{ width: 300 }}
/>
</NestedMenuItem>
<NestedMenuItem
label="Album"
parentMenuOpen={Boolean(anchorEl)}
>
<QBSelectWithRequest
label="Name"
getNewOptions={props.requestFunctions.getAlbums}
onSubmit={(s: string, exact: boolean) => {
onClose();
props.onCreateQuery({
a: QueryLeafBy.AlbumName,
leafOp: exact ? QueryLeafOp.Equals : QueryLeafOp.Like,
b: s
});
}}
style={{ width: 300 }}
/>
</NestedMenuItem>
<NestedMenuItem
label="Tag"
parentMenuOpen={Boolean(anchorEl)}
>
<BaseTagsItem />
</NestedMenuItem>
</Menu >
}