Web:Client:OAUth: add preview
This commit is contained in:
parent
f6dca051ac
commit
a34bedef1e
@ -1,6 +1,32 @@
|
||||
import styled from "styled-components";
|
||||
|
||||
//@ts-ignore
|
||||
import Box from "@docspace/components/box";
|
||||
import { hugeMobile, tablet } from "@docspace/components/utils/device";
|
||||
|
||||
const Container = styled.div`
|
||||
width: 100%;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 350px 350px;
|
||||
|
||||
gap: 16px;
|
||||
|
||||
.preview-container {
|
||||
margin-top: 16px;
|
||||
|
||||
width: fit-content;
|
||||
min-width: 350px;
|
||||
height: fit-content;
|
||||
|
||||
border: 1px solid #a3aeae;
|
||||
border-radius: 6px;
|
||||
|
||||
padding: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const FormContainer = styled.div`
|
||||
max-width: 350px;
|
||||
|
||||
display: flex;
|
||||
@ -85,12 +111,51 @@ const CheckboxRaw = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const Frame = styled(Box)`
|
||||
margin-top: 16px;
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
button {
|
||||
width: auto;
|
||||
max-width: auto;
|
||||
|
||||
padding: 0 20px;
|
||||
}
|
||||
`;
|
||||
|
||||
const CategorySubHeader = styled.div`
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 15px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 16px;
|
||||
|
||||
@media ${tablet} {
|
||||
&:not(&.copy-window-code) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media ${hugeMobile} {
|
||||
&:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export {
|
||||
Container,
|
||||
FormContainer,
|
||||
BlockContainer,
|
||||
HeaderRaw,
|
||||
InputGroup,
|
||||
InputRaw,
|
||||
CheckboxGroup,
|
||||
CheckboxRaw,
|
||||
Frame,
|
||||
CategorySubHeader,
|
||||
};
|
||||
|
@ -54,3 +54,9 @@ export interface ClientFormProps {
|
||||
|
||||
regenerateSecret?: (clientId: string) => Promise<string>;
|
||||
}
|
||||
|
||||
export interface PreviewProps {
|
||||
clientId: string;
|
||||
redirectURI: string;
|
||||
scopes: string[];
|
||||
}
|
||||
|
@ -0,0 +1,98 @@
|
||||
import React from "react";
|
||||
|
||||
//@ts-ignore
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
|
||||
//@ts-ignore
|
||||
import Box from "@docspace/components/box";
|
||||
//@ts-ignore
|
||||
import Textarea from "@docspace/components/textarea";
|
||||
//@ts-ignore
|
||||
import TabContainer from "@docspace/components/tabs-container";
|
||||
//@ts-ignore
|
||||
import SocialButton from "@docspace/components/social-button";
|
||||
|
||||
import ImagesLogoSvgUrl from "PUBLIC_DIR/images/logo/leftmenu.svg?url";
|
||||
|
||||
import { PreviewProps } from "../ClientForm.types";
|
||||
import { Frame, CategorySubHeader } from "../ClientForm.styled";
|
||||
|
||||
const Preview = ({ clientId, redirectURI, scopes }: PreviewProps) => {
|
||||
const getAuthLink = () => {
|
||||
const origin = window.location.origin;
|
||||
const path = "/oauth2/authorize";
|
||||
|
||||
const params: { [key: string]: string } = {
|
||||
response_type: "code",
|
||||
client_id: clientId,
|
||||
redirect_uri: redirectURI,
|
||||
scope: scopes[0],
|
||||
code_challenge_method: "S256",
|
||||
code_challenge: "ZX8YUY6qL0EweJXhjDug0S2XuKI8beOWb1LGujmgfuQ",
|
||||
};
|
||||
|
||||
const paramsString = [];
|
||||
|
||||
for (let key in params) {
|
||||
const str = `${key}=${params[key]}`;
|
||||
|
||||
paramsString.push(str);
|
||||
}
|
||||
|
||||
const link = `${origin}${path}?${paramsString.join("&")}`;
|
||||
|
||||
return link;
|
||||
};
|
||||
|
||||
const onDocSpaceLogin = () => {
|
||||
const url = getAuthLink();
|
||||
|
||||
window.open(
|
||||
url,
|
||||
"login",
|
||||
"width=800,height=500,status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=no"
|
||||
);
|
||||
};
|
||||
|
||||
const preview = (
|
||||
<Frame>
|
||||
<SocialButton
|
||||
iconName={ImagesLogoSvgUrl}
|
||||
label={"Sign in with DocSpace"}
|
||||
onClick={onDocSpaceLogin}
|
||||
/>
|
||||
</Frame>
|
||||
);
|
||||
|
||||
const codeBlock = "123";
|
||||
|
||||
const code = (
|
||||
<>
|
||||
<CategorySubHeader className="copy-window-code">
|
||||
{"Copy window code"}
|
||||
</CategorySubHeader>
|
||||
<Textarea value={codeBlock} />
|
||||
</>
|
||||
);
|
||||
|
||||
const dataTabs = [
|
||||
{
|
||||
key: "preview",
|
||||
title: "Preview",
|
||||
content: preview,
|
||||
},
|
||||
{
|
||||
key: "code",
|
||||
title: "Code",
|
||||
content: code,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="preview-container">
|
||||
<TabContainer elements={dataTabs} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Preview;
|
@ -17,8 +17,14 @@ import { OAuthStoreProps } from "SRC_DIR/store/OAuthStore";
|
||||
|
||||
import CheckboxComponent from "./components/Checkbox";
|
||||
|
||||
import { CheckboxGroup, Container, InputGroup } from "./ClientForm.styled";
|
||||
import {
|
||||
Container,
|
||||
FormContainer,
|
||||
CheckboxGroup,
|
||||
InputGroup,
|
||||
} from "./ClientForm.styled";
|
||||
import { ClientFormProps } from "./ClientForm.types";
|
||||
import Preview from "./components/Preview";
|
||||
|
||||
const ClientForm = ({
|
||||
id,
|
||||
@ -255,160 +261,169 @@ const ClientForm = ({
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Block>
|
||||
<BlockHeader header={"Basic info"} helpButtonText="" />
|
||||
<InputGroup>
|
||||
<InputHeader header={"App name"} />
|
||||
<Input
|
||||
value={form.appName}
|
||||
name={"appName"}
|
||||
placeholder={"Enter name"}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputHeader header={"App icon"} />
|
||||
<Input
|
||||
value={form.appIcon}
|
||||
name={"appIcon"}
|
||||
placeholder={"Add icon"}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputHeader header={"Description"} />
|
||||
<Input
|
||||
value={form.description}
|
||||
name={"description"}
|
||||
placeholder={"Enter description"}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</InputGroup>
|
||||
</Block>
|
||||
|
||||
{id && (
|
||||
<FormContainer>
|
||||
<Block>
|
||||
<BlockHeader header={"Client"} helpButtonText="" />
|
||||
<BlockHeader header={"Basic info"} helpButtonText="" />
|
||||
<InputGroup>
|
||||
<InputHeader header={"ID"} />
|
||||
<InputHeader header={"App name"} />
|
||||
<Input
|
||||
value={clientId}
|
||||
name={"ID"}
|
||||
placeholder={"Enter id"}
|
||||
value={form.appName}
|
||||
name={"appName"}
|
||||
placeholder={"Enter name"}
|
||||
onChange={onInputChange}
|
||||
isReadOnly
|
||||
withCopy
|
||||
/>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputHeader header={"Secret"} />
|
||||
<InputHeader header={"App icon"} />
|
||||
<Input
|
||||
value={secret}
|
||||
name={"secret"}
|
||||
placeholder={"Enter secret"}
|
||||
value={form.appIcon}
|
||||
name={"appIcon"}
|
||||
placeholder={"Add icon"}
|
||||
onChange={onInputChange}
|
||||
isReadOnly
|
||||
isSecret
|
||||
withCopy
|
||||
withButton
|
||||
buttonLabel="Reset"
|
||||
onClickButton={onResetClick}
|
||||
/>
|
||||
</InputGroup>
|
||||
|
||||
<InputGroup>
|
||||
<InputHeader header={"Authentication method "} />
|
||||
<InputHeader header={"Description"} />
|
||||
<Input
|
||||
value={form.authenticationMethod}
|
||||
name={"authenticationMethod"}
|
||||
placeholder={"Enter secret"}
|
||||
value={form.description}
|
||||
name={"description"}
|
||||
placeholder={"Enter description"}
|
||||
onChange={onInputChange}
|
||||
isReadOnly
|
||||
withCopy
|
||||
/>
|
||||
</InputGroup>
|
||||
</Block>
|
||||
)}
|
||||
|
||||
<Block>
|
||||
<BlockHeader header={"OAuth URLs"} helpButtonText="" />
|
||||
<InputGroup>
|
||||
<InputHeader header={"Redirect url"} />
|
||||
<Input
|
||||
value={form.redirectUrl}
|
||||
name={"redirectUrl"}
|
||||
placeholder={"Enter URL"}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputHeader header={"Logout redirect url"} />
|
||||
<Input
|
||||
value={form.logoutRedirectUrl}
|
||||
name={"logoutRedirectUrl"}
|
||||
placeholder={"Enter URL"}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</InputGroup>
|
||||
</Block>
|
||||
|
||||
<Block>
|
||||
<BlockHeader header={"Access scopes"} helpButtonText="" />
|
||||
<CheckboxGroup>
|
||||
{scopes.length > 0 &&
|
||||
scopes.map((scope) => (
|
||||
<CheckboxComponent
|
||||
key={`${scope.name}`}
|
||||
isChecked={checkedScopes.includes(scope.name)}
|
||||
onChange={() => onCheckboxChange(scope.name)}
|
||||
label={scope.name}
|
||||
description={scope.description}
|
||||
{id && (
|
||||
<Block>
|
||||
<BlockHeader header={"Client"} helpButtonText="" />
|
||||
<InputGroup>
|
||||
<InputHeader header={"ID"} />
|
||||
<Input
|
||||
value={clientId}
|
||||
name={"ID"}
|
||||
placeholder={"Enter id"}
|
||||
onChange={onInputChange}
|
||||
isReadOnly
|
||||
withCopy
|
||||
/>
|
||||
))}
|
||||
</CheckboxGroup>
|
||||
</Block>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputHeader header={"Secret"} />
|
||||
<Input
|
||||
value={secret}
|
||||
name={"secret"}
|
||||
placeholder={"Enter secret"}
|
||||
onChange={onInputChange}
|
||||
isReadOnly
|
||||
isSecret
|
||||
withCopy
|
||||
withButton
|
||||
buttonLabel="Reset"
|
||||
onClickButton={onResetClick}
|
||||
/>
|
||||
</InputGroup>
|
||||
|
||||
<Block>
|
||||
<BlockHeader header={"Support & Legal info"} helpButtonText="" />
|
||||
<InputGroup>
|
||||
<InputHeader header={"Authentication method "} />
|
||||
<Input
|
||||
value={form.authenticationMethod}
|
||||
name={"authenticationMethod"}
|
||||
placeholder={"Enter secret"}
|
||||
onChange={onInputChange}
|
||||
isReadOnly
|
||||
withCopy
|
||||
/>
|
||||
</InputGroup>
|
||||
</Block>
|
||||
)}
|
||||
|
||||
<InputGroup>
|
||||
<InputHeader header={"Privacy policy URL"} />
|
||||
<Input
|
||||
value={form.privacyURL}
|
||||
name={"privacyURL"}
|
||||
placeholder={"Enter URL"}
|
||||
onChange={onInputChange}
|
||||
<Block>
|
||||
<BlockHeader header={"OAuth URLs"} helpButtonText="" />
|
||||
<InputGroup>
|
||||
<InputHeader header={"Redirect url"} />
|
||||
<Input
|
||||
value={form.redirectUrl}
|
||||
name={"redirectUrl"}
|
||||
placeholder={"Enter URL"}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputHeader header={"Logout redirect url"} />
|
||||
<Input
|
||||
value={form.logoutRedirectUrl}
|
||||
name={"logoutRedirectUrl"}
|
||||
placeholder={"Enter URL"}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</InputGroup>
|
||||
</Block>
|
||||
|
||||
<Block>
|
||||
<BlockHeader header={"Access scopes"} helpButtonText="" />
|
||||
<CheckboxGroup>
|
||||
{scopes.length > 0 &&
|
||||
scopes.map((scope) => (
|
||||
<CheckboxComponent
|
||||
key={`${scope.name}`}
|
||||
isChecked={checkedScopes.includes(scope.name)}
|
||||
onChange={() => onCheckboxChange(scope.name)}
|
||||
label={scope.name}
|
||||
description={scope.description}
|
||||
/>
|
||||
))}
|
||||
</CheckboxGroup>
|
||||
</Block>
|
||||
|
||||
<Block>
|
||||
<BlockHeader header={"Support & Legal info"} helpButtonText="" />
|
||||
|
||||
<InputGroup>
|
||||
<InputHeader header={"Privacy policy URL"} />
|
||||
<Input
|
||||
value={form.privacyURL}
|
||||
name={"privacyURL"}
|
||||
placeholder={"Enter URL"}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputHeader header={"Terms of Service URL"} />
|
||||
<Input
|
||||
value={form.termsURL}
|
||||
name={"termsURL"}
|
||||
placeholder={"Enter URL"}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</InputGroup>
|
||||
</Block>
|
||||
|
||||
<div className="button-container">
|
||||
<Button
|
||||
//@ts-ignore
|
||||
label={"Save"}
|
||||
isDisabled={!isValid}
|
||||
size={"normal"}
|
||||
primary
|
||||
scale={isMobileOnly}
|
||||
onClick={onSaveClick}
|
||||
/>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputHeader header={"Terms of Service URL"} />
|
||||
<Input
|
||||
value={form.termsURL}
|
||||
name={"termsURL"}
|
||||
placeholder={"Enter URL"}
|
||||
onChange={onInputChange}
|
||||
<Button
|
||||
//@ts-ignore
|
||||
label={"Cancel"}
|
||||
size={"normal"}
|
||||
scale={isMobileOnly}
|
||||
onClick={onCancelClick}
|
||||
/>
|
||||
</InputGroup>
|
||||
</Block>
|
||||
|
||||
<div className="button-container">
|
||||
<Button
|
||||
//@ts-ignore
|
||||
label={"Save"}
|
||||
isDisabled={!isValid}
|
||||
size={"normal"}
|
||||
primary
|
||||
scale={isMobileOnly}
|
||||
onClick={onSaveClick}
|
||||
</div>
|
||||
</FormContainer>
|
||||
{id && (
|
||||
<Preview
|
||||
clientId={clientId}
|
||||
redirectURI={form.redirectUrl}
|
||||
scopes={checkedScopes}
|
||||
/>
|
||||
<Button
|
||||
//@ts-ignore
|
||||
label={"Cancel"}
|
||||
size={"normal"}
|
||||
scale={isMobileOnly}
|
||||
onClick={onCancelClick}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user