Files
outline/app/scenes/Settings/components/DomainManagement.tsx
dependabot[bot] fbd16d4b9a chore(deps-dev): bump prettier from 2.1.2 to 2.8.8 (#5372)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tom Moor <tom.moor@gmail.com>
2023-05-22 19:14:56 -07:00

154 lines
4.3 KiB
TypeScript

import { observer } from "mobx-react";
import { CloseIcon } from "outline-icons";
import * as React from "react";
import { Trans, useTranslation } from "react-i18next";
import styled from "styled-components";
import Button from "~/components/Button";
import Fade from "~/components/Fade";
import Flex from "~/components/Flex";
import Input from "~/components/Input";
import NudeButton from "~/components/NudeButton";
import Tooltip from "~/components/Tooltip";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import useStores from "~/hooks/useStores";
import useToasts from "~/hooks/useToasts";
import SettingRow from "./SettingRow";
type Props = {
onSuccess: () => void;
};
function DomainManagement({ onSuccess }: Props) {
const { auth } = useStores();
const team = useCurrentTeam();
const { t } = useTranslation();
const { showToast } = useToasts();
const [allowedDomains, setAllowedDomains] = React.useState([
...(team.allowedDomains ?? []),
]);
const [lastKnownDomainCount, updateLastKnownDomainCount] = React.useState(
allowedDomains.length
);
const [existingDomainsTouched, setExistingDomainsTouched] =
React.useState(false);
const handleSaveDomains = React.useCallback(async () => {
try {
await auth.updateTeam({
allowedDomains,
});
onSuccess();
setExistingDomainsTouched(false);
updateLastKnownDomainCount(allowedDomains.length);
} catch (err) {
showToast(err.message, {
type: "error",
});
}
}, [auth, allowedDomains, onSuccess, showToast]);
const handleRemoveDomain = async (index: number) => {
const newDomains = allowedDomains.filter((_, i) => index !== i);
setAllowedDomains(newDomains);
const touchedExistingDomain = index < lastKnownDomainCount;
if (touchedExistingDomain) {
setExistingDomainsTouched(true);
}
};
const handleAddDomain = () => {
const newDomains = [...allowedDomains, ""];
setAllowedDomains(newDomains);
};
const createOnDomainChangedHandler =
(index: number) => (ev: React.ChangeEvent<HTMLInputElement>) => {
const newDomains = allowedDomains.slice();
newDomains[index] = ev.currentTarget.value;
setAllowedDomains(newDomains);
const touchedExistingDomain = index < lastKnownDomainCount;
if (touchedExistingDomain) {
setExistingDomainsTouched(true);
}
};
const showSaveChanges =
existingDomainsTouched ||
allowedDomains.filter((value: string) => value !== "").length > // New domains were added
lastKnownDomainCount;
return (
<SettingRow
label={t("Allowed domains")}
name="allowedDomains"
description={t(
"The domains which should be allowed to create new accounts using SSO. Changing this setting does not affect existing user accounts."
)}
>
{allowedDomains.map((domain, index) => (
<Flex key={index} gap={4}>
<Input
key={index}
id={`allowedDomains${index}`}
value={domain}
autoFocus={!domain}
placeholder="example.com"
required
flex
onChange={createOnDomainChangedHandler(index)}
/>
<Remove>
<Tooltip tooltip={t("Remove domain")} placement="top">
<NudeButton onClick={() => handleRemoveDomain(index)}>
<CloseIcon />
</NudeButton>
</Tooltip>
</Remove>
</Flex>
))}
<Flex justify="space-between" gap={4} style={{ flexWrap: "wrap" }}>
{!allowedDomains.length ||
allowedDomains[allowedDomains.length - 1] !== "" ? (
<Fade>
<Button type="button" onClick={handleAddDomain} neutral>
{allowedDomains.length ? (
<Trans>Add another</Trans>
) : (
<Trans>Add a domain</Trans>
)}
</Button>
</Fade>
) : (
<span />
)}
{showSaveChanges && (
<Fade>
<Button
type="button"
onClick={handleSaveDomains}
disabled={auth.isSaving}
>
<Trans>Save changes</Trans>
</Button>
</Fade>
)}
</Flex>
</SettingRow>
);
}
const Remove = styled("div")`
margin-top: 6px;
`;
export default observer(DomainManagement);