mirror of
https://github.com/getredash/redash.git
synced 2026-03-22 19:00:09 -04:00
* Vertical navbar * Update vertical menu look and add create menu. * Make query editor work with vertical nav. * Dark mode * Fix create menu & make sidebar fixed. * Update Alert pages layout * Update System status pages * Update Queries and Dashboards list pages * Update Query Source and Query View pages * Use dark theme for mobile navbar * Update Dashboard page: fix Add widget/textbox panel positioning * Dashboard page: fix layout issues when container changes its size (fixes known issues: navbar expand/collapse, scrollbar appears/hides) * Fix dashboard page sticky header (there was a 15px space above it) * Fix embeds * Extract desktop navbar component; move mobile navbar and its styles to ApplicationLayout folder * Remove old app header * Fix tests * Restore version info block * Make Percy capture entire page * Make vertical navbar expand/collapse animation smoother (as it's currently impossible to disable it :-( ) * Fix misc UI issues (show Create label on expanded menu; fix some CSS; don't select items on click) * Allow to override navbars with DynamicComponent * Fix misc UI issues: expand/collapse button animation, menu items styles, menu expand/collapse animation * Hide submenu arrow; show username when menu is expanded * Refine CSS and make it more isolated; adjust colors * Update tests Co-authored-by: Arik Fraimovich <arik@arikfr.com>
82 lines
2.4 KiB
JavaScript
82 lines
2.4 KiB
JavaScript
import React, { useEffect, useState } from "react";
|
|
import PropTypes from "prop-types";
|
|
import ErrorBoundary, { ErrorBoundaryContext } from "@redash/viz/lib/components/ErrorBoundary";
|
|
import { Auth } from "@/services/auth";
|
|
import organizationStatus from "@/services/organizationStatus";
|
|
import ApplicationLayout from "./ApplicationLayout";
|
|
import ErrorMessage from "./ErrorMessage";
|
|
|
|
// This wrapper modifies `route.render` function and instead of passing `currentRoute` passes an object
|
|
// that contains:
|
|
// - `currentRoute.routeParams`
|
|
// - `pageTitle` field which is equal to `currentRoute.title`
|
|
// - `onError` field which is a `handleError` method of nearest error boundary
|
|
|
|
function UserSessionWrapper({ bodyClass, currentRoute, renderChildren }) {
|
|
const [isAuthenticated, setIsAuthenticated] = useState(!!Auth.isAuthenticated());
|
|
|
|
useEffect(() => {
|
|
let isCancelled = false;
|
|
Promise.all([Auth.requireSession(), organizationStatus.refresh()])
|
|
.then(() => {
|
|
if (!isCancelled) {
|
|
setIsAuthenticated(!!Auth.isAuthenticated());
|
|
}
|
|
})
|
|
.catch(() => {
|
|
if (!isCancelled) {
|
|
setIsAuthenticated(false);
|
|
}
|
|
});
|
|
return () => {
|
|
isCancelled = true;
|
|
};
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (bodyClass) {
|
|
document.body.classList.toggle(bodyClass, true);
|
|
return () => {
|
|
document.body.classList.toggle(bodyClass, false);
|
|
};
|
|
}
|
|
}, [bodyClass]);
|
|
|
|
if (!isAuthenticated) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<ApplicationLayout>
|
|
<React.Fragment key={currentRoute.key}>
|
|
<ErrorBoundary renderError={error => <ErrorMessage error={error} />}>
|
|
<ErrorBoundaryContext.Consumer>
|
|
{({ handleError }) =>
|
|
renderChildren({ ...currentRoute.routeParams, pageTitle: currentRoute.title, onError: handleError })
|
|
}
|
|
</ErrorBoundaryContext.Consumer>
|
|
</ErrorBoundary>
|
|
</React.Fragment>
|
|
</ApplicationLayout>
|
|
);
|
|
}
|
|
|
|
UserSessionWrapper.propTypes = {
|
|
bodyClass: PropTypes.string,
|
|
renderChildren: PropTypes.func,
|
|
};
|
|
|
|
UserSessionWrapper.defaultProps = {
|
|
bodyClass: null,
|
|
renderChildren: () => null,
|
|
};
|
|
|
|
export default function routeWithUserSession({ render, bodyClass, ...rest }) {
|
|
return {
|
|
...rest,
|
|
render: currentRoute => (
|
|
<UserSessionWrapper bodyClass={bodyClass} currentRoute={currentRoute} renderChildren={render} />
|
|
),
|
|
};
|
|
}
|