Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/web/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ ts_project(
"src/app/TauriLink.tsx",
"src/app/tauriIcpUtils.ts",
"src/auth.ts",
"src/auth/AuthPageWrapper.tsx",
"src/auth/CloudSignUpPage.tsx",
"src/auth/OrDivider.tsx",
"src/auth/PostSignUpPage.tsx",
Expand Down
15 changes: 15 additions & 0 deletions client/web/src/auth/AuthPageWrapper.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.logo {
display: block;
width: 4rem;
margin-bottom: 1rem;
}

.wrapper {
width: 100%;
display: flex;
align-items: center;
/* stylelint-disable declaration-property-unit-allowed-list */
margin-top: min(20vh, 20rem);
flex-direction: column;
flex: 1 1 auto;
}
47 changes: 47 additions & 0 deletions client/web/src/auth/AuthPageWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react'

import { useIsLightTheme } from '@sourcegraph/shared/src/theme'
import { H1, LinkOrSpan, Text } from '@sourcegraph/wildcard'

import { BrandLogo } from '../components/branding/BrandLogo'

import styles from './AuthPageWrapper.module.scss'

interface Props {
/** Title of the page. */
title: string
/** Optional second line item. */
description?: string
sourcegraphDotComMode: boolean
className?: string
}

export type AuthPageWrapperProps = React.PropsWithChildren<Props>

export const AuthPageWrapper: React.FunctionComponent<AuthPageWrapperProps> = ({
title,
description,
sourcegraphDotComMode,
className,
children,
}) => {
const isLightTheme = useIsLightTheme()

return (
<>
<div className={styles.wrapper}>
<LinkOrSpan to={sourcegraphDotComMode ? '/search' : undefined}>
<BrandLogo
className={styles.logo}
isLightTheme={isLightTheme}
variant="symbol"
disableSymbolSpin={true}
/>
</LinkOrSpan>
<H1>{title}</H1>
{description && <Text className="text-muted">{description}</Text>}
<div className={className}>{children}</div>
</div>
</>
)
}
5 changes: 0 additions & 5 deletions client/web/src/auth/CloudSignUpPage.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,3 @@
height: 3rem !important;
flex-shrink: 0;
}

.externals-auth-button {
background: var(--white);
color: var(--black) !important;
}
8 changes: 8 additions & 0 deletions client/web/src/auth/CloudSignUpPage.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ const context: Pick<SourcegraphContext, 'authProviders' | 'experimentalFeatures'
authenticationURL: '/.auth/gitlab/login?pc=https%3A%2F%2Fgitlab.com%2F',
serviceID: 'https://gitlab.com',
},
{
clientID: '002',
serviceType: 'openidconnect',
displayName: 'Google',
isBuiltin: false,
authenticationURL: '/.auth/openidconnect/login?pc=google',
serviceID: 'https://gitlab.com',
},
],
experimentalFeatures: {},
authMinPasswordLength: 0,
Expand Down
1 change: 0 additions & 1 deletion client/web/src/auth/CloudSignUpPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ export const CloudSignUpPage: React.FunctionComponent<React.PropsWithChildren<Pr
gitlabLabel="Continue with GitLab"
googleLabel="Continue with Google"
onClick={logEventAndSetFlags}
ctaClassName={styles.externalsAuthButton}
/>
</>
)
Expand Down
2 changes: 1 addition & 1 deletion client/web/src/auth/OrDivider.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { OrDivider } from './OrDivider'
const decorator: DecoratorFn = story => <div className="p-3 container">{story()}</div>

const config: Meta = {
title: 'web/OrDivider',
title: 'web/auth/OrDivider',
decorators: [decorator],
}

Expand Down
2 changes: 1 addition & 1 deletion client/web/src/auth/PostSignUpPage.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { WebStory } from '../components/WebStory'
import { PostSignUpPage } from './PostSignUpPage'

const config: Meta = {
title: 'web/src/auth/PostSignUpPage',
title: 'web/auth/PostSignUpPage',
}

export default config
Expand Down
3 changes: 3 additions & 0 deletions client/web/src/auth/RequestAccessPage.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.wrapper {
width: 27.5rem;
}
17 changes: 17 additions & 0 deletions client/web/src/auth/RequestAccessPage.story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Meta, Story } from '@storybook/react'

import { WebStory } from '../components/WebStory'

import { RequestAccessPage } from './RequestAccessPage'

const config: Meta = {
title: 'web/auth/RequestAccessPage',
}

export default config

export const Default: Story = () => <WebStory>{() => <RequestAccessPage />}</WebStory>

export const Done: Story = () => (
<WebStory initialEntries={[{ pathname: '/done' }]}>{() => <RequestAccessPage />}</WebStory>
)
171 changes: 76 additions & 95 deletions client/web/src/auth/RequestAccessPage.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import React, { useEffect, useState } from 'react'

import classNames from 'classnames'
import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom'

import { Text, Link, ErrorAlert, Form, Input, Button, LoadingSpinner, TextArea, Label } from '@sourcegraph/wildcard'
import { Text, Link, ErrorAlert, Form, Input, TextArea, Container, Alert } from '@sourcegraph/wildcard'

import { HeroPage } from '../components/HeroPage'
import { LoaderButton } from '../components/LoaderButton'
import { PageTitle } from '../components/PageTitle'
import type { SourcegraphContext } from '../jscontext'
import { PageRoutes } from '../routes.constants'
import { eventLogger } from '../tracking/eventLogger'
import { checkRequestAccessAllowed } from '../util/checkRequestAccessAllowed'

