Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agrim/dapi 536/copyproduction #38

Merged
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
},
"dependencies": {
"@deriv/deriv-api": "^1.0.11",
"@deriv/quill-icons": "^1.22.10",
"@deriv/ui": "^0.8.0",
"@docusaurus/core": "^3.3.2",
"@docusaurus/plugin-client-redirects": "^3.3.2",
Expand Down
2 changes: 2 additions & 0 deletions src/contexts/api-token/api-token.context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export interface IApiTokenContext {
isLoadingTokens: boolean;
currentToken: TTokenType;
updateCurrentToken: (token: TTokenType) => void;
lastTokenDisplayName: string;
setLastTokenDisplayName: (name: string) => void;
}

export const ApiTokenContext = React.createContext<IApiTokenContext | null>(null);
13 changes: 12 additions & 1 deletion src/contexts/api-token/api-token.provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type TTokenProviderProps = {
const ApiTokenProvider = ({ children }: TTokenProviderProps) => {
const [tokens, setTokens] = useState<TTokensArrayType>([]);
const [currentToken, setCurrentToken] = useState<TTokenType>();
const [lastTokenDisplayName, setLastTokenDisplayName] = useState<string>('');

const { send: getAllTokens, data, is_loading } = useWS('api_token');
const { is_authorized } = useAuthContext();
Expand Down Expand Up @@ -46,8 +47,18 @@ const ApiTokenProvider = ({ children }: TTokenProviderProps) => {
currentToken,
updateCurrentToken,
updateTokens,
lastTokenDisplayName,
setLastTokenDisplayName,
};
}, [currentToken, is_loading, tokens, updateCurrentToken, updateTokens]);
}, [
currentToken,
is_loading,
tokens,
updateCurrentToken,
updateTokens,
lastTokenDisplayName,
setLastTokenDisplayName,
]);

return <ApiTokenContext.Provider value={contextValue}>{children}</ApiTokenContext.Provider>;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const CreateTokenField = ({
setFormIsCleared(false);
}
}, [form_is_cleared]);

const getTokenNames = useMemo(() => {
const token_names = [];
for (const token_object of tokens) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ describe('Home Page', () => {
valid_for_ip: '',
},
],
lastTokenDisplayName: '',
}));

render(<ApiTokenForm />);
Expand Down Expand Up @@ -207,21 +208,6 @@ describe('Home Page', () => {

expect(mockCreateToken).not.toHaveBeenCalled();
});
it('Should open success dialog when token is created ', async () => {
const nameInput = screen.getByRole('textbox');
await act(async () => {
await userEvent.type(nameInput, 'test create token');
});

const submitButton = screen.getByRole('button', { name: /Create/i });

await act(async () => {
await userEvent.click(submitButton);
});

const modal = await screen.getByText('Your API token is ready to be used.');
expect(modal).toBeVisible();
shafin-deriv marked this conversation as resolved.
Show resolved Hide resolved
});

