From e85a79731eaaf7f52109dc66a93ad597330c13c5 Mon Sep 17 00:00:00 2001 From: Raman Yasel Date: Mon, 27 Jan 2025 21:26:15 +0300 Subject: [PATCH] fix: minor ui issues --- .../src/framework/context/AppContext.tsx | 4 - .../profile-settings-general-container.tsx | 12 +- .../profile-settings-keys-container.tsx | 6 +- .../dialogs/delete-alert-dialog.tsx | 2 +- .../components/skeletons/skeleton-table.tsx | 2 +- .../components/profile-settings-keys-list.tsx | 115 ++++++++++------- .../profile-settings-tokens-list.tsx | 122 ++++++++++-------- .../profile-settings-keys-page.tsx | 18 +-- 8 files changed, 161 insertions(+), 120 deletions(-) diff --git a/apps/gitness/src/framework/context/AppContext.tsx b/apps/gitness/src/framework/context/AppContext.tsx index fb8f04fc9..ba85ddc00 100644 --- a/apps/gitness/src/framework/context/AppContext.tsx +++ b/apps/gitness/src/framework/context/AppContext.tsx @@ -54,19 +54,15 @@ export const AppProvider: FC<{ children: ReactNode }> = ({ children }) => { } | null>(null) const fetchUser = async (): Promise => { - setIsUpdateUserLoading(true) - setUpdateUserLoadingError(null) try { const userResponse = await getUser({}) setCurrentUser(userResponse.body) - setIsUpdateUserLoading(false) } catch (error) { const typedError = error as GetUserErrorResponse setUpdateUserLoadingError({ type: ProfileSettingsErrorType.PROFILE, message: typedError.message || 'An unknown fetch user error occurred.' }) - setIsUpdateUserLoading(false) } } diff --git a/apps/gitness/src/pages-v2/profile-settings/profile-settings-general-container.tsx b/apps/gitness/src/pages-v2/profile-settings/profile-settings-general-container.tsx index f891b4d1b..db5008bbc 100644 --- a/apps/gitness/src/pages-v2/profile-settings/profile-settings-general-container.tsx +++ b/apps/gitness/src/pages-v2/profile-settings/profile-settings-general-container.tsx @@ -33,8 +33,6 @@ export const SettingsProfileGeneralPage: FC = () => { } ) - const isLoadingUser = isLoadingUserData || isUpdateUserLoading - const updateUserMutation = useUpdateUserMutation( {}, { @@ -117,14 +115,14 @@ export const SettingsProfileGeneralPage: FC = () => { ) diff --git a/apps/gitness/src/pages-v2/profile-settings/profile-settings-keys-container.tsx b/apps/gitness/src/pages-v2/profile-settings/profile-settings-keys-container.tsx index fb513c987..a822ec0de 100644 --- a/apps/gitness/src/pages-v2/profile-settings/profile-settings-keys-container.tsx +++ b/apps/gitness/src/pages-v2/profile-settings/profile-settings-keys-container.tsx @@ -86,7 +86,7 @@ export const SettingsProfileKeysPage = () => { order: 'asc' } - const { data: { body: tokenList, headers } = {} } = useListTokensQuery( + const { data: { body: tokenList, headers } = {}, isLoading: isLoadingTokenList } = useListTokensQuery( {}, { onError: (error: ListTokensErrorResponse) => { @@ -96,7 +96,7 @@ export const SettingsProfileKeysPage = () => { } ) - const { data: { body: publicKeysList } = {} } = useListPublicKeyQuery( + const { data: { body: publicKeysList } = {}, isLoading: isLoadingPublicKeys } = useListPublicKeyQuery( { queryParams }, { onError: (error: ListPublicKeyErrorResponse) => { @@ -226,6 +226,8 @@ export const SettingsProfileKeysPage = () => { error={apiError} headers={headers} useTranslationStore={useTranslationStore} + isLoadingTokenList={isLoadingTokenList} + isLoadingKeysList={isLoadingPublicKeys} /> = ({ return ( - + {t('component:deleteDialog.title', 'Are you sure?')} diff --git a/packages/ui/src/components/skeletons/skeleton-table.tsx b/packages/ui/src/components/skeletons/skeleton-table.tsx index 8f3d00067..f0a3c27c6 100644 --- a/packages/ui/src/components/skeletons/skeleton-table.tsx +++ b/packages/ui/src/components/skeletons/skeleton-table.tsx @@ -16,7 +16,7 @@ export const SkeletonTable = ({ className, countRows = 12, countColumns = 5 }: S return ( {Array.from({ length: countRows }).map((_, index) => ( - + {Array.from({ length: countColumns }).map((_, columnIndex) => ( diff --git a/packages/ui/src/views/profile-settings/components/profile-settings-keys-list.tsx b/packages/ui/src/views/profile-settings/components/profile-settings-keys-list.tsx index d73e5a08a..496df7095 100644 --- a/packages/ui/src/views/profile-settings/components/profile-settings-keys-list.tsx +++ b/packages/ui/src/views/profile-settings/components/profile-settings-keys-list.tsx @@ -1,6 +1,16 @@ import { FC } from 'react' -import { Icon, MoreActionsTooltip, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components' +import { + Icon, + MoreActionsTooltip, + SkeletonTable, + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow +} from '@/components' import { timeAgo } from '@utils/utils' import { TranslationStore } from '@views/repo' @@ -8,18 +18,24 @@ import { KeysList } from '../types' interface ProfileKeysListProps { publicKeys: KeysList[] + isLoading: boolean openAlertDeleteDialog: (params: { identifier: string; type: string }) => void useTranslationStore: () => TranslationStore } export const ProfileKeysList: FC = ({ publicKeys, + isLoading, openAlertDeleteDialog, useTranslationStore }) => { const { t } = useTranslationStore() + return ( - +
{t('views:profileSettings.name', 'Name')} @@ -28,55 +44,62 @@ export const ProfileKeysList: FC = ({ - - {publicKeys.length ? ( - publicKeys.map((key: KeysList) => ( - - -
- -
- {key.identifier} - {key.fingerprint} + + {isLoading ? ( + + ) : ( + + {publicKeys.length ? ( + publicKeys.map((key: KeysList) => ( + + +
+ +
+ + {key.identifier} + + {key.fingerprint} +
-
- - - {timeAgo(new Date(key.created!).getTime())} - - - {/* TODO: pass the data to KeysList item about last used date */} - {/* + + + {timeAgo(new Date(key.created!).getTime())} + + + {/* TODO: pass the data to KeysList item about last used date */} + {/* {key.last_used ? new Date(key.last_used).toLocaleString() : 'Never used'} */} - - - openAlertDeleteDialog({ identifier: key.identifier!, type: 'key' }) - } - ]} - /> + + + openAlertDeleteDialog({ identifier: key.identifier!, type: 'key' }) + } + ]} + /> + + + )) + ) : ( + + +

+ {t( + 'views:profileSettings.noDataKeysDescription', + 'There are no SSH keys associated with this account.' + )} +

- )) - ) : ( - - -

- {t( - 'views:profileSettings.noDataKeysDescription', - 'There are no SSH keys associated with this account.' - )} -

-
-
- )} - + )} + + )}
) } diff --git a/packages/ui/src/views/profile-settings/components/profile-settings-tokens-list.tsx b/packages/ui/src/views/profile-settings/components/profile-settings-tokens-list.tsx index 2a78c9400..695ebc1b1 100644 --- a/packages/ui/src/views/profile-settings/components/profile-settings-tokens-list.tsx +++ b/packages/ui/src/views/profile-settings/components/profile-settings-tokens-list.tsx @@ -1,6 +1,16 @@ import { FC } from 'react' -import { Icon, MoreActionsTooltip, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components' +import { + Icon, + MoreActionsTooltip, + SkeletonTable, + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow +} from '@/components' import { timeAgo } from '@/utils/utils' import { TranslationStore } from '@/views' @@ -8,18 +18,24 @@ import { TokensList } from '../types' interface ProfileTokensListProps { tokens: TokensList[] + isLoading: boolean openAlertDeleteDialog: (params: { identifier: string; type: string }) => void useTranslationStore: () => TranslationStore } export const ProfileTokensList: FC = ({ tokens, + isLoading, openAlertDeleteDialog, useTranslationStore }) => { const { t } = useTranslationStore() + return ( - +
{t('views:profileSettings.tokenTableHeader', 'Token')} @@ -29,58 +45,62 @@ export const ProfileTokensList: FC = ({ - - {tokens.length ? ( - tokens.map(token => ( - - - {token.identifier} - - -
- - {t('views:profileSettings.active', 'Active')} -
-
- - - {token.expires_at - ? new Date(token.expires_at).toLocaleString() - : t('views:profileSettings.noExpiration', 'No Expiration')} - - - - {timeAgo(new Date(token.issued_at!).getTime())} - - - { - openAlertDeleteDialog({ identifier: token.identifier!, type: 'token' }) + {isLoading ? ( + + ) : ( + + {tokens.length ? ( + tokens.map(token => ( + + + {token.identifier} + + +
+ + {t('views:profileSettings.active', 'Active')} +
+
+ + + {token.expires_at + ? new Date(token.expires_at).toLocaleString() + : t('views:profileSettings.noExpiration', 'No Expiration')} + + + + {timeAgo(new Date(token.issued_at!).getTime())} + + + { + openAlertDeleteDialog({ identifier: token.identifier!, type: 'token' }) + } } - } - ]} - /> + ]} + /> + +
+ )) + ) : ( + + +

+ {t( + 'views:profileSettings.noTokenDescription', + 'There are no personal access tokens associated with this account.' + )} +

- )) - ) : ( - - -

- {t( - 'views:profileSettings.noTokenDescription', - 'There are no personal access tokens associated with this account.' - )} -

-
-
- )} -
+ )} +
+ )}
) } diff --git a/packages/ui/src/views/profile-settings/profile-settings-keys-page.tsx b/packages/ui/src/views/profile-settings/profile-settings-keys-page.tsx index 67d2aa847..17deabbe8 100644 --- a/packages/ui/src/views/profile-settings/profile-settings-keys-page.tsx +++ b/packages/ui/src/views/profile-settings/profile-settings-keys-page.tsx @@ -1,6 +1,6 @@ import { FC } from 'react' -import { Button, Fieldset, FormSeparator, FormWrapper, Legend, SkeletonTable, Spacer } from '@/components' +import { Button, Fieldset, FormSeparator, FormWrapper, Legend, Spacer } from '@/components' import { ApiErrorType, SandboxLayout, TranslationStore } from '@/views' import { ProfileKeysList } from './components/profile-settings-keys-list' @@ -16,6 +16,8 @@ interface SettingsAccountKeysPageProps { headers?: Headers useProfileSettingsStore: () => IProfileSettingsStore useTranslationStore: () => TranslationStore + isLoadingTokenList: boolean + isLoadingKeysList: boolean } const ErrorMessage: FC<{ message: string }> = ({ message }) => ( @@ -31,7 +33,9 @@ const SettingsAccountKeysPage: FC = ({ openSshKeyDialog, openAlertDeleteDialog, useTranslationStore, - error + error, + isLoadingTokenList, + isLoadingKeysList // headers }) => { // @todo: Add pagination for tokens and keys lists in following PR @@ -66,14 +70,13 @@ const SettingsAccountKeysPage: FC = ({ {error?.type === ApiErrorType.TokenFetch ? ( - ) : tokens.length > 0 ? ( + ) : ( - ) : ( - )} @@ -95,14 +98,13 @@ const SettingsAccountKeysPage: FC = ({ {error?.type === ApiErrorType.KeyFetch ? ( - ) : publicKeys.length > 0 ? ( + ) : ( - ) : ( - )}