[7/n][project settings ui] member list cleanup (#40)

This commit is contained in:
Vivian Phung 2024-05-14 16:23:33 -04:00 committed by GitHub
commit 039753df56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 122 additions and 37 deletions

View File

@ -1,18 +1,15 @@
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
import { Permission, User } from 'gql-client';
import {
Select,
Option,
Chip,
} from '@snowballtools/material-tailwind-react-fork';
import { formatAddress } from 'utils/format';
import { RemoveMemberDialog } from 'components/projects/Dialog/RemoveMemberDialog'; import { RemoveMemberDialog } from 'components/projects/Dialog/RemoveMemberDialog';
import { Select, SelectOption } from 'components/shared/Select';
import { LoaderIcon } from 'components/shared/CustomIcon';
import { Tooltip } from 'components/shared/Tooltip'; import { Tooltip } from 'components/shared/Tooltip';
import { Button } from 'components/shared/Button'; import { Button } from 'components/shared/Button';
import { Permission, User } from 'gql-client';
import { formatAddress } from 'utils/format';
import { Tag } from 'components/shared/Tag';
const PERMISSION_OPTIONS = [ const PERMISSION_OPTIONS: SelectOption[] = [
{ {
label: 'View only', label: 'View only',
value: 'View', value: 'View',
@ -23,7 +20,7 @@ const PERMISSION_OPTIONS = [
}, },
]; ];
const DROPDOWN_OPTIONS = [ const DROPDOWN_OPTIONS: SelectOption[] = [
...PERMISSION_OPTIONS, ...PERMISSION_OPTIONS,
{ label: 'Remove member', value: 'remove' }, { label: 'Remove member', value: 'remove' },
]; ];
@ -50,16 +47,21 @@ const MemberCard = ({
onUpdateProjectMember, onUpdateProjectMember,
}: MemberCardProps) => { }: MemberCardProps) => {
const [ethAddress, emailDomain] = member.email.split('@'); const [ethAddress, emailDomain] = member.email.split('@');
const [selectedPermission, setSelectedPermission] = useState( const [selectedPermission, setSelectedPermission] = useState<SelectOption>(
permissions.join('+'), PERMISSION_OPTIONS.map((value) => {
permissions.join('+') === value.value;
}).pop() ?? {
label: 'View only',
value: 'View',
},
); );
const [removeMemberDialogOpen, setRemoveMemberDialogOpen] = useState(false); const [removeMemberDialogOpen, setRemoveMemberDialogOpen] = useState(false);
const handlePermissionChange = useCallback( const handlePermissionChange = useCallback(
async (value: string) => { async (value: SelectOption) => {
setSelectedPermission(value); setSelectedPermission(value);
if (value === 'remove') { if (value.value === 'remove') {
setRemoveMemberDialogOpen((prevVal) => !prevVal); setRemoveMemberDialogOpen((prevVal) => !prevVal);
// To display updated label in next render // To display updated label in next render
setTimeout(() => { setTimeout(() => {
@ -67,7 +69,7 @@ const MemberCard = ({
}); });
} else { } else {
if (onUpdateProjectMember) { if (onUpdateProjectMember) {
const permissions = value.split('+') as Permission[]; const permissions = value.value.split('+') as Permission[];
await onUpdateProjectMember({ permissions }); await onUpdateProjectMember({ permissions });
} }
} }
@ -95,34 +97,19 @@ const MemberCard = ({
<div className="basis-1/2"> <div className="basis-1/2">
{!isPending ? ( {!isPending ? (
<Select <Select
size="lg" options={DROPDOWN_OPTIONS}
size="md"
label={isOwner ? 'Owner' : ''} label={isOwner ? 'Owner' : ''}
disabled={isOwner} disabled={isOwner}
value={selectedPermission} value={selectedPermission}
onChange={(value) => handlePermissionChange(value!)} onChange={(value) => handlePermissionChange(value as SelectOption)}
selected={(_, index) => ( />
<span>{DROPDOWN_OPTIONS[index!]?.label}</span>
)}
>
{DROPDOWN_OPTIONS.map((permission, key) => (
<Option key={key} value={permission.value}>
^ {permission.label}
{permission.value === selectedPermission && (
<p className="float-right">^</p>
)}
</Option>
))}
</Select>
) : ( ) : (
<div className="flex justify-end gap-2"> <div className="flex justify-end gap-2">
<div> <div>
<Chip <Tag type="positive" size="sm" leftIcon={<LoaderIcon />}>
value="Pending" Pending
variant="outlined" </Tag>
color="orange"
size="sm"
icon={'^'}
/>
</div> </div>
<div> <div>
<Button <Button

View File

@ -0,0 +1,98 @@
import { Meta, StoryObj } from '@storybook/react';
import { User } from 'gql-client';
import MemberCard from 'components/projects/project/settings/MemberCard';
const meta: Meta<typeof MemberCard> = {
title: 'Project/Settings/MemberCard',
component: MemberCard,
tags: ['autodocs'],
argTypes: {
member: {
control: 'object',
},
isFirstCard: {
control: 'boolean',
},
isOwner: {
control: 'boolean',
},
isPending: {
control: 'boolean',
},
permissions: {
control: 'object',
},
},
} as Meta<typeof MemberCard>;
export default meta;
type Story = StoryObj<typeof MemberCard>;
const defaultUser = {
id: 'hellodsadass',
name: 'Vivian',
email: 'welcome@helloworld.com',
isVerified: true,
createdAt: 'blah',
updatedAt: 'blah',
gitHubToken: 'blah',
} as User;
export const Owner: Story = {
render: ({ member, isFirstCard, isOwner, isPending, permissions }) => (
<MemberCard
member={member}
isFirstCard={isFirstCard}
isOwner={isOwner}
isPending={isPending}
permissions={permissions}
/>
),
args: {
member: defaultUser,
isFirstCard: true,
isOwner: true,
isPending: false,
permissions: [],
},
};
export const ViewPlusEditMember: Story = {
render: ({ member, isFirstCard, isOwner, isPending, permissions }) => (
<MemberCard
member={member}
isFirstCard={isFirstCard}
isOwner={isOwner}
isPending={isPending}
permissions={permissions}
/>
),
args: {
member: defaultUser,
isFirstCard: true,
isOwner: false,
isPending: false,
permissions: ['View+Edit'],
},
};
export const ViewMember: Story = {
render: ({ member, isFirstCard, isOwner, isPending, permissions }) => (
<MemberCard
member={member}
isFirstCard={isFirstCard}
isOwner={isOwner}
isPending={isPending}
permissions={permissions}
/>
),
args: {
member: defaultUser,
isFirstCard: true,
isOwner: false,
isPending: false,
permissions: ['View'],
},
};