mirror of
https://github.com/getredash/redash.git
synced 2026-03-22 10:00:17 -04:00
* Migrate router and <app-view> to React: skeleton * Update layout on route change * Start moving page routes from angular to react * Move page routes to react except of public dashboard and visualization embed) * Move public dashboard and visualization embed routes to React * Replace $route/$routeParams usages * Some cleanup * Replace AngularJS $location service with implementation based on history library * Minor fix to how ApplicationView handles route change * Explicitly use global layout for each page instead of handling related stuff in ApplicationArea component * Error handling * Remove AngularJS and related dependencies * Move Parameter factory method to a separate file * Fix CSS (replace custom components with classes) * Fix: keep other url parts when updating location partially; refine code * Fix tests * Make router work in multi-org mode (respect <base> tag) * Optimzation: don't resolve route if path didn't change * Fix search input in header; error handling improvement (handle more errors in pages; global error handler for unhandled errors; dialog dismiss 'unhandled rejection' errors) * Fix page keys; fix navigateTo calls (third parameter not available) * Use relative links * Router: ignore location REPLACE events, resolve only on PUSH/POP * Fix tests * Remove unused jQuery reference * Show error from backend when creating Destination * Remove route.resolve where not necessary (used constant values) * New Query page: keep state on saving, reload when creating another new query * Use currentRoute.key instead of hard-coded keys for page components * Tidy up Router * Tidy up location service * Fix tests * Don't add parameters changes to browser's history * Fix test (improved fix) Co-authored-by: Gabriel Dutra <nesk.frz@gmail.com>
176 lines
4.6 KiB
JavaScript
176 lines
4.6 KiB
JavaScript
import { keys, some } from "lodash";
|
|
import React, { useCallback } from "react";
|
|
import PropTypes from "prop-types";
|
|
import classNames from "classnames";
|
|
import CreateDashboardDialog from "@/components/dashboards/CreateDashboardDialog";
|
|
import { currentUser } from "@/services/auth";
|
|
import organizationStatus from "@/services/organizationStatus";
|
|
import "./empty-state.less";
|
|
|
|
function Step({ show, completed, text, url, urlText, onClick }) {
|
|
if (!show) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<li className={classNames({ done: completed })}>
|
|
<a href={url} onClick={onClick}>
|
|
{urlText}
|
|
</a>{" "}
|
|
{text}
|
|
</li>
|
|
);
|
|
}
|
|
|
|
Step.propTypes = {
|
|
show: PropTypes.bool.isRequired,
|
|
completed: PropTypes.bool.isRequired,
|
|
text: PropTypes.string.isRequired,
|
|
url: PropTypes.string,
|
|
urlText: PropTypes.string,
|
|
onClick: PropTypes.func,
|
|
};
|
|
|
|
Step.defaultProps = {
|
|
url: null,
|
|
urlText: null,
|
|
onClick: null,
|
|
};
|
|
|
|
function EmptyState({
|
|
icon,
|
|
header,
|
|
description,
|
|
illustration,
|
|
helpLink,
|
|
onboardingMode,
|
|
showAlertStep,
|
|
showDashboardStep,
|
|
showInviteStep,
|
|
}) {
|
|
const isAvailable = {
|
|
dataSource: true,
|
|
query: true,
|
|
alert: showAlertStep,
|
|
dashboard: showDashboardStep,
|
|
inviteUsers: showInviteStep,
|
|
};
|
|
|
|
const isCompleted = {
|
|
dataSource: organizationStatus.objectCounters.data_sources > 0,
|
|
query: organizationStatus.objectCounters.queries > 0,
|
|
alert: organizationStatus.objectCounters.alerts > 0,
|
|
dashboard: organizationStatus.objectCounters.dashboards > 0,
|
|
inviteUsers: organizationStatus.objectCounters.users > 1,
|
|
};
|
|
|
|
const showCreateDashboardDialog = useCallback(() => {
|
|
CreateDashboardDialog.showModal().result.catch(() => {}); // ignore dismiss
|
|
}, []);
|
|
|
|
// Show if `onboardingMode=false` or any requested step not completed
|
|
const shouldShow = !onboardingMode || some(keys(isAvailable), step => isAvailable[step] && !isCompleted[step]);
|
|
|
|
if (!shouldShow) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div className="empty-state bg-white tiled">
|
|
<div className="empty-state__summary">
|
|
{header && <h4>{header}</h4>}
|
|
<h2>
|
|
<i className={icon} />
|
|
</h2>
|
|
<p>{description}</p>
|
|
<img
|
|
src={"/static/images/illustrations/" + illustration + ".svg"}
|
|
alt={illustration + " Illustration"}
|
|
width="75%"
|
|
/>
|
|
</div>
|
|
<div className="empty-state__steps">
|
|
<h4>Let's get started</h4>
|
|
<ol>
|
|
{currentUser.isAdmin && (
|
|
<Step
|
|
show={isAvailable.dataSource}
|
|
completed={isCompleted.dataSource}
|
|
url="data_sources/new"
|
|
urlText="Connect"
|
|
text="a Data Source"
|
|
/>
|
|
)}
|
|
{!currentUser.isAdmin && (
|
|
<Step
|
|
show={isAvailable.dataSource}
|
|
completed={isCompleted.dataSource}
|
|
text="Ask an account admin to connect a data source"
|
|
/>
|
|
)}
|
|
<Step
|
|
show={isAvailable.query}
|
|
completed={isCompleted.query}
|
|
url="queries/new"
|
|
urlText="Create"
|
|
text="your first Query"
|
|
/>
|
|
<Step
|
|
show={isAvailable.alert}
|
|
completed={isCompleted.alert}
|
|
url="alerts/new"
|
|
urlText="Create"
|
|
text="your first Alert"
|
|
/>
|
|
<Step
|
|
show={isAvailable.dashboard}
|
|
completed={isCompleted.dashboard}
|
|
onClick={showCreateDashboardDialog}
|
|
urlText="Create"
|
|
text="your first Dashboard"
|
|
/>
|
|
<Step
|
|
show={isAvailable.inviteUsers}
|
|
completed={isCompleted.inviteUsers}
|
|
url="users/new"
|
|
urlText="Invite"
|
|
text="your team members"
|
|
/>
|
|
</ol>
|
|
<p>
|
|
Need more support?{" "}
|
|
<a href={helpLink} target="_blank" rel="noopener noreferrer">
|
|
See our Help
|
|
<i className="fa fa-external-link m-l-5" aria-hidden="true" />
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
EmptyState.propTypes = {
|
|
icon: PropTypes.string,
|
|
header: PropTypes.string,
|
|
description: PropTypes.string.isRequired,
|
|
illustration: PropTypes.string.isRequired,
|
|
helpLink: PropTypes.string.isRequired,
|
|
|
|
onboardingMode: PropTypes.bool,
|
|
showAlertStep: PropTypes.bool,
|
|
showDashboardStep: PropTypes.bool,
|
|
showInviteStep: PropTypes.bool,
|
|
};
|
|
|
|
EmptyState.defaultProps = {
|
|
icon: null,
|
|
header: null,
|
|
|
|
onboardingMode: false,
|
|
showAlertStep: false,
|
|
showDashboardStep: false,
|
|
showInviteStep: false,
|
|
};
|
|
|
|
export default EmptyState;
|