it('Should have create button disabled in case of empty input or error message', async () => {
const submitButton = screen.getByRole('button', { name: /Create/i });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('CopyButton', () => {
jest.spyOn(navigator.clipboard, 'writeText');

it('should render the CopyButton', () => {
render(<CopyButton value='testvalue' has_admin />);
render(<CopyButton value='testvalue' has_admin={false} />);

const copy_button = screen.getByRole('button');
expect(copy_button).toBeInTheDocument();
Expand Down Expand Up @@ -79,7 +79,6 @@ describe('CopyButton', () => {

expect(modal).not.toBeInTheDocument();
});

it('should show a green check for 2 seconds when copied', async () => {
const user = userEvent.setup({ delay: null });
jest.useFakeTimers();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import CopyTokenDialog from '../CopyTokenDialog';
import styles from '../token-cell.module.scss';
import { StandaloneCopyRegularIcon } from '@deriv/quill-icons';

type TCopyButton = {
value: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { useEffect, useState } from 'react';
import { TTokenType } from '@site/src/types';
import { CellProps } from 'react-table';
import styles from './token-cell.module.scss';
import CopyButton from './CopyButton';

const ApiTokenCell = ({ cell }: React.PropsWithChildren<CellProps<TTokenType, string>>) => {
const [is_hiding_token, setIsHidingToken] = useState(true);
Expand All @@ -24,16 +23,7 @@ const ApiTokenCell = ({ cell }: React.PropsWithChildren<CellProps<TTokenType, st

return (
<div data-testid={'token-cell'} className={styles.token_cell}>
<div>{is_hiding_token ? <HiddenToken /> : cell.value}</div>
<CopyButton has_admin={has_admin_scope} value={token} />
<button
onClick={() => setIsHidingToken(!is_hiding_token)}
className={styles.eye_button}
data-testid='eye-button'
style={{
backgroundImage: is_hiding_token ? 'url(/img/eye_closed.svg)' : 'url(/img/eye_open.svg)',
}}
/>
<div>{cell.value}</div>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,82 +1,73 @@
@use 'src/styles/utility' as *;

.hidden_container {
display: flex;
gap: rem(0.45);
.hidden_character {
width: rem(0.5);
height: rem(0.5);
border-radius: 100%;
background-color: var(--ifm-color-emphasis-900);
display: flex;
gap: rem(0.45);
.hidden_character {
width: rem(0.5);
height: rem(0.5);
border-radius: 100%;
background-color: var(--ifm-color-emphasis-900);
}
}

.copy_button {
background-repeat: no-repeat;
background-position: 50%;
width: rem(2.4);
height: rem(2.4);
cursor: copy;
background-image: url(/img/copy.svg);
&:hover {
&::after {
content: 'Copy this token';
text-align: center;
position: absolute;
display: inline-block;
border-radius: 4px;
padding: rem(1);
color: var(--ifm-color-emphasis-100);
background-color: var(--ifm-color-emphasis-700);
font-size: var(--fontSizes-3xs);
top: calc(50% - 15px);
min-width: 100px;
transform: translate(-50%, -50%);
@media (max-width: 425px) {
top: calc(50% + 5px);
}
}
&::before {
content: 'Token copied!';
text-align: center;
position: absolute;
display: inline-block;
border-radius: 4px;
padding: rem(1);
color: var(--ifm-color-emphasis-100);
background-color: var(--ifm-color-emphasis-700);
font-size: var(--fontSizes-3xs);
top: calc(50% - 15px);
min-width: 100px;
transform: translate(-50%, -50%);
@media (max-width: 425px) {
top: calc(50% + 5px);
}
}
}
&.is_copying {
background-image: url(/img/check.svg);
border-radius: 100%;
background-color: var(--ifm-color-primary-lightest);
border: 1px solid var(--ifm-color-primary);
&:hover::after {
content: 'Token copied!';
}
}
}

.token_cell {
display: flex;
justify-content: center;
align-items: center;
gap: rem(1);
button {
position: relative;
min-width: rem(1.5);
min-height: rem(1.5);
background-repeat: no-repeat;
background-position: center;
background-color: var(--colors-greyLight200);
border: 1px solid var(--colors-greyLight400);
border-radius: 100%;
padding: rem(0.3);
&.copy_button {
cursor: copy;
background-image: url(/img/copy.svg);
}
&:hover {
&::after {
content: '';
text-align: center;
position: absolute;
display: inline-block;
border-radius: 4px;
padding: rem(1);
color: var(--ifm-color-emphasis-100);
background-color: var(--ifm-color-emphasis-700);
font-size: var(--fontSizes-3xs);
top: calc(-50% - 20px);
left: 50%;
min-width: 100px;
transform: translate(-50%, -50%);
}
&::before {
content: '';
position: absolute;
width: 0;
height: 0;
border-left: rem(0.7) solid transparent;
border-right: rem(0.7) solid transparent;
border-top: rem(0.7) solid var(--ifm-color-emphasis-700);
top: calc(-50% + 2px);
transform: translate(-50%, -50%);
left: 50%;
}
}
&.eye_button {
cursor: pointer;
&:hover::after {
content: 'Hide this token';
}
}
&.copy_button {
&:hover::after {
content: 'Copy this token';
}
&.is_copying {
background-image: url(/img/check.svg);
background-color: var(--ifm-color-primary-lightest);
border: 1px solid var(--ifm-color-primary);
&:hover::after {
content: 'Token copied!';
}
}
}
}
display: flex;
justify-content: left;
align-items: center;
gap: 0.625rem;
}
Loading
Loading