Skip to content

Commit

Permalink
Merge pull request eclipse-sw360#337 from toshiba/release/fix-linter-…
Browse files Browse the repository at this point in the history
…for-preferences

fix: linter for preferences
  • Loading branch information
heliocastro authored Oct 4, 2024
2 parents 29a3748 + 7225754 commit 56a300b
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 101 deletions.
56 changes: 35 additions & 21 deletions src/app/[locale]/preferences/components/NotificationSettingForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,48 +11,62 @@
'use client'

import { HttpStatus } from '@/object-types'
import { ApiUtils } from '@/utils/index'
import { ApiUtils, CommonUtils } from '@/utils/index'
import { getSession, signOut } from 'next-auth/react'
import { useTranslations } from 'next-intl'
import { PageButtonHeader } from 'next-sw360'
import { useCallback, useEffect, useState } from 'react'
import { ReactNode, useCallback, useEffect, useState } from 'react'
import { User } from '@/object-types'
import UserInformation from './UserInformation'
import UserPreferences from './UserPreferences'
import MessageService from '@/services/message.service'

const NotificationSettingForm = () => {
interface NotificationSetting {
wantsMailNotification: boolean
notificationPreferences: { [key: string]: boolean }
}

const NotificationSettingForm = () : ReactNode => {
const t = useTranslations('default')
const [user, setUser] = useState<User>(undefined)
const [notificationSetting, setNotificationSetting] = useState({
wantsMailNotification: undefined,
const [user, setUser] = useState<User | undefined>(undefined)
const [notificationSetting, setNotificationSetting] = useState<NotificationSetting>({
wantsMailNotification: false,
notificationPreferences: {},
})

const updateNotificationSetting = async () => {
const session = await getSession()
const response = await ApiUtils.PATCH('users/profile', notificationSetting, session.user.access_token)
if (response.status === HttpStatus.OK) {
MessageService.success(t('Your request completed successfully'))
if (!notificationSetting.wantsMailNotification) {
fetchData('users/profile')
try {
const session = await getSession()
if (CommonUtils.isNullOrUndefined(session))
return
const response = await ApiUtils.PATCH('users/profile', notificationSetting, session.user.access_token)

if (response.status === HttpStatus.OK) {
MessageService.success(t('Your request completed successfully'))
await fetchData('users/profile')
} else {
MessageService.error(t('Error while processing'))
}
return
} catch (error) {
console.error('An error occurred:', error)
MessageService.error(t('Error while processing'))
}
MessageService.error(t('Error while processing'))
}

const fetchData = useCallback(async (url: string) => {
const session = await getSession()
if (CommonUtils.isNullOrUndefined(session))
return
const response = await ApiUtils.GET(url, session.user.access_token)
if (response.status == HttpStatus.OK) {
const data = await response.json()

if (response.status === HttpStatus.OK) {
const data: User = await response.json() as User
setUser(data)
setNotificationSetting({
wantsMailNotification: data.wantsMailNotification,
notificationPreferences: data.notificationPreferences,
wantsMailNotification: data.wantsMailNotification ?? false,
notificationPreferences: data.notificationPreferences ?? {},
})
} else if (response.status == HttpStatus.UNAUTHORIZED) {
} else if (response.status === HttpStatus.UNAUTHORIZED) {
await signOut()
} else {
setUser(undefined)
Expand All @@ -64,7 +78,7 @@ const NotificationSettingForm = () => {
}

useEffect(() => {
fetchData('users/profile')
fetchData('users/profile').catch((error) => {console.error(error)})
}, [fetchData])

return (
Expand All @@ -90,4 +104,4 @@ const NotificationSettingForm = () => {
)
}

export default NotificationSettingForm
export default NotificationSettingForm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
'use client'

import { Preferences } from '@/object-types'
import { useEffect, useState } from 'react'
import { ReactNode, useEffect, useState } from 'react'
import { Accordion, Form } from 'react-bootstrap'
import styles from '../preferences.module.css'

Expand All @@ -25,7 +25,7 @@ interface Props {
setNotificationSetting: React.Dispatch<React.SetStateAction<NotificationSetting>>
}

const NotificationSettings = ({ notificationSetting, setNotificationSetting }: Props) => {
const NotificationSettings = ({ notificationSetting, setNotificationSetting }: Props) : ReactNode => {
const preferences = Preferences()
const [isClient, setIsClient] = useState(false)

Expand Down
127 changes: 79 additions & 48 deletions src/app/[locale]/preferences/components/TokensTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,73 +16,95 @@ import { ApiUtils, CommonUtils } from '@/utils/index'
import { getSession, signOut } from 'next-auth/react'
import { useTranslations } from 'next-intl'
import { Table, _ } from 'next-sw360'
import React, { useCallback, useEffect, useState } from 'react'
import React, { ReactNode, useCallback, useEffect, useState } from 'react'
import { Button } from 'react-bootstrap'

interface Props {
generatedToken: string
}

const TokensTable = ({ generatedToken }: Props) => {
const TokensTable = ({ generatedToken }: Props): ReactNode => {
const t = useTranslations('default')
const [tableData, setTableData] = useState([])
const [tableData, setTableData] = useState<(string | JSX.Element)[][]>([])

const fetchData = useCallback(async (url: string) => {
const session = await getSession()
const response = await ApiUtils.GET(url, session.user.access_token)
if (response.status == HttpStatus.OK) {
const data = (await response.json()) as Embedded<AccessToken, 'sw360:restApiTokens'>
if (data._embedded === undefined) {
try {
const session = await getSession()
if (CommonUtils.isNullOrUndefined(session)) return
const response = await ApiUtils.GET(url, session.user.access_token)

if (response.status === HttpStatus.OK) {
const data: Embedded<AccessToken, 'sw360:restApiTokens'> = (await response.json()) as Embedded<
AccessToken,
'sw360:restApiTokens'
>

const tableData = Object.values(data._embedded['sw360:restApiTokens']).map((token: AccessToken) => {
const expirationDate = new Date(
Date.parse(token.createdOn + ' +0000') +
token.numberOfDaysValid * 24 * 60 * 60 * 1000 -
new Date().getTimezoneOffset() * 60000,
)

return [
token.name,
new Date(Date.parse(token.createdOn + ' +0000') - new Date().getTimezoneOffset() * 60000)
.toISOString()
.slice(0, 19)
.replace('T', ' '),
expirationDate.toISOString().slice(0, 19).replace('T', ' '),
'[' + token.authorities.join(', ') + ']',
_(
<Button
variant='danger'
onClick={() => {
revokeToken(token.name).catch((error) => console.error(error))
}}
>
{t('Revoke Token')}
</Button>,
),
]
})
setTableData(tableData)
} else if (response.status === HttpStatus.UNAUTHORIZED) {
await signOut()
} else {
setTableData([])
return
}
const tableData = Object.values(data._embedded['sw360:restApiTokens']).map((token: AccessToken) => {
const expirationDate = new Date(
Date.parse(token.createdOn + ' +0000') +
token.numberOfDaysValid * 24 * 60 * 60 * 1000 -
new Date().getTimezoneOffset() * 60000
)
return [
token.name,
new Date(Date.parse(token.createdOn + ' +0000') - new Date().getTimezoneOffset() * 60000)
.toISOString()
.slice(0, 19)
.replace('T', ' '),
expirationDate.toISOString().slice(0, 19).replace('T', ' '),
'[' + token.authorities.join(', ') + ']',
_(
<Button variant='danger' onClick={() => revokeToken(token.name)}>
{t('Revoke Token')}
</Button>
),
]
})
setTableData(tableData)
} else if (response.status == HttpStatus.UNAUTHORIZED) {
await signOut()
} else {
} catch (error) {
console.error('Error fetching data:', error)
setTableData([])
}
}, [])

const revokeToken = async (tokenName: string) => {
const session = await getSession()
const response = await ApiUtils.DELETE(
CommonUtils.createUrlWithParams('users/tokens', { name: tokenName }),
session.user.access_token
)
if (response.status === HttpStatus.NO_CONTENT) {
MessageService.success(t('Revoke token sucessfully'))
fetchData('users/tokens')
} else if (response.status === HttpStatus.UNAUTHORIZED) {
signOut()
} else {
try {
const session = await getSession()
if (CommonUtils.isNullOrUndefined(session)) return
const response = await ApiUtils.DELETE(
CommonUtils.createUrlWithParams('users/tokens', { name: tokenName }),
session.user.access_token,
)

if (response.status === HttpStatus.NO_CONTENT) {
MessageService.success(t('Revoke token sucessfully'))
await fetchData('users/tokens')
} else if (response.status === HttpStatus.UNAUTHORIZED) {
await signOut()
} else {
MessageService.error(t('Error while processing'))
}
} catch (error) {
console.error('An error occurred while revoking token:', error)
MessageService.error(t('Error while processing'))
}
}

useEffect(() => {
fetchData('users/tokens')
fetchData('users/tokens').catch((error) => {
console.error(error)
})
}, [fetchData, generatedToken])

const columns = [
Expand Down Expand Up @@ -113,7 +135,16 @@ const TokensTable = ({ generatedToken }: Props) => {
},
]

return <div className='row'>{tableData.length > 0 && <Table columns={columns} data={tableData} />}</div>
return (
<div className='row'>
{tableData.length > 0 && (
<Table
columns={columns}
data={tableData}
/>
)}
</div>
)
}

export default React.memo(TokensTable)
export default React.memo(TokensTable)
64 changes: 44 additions & 20 deletions src/app/[locale]/preferences/components/UserAccessToken.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@
'use client'

import { HttpStatus } from '@/object-types'
import { ApiUtils } from '@/utils/index'
import MessageService from '@/services/message.service'
import { ApiUtils, CommonUtils } from '@/utils/index'
import { getSession } from 'next-auth/react'
import { useTranslations } from 'next-intl'
import { ShowInfoOnHover } from 'next-sw360'
import React, { useState } from 'react'
import React, { ReactNode, useState } from 'react'
import { Form } from 'react-bootstrap'
import styles from '../preferences.module.css'
import TokensTable from './TokensTable'
import MessageService from '@/services/message.service'

const UserAccessToken = () => {
const UserAccessToken = (): ReactNode => {
const t = useTranslations('default')
const [validated, setValidated] = useState(false)
const [tokenData, setTokenData] = useState({
Expand All @@ -34,23 +34,31 @@ const UserAccessToken = () => {
const generateToken = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault()
const form = event.currentTarget

if (form.checkValidity() === false) {
event.stopPropagation()
setValidated(true)
} else {
setValidated(false)
const session = await getSession()
const response = await ApiUtils.POST('users/tokens', tokenData, session.user.access_token)
const data = await response.json()
if (response.status == HttpStatus.CREATED) {
setGeneratedToken(data)
setTokenData({
name: '',
expirationDate: '',
authorities: ['READ'],
})
} else {
MessageService.error(data.message)
try {
const session = await getSession()
if (CommonUtils.isNullOrUndefined(session)) return
const response = await ApiUtils.POST('users/tokens', tokenData, session.user.access_token)

if (response.status === HttpStatus.CREATED) {
const data: string = (await response.json()) as string
setGeneratedToken(data)
setTokenData({
name: '',
expirationDate: '',
authorities: ['READ'],
})
} else {
const errorData: Record<string, string> = (await response.json()) as Record<string, string>
MessageService.error(errorData.string)
}
} catch (error) {
console.error('An error occurred:', error)
}
}
}
Expand Down Expand Up @@ -82,8 +90,18 @@ const UserAccessToken = () => {
<div className='row'>
<div className='col'>
<h4 className={styles.decorator}>{t('REST API Tokens')}</h4>
<Form noValidate validated={validated} id='generateTokenForm' onSubmit={generateToken}>
<table className='table summary-table' id='restInfoTable'>
<Form
noValidate
validated={validated}
id='generateTokenForm'
onSubmit={(event) => {
generateToken(event).catch((error) => console.error(error))
}}
>
<table
className='table summary-table'
id='restInfoTable'
>
<thead>
<tr>
<th colSpan={2}>{t('REST API Token')}</th>
Expand Down Expand Up @@ -161,14 +179,20 @@ const UserAccessToken = () => {
:
</td>
<td>
<label id='accesstoken' className='inlinelabel'>
<label
id='accesstoken'
className='inlinelabel'
>
<b>{generatedToken}</b>
</label>
</td>
</tr>
</tbody>
</table>
<button type='submit' className='btn btn-secondary'>
<button
type='submit'
className='btn btn-secondary'
>
{t('Generate Token')}
</button>
</Form>
Expand Down
Loading

0 comments on commit 56a300b

Please sign in to comment.