This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

semble / src / webapp / features / connections / containers / connectionsContainer / ConnectionsContainer.tsx
6.8 kB 206 lines
1'use client'; 2 3import useForwardConnections from '@/features/connections/lib/queries/useForwardConnections'; 4import useBackwardConnections from '@/features/connections/lib/queries/useBackwardConnections'; 5import useAllConnections from '@/features/connections/lib/queries/useAllConnections'; 6import InfiniteScroll from '@/components/contentDisplay/infiniteScroll/InfiniteScroll'; 7import { Box, Grid, Group, Stack } from '@mantine/core'; 8import ConnectionsContainerError from './Error.ConnectionsContainer'; 9import ConnectionItem from '@/features/connections/components/connectionItem/ConnectionItem'; 10import SembleEmptyTab from '@/features/semble/components/sembleEmptyTab/SembleEmptyTab'; 11import { BiLink } from 'react-icons/bi'; 12import { useDisclosure } from '@mantine/hooks'; 13import { ConnectionFilters } from '@/features/connections/components/connectionFilters/ConnectionFilters'; 14import DirectionToggle from '@/features/connections/components/connectionFilters/DirectionToggle'; 15import { useState } from 'react'; 16import { ConnectionType, ConnectionWithSourceAndTarget } from '@semble/types'; 17import EditConnectionModal from '@/features/connections/components/editConnectionModal/EditConnectionModal'; 18 19type Direction = 'to' | 'from' | 'all'; 20 21interface Props { 22 url: string; 23} 24 25export default function ConnectionsContainer(props: Props) { 26 const [modalOpened, { open: openModal, close: closeModal }] = 27 useDisclosure(false); 28 29 const [direction, setDirection] = useState<Direction>('all'); 30 const [connectionType, setConnectionType] = useState<ConnectionType | null>( 31 null, 32 ); 33 const [connectionToEdit, setConnectionToEdit] = useState<{ 34 connection: ConnectionWithSourceAndTarget['connection']; 35 targetUrl: string; 36 } | null>(null); 37 38 const handleOpenEditModal = ( 39 connection: ConnectionWithSourceAndTarget['connection'], 40 targetUrl: string, 41 ) => { 42 setConnectionToEdit({ connection, targetUrl }); 43 openModal(); 44 }; 45 46 const handleCloseModal = () => { 47 setConnectionToEdit(null); 48 closeModal(); 49 }; 50 51 const connectionTypes = connectionType ? [connectionType] : undefined; 52 53 const { 54 data: forwardData, 55 error: forwardError, 56 fetchNextPage: fetchNextForward, 57 hasNextPage: hasNextForward, 58 isFetchingNextPage: isFetchingNextForward, 59 isPending: isPendingForward, 60 } = useForwardConnections({ 61 url: props.url, 62 connectionTypes, 63 }); 64 65 const { 66 data: backwardData, 67 error: backwardError, 68 fetchNextPage: fetchNextBackward, 69 hasNextPage: hasNextBackward, 70 isFetchingNextPage: isFetchingNextBackward, 71 isPending: isPendingBackward, 72 } = useBackwardConnections({ 73 url: props.url, 74 connectionTypes, 75 }); 76 77 const { 78 data: allData, 79 error: allError, 80 fetchNextPage: fetchNextAll, 81 hasNextPage: hasNextAll, 82 isFetchingNextPage: isFetchingNextAll, 83 isPending: isPendingAll, 84 } = useAllConnections({ 85 url: props.url, 86 connectionTypes, 87 }); 88 89 const allForwardConnections = 90 forwardData?.pages.flatMap((page) => page.connections ?? []) ?? []; 91 const allBackwardConnections = 92 backwardData?.pages.flatMap((page) => page.connections ?? []) ?? []; 93 const allConnections = 94 allData?.pages.flatMap((page) => page.connections ?? []) ?? []; 95 96 const emptyMessage = 97 direction === 'all' 98 ? 'No connections found' 99 : `No connections found ${direction} this`; 100 101 if (forwardError || backwardError || allError) { 102 return <ConnectionsContainerError />; 103 } 104 105 const connections = 106 direction === 'to' 107 ? allForwardConnections 108 : direction === 'from' 109 ? allBackwardConnections 110 : allConnections; 111 const fetchNextPage = 112 direction === 'to' 113 ? fetchNextForward 114 : direction === 'from' 115 ? fetchNextBackward 116 : fetchNextAll; 117 const hasNextPage = 118 direction === 'to' 119 ? hasNextForward 120 : direction === 'from' 121 ? hasNextBackward 122 : hasNextAll; 123 const isFetchingNextPage = 124 direction === 'to' 125 ? isFetchingNextForward 126 : direction === 'from' 127 ? isFetchingNextBackward 128 : isFetchingNextAll; 129 const isPending = 130 direction === 'to' 131 ? isPendingForward 132 : direction === 'from' 133 ? isPendingBackward 134 : isPendingAll; 135 136 return ( 137 <> 138 <Stack gap={'md'} align="center"> 139 <Group justify="space-between" w={'100%'} maw={600}> 140 <DirectionToggle value={direction} onChange={setDirection} /> 141 <ConnectionFilters.Root 142 connectionType={connectionType} 143 onConnectionTypeChange={setConnectionType} 144 > 145 <ConnectionFilters.ConnectionTypeFilter /> 146 </ConnectionFilters.Root> 147 </Group> 148 149 {connections.length === 0 && !isPending ? ( 150 <SembleEmptyTab message={emptyMessage} icon={BiLink} /> 151 ) : ( 152 <InfiniteScroll 153 dataLength={connections.length} 154 hasMore={!!hasNextPage} 155 isInitialLoading={isPending} 156 isLoading={isFetchingNextPage} 157 loadMore={fetchNextPage} 158 > 159 <Grid gap="xl" mx={'auto'} maw={600} w={'100%'}> 160 {connections.map((connection, index) => { 161 // Determine the actual direction for this specific connection 162 // If direction is 'all', check if the source URL matches props.url 163 const isForward = 164 direction === 'all' 165 ? connection.source.url === props.url 166 : direction === 'to'; 167 const connectionDirection = isForward ? 'forward' : 'backward'; 168 const targetUrl = isForward 169 ? connection.target.url 170 : connection.source.url; 171 172 return ( 173 <Box 174 key={`${direction}-${index}`} 175 style={{ 176 contentVisibility: 'auto', 177 containIntrinsicSize: 'auto 200px', 178 }} 179 > 180 <Grid.Col span={12}> 181 <ConnectionItem 182 connection={connection} 183 direction={connectionDirection} 184 onEdit={() => { 185 handleOpenEditModal(connection.connection, targetUrl); 186 }} 187 /> 188 </Grid.Col> 189 </Box> 190 ); 191 })} 192 </Grid> 193 </InfiniteScroll> 194 )} 195 </Stack> 196 197 <EditConnectionModal 198 isOpen={modalOpened} 199 onClose={handleCloseModal} 200 sourceUrl={props.url} 201 targetUrl={connectionToEdit?.targetUrl} 202 connection={connectionToEdit?.connection} 203 /> 204 </> 205 ); 206}