Skip to content
Snippets Groups Projects
Unverified Commit 841d902b authored by Nick Fitzpatrick's avatar Nick Fitzpatrick Committed by GitHub
Browse files

SettingsSetting to Functional Component (#40318)

* SettingsSetting FC, change to named export

* adding unit test
parent 703ee9ec
No related branches found
No related tags found
No related merge requests found
import { push } from "react-router-redux";
import SettingsSetting from "metabase/admin/settings/components/SettingsSetting";
import { SettingsSetting } from "metabase/admin/settings/components/SettingsSetting";
import type { SettingElement } from "metabase/admin/settings/types";
import { useDispatch } from "metabase/lib/redux";
import { Tabs } from "metabase/ui";
......
......@@ -13,7 +13,7 @@ import Button from "metabase/core/components/Button";
import { isEmail, isEmpty } from "metabase/lib/utils";
import { CollapsibleSectionContent } from "./SettingsBatchForm.styled";
import SettingsSetting from "./SettingsSetting";
import { SettingsSetting } from "./SettingsSetting";
const VALIDATIONS = {
email: {
......
/* eslint-disable react/prop-types */
import PropTypes from "prop-types";
import { Component } from "react";
import { useEffect, useRef, useState } from "react";
import { useLocation } from "react-use";
import { jt } from "ttag";
import ExternalLink from "metabase/core/components/ExternalLink";
import { alpha, color } from "metabase/lib/colors";
import { settingToFormFieldId, getEnvVarDocsUrl } from "../utils";
import { getEnvVarDocsUrl, settingToFormFieldId } from "./../../settings/utils";
import SettingHeader from "./SettingHeader";
import {
SettingContent,
......@@ -33,62 +35,80 @@ const SETTING_WIDGET_MAP = {
hidden: () => null,
};
export default class SettingsSetting extends Component {
static propTypes = {
setting: PropTypes.object.isRequired,
settingValues: PropTypes.object,
onChange: PropTypes.func.isRequired,
onChangeSetting: PropTypes.func,
autoFocus: PropTypes.bool,
disabled: PropTypes.bool,
};
export const SettingsSetting = props => {
const { hash } = useLocation();
const [fancyStyle, setFancyStyle] = useState({});
const thisRef = useRef();
const { setting, settingValues, errorMessage } = props;
render() {
const { setting, settingValues, errorMessage } = this.props;
const settingId = settingToFormFieldId(setting);
useEffect(() => {
if (hash === `#${setting.key}` && thisRef.current) {
thisRef.current.scrollIntoView({
behavior: "smooth",
block: "center",
});
thisRef.current.focus();
let Widget = setting.widget || SETTING_WIDGET_MAP[setting.type];
if (!Widget) {
console.warn(
"No render method for setting type " +
setting.type +
", defaulting to string input.",
);
Widget = SettingInput;
setFancyStyle({
background: alpha("brand", 0.1),
boxShadow: `0 0 0 1px ${color("brand")}`,
});
setTimeout(() => {
setFancyStyle({});
}, 1500);
}
}, [hash, setting.key]);
const widgetProps = {
...setting.getProps?.(setting, settingValues),
...setting.props,
...this.props,
};
const settingId = settingToFormFieldId(setting);
return (
// TODO - this formatting needs to be moved outside this component
<SettingRoot data-testid={`${setting.key}-setting`}>
{!setting.noHeader && (
<SettingHeader id={settingId} setting={setting} />
)}
<SettingContent>
{setting.is_env_setting && !setting.forceRenderWidget ? (
<SettingEnvVarMessage>
{jt`This has been set by the ${(
<ExternalLink href={getEnvVarDocsUrl(setting.env_name)}>
{setting.env_name}
</ExternalLink>
)} environment variable.`}
</SettingEnvVarMessage>
) : (
<Widget id={settingId} {...widgetProps} />
)}
</SettingContent>
{errorMessage && (
<SettingErrorMessage>{errorMessage}</SettingErrorMessage>
)}
{setting.warning && (
<SettingWarningMessage>{setting.warning}</SettingWarningMessage>
)}
</SettingRoot>
let Widget = setting.widget || SETTING_WIDGET_MAP[setting.type];
if (!Widget) {
console.warn(
"No render method for setting type " +
setting.type +
", defaulting to string input.",
);
Widget = SettingInput;
}
}
const widgetProps = {
...setting.getProps?.(setting, settingValues),
...setting.props,
...props,
};
return (
// TODO - this formatting needs to be moved outside this component
<SettingRoot
data-testid={`${setting.key}-setting`}
ref={thisRef}
style={{
transition: "500ms ease all",
...fancyStyle,
}}
>
{!setting.noHeader && <SettingHeader id={settingId} setting={setting} />}
<SettingContent>
{setting.is_env_setting && !setting.forceRenderWidget ? (
<SettingEnvVarMessage>
{jt`This has been set by the ${(
<ExternalLink href={getEnvVarDocsUrl(setting.env_name)}>
{setting.env_name}
</ExternalLink>
)} environment variable.`}
</SettingEnvVarMessage>
) : (
<Widget id={settingId} {...widgetProps} />
)}
</SettingContent>
{errorMessage && (
<SettingErrorMessage>{errorMessage}</SettingErrorMessage>
)}
{setting.warning && (
<SettingWarningMessage>{setting.warning}</SettingWarningMessage>
)}
</SettingRoot>
);
};
......@@ -3,11 +3,8 @@ import styled from "@emotion/styled";
import { color } from "metabase/lib/colors";
export const SettingRoot = styled.li`
margin: 1rem 1rem 2rem;
&:first-child {
margin-top: 0;
}
padding: 0.5rem 1rem 2rem;
border-radius: 0.5rem;
`;
export const SettingContent = styled.div`
......
import { render, screen } from "__support__/ui";
import { SettingsSetting } from "./SettingsSetting";
const SETTING = {
key: "site-name",
display_name: "Site Name",
type: "string",
};
const setup = () => {
render(<SettingsSetting setting={SETTING} />);
};
describe("SettingsSetting", () => {
it("renders a setting", () => {
setup();
expect(screen.getByText("Site Name")).toBeInTheDocument();
});
it("highlights itself if it's key is in location.hash", () => {
const ogScrollIntoView = window.HTMLElement.prototype.scrollIntoView;
window.location.hash = "#site-name";
const mockScroll = jest.fn();
window.HTMLElement.prototype.scrollIntoView = mockScroll;
setup();
expect(screen.getByTestId("site-name-setting")).toHaveStyle(
"box-shadow: 0 0 0 1px #509EE3",
);
expect(mockScroll).toHaveBeenCalled();
window.location.hash = "";
window.HTMLElement.prototype.scrollIntoView = ogScrollIntoView;
});
});
......@@ -4,7 +4,7 @@ import PropTypes from "prop-types";
import CS from "metabase/css/core/index.css";
import MetabaseSettings from "metabase/lib/settings";
import SettingsSetting from "../SettingsSetting";
import { SettingsSetting } from "../SettingsSetting";
import VersionUpdateNotice from "./VersionUpdateNotice/VersionUpdateNotice";
......
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