import { SourcegraphIcon } from './icons'
import { AuthPageWrapper } from './AuthPageWrapper'
import { getReturnTo } from './SignInSignUpCommon'

import RequestAccessSignUpCommonStyles from './SignInSignUpCommon.module.scss'
import styles from './RequestAccessPage.module.scss'

interface RequestAccessFormProps {
export interface RequestAccessFormProps {
onSuccess: () => void
onError: (error?: any) => void
xhrHeaders: SourcegraphContext['xhrHeaders']
Expand Down Expand Up @@ -69,59 +68,50 @@ const RequestAccessForm: React.FunctionComponent<RequestAccessFormProps> = ({ on
}
}
return (
<Form onSubmit={handleSubmit} data-testid="request-access-form">
<Label className="w-100">
<Text alignment="left" className="mb-2">
Name
</Text>
<Input
id="name"
onChange={(event: React.ChangeEvent<HTMLInputElement>) => setName(event.target.value)}
required={true}
value={name}
disabled={loading}
autoCapitalize="off"
autoFocus={true}
className="form-group"
placeholder="Your name"
autoComplete="name"
/>
</Label>
<Label className="w-100">
<Text alignment="left" className="mb-2">
Email Address
</Text>
<Input
id="email"
onChange={(event: React.ChangeEvent<HTMLInputElement>) => setEmail(event.target.value)}
required={true}
value={email}
disabled={loading}
autoCapitalize="off"
autoFocus={true}
placeholder="Your work email to get access"
className="form-group"
autoComplete="email"
/>
</Label>
<Label className="w-100">
<Text alignment="left" className="mb-2">
Notes for administrator
</Text>
<TextArea
id="additionalInfo"
onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) => setAdditionalInfo(event.target.value)}
className="mb-4"
value={additionalInfo}
placeholder="Use this field to provide extra info for your access request"
/>
</Label>

<div className={classNames('form-group')}>
<Button display="block" type="submit" disabled={loading} variant="primary">
{loading ? <LoadingSpinner /> : 'Request access'}
</Button>
</div>
<Form onSubmit={handleSubmit} className="mb-0" data-testid="request-access-form">
<Input
id="name"
onChange={(event: React.ChangeEvent<HTMLInputElement>) => setName(event.target.value)}
required={true}
value={name}
disabled={loading}
autoCapitalize="off"
autoFocus={true}
placeholder="Your name"
autoComplete="name"
label="Name"
/>

<Input
id="email"
onChange={(event: React.ChangeEvent<HTMLInputElement>) => setEmail(event.target.value)}
required={true}
value={email}
disabled={loading}
autoCapitalize="off"
autoFocus={true}
placeholder="Your work email to get access"
autoComplete="email"
label="Email Address"
/>

<TextArea
id="additionalInfo"
onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) => setAdditionalInfo(event.target.value)}
value={additionalInfo}
placeholder="Use this field to provide extra info for your access request"
label="Notes for administrator"
className="mb-3"
/>

<LoaderButton
display="block"
loading={loading}
type="submit"
disabled={loading}
variant="primary"
label="Request access"
/>
</Form>
)
}
Expand All @@ -146,54 +136,45 @@ export const RequestAccessPage: React.FunctionComponent = () => {
return <Navigate to={PageRoutes.SignIn} replace={true} />
}

const body = (
<div className={classNames('mb-4 pb-5', RequestAccessSignUpCommonStyles.signinPageContainer)}>
{error && <ErrorAlert className="mt-4 mb-0 text-left" error={error} />}
<div
className={classNames(
'rounded p-4 my-3',
RequestAccessSignUpCommonStyles.signinSignupForm,
error ? 'mt-3' : 'mt-4'
)}
return (
<>
<PageTitle title="Request access" />
<AuthPageWrapper
title="Request access to Sourcegraph"
sourcegraphDotComMode={sourcegraphDotComMode}
className={styles.wrapper}
>
{error && <ErrorAlert error={error} />}
<Routes>
<Route
path="done"
element={
<Text data-testid="request-access-post-submit">
Thank you! We notified the admin of your request.
</Text>
<Container>
<Alert variant="info" data-testid="request-access-post-submit" className="mb-0">
Thank you! We notified the admin of your request.
</Alert>
</Container>
}
/>
<Route
path=""
element={
<RequestAccessForm
onError={setError}
xhrHeaders={xhrHeaders}
onSuccess={() => navigate('done')}
/>
<>
<Container>
<RequestAccessForm
onError={setError}
xhrHeaders={xhrHeaders}
onSuccess={() => navigate('done')}
/>
</Container>
<Text className="text-center mt-3">
Already have an account? <Link to={`/sign-in${location.search}`}>Sign in</Link>
</Text>
</>
}
/>
</Routes>
</div>
<Text className="mt-3">
Already have an account? <Link to={`/sign-in${location.search}`}>Sign in</Link>
</Text>
</div>
)

return (
<div className={RequestAccessSignUpCommonStyles.signinSignupPage}>
<PageTitle title="Request access" />
<HeroPage
icon={SourcegraphIcon}
iconLinkTo={sourcegraphDotComMode ? '/search' : undefined}
iconClassName="bg-transparent"
lessPadding={true}
title="Request access to Sourcegraph"
body={body}
/>
</div>
</AuthPageWrapper>
</>
)
}
5 changes: 2 additions & 3 deletions client/web/src/auth/ResetPasswordPage.module.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
.form {
margin: 0 auto;
max-width: 18rem;
.wrapper {
max-width: 20rem;
}
Loading