diff --git a/app/components/Input.tsx b/app/components/Input.tsx
index bb8893d4b..fd13ff7ae 100644
--- a/app/components/Input.tsx
+++ b/app/components/Input.tsx
@@ -175,6 +175,7 @@ function Input(
labelHidden,
onFocus,
onBlur,
+ children,
...rest
} = props;
@@ -211,6 +212,7 @@ function Input(
{...rest}
/>
)}
+ {children}
{error && (
diff --git a/app/scenes/Login/index.tsx b/app/scenes/Login/index.tsx
index 30d678bb1..7b6d9fea2 100644
--- a/app/scenes/Login/index.tsx
+++ b/app/scenes/Login/index.tsx
@@ -15,6 +15,7 @@ import Fade from "~/components/Fade";
import Flex from "~/components/Flex";
import Heading from "~/components/Heading";
import OutlineIcon from "~/components/Icons/OutlineIcon";
+import Input from "~/components/Input";
import LoadingIndicator from "~/components/LoadingIndicator";
import PageTitle from "~/components/PageTitle";
import TeamLogo from "~/components/TeamLogo";
@@ -34,11 +35,11 @@ function Header({ config }: { config?: Config | undefined }) {
const { t } = useTranslation();
const isSubdomain = !!config?.hostname;
- if (
- !isCloudHosted ||
- parseDomain(window.location.origin).custom ||
- Desktop.isElectron()
- ) {
+ if (!isCloudHosted || parseDomain(window.location.origin).custom) {
+ return null;
+ }
+
+ if (Desktop.isElectron() && !isSubdomain) {
return null;
}
@@ -56,6 +57,8 @@ type Props = {
function Login({ children }: Props) {
const location = useLocation();
const query = useQuery();
+ const notice = query.get("notice");
+
const { t, i18n } = useTranslation();
const { auth } = useStores();
const { config } = auth;
@@ -74,6 +77,22 @@ function Login({ children }: Props) {
setEmailLinkSentTo(email);
}, []);
+ const handleGoSubdomain = React.useCallback(async (event) => {
+ event.preventDefault();
+ const data = Object.fromEntries(new FormData(event.target));
+ const normalizedSubdomain = data.subdomain
+ .toString()
+ .toLowerCase()
+ .trim()
+ .replace(/^https?:\/\//, "");
+ const host = `https://${normalizedSubdomain}.getoutline.com`;
+ await Desktop.bridge.addCustomHost(host);
+
+ setTimeout(() => {
+ window.location.href = host;
+ }, 500);
+ }, []);
+
React.useEffect(() => {
auth.fetchConfig().catch(setError);
}, [auth]);
@@ -160,6 +179,43 @@ function Login({ children }: Props) {
);
}
+ if (Desktop.isElectron() && notice === "domain-required") {
+ return (
+
+
+
+
+ {t("Choose workspace")}
+
+ {t(
+ "This login method requires choosing your workspace to continue"
+ )}
+ …
+
+
+
+ .getoutline.com
+
+
+
+ {t("Continue")}
+
+
+
+ );
+ }
+
const hasMultipleProviders = config.providers.length > 1;
const defaultProvider = find(
config.providers,
@@ -275,6 +331,11 @@ const StyledHeading = styled(Heading)`
margin: 0;
`;
+const Domain = styled.div`
+ color: ${s("textSecondary")};
+ padding: 0 8px 0 0;
+`;
+
const CheckEmailIcon = styled(EmailIcon)`
margin-bottom: -1.5em;
`;
diff --git a/shared/i18n/locales/en_US/translation.json b/shared/i18n/locales/en_US/translation.json
index 38c1d37b0..26b36303e 100644
--- a/shared/i18n/locales/en_US/translation.json
+++ b/shared/i18n/locales/en_US/translation.json
@@ -633,6 +633,9 @@
"Custom domain setup": "Custom domain setup",
"Almost there": "Almost there",
"Your custom domain is successfully pointing at Outline. To complete the setup process please contact support.": "Your custom domain is successfully pointing at Outline. To complete the setup process please contact support.",
+ "Choose workspace": "Choose workspace",
+ "This login method requires choosing your workspace to continue": "This login method requires choosing your workspace to continue",
+ "subdomain": "subdomain",
"Check your email": "Check your email",
"A magic sign-in link has been sent to the email {{ emailLinkSentTo }} if an account exists.": "A magic sign-in link has been sent to the email {{ emailLinkSentTo }} if an account exists.",
"Back to login": "Back to login",