Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PersonTable #114

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

imths
Copy link

@imths imths commented Nov 22, 2024

Ticket Link

Groupings-1761

List of squashed commits

  • Add bogus functionality
  • Change linking in Admin page
  • Fix up issues from rebasing with main

Test Checklist

  • Unit Tests Passed
  • General Visual Inspection

@imths imths requested a review from JorWo November 22, 2024 22:48
import PersonTable from '@/app/admin/_components/personTable';
import { memberAttributeResults } from '@/lib/actions';

const PersonTab = async (searchParams) => {
Copy link
Contributor

@JorWo JorWo Nov 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure to set a type for searchParams, it would probably be: searchParams: { searchUid: string }. Also I recommend changing the searchParam from searchUid to uhIdentifier because that naming would cover both uid and uhUuid.

import { memberAttributeResults } from '@/lib/actions';

const PersonTab = async (searchParams) => {
const searchUid = searchParams.searchParams.searchUid;
Copy link
Contributor

@JorWo JorWo Nov 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I'm not sure why the searchParams object would make you access .searchParams

Comment on lines +7 to +8
const groupingsInfo = await managePersonResults(searchUid);
const userInfo = searchUid === undefined ? undefined : (await memberAttributeResults([searchUid])).results[0];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call these variables managePersonResults and memberAttributeResults so it's more clear what exactly we are passing into the PersonTable.

Comment on lines +9 to +14
const props = { groupingsInfo: groupingsInfo, userInfo: userInfo, searchUid: searchUid };

return (
<>
<div className="container">
<PersonTable {...props} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of defining a props object, follow the other components and how they define each prop individually.

@JorWo
Copy link
Contributor

JorWo commented Nov 22, 2024

Make sure all the file names are kebab case like person-table.tsx instead of camelCase like personTable.tsx.

const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
const [modalOpen, setModalOpen] = useState(false);
const [modalData, setModalData] = useState([]);
const [dummyBool, setDummyBool] = useState(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this dummyBool for?

Comment on lines +54 to +62
const numSelected = table.getSelectedRowModel().rows.length;
const arr = [];
let i;
for (i = 0; i < numSelected; i++) {
const original = table.getSelectedRowModel().rows[i].original;
if (original.inOwner) arr.push(original.path + ':owners');
if (original.inInclude) arr.push(original.path + ':include');
if (original.inExclude) arr.push(original.path + ':exclude');
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a very nice way to rewrite this code using the .flatMap function: (Generated by ChatGPT!)

const groups = table.getSelectedRowModel().rows.flatMap(({ original }) => {
    const { path, inOwner, inInclude, inExclude } = original;
    return [
        inOwner && `${path}:owners`,
        inInclude && `${path}:include`,
        inExclude && `${path}:exclude`,
    ].filter(groupPath => groupPath);
});

Comment on lines +88 to +92
<p className="text-[1.2rem] font-medium text-text-color md:justify-end pt-5 ps-2">
{userInfo === undefined
? ''
: '(' + userInfo.name + ', ' + userInfo.uid + ', ' + userInfo.uhUuid + ')'}
</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of the ternary operator, it's nicer to use the && operator:

{userInfo !== undefined && <p className="text-[1.2rem] font-medium text-text-color md:justify-end pt-5 ps-2">
    {'(' + userInfo.name + ', ' + userInfo.uid + ', ' + userInfo.uhUuid + ')'}
</p>}

Comment on lines +124 to +147
{validUid === 'FAILURE' && searchUid !== undefined ? (
<Alert variant="destructive" className="w-fit mb-7">
<AlertDescription>{searchUid} is not in any grouping.</AlertDescription>
</Alert>
) : (
''
)}
{validUid === undefined && searchUid !== '' ? (
<Alert variant="destructive" className="w-fit mb-7">
<AlertDescription>
There was an error searching for {searchUid}. <br />
Please ensure you have entered a valid UH member and try again.
</AlertDescription>
</Alert>
) : (
''
)}
{searchUid === '' ? (
<Alert variant="destructive" className="w-fit mb-7">
<AlertDescription>You must enter a UH member to search.</AlertDescription>
</Alert>
) : (
''
)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same goes for here, use the && operator instead of the ternary.

Comment on lines +155 to +159
onClick={
header.column.id === 'name'
? header.column.getToggleSortingHandler()
: () => void 0
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to disable sorting for a certain column in your person-table-columns.tsx file. Then you can just use the getToggleSortingHandler() without this ternary,

Comment on lines +171 to +173
{userInfo === undefined ? (
''
) : (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the && operator instead of the ternary, thanks.

Comment on lines +183 to +199
<PersonTableTooltip
value={'Manage grouping.'}
side={'top'}
desc={
<Link
href={`/groupings/${cell.row.original.path}`}
rel="noopener noreferrer"
target="_blank"
>
<ArrowUpRightFromSquare
size="1.25em"
className="text-text-primary"
data-testid={'arrow-up-right-from-square-icon'}
/>
</Link>
}
></PersonTableTooltip>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's preferred to pass in components as children instead of as a prop. Also the props value and side can be normal strings instead of strings wrapped {}.

Comment on lines +222 to +270
{cell.column.id === 'inOwner' && (
<div className="ml-1">
<p className={`${cell.row.original.inOwner ? 'text-red-500' : ''}`}>
{cell.row.original.inOwner ? 'Yes' : 'No'}
</p>
</div>
)}
{cell.column.id === 'inBasisAndInclude' && (
<div>
<p
className={`${
cell.row.original.inBasisAndInclude ? 'text-red-500' : ''
}`}
>
{cell.row.original.inBasisAndInclude ? 'Yes' : 'No'}
</p>
</div>
)}
{cell.column.id === 'inInclude' && (
<div className="ml-2">
<p
className={`${
cell.row.original.inInclude ? 'text-red-500' : ''
}`}
>
{cell.row.original.inInclude ? 'Yes' : 'No'}
</p>
</div>
)}
{cell.column.id === 'inExclude' && (
<div className="ml-2">
<p
className={`${
cell.row.original.inExclude ? 'text-red-500' : ''
}`}
>
{cell.row.original.inExclude ? 'Yes' : 'No'}
</p>
</div>
)}
{cell.column.id === 'remove' && (
<div className="ml-3">
<input
type="checkbox"
checked={row.getIsSelected()}
onChange={row.getToggleSelectedHandler()}
/>
</div>
)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These && statements should be moved to the person-table-columns.tsx file. Reference how the groupings-table-columns.tsx file does it.

</TableBody>
)}
</Table>
{userInfo === undefined ? '' : <PaginationBar table={table} />}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the && operator here too.

}: {
desc: React.ReactNode;
value: string;
side: Side | undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the type for side is supposed to be a string or more precisely: "top" | "right" | "bottom" | "left"

Comment on lines +24 to +25
`z-50 overflow-hidden rounded-md border border-slate-200 bg-white px-3 py-1.5
text-sm text-slate-950 shadow-md animate-in fade-in-0 zoom-in-95
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep the tooltip as bg-black and text-white since most of the tooltips are those colors. If you are planning to use the tooltip with a white background and black text, change that component individually.

type="search"
className="rounded-[-0.25rem] rounded-l-[0.25rem]"
maxLength={8}
placeholder={searchUid === null || searchUid === '' ? 'UH Username' : searchUid}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the placeholder needs to be the searchUid since the placeholder is just the text that displays when the input is empty.

modalData
}: {
open: boolean;
close: MouseEventHandler;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type for close seems incorrect, maybe close should be renamed to onClose and the type would be: () => void

Comment on lines +114 to +115
<Button
className="rounded-[-0.25rem] rounded-r-[0.25rem]"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I always thought it was weird that our button is not rounded on the left side. Let's keep the button normal and not straighten the left side, thanks.

@JorWo
Copy link
Contributor

JorWo commented Nov 23, 2024

Could you switch out these Lucide React icons for FontAwesome? Thanks.
image

@JorWo
Copy link
Contributor

JorWo commented Nov 23, 2024

There should be a remove modal that appears after pressing the remove button:
image

@JorWo
Copy link
Contributor

JorWo commented Nov 23, 2024

Missing the "No groupings have been selected" alert:
image

@JorWo
Copy link
Contributor

JorWo commented Nov 23, 2024

I think we can go without the tooltip arrows, the shadcn/ui ones look a bit odd:
image
image
Also, for those tooltips the period at the end isn't needed. Additionally, add the cursor-pointer class to the crown icon so the user knows it's clickable.

@JorWo
Copy link
Contributor

JorWo commented Nov 23, 2024

I would love to see a manage-person-table-skeleton.tsx (similar to groupings-table-skeleton.tsx) as the loading file. The page seems unresponsive when fetching a lot of data, for example when searching mhodges.

Note that since this table doesn't use localStorage, you can just create a loading.tsx file next to page.tsx: https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming

@JorWo
Copy link
Contributor

JorWo commented Nov 23, 2024

This seems to be only an issue on Windows, the OwnersModal has scroll bars. Replacing overflow-scroll to overflow-auto class to AlertDialogDescription component should fix it
image

@JorWo
Copy link
Contributor

JorWo commented Nov 23, 2024

Make sure the TailwindCSS handles smaller screen sizes, thanks.
image

@JorWo
Copy link
Contributor

JorWo commented Nov 23, 2024

The Filter Groupings... box is missing the x button:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants