-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #479 from IQSS/feat/470-user-panel-api-token
Feat/470 user panel api token
- Loading branch information
Showing
17 changed files
with
324 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline | |
- **Stack:** NEW Stack element to manage layouts. | ||
- **TransferList:** NEW TransferList component to transfer items between two list, also sortable. | ||
- **Table:** extend Props Interface to accept `bordered` prop to add or remove borders on all sides of the table and cells. Defaults to true. | ||
- **Tab:** extend Props Interface to accept `disabled` prop to disable the tab. | ||
|
||
# [1.1.0](https://github.com/IQSS/dataverse-frontend/compare/@iqss/[email protected]...@iqss/[email protected]) (2024-03-12) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"pageTitle": "Account", | ||
"tabs": { | ||
"myData": "My Data", | ||
"notifications": "Notifications", | ||
"accountInformation": "Account Information", | ||
"apiToken": "API Token" | ||
}, | ||
"apiToken": { | ||
"helperText": "Your API Token is valid for a year. Check out our <anchor>API Guide</anchor> for more information on using your API Token with the Dataverse APIs.", | ||
"notCreatedApiToken": "API Token for Dataverse Admin has not been created.", | ||
"expirationDate": "Expiration date", | ||
"copyToClipboard": "Copy to Clipboard", | ||
"recreateToken": "Recreate Token", | ||
"revokeToken": "Revoke Token", | ||
"createToken": "Create Token" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
@import 'node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module'; | ||
|
||
.tab-container { | ||
padding: 1rem; | ||
} | ||
|
||
.helper-text { | ||
color: $dv-subtext-color; | ||
font-size: 14px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { useEffect } from 'react' | ||
import { useTranslation } from 'react-i18next' | ||
import { Tabs } from '@iqss/dataverse-design-system' | ||
import { useLoading } from '../loading/LoadingContext' | ||
import { AccountHelper, AccountPanelTabKey } from './AccountHelper' | ||
import { ApiTokenSection } from './api-token-section/ApiTokenSection' | ||
import { BreadcrumbsGenerator } from '../shared/hierarchy/BreadcrumbsGenerator' | ||
import { UpwardHierarchyNodeMother } from '../../../tests/component/shared/hierarchy/domain/models/UpwardHierarchyNodeMother' | ||
import styles from './Account.module.scss' | ||
|
||
const tabsKeys = AccountHelper.ACCOUNT_PANEL_TABS_KEYS | ||
|
||
interface AccountProps { | ||
defaultActiveTabKey: AccountPanelTabKey | ||
} | ||
|
||
export const Account = ({ defaultActiveTabKey }: AccountProps) => { | ||
const { t } = useTranslation('account') | ||
const { setIsLoading } = useLoading() | ||
|
||
const rootHierarchy = UpwardHierarchyNodeMother.createCollection({ | ||
name: 'Root', | ||
id: 'root' | ||
}) | ||
|
||
useEffect(() => { | ||
setIsLoading(false) | ||
}, [setIsLoading]) | ||
|
||
return ( | ||
<section> | ||
<BreadcrumbsGenerator hierarchy={rootHierarchy} withActionItem actionItemText="Account" /> | ||
|
||
<header> | ||
<h1>{t('pageTitle')}</h1> | ||
</header> | ||
|
||
<Tabs defaultActiveKey={defaultActiveTabKey}> | ||
<Tabs.Tab eventKey={tabsKeys.myData} title={t('tabs.myData')} disabled> | ||
<div className={styles['tab-container']}></div> | ||
</Tabs.Tab> | ||
<Tabs.Tab eventKey={tabsKeys.notifications} title={t('tabs.notifications')} disabled> | ||
<div className={styles['tab-container']}></div> | ||
</Tabs.Tab> | ||
<Tabs.Tab | ||
eventKey={tabsKeys.accountInformation} | ||
title={t('tabs.accountInformation')} | ||
disabled> | ||
<div className={styles['tab-container']}></div> | ||
</Tabs.Tab> | ||
<Tabs.Tab eventKey={tabsKeys.apiToken} title={t('tabs.apiToken')}> | ||
<div className={styles['tab-container']}> | ||
<ApiTokenSection /> | ||
</div> | ||
</Tabs.Tab> | ||
</Tabs> | ||
</section> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { ReactElement } from 'react' | ||
import { useSearchParams } from 'react-router-dom' | ||
import { AccountHelper } from './AccountHelper' | ||
import { Account } from './Account' | ||
|
||
export class AccountFactory { | ||
static create(): ReactElement { | ||
return <AccountWithSearchParams /> | ||
} | ||
} | ||
|
||
function AccountWithSearchParams() { | ||
const [searchParams] = useSearchParams() | ||
const defaultActiveTabKey = AccountHelper.defineSelectedTabKey(searchParams) | ||
|
||
return <Account defaultActiveTabKey={defaultActiveTabKey} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
export class AccountHelper { | ||
static ACCOUNT_PANEL_TABS_KEYS = { | ||
myData: 'myData', | ||
notifications: 'notifications', | ||
accountInformation: 'accountInformation', | ||
apiToken: 'apiToken' | ||
} as const | ||
|
||
static ACCOUNT_PANEL_TAB_QUERY_KEY = 'tab' | ||
|
||
public static defineSelectedTabKey(searchParams: URLSearchParams): AccountPanelTabKey { | ||
const tabValue = searchParams.get(this.ACCOUNT_PANEL_TAB_QUERY_KEY) | ||
|
||
return ( | ||
this.ACCOUNT_PANEL_TABS_KEYS[tabValue as keyof typeof this.ACCOUNT_PANEL_TABS_KEYS] ?? | ||
this.ACCOUNT_PANEL_TABS_KEYS.myData | ||
) | ||
} | ||
} | ||
|
||
export type AccountPanelTabKey = | ||
(typeof AccountHelper.ACCOUNT_PANEL_TABS_KEYS)[keyof typeof AccountHelper.ACCOUNT_PANEL_TABS_KEYS] |
32 changes: 32 additions & 0 deletions
32
src/sections/account/api-token-section/ApiTokenSection.module.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
@import 'node_modules/@iqss/dataverse-design-system/src/lib/assets/styles/design-tokens/colors.module'; | ||
|
||
.exp-date { | ||
display: flex; | ||
gap: 1.5rem; | ||
align-items: center; | ||
padding-left: 0.5rem; | ||
font-weight: bold; | ||
|
||
time { | ||
font-weight: normal; | ||
} | ||
|
||
@media (min-width: 768px) { | ||
gap: 3rem; | ||
} | ||
} | ||
|
||
.api-token { | ||
padding: 0.5rem 1rem; | ||
background-color: #f7f7f9; | ||
border: solid 1px $dv-border-color; | ||
border-radius: 4px; | ||
} | ||
|
||
.btns-wrapper { | ||
display: flex; | ||
flex-wrap: wrap; | ||
gap: 0.5rem; | ||
align-items: center; | ||
padding-top: 1rem; | ||
} |
71 changes: 71 additions & 0 deletions
71
src/sections/account/api-token-section/ApiTokenSection.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { Trans, useTranslation } from 'react-i18next' | ||
import { Button } from '@iqss/dataverse-design-system' | ||
import accountStyles from '../Account.module.scss' | ||
import styles from './ApiTokenSection.module.scss' | ||
|
||
export const ApiTokenSection = () => { | ||
const { t } = useTranslation('account', { keyPrefix: 'apiToken' }) | ||
|
||
const apiToken = '999fff-666rrr-this-is-not-a-real-token-123456' | ||
const expirationDate = '2025-09-04' | ||
|
||
const copyToClipboard = () => { | ||
navigator.clipboard.writeText(apiToken).catch( | ||
/* istanbul ignore next */ (error) => { | ||
console.error('Failed to copy text:', error) | ||
} | ||
) | ||
} | ||
|
||
return ( | ||
<> | ||
<p className={accountStyles['helper-text']}> | ||
<Trans | ||
t={t} | ||
i18nKey="helperText" | ||
components={{ | ||
anchor: ( | ||
<a | ||
href="http://guides.dataverse.org/en/latest/api" | ||
target="_blank" | ||
rel="noreferrer" | ||
/> | ||
) | ||
}} | ||
/> | ||
</p> | ||
{apiToken ? ( | ||
<> | ||
<p className={styles['exp-date']}> | ||
{t('expirationDate')} <time dateTime={expirationDate}>{expirationDate}</time> | ||
</p> | ||
<div className={styles['api-token']}> | ||
<code data-testid="api-token">{apiToken}</code> | ||
</div> | ||
<div className={styles['btns-wrapper']} role="group"> | ||
<Button variant="secondary" onClick={copyToClipboard}> | ||
{t('copyToClipboard')} | ||
</Button> | ||
<Button variant="secondary" disabled> | ||
{t('recreateToken')} | ||
</Button> | ||
<Button variant="secondary" disabled> | ||
{t('revokeToken')} | ||
</Button> | ||
</div> | ||
</> | ||
) : ( | ||
<> | ||
<div className={styles['api-token']}> | ||
<code data-testid="api-token">{t('notCreatedApiToken')}</code> | ||
</div> | ||
<div className={styles['btns-wrapper']} role="group"> | ||
<Button variant="secondary" disabled> | ||
{t('createToken')} | ||
</Button> | ||
</div> | ||
</> | ||
)} | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Meta, StoryObj } from '@storybook/react' | ||
import { Account } from '../../sections/account/Account' | ||
import { WithI18next } from '../WithI18next' | ||
import { WithLayout } from '../WithLayout' | ||
import { WithLoggedInUser } from '../WithLoggedInUser' | ||
import { AccountHelper } from '../../sections/account/AccountHelper' | ||
|
||
const meta: Meta<typeof Account> = { | ||
title: 'Pages/Account', | ||
component: Account, | ||
decorators: [WithI18next, WithLayout, WithLoggedInUser], | ||
parameters: { | ||
// Sets the delay for all stories. | ||
chromatic: { delay: 15000, pauseAnimationAtEnd: true } | ||
} | ||
} | ||
export default meta | ||
type Story = StoryObj<typeof Account> | ||
|
||
export const APITokenTab: Story = { | ||
render: () => <Account defaultActiveTabKey={AccountHelper.ACCOUNT_PANEL_TABS_KEYS.apiToken} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { Account } from '../../../../src/sections/account/Account' | ||
|
||
describe('Account', () => { | ||
it('should render the correct breadcrumbs', () => { | ||
cy.mountAuthenticated(<Account />) | ||
|
||
cy.findByRole('link', { name: 'Root' }).should('exist') | ||
|
||
cy.get('li[aria-current="page"]') | ||
.should('exist') | ||
.should('have.text', 'Account') | ||
.should('have.class', 'active') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { ApiTokenSection } from '../../../../src/sections/account/api-token-section/ApiTokenSection' | ||
|
||
describe('ApiTokenSection', () => { | ||
beforeEach(() => { | ||
cy.mountAuthenticated(<ApiTokenSection />) | ||
}) | ||
|
||
it('should copy the api token to the clipboard', () => { | ||
cy.window().then((win) => { | ||
cy.stub(win.navigator.clipboard, 'writeText').resolves() | ||
|
||
cy.findByRole('button', { name: /Copy to Clipboard/ }).click() | ||
|
||
cy.get('[data-testid="api-token"]').then(($element) => { | ||
const textToCopy = $element.text() | ||
|
||
// eslint-disable-next-line @typescript-eslint/unbound-method | ||
cy.wrap(win.navigator.clipboard.writeText).should('be.calledWith', textToCopy) | ||
}) | ||
}) | ||
}) | ||
|
||
// TODO: When we get the api token from the use case, we could mock the response and test more things. | ||
}) |