mirror of
https://github.com/harness/drone.git
synced 2025-05-21 19:39:59 +08:00
206 lines
7.0 KiB
TypeScript
206 lines
7.0 KiB
TypeScript
import React, { useCallback, useMemo } from 'react'
|
|
import {
|
|
Avatar,
|
|
Button,
|
|
ButtonVariation,
|
|
Container,
|
|
Layout,
|
|
Page,
|
|
StringSubstitute,
|
|
TableV2,
|
|
Text,
|
|
useToaster
|
|
} from '@harnessio/uicore'
|
|
import { Color, FontVariation } from '@harnessio/design-system'
|
|
import type { CellProps, Column } from 'react-table'
|
|
import { Render } from 'react-jsx-match'
|
|
|
|
import { useConfirmAct } from 'hooks/useConfirmAction'
|
|
import { usePageIndex } from 'hooks/usePageIndex'
|
|
import { useStrings } from 'framework/strings'
|
|
import { TypesUser, useAdminDeleteUser, useAdminListUsers, useUpdateUserAdmin } from 'services/code'
|
|
import { getErrorMessage } from 'utils/Utils'
|
|
import { ResourceListingPagination } from 'components/ResourceListingPagination/ResourceListingPagination'
|
|
import { OptionsMenuButton } from 'components/OptionsMenuButton/OptionsMenuButton'
|
|
import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner'
|
|
|
|
import useAddUserModal from 'components/UserManagementFlows/AddUserModal'
|
|
import useResetPasswordModal from 'components/UserManagementFlows/ResetPassword'
|
|
|
|
import css from './UsersListing.module.scss'
|
|
|
|
const UsersListing = () => {
|
|
const { getString } = useStrings()
|
|
const { showSuccess, showError } = useToaster()
|
|
const [page, setPage] = usePageIndex()
|
|
|
|
const { data, response, refetch, loading } = useAdminListUsers({
|
|
queryParams: {
|
|
page
|
|
}
|
|
})
|
|
const { mutate: deleteUser } = useAdminDeleteUser({})
|
|
const { openModal } = useAddUserModal({ onClose: refetch })
|
|
const { openModal: openResetPasswordModal } = useResetPasswordModal()
|
|
const onConfirmAct = useConfirmAct()
|
|
const handleDeleteUser = useCallback(
|
|
async (userId: string, displayName?: string) =>
|
|
await onConfirmAct({
|
|
action: async () => {
|
|
try {
|
|
await deleteUser(userId)
|
|
showSuccess(getString('newUserModal.userDeleted', { name: displayName }))
|
|
refetch()
|
|
} catch (error) {
|
|
showError(getErrorMessage(error))
|
|
}
|
|
},
|
|
message: (
|
|
<Text font={{ variation: FontVariation.BODY2 }}>
|
|
<StringSubstitute
|
|
str={getString('userManagement.deleteUserMsg', { displayName, userId })}
|
|
vars={{ avatar: <Avatar name={displayName} /> }}
|
|
/>
|
|
</Text>
|
|
),
|
|
intent: 'danger',
|
|
title: getString('userManagement.deleteUser')
|
|
}),
|
|
[deleteUser, getString, onConfirmAct, refetch, showError, showSuccess]
|
|
)
|
|
|
|
const columns: Column<TypesUser>[] = useMemo(
|
|
() => [
|
|
{
|
|
Header: getString('displayName'),
|
|
width: '30%',
|
|
Cell: ({ row }: CellProps<TypesUser>) => {
|
|
return (
|
|
<Layout.Horizontal style={{ alignItems: 'center' }}>
|
|
<Avatar
|
|
name={row.original.display_name}
|
|
size="normal"
|
|
hoverCard={false}
|
|
color={Color.WHITE}
|
|
backgroundColor={Color.PRIMARY_7}
|
|
/>
|
|
<Text font={{ variation: FontVariation.SMALL_SEMI }} margin={{ right: 'small' }} lineClamp={1}>
|
|
{row.original.display_name}
|
|
</Text>
|
|
<Render when={row.original.admin}>
|
|
<Text font={{ variation: FontVariation.TINY_SEMI }} color={Color.PRIMARY_9} className={css.adminBadge}>
|
|
{getString('admin')}
|
|
</Text>
|
|
</Render>
|
|
</Layout.Horizontal>
|
|
)
|
|
}
|
|
},
|
|
{
|
|
Header: getString('userId'),
|
|
width: '30%',
|
|
Cell: ({ row }: CellProps<TypesUser>) => (
|
|
<Text font={{ variation: FontVariation.SMALL_SEMI }} lineClamp={1}>
|
|
{row.original.uid}
|
|
</Text>
|
|
)
|
|
},
|
|
{
|
|
Header: getString('email'),
|
|
width: '35%',
|
|
Cell: ({ row }: CellProps<TypesUser>) => {
|
|
return (
|
|
<Text font={{ variation: FontVariation.SMALL }} lineClamp={1}>
|
|
{row.original.email}
|
|
</Text>
|
|
)
|
|
}
|
|
},
|
|
{
|
|
accessor: 'uid',
|
|
Header: '',
|
|
width: '5%',
|
|
Cell: ({ row }: CellProps<TypesUser>) => {
|
|
const { mutate: updateAdmin } = useUpdateUserAdmin({ user_uid: row.original.uid || '' })
|
|
|
|
const handleUpdateAdmin = async () =>
|
|
await onConfirmAct({
|
|
action: async () => {
|
|
try {
|
|
await updateAdmin({ admin: !row.original.admin })
|
|
showSuccess(getString('userUpdateSuccess'))
|
|
refetch()
|
|
} catch (error) {
|
|
showError(getErrorMessage(error))
|
|
}
|
|
},
|
|
message: (
|
|
<Text font={{ variation: FontVariation.BODY2 }}>
|
|
<StringSubstitute
|
|
str={getString(
|
|
row.original.admin ? 'userManagement.removeAdminMsg' : 'userManagement.setAsAdminMsg',
|
|
{
|
|
displayName: row.original.display_name,
|
|
userId: row.original.uid
|
|
}
|
|
)}
|
|
vars={{ avatar: <Avatar name={row.original.display_name} /> }}
|
|
/>
|
|
</Text>
|
|
),
|
|
intent: 'primary',
|
|
title: getString(row.original.admin ? 'removeAdmin' : 'setAsAdmin')
|
|
})
|
|
|
|
return (
|
|
<OptionsMenuButton
|
|
tooltipProps={{ isDark: true }}
|
|
items={[
|
|
{
|
|
text: row.original.admin ? getString('removeAdmin') : getString('setAsAdmin'),
|
|
onClick: () => handleUpdateAdmin()
|
|
},
|
|
{
|
|
text: getString('userManagement.resetPassword'),
|
|
onClick: () => openResetPasswordModal({ userInfo: row.original })
|
|
},
|
|
{
|
|
text: getString('editUser'),
|
|
onClick: () => openModal({ isEditing: true, userInfo: row.original })
|
|
},
|
|
{
|
|
text: getString('deleteUser'),
|
|
onClick: () => handleDeleteUser(row.original.uid as string, row.original.display_name)
|
|
}
|
|
]}
|
|
/>
|
|
)
|
|
}
|
|
}
|
|
],
|
|
[getString, handleDeleteUser, onConfirmAct, openModal, openResetPasswordModal, refetch, showError, showSuccess]
|
|
)
|
|
|
|
return (
|
|
<Container className={css.mainCtn}>
|
|
<Page.Header title={getString('users')} />
|
|
<Page.Body>
|
|
<Container padding="xlarge">
|
|
<LoadingSpinner visible={loading} />
|
|
<Button
|
|
icon="plus"
|
|
text={getString('userManagement.newUser')}
|
|
variation={ButtonVariation.PRIMARY}
|
|
margin={{ bottom: 'medium' }}
|
|
onClick={() => openModal({})}
|
|
/>
|
|
<TableV2 data={data || []} columns={columns} />
|
|
<ResourceListingPagination response={response} page={page} setPage={setPage} />
|
|
</Container>
|
|
</Page.Body>
|
|
</Container>
|
|
)
|
|
}
|
|
|
|
export default UsersListing
|