Skip to content
Snippets Groups Projects
Unverified Commit e14d88c4 authored by Gustavo Saiani's avatar Gustavo Saiani Committed by GitHub
Browse files

Improve SettingsUpdatesForm component (#16988)

parent 4fdf2b85
No related branches found
No related tags found
No related merge requests found
import React from "react";
import PropTypes from "prop-types";
import cx from "classnames";
import MetabaseSettings from "metabase/lib/settings";
import SettingsSetting from "../SettingsSetting";
import VersionUpdateNotice from "./VersionUpdateNotice/VersionUpdateNotice";
export default function SettingsUpdatesForm({ elements, updateSetting }) {
const settings = elements.map((setting, index) => (
<SettingsSetting
key={setting.key}
setting={setting}
onChange={value => updateSetting(setting, value)}
autoFocus={index === 0}
/>
));
return (
<div style={{ width: "585px" }}>
{!MetabaseSettings.isHosted() && <ul>{settings}</ul>}
<div className="px2">
<div
className={cx("pt3", {
"border-top": !MetabaseSettings.isHosted(),
})}
>
<VersionUpdateNotice />
</div>
</div>
</div>
);
}
SettingsUpdatesForm.propTypes = {
elements: PropTypes.array,
updateSetting: PropTypes.func,
};
import React from "react";
import { render, screen } from "@testing-library/react";
import { render as renderRTL, screen } from "@testing-library/react";
import MetabaseSettings from "../../../../metabase/lib/settings";
import MetabaseSettings from "metabase/lib/settings";
import SettingsUpdatesForm from "./SettingsUpdatesForm";
const elements = [
{
key: "key",
widget: "widget",
},
];
const render = () => {
renderRTL(<SettingsUpdatesForm elements={elements} />);
};
describe("SettingsUpdatesForm", () => {
it("shows custom message for Cloud installations", () => {
const isHostedSpy = jest.spyOn(MetabaseSettings, "isHosted");
isHostedSpy.mockImplementation(() => true);
render(<SettingsUpdatesForm elements={elements} />);
render();
screen.getByText(/Metabase Cloud keeps your instance up-to-date/);
isHostedSpy.mockRestore();
......@@ -25,14 +30,14 @@ describe("SettingsUpdatesForm", () => {
const versionIsLatestSpy = jest.spyOn(MetabaseSettings, "versionIsLatest");
versionIsLatestSpy.mockImplementation(() => true);
render(<SettingsUpdatesForm elements={elements} />);
render();
screen.getByText(/which is the latest and greatest/);
versionIsLatestSpy.mockRestore();
});
it("shows correct message when no version checks have been run", () => {
render(<SettingsUpdatesForm elements={elements} />);
render();
screen.getByText("No successful checks yet.");
});
......@@ -40,7 +45,7 @@ describe("SettingsUpdatesForm", () => {
const versionIsLatestSpy = jest.spyOn(MetabaseSettings, "versionIsLatest");
versionIsLatestSpy.mockImplementation(() => true);
render(<SettingsUpdatesForm elements={elements} />);
render();
screen.getByText("Migrate to Metabase Cloud.");
versionIsLatestSpy.mockRestore();
......@@ -50,7 +55,7 @@ describe("SettingsUpdatesForm", () => {
const versionIsLatestSpy = jest.spyOn(MetabaseSettings, "versionIsLatest");
versionIsLatestSpy.mockImplementation(() => false);
render(<SettingsUpdatesForm elements={elements} />);
render();
expect(screen.queryByText("Migrate to Metabase Cloud.")).toBeNull();
versionIsLatestSpy.mockRestore();
......
/* eslint-disable react/prop-types */
import React, { Component } from "react";
import React from "react";
import PropTypes from "prop-types";
import { t, jt } from "ttag";
import { t } from "ttag";
import { Flex, Box } from "grid-styled";
import cx from "classnames";
import MetabaseSettings from "metabase/lib/settings";
import SettingsSetting from "./SettingsSetting";
import HostingInfoLink from "metabase/admin/settings/components/widgets/HostingInfoLink";
import Icon from "metabase/components/Icon";
import Text from "metabase/components/type/Text";
import ExternalLink from "metabase/components/ExternalLink";
import MetabaseSettings from "metabase/lib/settings";
export default class SettingsUpdatesForm extends Component {
static propTypes = {
elements: PropTypes.array,
};
export default function VersionUpdateNotice() {
const currentVersion = formatVersion(MetabaseSettings.currentVersion());
renderVersionUpdateNotice() {
const currentVersion = formatVersion(MetabaseSettings.currentVersion());
if (MetabaseSettings.isHosted()) {
return <CloudCustomers currentVersion={currentVersion} />;
}
if (MetabaseSettings.isHosted()) {
return (
<div>{jt`Metabase Cloud keeps your instance up-to-date. You're currently on version ${currentVersion}. Thanks for being a customer!`}</div>
);
}
if (MetabaseSettings.versionIsLatest()) {
return <OnLatestVersion currentVersion={currentVersion} />;
}
if (MetabaseSettings.versionIsLatest()) {
const shouldShowHostedCta = !MetabaseSettings.isEnterprise();
return (
<div>
<div className="p2 bg-brand bordered rounded border-brand text-white text-bold">
{jt`You're running Metabase ${currentVersion} which is the latest and greatest!`}
</div>
{shouldShowHostedCta && <HostingCTA />}
</div>
);
} else if (MetabaseSettings.newVersionAvailable()) {
const latestVersion = MetabaseSettings.latestVersion();
const versionInfo = MetabaseSettings.versionInfo();
return (
<div>
<div className="p2 bg-green bordered rounded border-success flex flex-row align-center justify-between">
<span className="text-white text-bold">
{jt`Metabase ${formatVersion(latestVersion)} is available.`}{" "}
{jt`You're running ${currentVersion}`}
</span>
<ExternalLink
data-metabase-event={
"Updates Settings; Update link clicked; " + latestVersion
}
className="Button Button--white Button--medium borderless"
href={
"https://www.metabase.com/docs/" +
latestVersion +
"/operations-guide/upgrading-metabase.html"
}
>
{t`Update`}
</ExternalLink>
</div>
<div
className="text-medium bordered rounded p2 mt2 overflow-y-scroll"
style={{ height: 330 }}
>
<h3 className="pb3 text-uppercase">{t`What's Changed:`}</h3>
<Version version={versionInfo.latest} />
{versionInfo.older &&
versionInfo.older.map((version, index) => (
<Version key={index} version={version} />
))}
</div>
{!MetabaseSettings.isHosted() && <HostingCTA />}
</div>
);
} else {
return <div>{t`No successful checks yet.`}</div>;
}
if (MetabaseSettings.newVersionAvailable()) {
return <NewVersionAvailable currentVersion={currentVersion} />;
}
render() {
const { elements, updateSetting } = this.props;
const settings = elements.map((setting, index) => (
<SettingsSetting
key={setting.key}
setting={setting}
onChange={value => updateSetting(setting, value)}
autoFocus={index === 0}
/>
));
return (
<div style={{ width: "585px" }}>
{!MetabaseSettings.isHosted() && <ul>{settings}</ul>}
<div className="px2">
<div
className={cx("pt3", {
"border-top": !MetabaseSettings.isHosted(),
})}
>
{this.renderVersionUpdateNotice()}
</div>
</div>
return <div>{t`No successful checks yet.`}</div>;
}
function CloudCustomers({ currentVersion }) {
return (
<div>
{t`Metabase Cloud keeps your instance up-to-date. You're currently on version ${currentVersion}. Thanks for being a customer!`}
</div>
);
}
CloudCustomers.propTypes = {
currentVersion: PropTypes.string.isRequired,
};
function OnLatestVersion({ currentVersion }) {
const shouldShowHostedCta = !MetabaseSettings.isEnterprise();
return (
<div>
<div className="p2 bg-brand bordered rounded border-brand text-white text-bold">
{t`You're running Metabase ${currentVersion} which is the latest and greatest!`}
</div>
);
}
{shouldShowHostedCta && <HostingCTA />}
</div>
);
}
function Version({ version }) {
if (!version) {
return null;
}
OnLatestVersion.propTypes = {
currentVersion: PropTypes.string.isRequired,
};
function NewVersionAvailable({ currentVersion }) {
const latestVersion = MetabaseSettings.latestVersion();
const versionInfo = MetabaseSettings.versionInfo();
return (
<div className="pb3">
<h3 className="text-medium">
{formatVersion(version.version)}{" "}
{version.patch ? "(" + t`patch release` + ")" : null}
</h3>
<ul style={{ listStyleType: "disc", listStylePosition: "inside" }}>
{version.highlights &&
version.highlights.map((highlight, index) => (
<li key={index} style={{ lineHeight: "1.5" }} className="pl1">
{highlight}
</li>
<div>
<div className="p2 bg-green bordered rounded border-success flex flex-row align-center justify-between">
<span className="text-white text-bold">
{t`Metabase ${formatVersion(latestVersion)} is available.`}{" "}
{t`You're running ${currentVersion}`}
</span>
<ExternalLink
data-metabase-event={
"Updates Settings; Update link clicked; " + latestVersion
}
className="Button Button--white Button--medium borderless"
href={
"https://www.metabase.com/docs/" +
latestVersion +
"/operations-guide/upgrading-metabase.html"
}
>
{t`Update`}
</ExternalLink>
</div>
<div
className="text-medium bordered rounded p2 mt2 overflow-y-scroll"
style={{ height: 330 }}
>
<h3 className="pb3 text-uppercase">{t`What's Changed:`}</h3>
<Version version={versionInfo.latest} />
{versionInfo.older &&
versionInfo.older.map((version, index) => (
<Version key={index} version={version} />
))}
</ul>
</div>
{!MetabaseSettings.isHosted() && <HostingCTA />}
</div>
);
}
NewVersionAvailable.propTypes = {
currentVersion: PropTypes.string.isRequired,
};
function HostingCTA() {
if (MetabaseSettings.isEnterprise()) {
return null;
......@@ -167,6 +137,33 @@ function HostingCTA() {
);
}
function Version({ version }) {
if (!version) {
return null;
}
return (
<div className="pb3">
<h3 className="text-medium">
{formatVersion(version.version)}{" "}
{version.patch ? "(" + t`patch release` + ")" : null}
</h3>
<ul style={{ listStyleType: "disc", listStylePosition: "inside" }}>
{version.highlights &&
version.highlights.map((highlight, index) => (
<li key={index} style={{ lineHeight: "1.5" }} className="pl1">
{highlight}
</li>
))}
</ul>
</div>
);
}
Version.propTypes = {
version: PropTypes.object.isRequired,
};
function formatVersion(versionLabel = "") {
return versionLabel.replace(/^v/, "");
}
......@@ -16,7 +16,7 @@ import EmbeddingLegalese from "./components/widgets/EmbeddingLegalese";
import EmbeddingLevel from "./components/widgets/EmbeddingLevel";
import FormattingWidget from "./components/widgets/FormattingWidget";
import SettingsUpdatesForm from "./components/SettingsUpdatesForm";
import SettingsUpdatesForm from "./components/SettingsUpdatesForm/SettingsUpdatesForm";
import SettingsEmailForm from "./components/SettingsEmailForm";
import SettingsSetupList from "./components/SettingsSetupList";
import SettingsSlackForm from "./components/SettingsSlackForm";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment