Skip to content
Snippets Groups Projects
Unverified Commit 2dd18496 authored by Nemanja Glumac's avatar Nemanja Glumac Committed by GitHub
Browse files

Remove unused New User Onboarding Modal (#14129)

* Remove related unit tests

* Remove new user onboarding modal and related component

* Remove greeting function
parent e8b0bcca
Branches
Tags
No related merge requests found
/* @flow */
import React from "react";
import { color } from "metabase/lib/colors";
type Props = {
activeDotColor?: string,
currentStep: number,
dotSize?: number,
goToStep?: (step: number) => void,
steps: [],
};
const StepIndicators = ({
activeDotColor = color("brand"),
currentStep = 0,
dotSize = 8,
goToStep,
steps,
}: Props) => (
<ol className="flex">
{steps.map((step, index) => (
<li
onClick={() => goToStep && goToStep(index + 1)}
style={{
width: dotSize,
height: dotSize,
borderRadius: 99,
cursor: "pointer",
marginLeft: 2,
marginRight: 2,
backgroundColor:
index + 1 === currentStep ? activeDotColor : color("text-light"),
transition: "background 600ms ease-in",
}}
key={index}
/>
))}
</ol>
);
export default StepIndicators;
/* @flow */
import React, { Component } from "react";
import StepIndicators from "metabase/components/StepIndicators";
import RetinaImage from "react-retina-image";
import { t } from "ttag";
import MetabaseSettings from "metabase/lib/settings";
import { color } from "metabase/lib/colors";
type Props = {
onClose: () => void,
};
type State = {
step: number,
};
const STEPS = [
{
title: t`Ask questions and explore`,
text: t`Click on charts or tables to explore, or ask a new question using the easy interface or the powerful SQL editor.`,
image: (
<RetinaImage
className="absolute full"
style={{ top: 30 }}
src={`app/assets/img/welcome-modal-1.png`}
/>
),
},
{
title: t`Make your own charts`,
text: t`Create line charts, scatter plots, maps, and more.`,
image: (
<RetinaImage
className="absolute ml-auto mr-auto inline-block left right"
style={{ bottom: -20 }}
src={`app/assets/img/welcome-modal-2.png`}
/>
),
},
{
title: t`Share what you find`,
text: t`Create powerful and flexible dashboards, and send regular updates via email or Slack.`,
image: (
<RetinaImage
className="absolute ml-auto mr-auto inline-block left right"
style={{ bottom: -30 }}
src={`app/assets/img/welcome-modal-3.png`}
/>
),
},
];
export default class NewUserOnboardingModal extends Component {
props: Props;
state: State = {
step: 1,
};
nextStep = () => {
const stepCount = MetabaseSettings.get("has-sample-dataset?") ? 3 : 2;
const nextStep = this.state.step + 1;
if (nextStep <= stepCount) {
this.setState({ step: nextStep });
} else {
this.props.onClose();
}
};
render() {
const { step } = this.state;
const currentStep = STEPS[step - 1];
return (
<div>
<OnboardingImages currentStep={currentStep} />
<div className="p4 pb3 text-centered">
<h2>{currentStep.title}</h2>
<p
className="ml-auto mr-auto text-paragraph"
style={{ maxWidth: 420 }}
>
{currentStep.text}
</p>
<div className="flex align-center py2 relative">
<div className="ml-auto mr-auto">
<StepIndicators
currentStep={step}
steps={STEPS}
goToStep={step => this.setState({ step })}
/>
</div>
<a
className="link flex-align-right text-bold absolute right"
onClick={() => this.nextStep()}
>
{step === 3 ? t`Let's go` : t`Next`}
</a>
</div>
</div>
</div>
);
}
}
const OnboardingImages = ({ currentStep }, { currentStep: object }) => (
<div
style={{
position: "relative",
backgroundColor: color("bg-medium"),
borderBottom: `1px solid ${color("border")}`,
height: 254,
paddingTop: "3em",
paddingBottom: "3em",
}}
>
{currentStep.image}
</div>
);
......@@ -4,14 +4,11 @@ import { connect } from "react-redux";
import { t } from "ttag";
import { push } from "react-router-redux";
import Greeting from "metabase/lib/greeting";
import Modal from "metabase/components/Modal";
import Card from "metabase/components/Card";
import Subhead from "metabase/components/type/Subhead";
import Activity from "../components/Activity";
import RecentViews from "../components/RecentViews";
import NewUserOnboardingModal from "../components/NewUserOnboardingModal";
import NextStep from "../components/NextStep";
import * as homepageActions from "../actions";
......@@ -23,7 +20,6 @@ const mapStateToProps = (state, props) => ({
activity: getActivity(state),
recentViews: getRecentViews(state),
user: getUser(state),
showOnboarding: "new" in props.location.query,
});
const mapDispatchToProps = {
......@@ -38,7 +34,6 @@ const mapDispatchToProps = {
export default class HomepageApp extends Component {
static propTypes = {
onChangeLocation: PropTypes.func.isRequired,
showOnboarding: PropTypes.bool.isRequired,
user: PropTypes.object.isRequired,
// TODO - these should be used by their call sites rather than passed
activity: PropTypes.array,
......@@ -50,29 +45,11 @@ export default class HomepageApp extends Component {
constructor(props) {
super(props);
this.state = {
greeting: Greeting.sayHello(props.user && props.user.first_name),
onboarding: props.showOnboarding,
};
}
completeOnboarding() {
this.setState({ onboarding: false });
}
render() {
const { user } = this.props;
return (
<Box mx={4}>
{this.state.onboarding ? (
<Modal>
<NewUserOnboardingModal
user={user}
onClose={() => this.completeOnboarding()}
/>
</Modal>
) : null}
<Box py={3}>
<Subhead>{t`Activity`}</Subhead>
</Box>
......
import { click } from "__support__/enzyme";
import React from "react";
import { shallow } from "enzyme";
import { color } from "metabase/lib/colors";
import StepIndicators from "metabase/components/StepIndicators";
describe("Step indicators", () => {
const steps = [{}, {}, {}];
it("should render as many indicators as steps", () => {
const wrapper = shallow(<StepIndicators steps={steps} />);
expect(wrapper.find("li").length).toEqual(steps.length);
});
it("should indicate the current step", () => {
const wrapper = shallow(<StepIndicators steps={steps} currentStep={1} />);
expect(wrapper.find("li").get(0).props.style.backgroundColor).toEqual(
color("brand"),
);
});
describe("goToStep", () => {
it("should call goToStep with the proper number when a step is clicked", () => {
const goToStep = jest.fn();
const wrapper = shallow(
<StepIndicators steps={steps} goToStep={goToStep} currentStep={1} />,
);
const targetIndicator = wrapper.find("li").first();
click(targetIndicator);
expect(goToStep).toHaveBeenCalledWith(1);
});
});
});
import { click } from "__support__/enzyme";
import React from "react";
import { shallow } from "enzyme";
import NewUserOnboardingModal from "metabase/home/components/NewUserOnboardingModal";
describe("new user onboarding modal", () => {
describe("advance steps", () => {
it("should advance through steps properly", () => {
const wrapper = shallow(<NewUserOnboardingModal />);
const nextButton = wrapper.find("a");
expect(wrapper.state().step).toEqual(1);
click(nextButton);
expect(wrapper.state().step).toEqual(2);
});
it("should close if on the last step", () => {
const onClose = jest.fn();
const wrapper = shallow(<NewUserOnboardingModal onClose={onClose} />);
// go to the last step
wrapper.setState({ step: 3 });
const nextButton = wrapper.find("a");
expect(nextButton.text()).toEqual("Let's go");
click(nextButton);
expect(onClose.mock.calls.length).toEqual(1);
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment