Skip to content

Commit

Permalink
Merge branch 'master' into dependabot/npm_and_yarn/compose/neurosynth…
Browse files Browse the repository at this point in the history
…-frontend/multi-81f6ed4da7
  • Loading branch information
nicoalee committed Jan 6, 2025
2 parents faa0632 + a6b7c8c commit 21cc012
Show file tree
Hide file tree
Showing 9 changed files with 442 additions and 135 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/deploy-to-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ jobs:
# Wait for PostgreSQL to be ready
until docker compose exec store_pgsql pg_isready; do sleep 5; done
docker compose exec store flask db migrate
docker compose exec store flask db upgrade
docker compose exec neurostore flask db migrate
docker compose exec neurostore flask db upgrade
'
- name: Run Docker commands in compose directory if changes detected
Expand Down
129 changes: 63 additions & 66 deletions compose/neurosynth-frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,82 +1,79 @@
import Close from "@mui/icons-material/Close";
import { IconButton } from "@mui/material";
import { AxiosError } from "axios";
import useGoogleAnalytics from "hooks/useGoogleAnalytics";
import { SnackbarKey, SnackbarProvider } from "notistack";
import { useEffect, useRef } from "react";
import { QueryCache, QueryClient, QueryClientProvider } from "react-query";
import Navbar from "components/Navbar/Navbar";
import useGetToken from "./hooks/useGetToken";
import BaseNavigation from "pages/BaseNavigation/BaseNavigation";
import { useLocation } from "react-router-dom";
import Downbanner from "components/Downbanner";
import Close from '@mui/icons-material/Close';
import { IconButton } from '@mui/material';
import { AxiosError } from 'axios';
import useGoogleAnalytics from 'hooks/useGoogleAnalytics';
import { SnackbarKey, SnackbarProvider } from 'notistack';
import { useEffect, useRef } from 'react';
import { QueryCache, QueryClient, QueryClientProvider } from 'react-query';
import Navbar from 'components/Navbar/Navbar';
import useGetToken from './hooks/useGetToken';
import BaseNavigation from 'pages/BaseNavigation/BaseNavigation';
import { useLocation } from 'react-router-dom';

const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: 0,
refetchOnWindowFocus: false,
// staleTime: 5000, // https://tkdodo.eu/blog/practical-react-query#the-defaults-explained
defaultOptions: {
queries: {
retry: 0,
refetchOnWindowFocus: false,
// staleTime: 5000, // https://tkdodo.eu/blog/practical-react-query#the-defaults-explained
},
},
},
queryCache: new QueryCache({
onError: (error) => {
console.log({ error });
const responseStatus = (error as AxiosError)?.response?.status;
if (responseStatus && responseStatus === 404) {
console.error("could not find resource");
}
},
}),
queryCache: new QueryCache({
onError: (error) => {
console.log({ error });
const responseStatus = (error as AxiosError)?.response?.status;
if (responseStatus && responseStatus === 404) {
console.error('could not find resource');
}
},
}),
});

declare global {
interface Window {
gtag?: (
type: "event" | "config" | "get" | "set" | "consent",
action: "login" | "page_view",
options?: any
) => void;
}
interface Window {
gtag?: (
type: 'event' | 'config' | 'get' | 'set' | 'consent',
action: 'login' | 'page_view',
options?: any
) => void;
}
}

