Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
effe8e3
replace dataset card
longshuicy Oct 10, 2022
dfec550
Explore page cleanup (#108)
lmarini Oct 10, 2022
142cc43
Merge branch 'main' into 131-custom-widget-and-appearance-for-reactiv…
longshuicy Oct 10, 2022
7e33d7e
remove wrong primary
longshuicy Oct 10, 2022
d39146d
add layout
longshuicy Oct 10, 2022
27bb878
add styling
longshuicy Oct 11, 2022
d6a5232
customize the searchbox
longshuicy Oct 11, 2022
c4a4cb0
styling the search dataset page
longshuicy Oct 11, 2022
69add83
add links to the side bar
longshuicy Oct 11, 2022
faf29d3
add files table
longshuicy Oct 11, 2022
60229b4
default to its original
longshuicy Oct 11, 2022
b19649d
add TODOs
longshuicy Oct 12, 2022
0d9a92e
Added endpoint to search both file and dataset.
ddey2 Oct 13, 2022
f7e569f
embed datasearch to topbar
longshuicy Oct 14, 2022
e801032
add embedded search to the correct place
longshuicy Oct 14, 2022
ebd7317
wrap the search base on parent comp and dynamically switching between…
longshuicy Oct 14, 2022
c3f1577
embedded search working now
longshuicy Oct 14, 2022
8c98f9e
Merge branch '137-create-endpoint-to-search-both-dataset-and-file' in…
longshuicy Oct 14, 2022
3915eba
multi search
longshuicy Oct 14, 2022
c1c4d7c
combine two searches into one
longshuicy Oct 17, 2022
1065662
identify based on index
longshuicy Oct 17, 2022
05a5f13
Merge branch 'main' into dropdown-toggle-between-indices
longshuicy Oct 17, 2022
c31af35
work on result component
longshuicy Oct 17, 2022
1efa604
initial styles
longshuicy Oct 17, 2022
e86b6a4
add more index
longshuicy Oct 18, 2022
5e52597
include more fields on file
longshuicy Oct 18, 2022
7822ea5
fix typo
longshuicy Oct 18, 2022
476b7fb
no need to pass dataset name as a query parameter; get that info from…
longshuicy Oct 18, 2022
8d1c550
black linting
longshuicy Oct 18, 2022
35cf77b
use react router link instead of the refreshing link
longshuicy Oct 19, 2022
320e85d
remove unused component
longshuicy Oct 21, 2022
d9f957a
add error boundary
longshuicy Oct 21, 2022
8cd13dd
bump mui icon version up; use dataset icon
longshuicy Oct 24, 2022
b73f6cc
Merge branch 'main' into 131-custom-widget-and-appearance-for-reactiv…
longshuicy Oct 24, 2022
3998000
Merge branch '131-custom-widget-and-appearance-for-reactivesearch' in…
longshuicy Oct 24, 2022
c4ab9e6
add logic to refresh
longshuicy Oct 24, 2022
3823d85
when expire redirect to login
longshuicy Oct 24, 2022
9909210
add refresh mechanism
longshuicy Oct 24, 2022
2871ad8
separate out search error boundary
longshuicy Oct 24, 2022
417bc8b
change route back
longshuicy Oct 24, 2022
a82ba83
Merge branch 'main' into 131-custom-widget-and-appearance-for-reactiv…
longshuicy Oct 26, 2022
6d78112
Merge branch '131-custom-widget-and-appearance-for-reactivesearch' in…
longshuicy Oct 26, 2022
ff638a8
Merge branch 'main' into 132-reactive-search-routes-when-token-expire…
longshuicy Oct 26, 2022
c919f3e
put hard coded search endpoint to config
longshuicy Oct 26, 2022
10b6355
breadcrumb functional now
longshuicy Oct 31, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions frontend/src/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface Config{
KeycloakLogout: string;
KeycloakRefresh: string;
KeycloakRegister: string;
searchEndpoint: string;
}

const config:Config = <Config>{};
Expand All @@ -31,4 +32,7 @@ config["KeycloakLogout"] = config.KeycloakBaseURL + "/logout";
config["KeycloakRefresh"] = config.KeycloakBaseURL + "/refresh_token";
config["KeycloakRegister"] = config.KeycloakBaseURL + "/register";

// elasticsearch
config["searchEndpoint"] = config.hostname + "/api/v2/elasticsearch";

export default config;
207 changes: 104 additions & 103 deletions frontend/src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import {useEffect} from 'react';
import {styled, useTheme} from '@mui/material/styles';
import Box from '@mui/material/Box';
import Drawer from '@mui/material/Drawer';
Expand All @@ -22,10 +23,11 @@ import {useSelector} from "react-redux";
import {RootState} from "../types/data";
import {AddBox, Explore} from "@material-ui/icons";
import {EmbeddedSearch} from "./search/EmbeddedSearch";
import {SearchErrorBoundary} from "./search/SearchErrorBoundary";
import {searchTheme} from "../theme";
import {ReactiveBase} from "@appbaseio/reactivesearch";
import Cookies from "universal-cookie";
import {useEffect} from "react";
import config from '../app.config';

const cookies = new Cookies();

Expand All @@ -50,6 +52,7 @@ const Main = styled('main', {shouldForwardProp: (prop) => prop !== 'open'})<{
}),
}));


