StoragePoliciesBucketRow.tsx108 lines · main
| 1 | import { FilesBucket as FilesBucketIcon } from 'icons' |
| 2 | import { noop } from 'lodash' |
| 3 | import { forwardRef, type CSSProperties } from 'react' |
| 4 | import { |
| 5 | Badge, |
| 6 | Button, |
| 7 | Card, |
| 8 | CardContent, |
| 9 | CardHeader, |
| 10 | CardTitle, |
| 11 | Table, |
| 12 | TableBody, |
| 13 | TableHead, |
| 14 | TableHeader, |
| 15 | TableRow, |
| 16 | Tooltip, |
| 17 | TooltipContent, |
| 18 | TooltipTrigger, |
| 19 | } from 'ui' |
| 20 | |
| 21 | import { PolicyRow } from '@/components/interfaces/Auth/Policies/PolicyTableRow/PolicyRow' |
| 22 | import type { Policy } from '@/components/interfaces/Auth/Policies/PolicyTableRow/PolicyTableRow.utils' |
| 23 | import { PUBLIC_BUCKET_TOOLTIP } from '@/components/interfaces/Storage/Storage.constants' |
| 24 | import { Bucket } from '@/data/storage/buckets-query' |
| 25 | |
| 26 | interface StoragePoliciesBucketRowProps { |
| 27 | table: string |
| 28 | label: string |
| 29 | bucket?: Bucket |
| 30 | policies: Policy[] |
| 31 | style?: CSSProperties |
| 32 | onSelectPolicyAdd: (bucketName: string | undefined, table: string) => void |
| 33 | onSelectPolicyEdit: (policy: Policy, bucketName: string, table: string) => void |
| 34 | onSelectPolicyDelete: (policy: Policy) => void |
| 35 | } |
| 36 | |
| 37 | export const StoragePoliciesBucketRow = forwardRef<HTMLDivElement, StoragePoliciesBucketRowProps>( |
| 38 | ( |
| 39 | { |
| 40 | table = '', |
| 41 | label = '', |
| 42 | bucket, |
| 43 | policies = [], |
| 44 | style, |
| 45 | onSelectPolicyAdd = noop, |
| 46 | onSelectPolicyEdit = noop, |
| 47 | onSelectPolicyDelete = noop, |
| 48 | }, |
| 49 | ref |
| 50 | ) => { |
| 51 | return ( |
| 52 | <Card ref={ref} style={style}> |
| 53 | <CardHeader className="flex flex-row w-full items-center justify-between gap-2 space-y-0"> |
| 54 | <div className="flex flex-1 min-w-0 items-center gap-3"> |
| 55 | <FilesBucketIcon className="text-foreground-muted" size={16} strokeWidth={1.5} /> |
| 56 | <div className="flex flex-1 min-w-0 items-center gap-1.5"> |
| 57 | <CardTitle className="truncate">{label}</CardTitle> |
| 58 | {bucket?.public && ( |
| 59 | <Tooltip> |
| 60 | <TooltipTrigger asChild> |
| 61 | <Badge variant="warning" className="flex"> |
| 62 | Public |
| 63 | </Badge> |
| 64 | </TooltipTrigger> |
| 65 | <TooltipContent side="top">{PUBLIC_BUCKET_TOOLTIP}</TooltipContent> |
| 66 | </Tooltip> |
| 67 | )} |
| 68 | </div> |
| 69 | </div> |
| 70 | <Button type="outline" onClick={() => onSelectPolicyAdd(bucket?.name, table)}> |
| 71 | New policy |
| 72 | </Button> |
| 73 | </CardHeader> |
| 74 | {policies.length === 0 ? ( |
| 75 | <CardContent> |
| 76 | <p className="text-sm text-foreground-lighter">No policies created yet</p> |
| 77 | </CardContent> |
| 78 | ) : ( |
| 79 | <CardContent className="p-0"> |
| 80 | <Table className="table-fixed"> |
| 81 | <TableHeader> |
| 82 | <TableRow> |
| 83 | <TableHead className="w-[40%]">Name</TableHead> |
| 84 | <TableHead className="w-[20%]">Command</TableHead> |
| 85 | <TableHead className="w-[30%]">Applied to</TableHead> |
| 86 | <TableHead className="text-right"> |
| 87 | <span className="sr-only">Actions</span> |
| 88 | </TableHead> |
| 89 | </TableRow> |
| 90 | </TableHeader> |
| 91 | <TableBody> |
| 92 | {policies.map((policy) => ( |
| 93 | <PolicyRow |
| 94 | key={policy.id ?? policy.name} |
| 95 | policy={policy} |
| 96 | onSelectEditPolicy={(p) => onSelectPolicyEdit(p, bucket?.name ?? '', table)} |
| 97 | onSelectDeletePolicy={onSelectPolicyDelete} |
| 98 | /> |
| 99 | ))} |
| 100 | </TableBody> |
| 101 | </Table> |
| 102 | </CardContent> |
| 103 | )} |
| 104 | </Card> |
| 105 | ) |
| 106 | } |
| 107 | ) |
| 108 | StoragePoliciesBucketRow.displayName = 'StoragePoliciesBucketRow' |