function App() {
const notistackRef = useRef<SnackbarProvider>(null);
useGetToken();
useGoogleAnalytics();
const notistackRef = useRef<SnackbarProvider>(null);
useGetToken();
useGoogleAnalytics();

const location = useLocation();
useEffect(() => {
if (window.gtag) {
window.gtag("event", "page_view", {
page_path: `${location.pathname}${location.search}`,
});
}
}, [location]);
const location = useLocation();
useEffect(() => {
if (window.gtag) {
window.gtag('event', 'page_view', {
page_path: `${location.pathname}${location.search}`,
});
}
}, [location]);

const handleCloseSnackbar =
(key: SnackbarKey) => (_event: React.MouseEvent) => {
if (notistackRef?.current?.closeSnackbar)
notistackRef.current?.closeSnackbar(key);
const handleCloseSnackbar = (key: SnackbarKey) => (_event: React.MouseEvent) => {
if (notistackRef?.current?.closeSnackbar) notistackRef.current?.closeSnackbar(key);
};

return (
<QueryClientProvider client={queryClient}>
<SnackbarProvider
ref={notistackRef}
autoHideDuration={8000}
action={(key) => (
<IconButton onClick={handleCloseSnackbar(key)}>
<Close sx={{ color: "white" }} />
</IconButton>
)}
>
<Downbanner />
<Navbar />
<BaseNavigation />
</SnackbarProvider>
</QueryClientProvider>
);
return (
<QueryClientProvider client={queryClient}>
<SnackbarProvider
ref={notistackRef}
autoHideDuration={8000}
action={(key) => (
<IconButton onClick={handleCloseSnackbar(key)}>
<Close sx={{ color: 'white' }} />
</IconButton>
)}
>
{/* <Banner /> */}
<Navbar />
<BaseNavigation />
</SnackbarProvider>
</QueryClientProvider>
);
}

export default App;
64 changes: 64 additions & 0 deletions compose/neurosynth-frontend/src/components/Banner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Cancel } from '@mui/icons-material';
import EmojiPeopleIcon from '@mui/icons-material/EmojiPeople';
import { Box, IconButton, Link } from '@mui/material';
import BaseNavigationStyles from 'pages/BaseNavigation/BaseNavigation.styles';
import { useState } from 'react';

const localStorageBannerKey = 'hide-banner-nov-20-2024';

const Banner: React.FC = () => {
const shouldHide = !!localStorage.getItem(localStorageBannerKey);
const [hideBanner, setHideBanner] = useState(shouldHide);

if (hideBanner) return <></>;

return (
<Box
sx={{
backgroundColor: 'primary.dark',
color: 'primary.contrastText',
width: '100%',
paddingY: '0.5rem',
}}
>
<Box
sx={[
BaseNavigationStyles.pagesContainer,
{
marginY: '0',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
},
]}
>
<Box display="flex" alignItems="center">
<EmojiPeopleIcon sx={{ mr: '1rem' }} />
Join us next Wednesday, December 4th 2024 at 10:00 ET for the Neurosynth Compose Virtual Town Hall!{' '}
<Link
color="primary.contrastText"
sx={{ marginLeft: '4px' }}
href="https://tally.so/r/nWePVR"
target="_blank"
>
Click here to register
</Link>
</Box>
<IconButton
onClick={() => {
localStorage.setItem(localStorageBannerKey, 'true');
setHideBanner(true);
}}
sx={{
padding: 0,
':hover': { backgroundColor: 'gray' },
}}
>
<Cancel />
</IconButton>
</Box>
</Box>
);
};

export default Banner;
65 changes: 0 additions & 65 deletions compose/neurosynth-frontend/src/components/Downbanner.tsx

This file was deleted.

10 changes: 8 additions & 2 deletions store/neurostore/resources/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from flask import abort, request, current_app # jsonify
from flask.views import MethodView

from psycopg2 import errors

import sqlalchemy as sa
import sqlalchemy.sql.expression as sae
from sqlalchemy.orm import (
Expand All @@ -21,7 +23,7 @@

from ..core import cache
from ..database import db
from .utils import get_current_user
from .utils import get_current_user, validate_search_query, pubmed_to_tsquery
from ..models import (
StudysetStudy,
AnnotationAnalysis,
Expand Down Expand Up @@ -613,7 +615,11 @@ def search(self):
if s is not None and s.isdigit():
q = q.filter_by(pmid=s)
elif s is not None and self._fulltext_fields:
tsquery = sa.func.websearch_to_tsquery("english", s)
try:
validate_search_query(s)
except errors.SyntaxError as e:
abort(400, description=e.args[0])
tsquery = func.to_tsquery('english', pubmed_to_tsquery(s))
q = q.filter(m._ts_vector.op("@@")(tsquery))

# Alternatively (or in addition), search on individual fields.
Expand Down
Loading

0 comments on commit 21cc012

Please sign in to comment.