|
|
@ -1,4 +1,4 @@ |
|
|
|
import { type ReactNode, useCallback, useState } from 'react'; |
|
|
|
import { type ReactNode, useCallback, useState, useMemo } from 'react'; |
|
|
|
import { Globe2, Loader2, Lock } from 'lucide-react'; |
|
|
|
import { Globe2, Loader2, Lock } from 'lucide-react'; |
|
|
|
import { type ListFriendsResponse, ShareFriendList } from './ShareFriendList'; |
|
|
|
import { type ListFriendsResponse, ShareFriendList } from './ShareFriendList'; |
|
|
|
import { TransferToTeamList } from './TransferToTeamList'; |
|
|
|
import { TransferToTeamList } from './TransferToTeamList'; |
|
|
@ -49,7 +49,10 @@ export function ShareOptionsModal(props: ShareOptionsModalProps) { |
|
|
|
const [isSettingsUpdated, setIsSettingsUpdated] = useState(false); |
|
|
|
const [isSettingsUpdated, setIsSettingsUpdated] = useState(false); |
|
|
|
const [friends, setFriends] = useState<ListFriendsResponse>([]); |
|
|
|
const [friends, setFriends] = useState<ListFriendsResponse>([]); |
|
|
|
const [teams, setTeams] = useState<UserTeamItem[]>([]); |
|
|
|
const [teams, setTeams] = useState<UserTeamItem[]>([]); |
|
|
|
const [members, setMembers] = useState<TeamMemberList[]>([]); |
|
|
|
|
|
|
|
|
|
|
|
// Using global team members loading state to avoid glitchy UI when switching between teams
|
|
|
|
|
|
|
|
const [isTeamMembersLoading, setIsTeamMembersLoading] = useState(false); |
|
|
|
|
|
|
|
const membersCache = useMemo(() => new Map<string, TeamMemberList[]>(), []); |
|
|
|
|
|
|
|
|
|
|
|
const [visibility, setVisibility] = useState(defaultVisibility); |
|
|
|
const [visibility, setVisibility] = useState(defaultVisibility); |
|
|
|
const [sharedTeamMemberIds, setSharedTeamMemberIds] = useState<string[]>( |
|
|
|
const [sharedTeamMemberIds, setSharedTeamMemberIds] = useState<string[]>( |
|
|
@ -118,7 +121,7 @@ export function ShareOptionsModal(props: ShareOptionsModalProps) { |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const handleTransferToTeam = useCallback( |
|
|
|
const handleTransferToTeam = useCallback( |
|
|
|
async (teamId: string) => { |
|
|
|
async (teamId: string, sharedTeamMemberIds: string[]) => { |
|
|
|
if (!roadmapId) { |
|
|
|
if (!roadmapId) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -128,6 +131,7 @@ export function ShareOptionsModal(props: ShareOptionsModalProps) { |
|
|
|
`${import.meta.env.PUBLIC_API_URL}/v1-transfer-roadmap/${roadmapId}`, |
|
|
|
`${import.meta.env.PUBLIC_API_URL}/v1-transfer-roadmap/${roadmapId}`, |
|
|
|
{ |
|
|
|
{ |
|
|
|
teamId, |
|
|
|
teamId, |
|
|
|
|
|
|
|
sharedTeamMemberIds, |
|
|
|
} |
|
|
|
} |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
@ -187,6 +191,7 @@ export function ShareOptionsModal(props: ShareOptionsModalProps) { |
|
|
|
defaultSharedFriendIds.length > 0 ? defaultSharedFriendIds : [] |
|
|
|
defaultSharedFriendIds.length > 0 ? defaultSharedFriendIds : [] |
|
|
|
); |
|
|
|
); |
|
|
|
} else if (visibility === 'team' && teamId) { |
|
|
|
} else if (visibility === 'team' && teamId) { |
|
|
|
|
|
|
|
setIsTeamMembersLoading(true); |
|
|
|
setSharedTeamMemberIds( |
|
|
|
setSharedTeamMemberIds( |
|
|
|
defaultSharedMemberIds?.length > 0 ? defaultSharedMemberIds : [] |
|
|
|
defaultSharedMemberIds?.length > 0 ? defaultSharedMemberIds : [] |
|
|
|
); |
|
|
|
); |
|
|
@ -225,24 +230,50 @@ export function ShareOptionsModal(props: ShareOptionsModalProps) { |
|
|
|
setSharedFriendIds={setSharedFriendIds} |
|
|
|
setSharedFriendIds={setSharedFriendIds} |
|
|
|
/> |
|
|
|
/> |
|
|
|
)} |
|
|
|
)} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* For Team Roadmap */} |
|
|
|
|
|
|
|
{visibility === 'team' && teamId && ( |
|
|
|
|
|
|
|
<ShareTeamMemberList |
|
|
|
|
|
|
|
teamId={teamId} |
|
|
|
|
|
|
|
sharedTeamMemberIds={sharedTeamMemberIds} |
|
|
|
|
|
|
|
setSharedTeamMemberIds={setSharedTeamMemberIds} |
|
|
|
|
|
|
|
membersCache={membersCache} |
|
|
|
|
|
|
|
isTeamMembersLoading={isTeamMembersLoading} |
|
|
|
|
|
|
|
setIsTeamMembersLoading={setIsTeamMembersLoading} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
)} |
|
|
|
|
|
|
|
|
|
|
|
{canTransferRoadmap && ( |
|
|
|
{canTransferRoadmap && ( |
|
|
|
|
|
|
|
<> |
|
|
|
<TransferToTeamList |
|
|
|
<TransferToTeamList |
|
|
|
teams={teams} |
|
|
|
teams={teams} |
|
|
|
setTeams={setTeams} |
|
|
|
setTeams={setTeams} |
|
|
|
selectedTeamId={selectedTeamId} |
|
|
|
selectedTeamId={selectedTeamId} |
|
|
|
setSelectedTeamId={setSelectedTeamId} |
|
|
|
setSelectedTeamId={setSelectedTeamId} |
|
|
|
|
|
|
|
isTeamMembersLoading={isTeamMembersLoading} |
|
|
|
|
|
|
|
setIsTeamMembersLoading={setIsTeamMembersLoading} |
|
|
|
|
|
|
|
onTeamChange={() => { |
|
|
|
|
|
|
|
setIsTeamMembersLoading(true); |
|
|
|
|
|
|
|
setSharedTeamMemberIds([]); |
|
|
|
|
|
|
|
}} |
|
|
|
/> |
|
|
|
/> |
|
|
|
)} |
|
|
|
{selectedTeamId && ( |
|
|
|
|
|
|
|
<> |
|
|
|
{/* For Team Roadmap */} |
|
|
|
<hr className="-mx-4 my-4" /> |
|
|
|
{visibility === 'team' && teamId && ( |
|
|
|
<div className="mb-4"> |
|
|
|
<ShareTeamMemberList |
|
|
|
<ShareTeamMemberList |
|
|
|
teamId={teamId} |
|
|
|
title="Select who can access this roadmap. You can change this later." |
|
|
|
|
|
|
|
teamId={selectedTeamId!} |
|
|
|
sharedTeamMemberIds={sharedTeamMemberIds} |
|
|
|
sharedTeamMemberIds={sharedTeamMemberIds} |
|
|
|
setSharedTeamMemberIds={setSharedTeamMemberIds} |
|
|
|
setSharedTeamMemberIds={setSharedTeamMemberIds} |
|
|
|
members={members} |
|
|
|
membersCache={membersCache} |
|
|
|
setMembers={setMembers} |
|
|
|
isTeamMembersLoading={isTeamMembersLoading} |
|
|
|
|
|
|
|
setIsTeamMembersLoading={setIsTeamMembersLoading} |
|
|
|
/> |
|
|
|
/> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</> |
|
|
|
|
|
|
|
)} |
|
|
|
|
|
|
|
</> |
|
|
|
)} |
|
|
|
)} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
@ -255,17 +286,23 @@ export function ShareOptionsModal(props: ShareOptionsModalProps) { |
|
|
|
Close |
|
|
|
Close |
|
|
|
</button> |
|
|
|
</button> |
|
|
|
|
|
|
|
|
|
|
|
{canTransferRoadmap ? ( |
|
|
|
{canTransferRoadmap && ( |
|
|
|
<UpdateAction |
|
|
|
<UpdateAction |
|
|
|
disabled={isUpdateDisabled || isLoading} |
|
|
|
disabled={ |
|
|
|
|
|
|
|
isUpdateDisabled || isLoading || sharedTeamMemberIds.length === 0 |
|
|
|
|
|
|
|
} |
|
|
|
onClick={() => { |
|
|
|
onClick={() => { |
|
|
|
handleTransferToTeam(selectedTeamId!).then(() => null); |
|
|
|
handleTransferToTeam(selectedTeamId!, sharedTeamMemberIds).then( |
|
|
|
|
|
|
|
() => null |
|
|
|
|
|
|
|
); |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
{isLoading && <Loader2 className="h-4 w-4 animate-spin" />} |
|
|
|
{isLoading && <Loader2 className="h-4 w-4 animate-spin" />} |
|
|
|
Transfer |
|
|
|
Transfer |
|
|
|
</UpdateAction> |
|
|
|
</UpdateAction> |
|
|
|
) : ( |
|
|
|
)} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{!canTransferRoadmap && ( |
|
|
|
<UpdateAction |
|
|
|
<UpdateAction |
|
|
|
disabled={isUpdateDisabled || isLoading} |
|
|
|
disabled={isUpdateDisabled || isLoading} |
|
|
|
onClick={() => { |
|
|
|
onClick={() => { |
|
|
|