Skip to content

Commit

Permalink
Genomics login modal with homepage as backdrop (#1220)
Browse files Browse the repository at this point in the history
* Use homepage as backdrop when login modal is displayed

* Clean up some logic and ensure homepage does not remount when login modal is opened
  • Loading branch information
dmfalke authored Oct 7, 2024
1 parent 3f33d8d commit 6fec896
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 77 deletions.
6 changes: 3 additions & 3 deletions packages/libs/eda/src/lib/map/MapVeuContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ export function MapVeuContainer(mapVeuContainerProps: Props) {
path={`${path}/studies`}
exact
render={() => (
<Page requireLogin={false}>
<Page>
<StudyList subsettingClient={edaClient} />
</Page>
)}
/>
<Route
path={`${path}/public`}
render={() => (
<Page requireLogin={false}>
<Page>
<PublicAnalysesRoute
analysisClient={analysisClient}
subsettingClient={edaClient}
Expand All @@ -121,7 +121,7 @@ export function MapVeuContainer(mapVeuContainerProps: Props) {
}>
) => {
return (
<Page requireLogin={false}>
<Page>
<ImportAnalysis
{...props.match.params}
analysisClient={analysisClient}
Expand Down
4 changes: 2 additions & 2 deletions packages/libs/eda/src/lib/map/analysis/MapAnalysis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export function MapAnalysis(props: Props) {

if (geoConfigs == null || geoConfigs.length === 0)
return (
<Page requireLogin={false}>
<Page>
<h1>Incompatible Study</h1>
<div css={{ fontSize: '1.2em' }}>
<p>This study does not contain map-specific variables.</p>
Expand All @@ -141,7 +141,7 @@ export function MapAnalysis(props: Props) {
);
if (appStateAndSetters.analysisState.error) {
return (
<Page requireLogin={false}>
<Page>
<AnalysisError
error={appStateAndSetters.analysisState.error}
baseAnalysisPath={location.pathname}
Expand Down
9 changes: 3 additions & 6 deletions packages/libs/wdk-client/src/Components/Layout/Page.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
/**
* Page wrapper used by view controllers.
*/
import React, { useEffect } from 'react';
import { withRouter, RouteComponentProps, useHistory } from 'react-router';
import React from 'react';
import { withRouter, RouteComponentProps } from 'react-router';
import { wrappable, makeClassNameHelper } from '../../Utils/ComponentUtils';
import Header from '../../Components/Layout/Header';
import Footer from '../../Components/Layout/Footer';
import ErrorBoundary from '../../Core/Controllers/ErrorBoundary';
import { useScrollUpOnRouteChange } from '../../Hooks/Page';
import { useDispatch } from 'react-redux';
import { showLoginForm } from '../../Actions/UserSessionActions';
import { useWdkService } from '../../Hooks/WdkServiceHook';

export type Props = RouteComponentProps<any> & {
classNameModifier?: string;
children: React.ReactNode;
requireLogin: boolean;
isFullScreen?: boolean;
isAccessDenied?: boolean;
};

const cx = makeClassNameHelper('wdk-RootContainer');
Expand Down
92 changes: 42 additions & 50 deletions packages/libs/wdk-client/src/Core/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import Banner from '@veupathdb/coreui/lib/components/banners/Banner';
import { Link } from 'react-router-dom';

import './Style/wdk-Button.scss';
import { User } from '../Utils/WdkUser';
import { IndexController, NotFoundController } from '../Controllers';

type Props = {
requireLogin: boolean;
Expand All @@ -43,7 +45,7 @@ type Props = {

interface State {
location: Location;
accessDenied?: boolean;
user?: User;
}

const REACT_ROUTER_LINK_CLASSNAME = 'wdk-ReactRouterLink';
Expand Down Expand Up @@ -116,34 +118,16 @@ export default class Root extends React.Component<Props, State> {
);
}

doLoginLogic() {
// allow some pages non-login access
const activeRoute = this.getActiveRoute();
const requireLogin =
activeRoute?.requiresLogin === false ? false : this.props.requireLogin;
if (!requireLogin) {
this.setState({ accessDenied: false });
} else {
this.props.wdkDependencies.wdkService.getCurrentUser().then((user) => {
this.setState({ accessDenied: user.isGuest });
});
}
loadUser() {
this.props.wdkDependencies.wdkService.getCurrentUser().then((user) => {
this.setState({ user });
});
}

componentDidMount() {
/** install global click handler */
document.addEventListener('click', this.handleGlobalClick);
this.doLoginLogic();
}

componentDidUpdate(
prevProps: Readonly<Props>,
prevState: Readonly<State>,
snapshot?: any
): void {
if (this.state.location.pathname !== prevState.location.pathname) {
this.doLoginLogic();
}
this.loadUser();
}

componentWillUnmount() {
Expand All @@ -152,13 +136,40 @@ export default class Root extends React.Component<Props, State> {
}

render() {
const { staticContent } = this.props;
const { staticContent, routes } = this.props;
const { user } = this.state;
const activeRoute = this.getActiveRoute();
const rootClassNameModifier = activeRoute?.rootClassNameModifier;
const isFullscreen = activeRoute?.isFullscreen;

if (this.state.accessDenied == null) return 'Loading...';
if (user == null) return 'Loading...';

// allow some pages non-login access
const requireLogin =
activeRoute?.requiresLogin === false ? false : this.props.requireLogin;
const accessDenied = requireLogin ? user.isGuest : false;
const activeRouteContent = (
<Switch>
{accessDenied ? (
<WdkRoute
key="/"
path="*"
component={IndexController}
requiresLogin={false}
/>
) : (
routes.map((route) => (
<WdkRoute
key={route.path}
path={route.path}
component={route.component}
exact={route.exact ?? true}
requiresLogin={route.requiresLogin ?? false}
/>
))
)}
</Switch>
);
return (
<Provider store={this.props.store}>
<ErrorBoundary>
Expand All @@ -170,7 +181,7 @@ export default class Root extends React.Component<Props, State> {
<UnhandledErrorsController />
<LoginFormController />
<Modal
visible={this.state.accessDenied}
visible={accessDenied}
toggleVisible={noop}
styleOverrides={{
position: {
Expand Down Expand Up @@ -238,31 +249,12 @@ export default class Root extends React.Component<Props, State> {
</Modal>
<Page
classNameModifier={rootClassNameModifier}
requireLogin={this.props.requireLogin}
isFullScreen={isFullscreen}
isAccessDenied={accessDenied}
>
{staticContent ? (
safeHtml(staticContent, null, 'div')
) : (
<Switch>
{this.props.routes.map(
({
path,
exact = true,
component,
requiresLogin = false,
}) => (
<WdkRoute
key={path}
exact={exact == null ? false : exact}
path={path}
component={component}
requiresLogin={requiresLogin}
/>
)
)}
</Switch>
)}
{staticContent
? safeHtml(staticContent, null, 'div')
: activeRouteContent}
</Page>
</PluginContext.Provider>
</WdkDependenciesContext.Provider>
Expand Down
3 changes: 2 additions & 1 deletion packages/libs/wdk-client/src/Core/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ import Error from '../Components/PageStatus/Error';
const routes: RouteEntry[] = [
{
path: '/',
component: () => <IndexController />,
requiresLogin: false,
component: IndexController,
},

{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import { apiActions } from './components/strategies/ApiStepDetailsActions';
import { VEuPathDBHomePage } from './components/homepage/VEuPathDBHomePage';
import { BlockRecordAttributeSection } from '@veupathdb/wdk-client/lib/Views/Records/RecordAttributes/RecordAttributeSection';

import GenomicsIndexController from './controllers/GenomicsIndexController';

import './record-page-new-feature.scss';

import {
Expand All @@ -38,6 +40,7 @@ import { workspaceThemeOptions as MUIThemeOptions } from '@veupathdb/eda/lib/wor

import UIThemeProvider from '@veupathdb/coreui/lib/components/theming/UIThemeProvider';
import { colors } from '@veupathdb/coreui';
import { ErrorBoundary } from '@veupathdb/wdk-client/lib/Controllers';

export const SiteHeader = () => ApiSiteHeader;

Expand Down Expand Up @@ -479,12 +482,16 @@ export function StrategyWorkspaceController(DefaultComponent) {
};
}

export function IndexController() {
return GenomicsIndexController;
}

export function Page() {
return function VuPathDBPage(props) {
useScrollUpOnRouteChange();

const location = useLocation();
const isHomePage = location.pathname === '/';
const isHomePage = location.pathname === '/' || props.isAccessDenied;
const params = new URLSearchParams(location.search);
const galaxyUrl = params.get('galaxy_url');
const MUITheme = createMUITheme(MUIThemeOptions);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { FeaturedTools } from '@veupathdb/web-common/lib/components/homepage/FeaturedTools';
import { WorkshopExercises } from '@veupathdb/web-common/lib/components/homepage/WorkshopExercises';
import React from 'react';

export default function GenomicsIndexController() {
return (
<React.Fragment>
<FeaturedTools />
<hr />
<WorkshopExercises />
</React.Fragment>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import QueryGridController from './components/controllers/QueryGridController';
import { JBrowseController } from './components/controllers/JBrowseController';
import { PlasmoApController } from './components/controllers/PlasmoApController';

import { FeaturedTools } from '@veupathdb/web-common/lib/components/homepage/FeaturedTools';
import { WorkshopExercises } from '@veupathdb/web-common/lib/components/homepage/WorkshopExercises';
import { useUserDatasetsWorkspace } from '@veupathdb/web-common/lib/config';

import {
Expand Down Expand Up @@ -201,18 +199,6 @@ export const wrapRoutes = (ebrcRoutes) => [
component: () => <SampleForm />,
},

{
path: '/',
requiresLogin: false,
component: () => (
<React.Fragment>
<FeaturedTools />
<hr />
<WorkshopExercises />
</React.Fragment>
),
},

{
path: '/jbrowse',
component: JBrowseController,
Expand Down

0 comments on commit 6fec896

Please sign in to comment.