add loading state for org members and roles

This commit is contained in:
Joshen Lim committed 2023-03-23 15:05:36 +08:00
1 parent c8bea30f69
commit dc741f388d
2 files changed
+44 -38

No files matched your search

@@ -2,27 +2,21 @@ import Image from 'next/image'
import * as Tooltip from '@radix-ui/react-tooltip'
import { useState, Fragment } from 'react'
import { observer } from 'mobx-react-lite'
import {
Badge,
Button,
Loading,
Listbox,
IconUser,
Modal,
IconAlertCircle,
IconHelpCircle,
} from 'ui'
import { Badge, Button, Loading, Listbox, IconUser, Modal, IconAlertCircle, IconLoader } from 'ui'
import { Member, Role } from 'types'
import { Member } from 'types'
import { useStore, useParams } from 'hooks'
import { isInviteExpired, getUserDisplayName } from '../Organization.utils'
import { useProfileQuery } from 'data/profile/profile-query'
import { useOrganizationMemberUpdateMutation } from 'data/organizations/organization-member-update-mutation'
import ShimmeringLoader from 'components/ui/ShimmeringLoader'
import Table from 'components/to-be-cleaned/Table'
import MemberActions from './MemberActions'
import RolesHelperModal from './RolesHelperModal/RolesHelperModal'
import { getRolesManagementPermissions } from './TeamSettings.utils'
import { isInviteExpired, getUserDisplayName } from '../Organization.utils'
import { useProfileQuery } from 'data/profile/profile-query'
import { useOrganizationRolesQuery } from 'data/organizations/organization-roles-query'
import { useOrganizationDetailQuery } from 'data/organizations/organization-detail-query'
import { useOrganizationMemberUpdateMutation } from 'data/organizations/organization-member-update-mutation'
interface SelectedMember extends Member {
oldRoleId: number
@@ -30,24 +24,38 @@ interface SelectedMember extends Member {
}
export interface MembersViewProps {
roles: Role[]
members: Member[]
searchString: string
}
const MembersView = ({ searchString, roles, members }: MembersViewProps) => {
const MembersView = ({ searchString }: MembersViewProps) => {
const { ui } = useStore()
const { slug } = useParams()
const { data: profile } = useProfileQuery()
const { data: detailData, isLoading: isLoadingOrgDetails } = useOrganizationDetailQuery({ slug })
const { data: rolesData, isLoading: isLoadingRoles } = useOrganizationRolesQuery({ slug })
const { mutate: updateOrganizationMember, isLoading } = useOrganizationMemberUpdateMutation({
onSuccess() {
ui.setNotification({
category: 'success',
message: `Successfully updated role for ${getUserDisplayName(selectedMember)}`,
})
},
onError() {
ui.setNotification({
category: 'error',
message: `Failed to update role for ${getUserDisplayName(selectedMember)}`,
})
},
})
const roles = rolesData?.roles ?? []
const members = detailData?.members ?? []
const { rolesAddable, rolesRemovable } = getRolesManagementPermissions(roles)
const [selectedMember, setSelectedMember] = useState<SelectedMember>()
const [userRoleChangeModalVisible, setUserRoleChangeModalVisible] = useState(false)
if (!members) return <div />
const filteredMembers = (
!searchString
? members
@@ -68,21 +76,6 @@ const MembersView = ({ searchString, roles, members }: MembersViewProps) => {
return roles.find((x: any) => x.id === id)?.name
}
const { isLoading, mutate } = useOrganizationMemberUpdateMutation({
onSuccess() {
ui.setNotification({
category: 'success',
message: `Successfully updated role for ${getUserDisplayName(selectedMember)}`,
})
},
onError() {
ui.setNotification({
category: 'error',
message: `Failed to update role for ${getUserDisplayName(selectedMember)}`,
})
},
})
const handleRoleChange = async () => {
if (!selectedMember) return
@@ -95,11 +88,20 @@ const MembersView = ({ searchString, roles, members }: MembersViewProps) => {
throw new Error('gotrue_id is required')
}
mutate({ slug, gotrueId: gotrue_id, roleId: newRoleId })
updateOrganizationMember({ slug, gotrueId: gotrue_id, roleId: newRoleId })
setUserRoleChangeModalVisible(false)
}
if (isLoadingOrgDetails) {
return (
<div className="py-4 space-y-2">
<ShimmeringLoader />
<ShimmeringLoader className="w-3/4" />
<ShimmeringLoader className="w-1/2" />
</div>
)
}
return (
<>
<div className="rounded">
@@ -185,7 +187,11 @@ const MembersView = ({ searchString, roles, members }: MembersViewProps) => {
</Table.td>
<Table.td>
{role !== undefined ? (
{isLoadingRoles ? (
<div className="w-[140px]">
<IconLoader className="animate-spin" size={16} strokeWidth={1.5} />
</div>
) : role !== undefined ? (
<Tooltip.Root delayDuration={0}>
<Tooltip.Trigger className="w-[140px]">
<Listbox
@@ -117,7 +117,7 @@ const TeamSettings = () => {
</div>
</div>
<div className="container my-4 max-w-4xl space-y-8">
<MembersView searchString={searchString} roles={roles} members={members} />
<MembersView searchString={searchString} />
</div>
</>
)