feat: Implement a vocabulary search
This commit is contained in:
@@ -4,6 +4,15 @@ import Grid from "@material-ui/core/Grid";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Dialog from "@material-ui/core/Dialog";
|
||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||
import DialogContent from "@material-ui/core/DialogContent";
|
||||
/* import DialogContentText from "@material-ui/core/DialogContentText"; */
|
||||
import DialogActions from "@material-ui/core/DialogActions";
|
||||
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
|
||||
import { IVocab, VocabType } from "../models/vocab";
|
||||
|
||||
@@ -12,14 +21,19 @@ import VocabularyData from "../components/VocabularyData";
|
||||
interface IProps {
|
||||
getVocab: () => Promise<IVocab[]>;
|
||||
|
||||
searchOpen: boolean;
|
||||
searchTerm: string;
|
||||
loading: boolean;
|
||||
vocab: IVocab[];
|
||||
|
||||
setLoading: (state: boolean) => void;
|
||||
setVocab: (vocab: IVocab[]) => void;
|
||||
setSearchOpen: (state: boolean) => void;
|
||||
setSearchTerm: (term: string) => void;
|
||||
}
|
||||
|
||||
export default class VocabPage extends React.Component<IProps> {
|
||||
// Internal counter for dynmic children
|
||||
private uid = 0;
|
||||
genUID = () => {
|
||||
return `VOCABPAGE-${this.uid++}`;
|
||||
@@ -34,7 +48,30 @@ export default class VocabPage extends React.Component<IProps> {
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
// Reset the search term
|
||||
this.props.setSearchTerm("");
|
||||
}
|
||||
|
||||
openSearch = () => {
|
||||
this.props.setSearchOpen(true);
|
||||
}
|
||||
closeSearch = () => {
|
||||
this.props.setSearchOpen(false);
|
||||
}
|
||||
|
||||
vocabToCard = (voc: IVocab) => {
|
||||
// Do we need to apply a search filter?
|
||||
const { searchTerm } = this.props;
|
||||
if (searchTerm !== "") {
|
||||
// Just ignore the vocabulary item if it does
|
||||
// not match the "query"
|
||||
const lower = voc.latin.grundform.toLowerCase();
|
||||
if (!lower.startsWith(searchTerm.toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const vocabTypeToStr = {
|
||||
[VocabType.NOMEN]: "Nomen",
|
||||
[VocabType.VERB]: "Verb",
|
||||
@@ -50,6 +87,12 @@ export default class VocabPage extends React.Component<IProps> {
|
||||
</Paper>;
|
||||
}
|
||||
|
||||
applySearchFilter = (e: any) => {
|
||||
// Not sure how much this does
|
||||
e.preventDefault();
|
||||
this.closeSearch();
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.loading) {
|
||||
return <div>
|
||||
@@ -71,9 +114,45 @@ export default class VocabPage extends React.Component<IProps> {
|
||||
</div>;
|
||||
}
|
||||
|
||||
// Trigger a search when the user presses the return key
|
||||
const onEnter = (event: any) => {
|
||||
if (event.key === "Enter") {
|
||||
this.applySearchFilter(event);
|
||||
}
|
||||
};
|
||||
|
||||
const { vocab } = this.props;
|
||||
return <div className="content">
|
||||
{vocab.map(this.vocabToCard)}
|
||||
<div className="vocab-bottom-spacer" />
|
||||
|
||||
<Dialog
|
||||
open={this.props.searchOpen}
|
||||
onClose={this.closeSearch}>
|
||||
<DialogTitle>
|
||||
Suche
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<TextField
|
||||
helperText="Suche nach Vokabeln"
|
||||
onKeyPress={onEnter}
|
||||
value={this.props.searchTerm}
|
||||
onChange={(event) => this.props.setSearchTerm(event.target.value)} />
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={this.applySearchFilter} color="primary">
|
||||
Suchen
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
||||
<Button
|
||||
className="vocab-search-fab"
|
||||
variant="fab"
|
||||
color="primary"
|
||||
onClick={this.openSearch}>
|
||||
<SearchIcon />
|
||||
</Button>
|
||||
</div>;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user