Skip to content

Commit 6ab302f

Browse files
author
Amir Zouerami
committed
🔨 FIX: fixes the scrolling issue with admin panel.
1 parent 67265c7 commit 6ab302f

File tree

1 file changed

+101
-103
lines changed

1 file changed

+101
-103
lines changed

src/components/projects/ProjectAccessForm.tsx

Lines changed: 101 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { useToast } from '@/hooks/use-toast';
22
import { Button } from '@/components/ui/button';
33
import { useTeams } from '@/hooks/api/useTeams';
4+
import { useUsers } from '@/hooks/api/useUsers';
45
import React, { useState, useEffect } from 'react';
56
import { useUpdateProject } from '@/hooks/api/useProjects';
67
import { Project, AccessControlList } from '@/types/types';
7-
import { useUsers, SanitizedUser } from '@/hooks/api/useUsers';
88
import { X, ChevronsUpDown, Users as TeamsIcon } from 'lucide-react';
99
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
1010
import { Table, TableBody, TableCell, TableRow } from '@/components/ui/table';
@@ -57,8 +57,7 @@ const Selector = ({
5757
onSelect={() => {
5858
onSelect(item.id);
5959
setOpen(false);
60-
}}
61-
>
60+
}}>
6261
{item.name}
6362
</CommandItem>
6463
))}
@@ -98,8 +97,7 @@ const ProjectAccessForm: React.FC<ProjectAccessFormProps> = ({ project, isOpen,
9897

9998
if (action === 'add' && !currentList.includes(value)) {
10099
currentList.push(value);
101-
}
102-
else if (action === 'remove') {
100+
} else if (action === 'remove') {
103101
(newAccess[list] as any)[type] = currentList.filter(item => item !== value);
104102
}
105103
return newAccess;
@@ -120,8 +118,7 @@ const ProjectAccessForm: React.FC<ProjectAccessFormProps> = ({ project, isOpen,
120118

121119
toast({ title: 'Success', description: 'Project access updated successfully.' });
122120
onClose();
123-
}
124-
catch (error: any) {
121+
} catch (error: any) {
125122
toast({
126123
title: 'Error',
127124
description: error.error || 'Failed to update project access.',
@@ -155,76 +152,79 @@ const ProjectAccessForm: React.FC<ProjectAccessFormProps> = ({ project, isOpen,
155152
/>
156153
</div>
157154
</CardHeader>
158-
<CardContent>
159-
<Table>
160-
<TableBody>
161-
{userItems.length === 0 && teamItems.length === 0 && (
162-
<TableRow>
163-
<TableCell className="text-center text-muted-foreground">No entries.</TableCell>
164-
</TableRow>
165-
)}
166-
{userItems.map(userId => {
167-
const user = getUserById(userId);
168-
return (
169-
<TableRow key={`user-${userId}`}>
170-
<TableCell className="flex items-center gap-2">
171-
<Avatar className="h-6 w-6">
172-
<AvatarImage src={user?.profileImage} />
173-
<AvatarFallback>{user?.username.substring(0, 2).toUpperCase()}</AvatarFallback>
174-
</Avatar>
175-
<span>{user?.username || 'Unknown User'}</span>
176-
</TableCell>
177-
<TableCell className="text-right">
178-
<Button
179-
variant="ghost"
180-
size="icon"
181-
onClick={() => handleModify('remove', list, 'users', userId)}
182-
>
183-
<X className="h-4 w-4" />
184-
</Button>
185-
</TableCell>
186-
</TableRow>
187-
);
188-
})}
189-
{teamItems.map(teamId => {
190-
const team = allTeams.find(t => t.id === teamId);
191-
return (
192-
<TableRow key={`team-${teamId}`}>
193-
<TableCell className="flex items-center gap-2">
194-
<TeamsIcon className="h-5 w-5 text-muted-foreground" />
195-
<span>{team?.name || 'Unknown Team'}</span>
196-
</TableCell>
197-
<TableCell className="text-right">
198-
<Button
199-
variant="ghost"
200-
size="icon"
201-
onClick={() => handleModify('remove', list, 'teams', teamId)}
202-
>
203-
<X className="h-4 w-4" />
204-
</Button>
205-
</TableCell>
206-
</TableRow>
207-
);
208-
})}
209-
</TableBody>
210-
</Table>
155+
<CardContent className="p-0">
156+
<div className="max-h-32 overflow-y-auto border-t">
157+
{userItems.length === 0 && teamItems.length === 0 ? (
158+
<div className="p-4 text-center text-muted-foreground text-sm">No entries.</div>
159+
) : (
160+
<Table>
161+
<TableBody>
162+
{userItems.map(userId => {
163+
const user = getUserById(userId);
164+
return (
165+
<TableRow key={`user-${userId}`}>
166+
<TableCell className="flex items-center gap-2 py-2">
167+
<Avatar className="h-6 w-6">
168+
<AvatarImage src={user?.profileImage} />
169+
<AvatarFallback className="text-xs">
170+
{user?.username.substring(0, 2).toUpperCase()}
171+
</AvatarFallback>
172+
</Avatar>
173+
<span className="text-sm">{user?.username || 'Unknown User'}</span>
174+
</TableCell>
175+
<TableCell className="text-right py-2">
176+
<Button
177+
variant="ghost"
178+
size="sm"
179+
className="h-6 w-6 p-0"
180+
onClick={() => handleModify('remove', list, 'users', userId)}>
181+
<X className="h-3 w-3" />
182+
</Button>
183+
</TableCell>
184+
</TableRow>
185+
);
186+
})}
187+
188+
{teamItems.map(teamId => {
189+
const team = allTeams.find(t => t.id === teamId);
190+
return (
191+
<TableRow key={`team-${teamId}`}>
192+
<TableCell className="flex items-center gap-2 py-2">
193+
<TeamsIcon className="h-4 w-4 text-muted-foreground" />
194+
<span className="text-sm">{team?.name || 'Unknown Team'}</span>
195+
</TableCell>
196+
<TableCell className="text-right py-2">
197+
<Button
198+
variant="ghost"
199+
size="sm"
200+
className="h-6 w-6 p-0"
201+
onClick={() => handleModify('remove', list, 'teams', teamId)}>
202+
<X className="h-3 w-3" />
203+
</Button>
204+
</TableCell>
205+
</TableRow>
206+
);
207+
})}
208+
</TableBody>
209+
</Table>
210+
)}
211+
</div>
211212
</CardContent>
212213
</Card>
213214
);
214215
};
215216

216217
return (
217218
<Dialog open={isOpen} onOpenChange={onClose}>
218-
<DialogContent className="max-w-4xl">
219-
<DialogHeader>
219+
<DialogContent className="max-w-4xl max-h-[90vh] overflow-hidden flex flex-col">
220+
<DialogHeader className="flex-shrink-0">
220221
<DialogTitle>Manage Access for "{project.name}"</DialogTitle>
221-
222222
<DialogDescription>
223223
Control who can see and manage this project. Changes are not saved until you click the save button.
224224
</DialogDescription>
225225
</DialogHeader>
226226

227-
<div className="space-y-6 py-4">
227+
<div className="flex-1 overflow-y-auto space-y-4 py-4">
228228
{renderAccessList('Project Owners', 'owners')}
229229
{renderAccessList('General Access', 'allow')}
230230

@@ -239,52 +239,50 @@ const ProjectAccessForm: React.FC<ProjectAccessFormProps> = ({ project, isOpen,
239239
/>
240240
</CardHeader>
241241

242-
<CardContent>
243-
<Table>
244-
<TableBody>
245-
{access.deny.users.length > 0 ? (
246-
access.deny.users.map(userId => {
247-
const user = getUserById(userId);
248-
249-
return (
250-
<TableRow key={`deny-${userId}`}>
251-
<TableCell className="flex items-center gap-2">
252-
<Avatar className="h-6 w-6">
253-
<AvatarImage src={user?.profileImage} />
254-
<AvatarFallback>{user?.username.substring(0, 2).toUpperCase()}</AvatarFallback>
255-
</Avatar>
256-
257-
<span>{user?.username || 'Unknown User'}</span>
258-
</TableCell>
259-
260-
<TableCell className="text-right">
261-
<Button
262-
variant="ghost"
263-
size="icon"
264-
onClick={() => handleModify('remove', 'deny', 'users', userId)}
265-
>
266-
<X className="h-4 w-4" />
267-
</Button>
268-
</TableCell>
269-
</TableRow>
270-
);
271-
})
272-
) : (
273-
<TableRow>
274-
<TableCell className="text-center text-muted-foreground">No entries.</TableCell>
275-
</TableRow>
276-
)}
277-
</TableBody>
278-
</Table>
242+
<CardContent className="p-0">
243+
<div className="max-h-32 overflow-y-auto border-t">
244+
{access.deny.users.length > 0 ? (
245+
<Table>
246+
<TableBody>
247+
{access.deny.users.map(userId => {
248+
const user = getUserById(userId);
249+
return (
250+
<TableRow key={`deny-${userId}`}>
251+
<TableCell className="flex items-center gap-2 py-2">
252+
<Avatar className="h-6 w-6">
253+
<AvatarImage src={user?.profileImage} />
254+
<AvatarFallback className="text-xs">
255+
{user?.username.substring(0, 2).toUpperCase()}
256+
</AvatarFallback>
257+
</Avatar>
258+
<span className="text-sm">{user?.username || 'Unknown User'}</span>
259+
</TableCell>
260+
<TableCell className="text-right py-2">
261+
<Button
262+
variant="ghost"
263+
size="sm"
264+
className="h-6 w-6 p-0"
265+
onClick={() => handleModify('remove', 'deny', 'users', userId)}>
266+
<X className="h-3 w-3" />
267+
</Button>
268+
</TableCell>
269+
</TableRow>
270+
);
271+
})}
272+
</TableBody>
273+
</Table>
274+
) : (
275+
<div className="p-4 text-center text-muted-foreground text-sm">No entries.</div>
276+
)}
277+
</div>
279278
</CardContent>
280279
</Card>
281280
</div>
282281

283-
<DialogFooter>
282+
<DialogFooter className="flex-shrink-0">
284283
<Button variant="outline" onClick={onClose}>
285284
Cancel
286285
</Button>
287-
288286
<Button onClick={handleSubmit} disabled={updateProjectMutation.isPending}>
289287
{updateProjectMutation.isPending ? 'Saving...' : 'Save Changes'}
290288
</Button>

0 commit comments

Comments
 (0)