feat: custom show/hide datatable col

This commit is contained in:
pa
2026-03-04 23:12:41 +09:00
parent 1decec4c69
commit 1be9d13cd4
11 changed files with 400 additions and 104 deletions

View File

@@ -20,24 +20,27 @@ import { i18n } from '../../plugin';
const { t } = i18n.global;
const sortButton = ({ column, label, descFirst = false }) => (
<Button
variant="ghost"
size="sm"
class="-ml-2 h-8 px-2"
onClick={() => {
const sorted = column.getIsSorted();
if (!sorted && descFirst) {
column.toggleSorting(true);
return;
}
column.toggleSorting(sorted === 'asc');
}}
>
{label}
<ArrowUpDown class="ml-1 h-4 w-4" />
</Button>
);
const sortButton = ({ column, label, descFirst = false }) => {
const resolvedLabel = typeof label === 'function' ? label() : label;
return (
<Button
variant="ghost"
size="sm"
class="-ml-2 h-8 px-2"
onClick={() => {
const sorted = column.getIsSorted();
if (!sorted && descFirst) {
column.toggleSorting(true);
return;
}
column.toggleSorting(sorted === 'asc');
}}
>
{resolvedLabel}
<ArrowUpDown class="ml-1 h-4 w-4" />
</Button>
);
};
const getInstanceIconWeight = (item) => {
if (!item) return 0;
@@ -70,6 +73,7 @@ export const createColumns = ({
header: () => t('table.playerList.avatar'),
size: 70,
enableSorting: false,
meta: { label: () => t('table.playerList.avatar') },
cell: ({ row }) => {
const userRef = row.original?.ref;
const src = userImage(userRef);
@@ -89,8 +93,12 @@ export const createColumns = ({
id: 'timer',
accessorFn: (row) => row?.timer,
header: ({ column }) =>
sortButton({ column, label: t('table.playerList.timer') }),
sortButton({
column,
label: () => t('table.playerList.timer')
}),
size: 90,
meta: { label: () => t('table.playerList.timer') },
sortingFn: (rowA, rowB) =>
(rowA.original?.timer ?? 0) - (rowB.original?.timer ?? 0),
cell: ({ row }) => <Timer epoch={row.original?.timer} />
@@ -101,9 +109,10 @@ export const createColumns = ({
header: ({ column }) =>
sortButton({
column,
label: t('table.playerList.displayName')
label: () => t('table.playerList.displayName')
}),
size: 200,
meta: { label: () => t('table.playerList.displayName') },
sortingFn: (rowA, rowB) =>
sortAlphabetically(rowA.original, rowB.original, 'displayName'),
cell: ({ row }) => {
@@ -118,8 +127,9 @@ export const createColumns = ({
id: 'rank',
accessorFn: (row) => row?.ref?.$trustSortNum,
header: ({ column }) =>
sortButton({ column, label: t('table.playerList.rank') }),
sortButton({ column, label: () => t('table.playerList.rank') }),
size: 110,
meta: { label: () => t('table.playerList.rank') },
sortingFn: (rowA, rowB) =>
(rowA.original?.ref?.$trustSortNum ?? 0) -
(rowB.original?.ref?.$trustSortNum ?? 0),
@@ -143,7 +153,8 @@ export const createColumns = ({
size: 200,
minSize: 100,
meta: {
stretch: true
stretch: true,
label: () => t('table.playerList.status')
},
enableSorting: false,
cell: ({ row }) => {
@@ -170,9 +181,13 @@ export const createColumns = ({
id: 'photonId',
accessorFn: (row) => row?.photonId,
header: ({ column }) =>
sortButton({ column, label: t('table.playerList.photonId') }),
sortButton({
column,
label: () => t('table.playerList.photonId')
}),
size: 110,
enableHiding: true,
meta: { label: () => t('table.playerList.photonId') },
sortingFn: (rowA, rowB) =>
(rowA.original?.photonId ?? 0) - (rowB.original?.photonId ?? 0),
cell: ({ row }) => {
@@ -212,13 +227,14 @@ export const createColumns = ({
header: ({ column }) =>
sortButton({
column,
label: t('table.playerList.icon'),
label: () => t('table.playerList.icon'),
descFirst: true
}),
size: 90,
accessorFn: (row) => getInstanceIconWeight(row),
meta: {
class: 'text-center'
class: 'text-center',
label: () => t('table.playerList.icon')
},
sortingFn: (rowA, rowB, columnId) => {
const a = rowA.original;
@@ -291,6 +307,7 @@ export const createColumns = ({
header: () => t('table.playerList.platform'),
size: 90,
enableSorting: false,
meta: { label: () => t('table.playerList.platform') },
cell: ({ row }) => {
const userRef = row.original?.ref;
const platform = userRef?.$platform;
@@ -330,6 +347,7 @@ export const createColumns = ({
header: () => t('table.playerList.language'),
size: 100,
enableSorting: false,
meta: { label: () => t('table.playerList.language') },
cell: ({ row }) => {
const userRef = row.original?.ref;
const langs = userRef?.$languages ?? [];
@@ -366,6 +384,7 @@ export const createColumns = ({
header: () => t('table.playerList.bioLink'),
size: 100,
enableSorting: false,
meta: { label: () => t('table.playerList.bioLink') },
cell: ({ row }) => {
const links =
row.original?.ref?.bioLinks?.filter(Boolean) ?? [];
@@ -402,7 +421,8 @@ export const createColumns = ({
size: 150,
minSize: 20,
meta: {
stretch: true
stretch: true,
label: () => t('table.playerList.note')
},
enableSorting: false,
cell: ({ row }) => {