const SearchDiv = styled("div")(({ theme }) => ({
position: "relative",
marginLeft: theme.spacing(3),
Expand Down Expand Up @@ -94,6 +97,7 @@ const link = {
m: 2,
};

const headers = {"Authorization": cookies.get("Authorization")};

export default function PersistentDrawerLeft(props) {
const {children} = props;
Expand Down Expand Up @@ -123,113 +127,110 @@ export default function PersistentDrawerLeft(props) {
const loggedOut = useSelector((state: RootState) => state.error.loggedOut);


// @ts-ignore
return (
// Wrap reactive search base on the most outside component
<ReactiveBase
// TODO put it in the Config file or other ways to dynamically pass in
url="http://localhost:8000/api/v2/elasticsearch"
app="file,dataset"
headers={{"Authorization": cookies.get("Authorization")}}
// transformResponse={(elasticsearchResponse) => {
// console.log(elasticsearchResponse)
// // if (elasticsearchResponse.detail.error === "invalid_token"){
// // console.log("token expired!");
// // }
// }}
theme={searchTheme}
url={config.searchEndpoint}
app="file,dataset"
headers={headers}
theme={searchTheme}
>
<Box sx={{display: 'flex'}}>
<CssBaseline/>
<AppBar position="fixed" open={open}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
sx={{mr: 2, ...(open && {display: 'none'})}}
>
<MenuIcon/>
</IconButton>
<Link href="/">
<Box component="img" src="../../public/clowder-logo-sm.svg" alt="clowder-logo-sm" sx={{verticalAlign:"middle"}}/>
</Link>

{/*for searching*/}
<SearchDiv hidden={embeddedSearchHidden}>
<EmbeddedSearch />
</SearchDiv>
<Box sx={{ flexGrow: 1 }} />
<Box sx={{marginLeft: "auto"}}>
{
loggedOut ?
<>
<Link href="/auth/register" sx={link}>Register</Link>
<Link href="/auth/login" sx={link}>Login</Link>
</>
:
<Link href="/auth/logout" sx={link}>Logout</Link>
}
</Box>
</Toolbar>
</AppBar>
<Drawer
sx={{
width: drawerWidth,
flexShrink: 0,
'& .MuiDrawer-paper': {
<SearchErrorBoundary>
<Box sx={{display: 'flex'}}>
<CssBaseline/>
<AppBar position="fixed" open={open}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
sx={{mr: 2, ...(open && {display: 'none'})}}
>
<MenuIcon/>
</IconButton>
<Link href="/">
<Box component="img" src="../../public/clowder-logo-sm.svg" alt="clowder-logo-sm"
sx={{verticalAlign: "middle"}}/>
</Link>

{/*for searching*/}
<SearchDiv hidden={embeddedSearchHidden}>
<EmbeddedSearch/>
</SearchDiv>
<Box sx={{flexGrow: 1}}/>
<Box sx={{marginLeft: "auto"}}>
{
loggedOut ?
<>
<Link href="/auth/register" sx={link}>Register</Link>
<Link href="/auth/login" sx={link}>Login</Link>
</>
:
<Link href="/auth/logout" sx={link}>Logout</Link>
}
</Box>
</Toolbar>
</AppBar>
<Drawer
sx={{
width: drawerWidth,
boxSizing: 'border-box',
},
}}
variant="persistent"
anchor="left"
open={open}
>
<DrawerHeader>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'ltr' ? <ChevronLeftIcon/> : <ChevronRightIcon/>}
</IconButton>
</DrawerHeader>
<Divider/>
<List>
<ListItem key={"explore"} disablePadding>
<ListItemButton component={RouterLink} to="/">
<ListItemIcon>
<Explore/>
</ListItemIcon>
<ListItemText primary={"Explore"}/>
</ListItemButton>
</ListItem>
</List>
<Divider/>
<List>
<ListItem key={"search"} disablePadding>
<ListItemButton component={RouterLink} to="/search">
<ListItemIcon>
<SearchDatasetIcon/>
</ListItemIcon>
<ListItemText primary={"Search"}/>
</ListItemButton>
</ListItem>
</List>
<Divider/>
<List>
<ListItem key={"newdataset"} disablePadding>
<ListItemButton component={RouterLink} to="/create-dataset">
<ListItemIcon>
<AddBox/>
</ListItemIcon>
<ListItemText primary={"New Dataset"}/>
</ListItemButton>
</ListItem>
</List>
</Drawer>
<Main open={open}>
<DrawerHeader/>
{children}
</Main>
</Box>
flexShrink: 0,
'& .MuiDrawer-paper': {
width: drawerWidth,
boxSizing: 'border-box',
},
}}
variant="persistent"
anchor="left"
open={open}
>
<DrawerHeader>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'ltr' ? <ChevronLeftIcon/> : <ChevronRightIcon/>}
</IconButton>
</DrawerHeader>
<Divider/>
<List>
<ListItem key={"explore"} disablePadding>
<ListItemButton component={RouterLink} to="/">
<ListItemIcon>
<Explore/>
</ListItemIcon>
<ListItemText primary={"Explore"}/>
</ListItemButton>
</ListItem>
</List>
<Divider/>
<List>
<ListItem key={"search"} disablePadding>
<ListItemButton component={RouterLink} to="/search">
<ListItemIcon>
<SearchDatasetIcon/>
</ListItemIcon>
<ListItemText primary={"Search"}/>
</ListItemButton>
</ListItem>
</List>
<Divider/>
<List>
<ListItem key={"newdataset"} disablePadding>
<ListItemButton component={RouterLink} to="/create-dataset">
<ListItemIcon>
<AddBox/>
</ListItemIcon>
<ListItemText primary={"New Dataset"}/>
</ListItemButton>
</ListItem>
</List>
</Drawer>
<Main open={open}>
<DrawerHeader/>
{children}
</Main>
</Box>
</SearchErrorBoundary>
</ReactiveBase>
);
}
1 change: 0 additions & 1 deletion frontend/src/components/navigation/BreadCrumb.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import Typography from "@mui/material/Typography";
import Breadcrumbs from "@mui/material/Breadcrumbs";
import {Button} from "@mui/material";
import {useNavigate} from "react-router-dom";
Expand Down
32 changes: 15 additions & 17 deletions frontend/src/components/search/Search.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import React from "react";
import {DataSearch, ReactiveList, MultiDropdownList, SingleDropdownRange} from "@appbaseio/reactivesearch";
import {parseDate} from "../../utils/common";

import DatasetCard from "../datasets/DatasetCard";
import {DataSearch, MultiDropdownList, ReactiveList, SingleDropdownRange} from "@appbaseio/reactivesearch";
import {Grid} from "@mui/material";
import Layout from "../Layout";
import {FilesTableFileEntry} from "../files/FilesTableFileEntry";
import { SearchResult } from "./SearchResult";
import {SearchResult} from "./SearchResult";


export function Search() {
Expand All @@ -25,9 +21,11 @@ export function Search() {
queryFormat="or"
fuzziness={0}
debounce={100}
react={{ and: ["creatorfilter",
react={{
and: ["creatorfilter",
"downloadfilter",
"modifyfilter"]}}
"modifyfilter"]
}}
// apply react to the filter
URLParams={true}
showFilter={true}
Expand All @@ -37,8 +35,8 @@ export function Search() {
{field: "name", weight: 3},
{field: "description", weight: 2},
{field: "author.keyword", weight: 1},
{field: "creator.keyword", weight:1}
]}
{field: "creator.keyword", weight: 1}
]}
// placeholder="Search for Dataset"
innerClass={{
title: "search-title",
Expand All @@ -64,9 +62,9 @@ export function Search() {
<SingleDropdownRange
componentId="downloadfilter"
dataField="download"
data={[{ start: 0, label: "0 time and up" },
{ start: 10, label: "10 times and up" },
{ start: 100, label: "100 times and up" },
data={[{start: 0, label: "0 time and up"},
{start: 10, label: "10 times and up"},
{start: 100, label: "100 times and up"},
]}
placeholder="Download Times: All"
innerClass={{
Expand All @@ -78,9 +76,10 @@ export function Search() {
<SingleDropdownRange
componentId="modifyfilter"
dataField="modified"
data={[{ start: 0, label: "0 time and up" },
{ start: 10, label: "10 times and up" },
{ start: 100, label: "100 times and up" },
data={[{start: 0, label: "0 time and up"},
{start: 10, label: "10 times and up"},
{start: 100, label: "100 times and up"},

]}
placeholder="Modify Times: All"
innerClass={{
Expand All @@ -89,7 +88,6 @@ export function Search() {
/>
</Grid>
</Grid>

{/*result*/}
<ReactiveList componentId="results" dataField="_score" size={20} pagination={true}
react={{
Expand Down
37 changes: 37 additions & 0 deletions frontend/src/components/search/SearchErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from "react";
import {ErrorBoundary} from "@appbaseio/reactivesearch";
import {V2} from "../../openapi";
import {Navigate} from "react-router-dom";


import Cookies from "universal-cookie";

const cookies = new Cookies();

export function SearchErrorBoundary(props) {

const {children} = props;

return (
<ErrorBoundary
renderError={error => (
<>
{
(() => {
if (error["status"] === 401 || error["status"] === 403) {
V2.OpenAPI.TOKEN = undefined;
cookies.remove("Authorization", {path: "/"});
return <Navigate to="/auth/login"/>;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot properly do the refresh token logic here; for now just redirect to the login page

} else {
// TODO add prettier message or report function
return <h1>An error has happened.</h1>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will trigger when elasticsearch is dead (e.g. 500 internal error)

}
})()
}
</>
)}
>
{children}
</ErrorBoundary>
)
}