fix: fix UI regression related to DataTable (#17943)
* fix: fix UI regression regarding DataTable * update comment
This commit is contained in:
1 parent
b33ca2f937
commit
27cd2457e8
5 files changed
+127
-102
No files matched your search
@@ -62,12 +62,13 @@ export function DataTable<TData, TValue>({
|
||||
|
||||
const columnSizeVars = useMemo(() => {
|
||||
const headers = table.getFlatHeaders();
|
||||
const colSizes: { [key: string]: number } = {};
|
||||
const colSizes: { [key: string]: string } = {};
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const header = headers[i]!;
|
||||
colSizes[`--header-${header.id}-size`] = header.getSize();
|
||||
colSizes[`--col-${header.column.id}-size`] = header.column.getSize();
|
||||
const isAutoWidth = header.column.columnDef.meta?.autoWidth;
|
||||
colSizes[`--header-${header.id}-size`] = isAutoWidth ? "auto" : `${header.getSize()}px`;
|
||||
colSizes[`--col-${header.column.id}-size`] = isAutoWidth ? "auto" : `${header.column.getSize()}px`;
|
||||
}
|
||||
return colSizes;
|
||||
}, [table.getFlatHeaders(), table.getState().columnSizingInfo, table.getState().columnSizing]);
|
||||
@@ -102,7 +103,7 @@ export function DataTable<TData, TValue>({
|
||||
style={{
|
||||
...(meta?.sticky?.position === "left" && { left: `${meta.sticky.gap || 0}px` }),
|
||||
...(meta?.sticky?.position === "right" && { right: `${meta.sticky.gap || 0}px` }),
|
||||
width: `calc(var(--header-${header?.id}-size) * 1px)`,
|
||||
width: `var(--header-${header?.id}-size)`,
|
||||
}}
|
||||
className={classNames(
|
||||
"flex shrink-0 items-center",
|
||||
@@ -162,7 +163,7 @@ export function DataTable<TData, TValue>({
|
||||
style={{
|
||||
...(meta?.sticky?.position === "left" && { left: `${meta.sticky.gap || 0}px` }),
|
||||
...(meta?.sticky?.position === "right" && { right: `${meta.sticky.gap || 0}px` }),
|
||||
width: `calc(var(--col-${cell.column.id}-size) * 1px)`,
|
||||
width: `var(--col-${cell.column.id}-size)`,
|
||||
}}
|
||||
className={classNames(
|
||||
"flex shrink-0 items-center overflow-hidden",
|
||||
|
||||
@@ -28,6 +28,7 @@ const GroupTeamMappingTable = () => {
|
||||
{
|
||||
id: "name",
|
||||
header: t("team"),
|
||||
size: 200,
|
||||
cell: ({ row }) => {
|
||||
const { name } = row.original;
|
||||
|
||||
@@ -37,6 +38,7 @@ const GroupTeamMappingTable = () => {
|
||||
{
|
||||
id: "group",
|
||||
header: t("group_name"),
|
||||
size: 200,
|
||||
cell: ({ row }) => {
|
||||
const { id, groupNames, directoryId } = row.original;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ import {
|
||||
DialogFooter,
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
DropdownMenuPortal,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
@@ -283,6 +284,7 @@ export default function MemberList(props: Props) {
|
||||
id: "select",
|
||||
enableHiding: false,
|
||||
enableSorting: false,
|
||||
size: 30,
|
||||
header: ({ table }) => (
|
||||
<Checkbox
|
||||
checked={table.getIsAllPageRowsSelected()}
|
||||
@@ -305,6 +307,7 @@ export default function MemberList(props: Props) {
|
||||
accessorFn: (data) => data.email,
|
||||
enableHiding: false,
|
||||
header: `Member (${totalDBRowCount})`,
|
||||
size: 250,
|
||||
cell: ({ row }) => {
|
||||
const { username, email, avatarUrl, accepted, name } = row.original;
|
||||
const memberName =
|
||||
@@ -344,6 +347,7 @@ export default function MemberList(props: Props) {
|
||||
id: "role",
|
||||
accessorFn: (data) => data.role,
|
||||
header: "Role",
|
||||
size: 100,
|
||||
cell: ({ row, table }) => {
|
||||
const { role, accepted } = row.original;
|
||||
return (
|
||||
@@ -387,6 +391,10 @@ export default function MemberList(props: Props) {
|
||||
},
|
||||
{
|
||||
id: "actions",
|
||||
size: 80,
|
||||
meta: {
|
||||
sticky: { position: "right" },
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const user = row.original;
|
||||
const isSelf = user.id === session?.user.id;
|
||||
@@ -454,99 +462,8 @@ export default function MemberList(props: Props) {
|
||||
StartIcon="ellipsis"
|
||||
/>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem>
|
||||
<DropdownItem
|
||||
type="button"
|
||||
onClick={() =>
|
||||
dispatch({
|
||||
type: "EDIT_USER_SHEET",
|
||||
payload: {
|
||||
user,
|
||||
showModal: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
StartIcon="pencil">
|
||||
{t("edit")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
{impersonationMode && (
|
||||
<>
|
||||
<DropdownMenuItem>
|
||||
<DropdownItem
|
||||
type="button"
|
||||
onClick={() =>
|
||||
dispatch({
|
||||
type: "SET_IMPERSONATE_ID",
|
||||
payload: {
|
||||
user,
|
||||
showModal: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
StartIcon="lock">
|
||||
{t("impersonate")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
)}
|
||||
{resendInvitation && (
|
||||
<DropdownMenuItem>
|
||||
<DropdownItem
|
||||
type="button"
|
||||
onClick={() => {
|
||||
resendInvitationMutation.mutate({
|
||||
teamId: props.team?.id,
|
||||
email: user.email,
|
||||
language: i18n.language,
|
||||
});
|
||||
}}
|
||||
StartIcon="send">
|
||||
{t("resend_invitation")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem>
|
||||
<DropdownItem
|
||||
type="button"
|
||||
onClick={() =>
|
||||
dispatch({
|
||||
type: "SET_DELETE_ID",
|
||||
payload: {
|
||||
user,
|
||||
showModal: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
color="destructive"
|
||||
StartIcon="user-x">
|
||||
{t("remove")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</Dropdown>
|
||||
)}
|
||||
</ButtonGroup>
|
||||
<div className="flex md:hidden">
|
||||
<Dropdown>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button type="button" variant="icon" color="minimal" StartIcon="ellipsis" />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem className="outline-none">
|
||||
<DropdownItem
|
||||
disabled={!user.accepted}
|
||||
href={!user.accepted ? undefined : `/${user.username}`}
|
||||
target="_blank"
|
||||
type="button"
|
||||
StartIcon="external-link">
|
||||
{t("view_public_page")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
{editMode && (
|
||||
<>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem>
|
||||
<DropdownItem
|
||||
type="button"
|
||||
@@ -563,10 +480,46 @@ export default function MemberList(props: Props) {
|
||||
{t("edit")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
{impersonationMode && (
|
||||
<>
|
||||
<DropdownMenuItem>
|
||||
<DropdownItem
|
||||
type="button"
|
||||
onClick={() =>
|
||||
dispatch({
|
||||
type: "SET_IMPERSONATE_ID",
|
||||
payload: {
|
||||
user,
|
||||
showModal: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
StartIcon="lock">
|
||||
{t("impersonate")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
)}
|
||||
{resendInvitation && (
|
||||
<DropdownMenuItem>
|
||||
<DropdownItem
|
||||
type="button"
|
||||
onClick={() => {
|
||||
resendInvitationMutation.mutate({
|
||||
teamId: props.team?.id,
|
||||
email: user.email,
|
||||
language: i18n.language,
|
||||
});
|
||||
}}
|
||||
StartIcon="send">
|
||||
{t("resend_invitation")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem>
|
||||
<DropdownItem
|
||||
type="button"
|
||||
color="destructive"
|
||||
onClick={() =>
|
||||
dispatch({
|
||||
type: "SET_DELETE_ID",
|
||||
@@ -576,13 +529,72 @@ export default function MemberList(props: Props) {
|
||||
},
|
||||
})
|
||||
}
|
||||
color="destructive"
|
||||
StartIcon="user-x">
|
||||
{t("remove")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
</>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenuPortal>
|
||||
</Dropdown>
|
||||
)}
|
||||
</ButtonGroup>
|
||||
<div className="flex md:hidden">
|
||||
<Dropdown>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button type="button" variant="icon" color="minimal" StartIcon="ellipsis" />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem className="outline-none">
|
||||
<DropdownItem
|
||||
disabled={!user.accepted}
|
||||
href={!user.accepted ? undefined : `/${user.username}`}
|
||||
target="_blank"
|
||||
type="button"
|
||||
StartIcon="external-link">
|
||||
{t("view_public_page")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
{editMode && (
|
||||
<>
|
||||
<DropdownMenuItem>
|
||||
<DropdownItem
|
||||
type="button"
|
||||
onClick={() =>
|
||||
dispatch({
|
||||
type: "EDIT_USER_SHEET",
|
||||
payload: {
|
||||
user,
|
||||
showModal: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
StartIcon="pencil">
|
||||
{t("edit")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<DropdownItem
|
||||
type="button"
|
||||
color="destructive"
|
||||
onClick={() =>
|
||||
dispatch({
|
||||
type: "SET_DELETE_ID",
|
||||
payload: {
|
||||
user,
|
||||
showModal: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
StartIcon="user-x">
|
||||
{t("remove")}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
</>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenuPortal>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -95,6 +95,7 @@ export function AvailabilitySliderTable(props: { userTimeFormat: number | null;
|
||||
id: "member",
|
||||
accessorFn: (data) => data.username,
|
||||
header: "Member",
|
||||
size: 200,
|
||||
cell: ({ row }) => {
|
||||
const { username, email, timeZone, name, avatarUrl, profile } = row.original;
|
||||
return (
|
||||
@@ -125,6 +126,7 @@ export function AvailabilitySliderTable(props: { userTimeFormat: number | null;
|
||||
id: "timezone",
|
||||
accessorFn: (data) => data.timeZone,
|
||||
header: "Timezone",
|
||||
size: 160,
|
||||
cell: ({ row }) => {
|
||||
const { timeZone } = row.original;
|
||||
const timeRaw = dayjs().tz(timeZone);
|
||||
@@ -146,6 +148,9 @@ export function AvailabilitySliderTable(props: { userTimeFormat: number | null;
|
||||
},
|
||||
{
|
||||
id: "slider",
|
||||
meta: {
|
||||
autoWidth: true,
|
||||
},
|
||||
header: () => {
|
||||
return (
|
||||
<div className="flex items-center space-x-2">
|
||||
|
||||
Vendored
+5
@@ -7,5 +7,10 @@ declare module "@tanstack/table-core" {
|
||||
gap?: number;
|
||||
};
|
||||
filterType?: "select" | "text";
|
||||
|
||||
// `autoWidth` can make the column size dynamic,
|
||||
// allowing each row to have a different width based on its content.
|
||||
// As a result, scrolling may be flaky, unless the content size is consistent.
|
||||
autoWidth?: boolean;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user