frontend/app/searchnbrowse/SearchBarFile.tsx (113 lines of code) (raw):
import React, {useContext, useEffect, useState} from "react";
import { Grid, Input, MenuItem, Select } from "@material-ui/core";
import VaultSelector from "./NewVaultSelector";
import SortSelector from "../common/SortSelector";
import GnmTypeSelector from "../common/GnmTypeSelector";
import SearchComponentContext from "./SearchComponentContext";
interface SearchBarFileProps {
searchUrlChanged: (newUrl: string) => void;
}
const SearchBarFile: React.FC<SearchBarFileProps> = (props) => {
const [internalError, setInternalError] = useState<string | undefined>(
undefined
);
const [filePath, setFilePath] = useState("");
const [selectedVault, setSelectedVault] = useState<string | undefined>(
undefined
);
const [sortField, setSortField] = useState("MXFS_ARCHIVE_TIME");
const [sortOrder, setSortOrder] = useState("Descending");
const [currentGnmType, setCurrentGnmType] = useState("any");
const searchComponentContext = useContext(SearchComponentContext);
/**
* rebuild the target url whenever the paramers change
*/
useEffect(() => {
const urlBase = "/api/vault/" + selectedVault + "/list";
const params: Record<string, string> = {
sortField: sortField,
sortDir: sortOrder,
forFile: filePath,
typeFilter: currentGnmType == "any" ? "" : currentGnmType,
};
const queryTerms = Object.keys(params)
.filter((fieldName) => params[fieldName] !== "")
.map((fieldName) => `${fieldName}=${params[fieldName]}`);
const url =
queryTerms.length > 0 ? urlBase + "?" + queryTerms.join("&") : urlBase;
props.searchUrlChanged(url);
}, [filePath, selectedVault, sortField, sortOrder, currentGnmType]);
if (internalError) {
return (
<div className="searchbar">
<p className="error">
The search bar component failed: {internalError}
</p>
<p className="error">Please reload the page</p>
</div>
);
}
return (
<Grid
direction="row"
container
spacing={3}
justify="space-around"
alignItems="flex-end"
style={{ paddingLeft: "1em", paddingRight: "1em" }}
>
<Grid item>
<VaultSelector
currentvault={selectedVault ?? ""}
vaultWasChanged={(newVault) => {
setSelectedVault(newVault);
searchComponentContext.vaultIdUpdated(newVault);
}}
/>
</Grid>
<Grid item>
<label htmlFor="filePathSearch">File path: </label>
<Input
type="text"
id="filePathSearch"
onChange={(evt) => setFilePath(evt.target.value)}
value={filePath}
/>
</Grid>
<Grid item>
<label htmlFor="gnmtype-selector">Media type: </label>
<GnmTypeSelector
id="gnmtype-selector"
selectedType={currentGnmType}
onChange={(newValue) => setCurrentGnmType(newValue)}
/>
</Grid>
<Grid item>
<label htmlFor="sort-field-selector">Sort by:</label>
<Select
id="sort-field-selector"
value={sortField}
style={{ paddingRight: "0.5em" }}
onChange={(evt) => setSortField(evt.target.value as string)}
>
//see FileListController
<MenuItem value="MXFS_ARCHIVE_TIME">Archive time</MenuItem>
<MenuItem value="MXFS_CREATION_TIME">Created time</MenuItem>
<MenuItem value="MXFS_MODIFICATION_TIME">Modified time</MenuItem>
<MenuItem value="MXFS_FILEEXT">File type</MenuItem>
<MenuItem value="MXFS_FILENAME">File name</MenuItem>
<MenuItem value="DPSP_SIZE">File size</MenuItem>
</Select>
<Select
id="sort-dir-selector"
value={sortOrder}
onChange={(evt) => setSortOrder(evt.target.value as string)}
>
<MenuItem value="Descending">
{sortField?.includes("TIME") ? "Most recent first" : "Descending"}
</MenuItem>
<MenuItem value="Ascending">
{sortField?.includes("TIME") ? "Oldest first" : "Ascending"}
</MenuItem>
</Select>
</Grid>
</Grid>
);
};
export default SearchBarFile;