mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-04 22:06:06 +02:00
feat: custom show/hide datatable col
This commit is contained in:
@@ -225,6 +225,7 @@ export const columns = [
|
||||
{
|
||||
accessorKey: 'created_at',
|
||||
size: 140,
|
||||
meta: { label: () => t('table.feed.date') },
|
||||
header: ({ column }) => (
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -257,6 +258,7 @@ export const columns = [
|
||||
accessorKey: 'type',
|
||||
size: 130,
|
||||
header: () => t('table.feed.type'),
|
||||
meta: { label: () => t('table.feed.type') },
|
||||
cell: ({ row }) => {
|
||||
const type = row.getValue('type');
|
||||
return (
|
||||
@@ -272,6 +274,7 @@ export const columns = [
|
||||
accessorKey: 'displayName',
|
||||
size: 190,
|
||||
header: () => t('table.feed.user'),
|
||||
meta: { label: () => t('table.feed.user') },
|
||||
cell: ({ row }) => {
|
||||
const { showUserDialog } = useUserStore();
|
||||
const original = row.original;
|
||||
@@ -291,7 +294,8 @@ export const columns = [
|
||||
enableSorting: false,
|
||||
minSize: 100,
|
||||
meta: {
|
||||
stretch: true
|
||||
stretch: true,
|
||||
label: () => t('table.feed.detail')
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const original = row.original;
|
||||
|
||||
@@ -17,24 +17,27 @@ import {
|
||||
|
||||
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 compareNumbers = (a, b) => (a ?? 0) - (b ?? 0);
|
||||
|
||||
@@ -143,10 +146,11 @@ export const createColumns = ({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('table.friendList.no'),
|
||||
label: () => t('table.friendList.no'),
|
||||
descFirst: true
|
||||
}),
|
||||
size: 100,
|
||||
meta: { label: () => t('table.friendList.no') },
|
||||
sortingFn: sortByNumber((row) => row?.$friendNumber ?? 0),
|
||||
cell: ({ row }) => <span>{row.original?.$friendNumber || ''}</span>
|
||||
},
|
||||
@@ -156,6 +160,7 @@ export const createColumns = ({
|
||||
header: () => t('table.friendList.avatar'),
|
||||
size: 90,
|
||||
enableSorting: false,
|
||||
meta: { label: () => t('table.friendList.avatar') },
|
||||
cell: ({ row }) => {
|
||||
const src = userImage(row.original, true);
|
||||
return src ? (
|
||||
@@ -175,9 +180,10 @@ export const createColumns = ({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('table.friendList.displayName')
|
||||
label: () => t('table.friendList.displayName')
|
||||
}),
|
||||
size: 200,
|
||||
meta: { label: () => t('table.friendList.displayName') },
|
||||
sortingFn: sortByString((row) => row?.displayName ?? ''),
|
||||
cell: ({ row }) => {
|
||||
const style = randomUserColours?.value
|
||||
@@ -196,9 +202,10 @@ export const createColumns = ({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('table.friendList.rank')
|
||||
label: () => t('table.friendList.rank')
|
||||
}),
|
||||
size: 140,
|
||||
meta: { label: () => t('table.friendList.rank') },
|
||||
sortingFn: sortByNumber((row) => row?.$trustSortNum ?? 0),
|
||||
cell: ({ row }) => {
|
||||
if (randomUserColours?.value) {
|
||||
@@ -222,11 +229,15 @@ export const createColumns = ({
|
||||
id: 'status',
|
||||
accessorFn: (row) => row?.status,
|
||||
header: ({ column }) =>
|
||||
sortButton({ column, label: t('table.friendList.status') }),
|
||||
sortButton({
|
||||
column,
|
||||
label: () => t('table.friendList.status')
|
||||
}),
|
||||
minSize: 200,
|
||||
sortingFn: sortByStatus,
|
||||
meta: {
|
||||
stretch: true
|
||||
stretch: true,
|
||||
label: () => t('table.friendList.status')
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const status = row.original?.status;
|
||||
@@ -250,8 +261,12 @@ export const createColumns = ({
|
||||
id: 'language',
|
||||
accessorFn: (row) => row?.$languages,
|
||||
header: ({ column }) =>
|
||||
sortButton({ column, label: t('table.friendList.language') }),
|
||||
sortButton({
|
||||
column,
|
||||
label: () => t('table.friendList.language')
|
||||
}),
|
||||
size: 130,
|
||||
meta: { label: () => t('table.friendList.language') },
|
||||
sortingFn: sortByLanguages,
|
||||
cell: ({ row }) => (
|
||||
<div class="flex items-center">
|
||||
@@ -279,6 +294,7 @@ export const createColumns = ({
|
||||
header: () => t('table.friendList.bioLink'),
|
||||
size: 130,
|
||||
enableSorting: false,
|
||||
meta: { label: () => t('table.friendList.bioLink') },
|
||||
cell: ({ row }) => (
|
||||
<div class="flex items-center">
|
||||
{(row.original?.bioLinks ?? [])
|
||||
@@ -305,12 +321,13 @@ export const createColumns = ({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('table.friendList.joinCount')
|
||||
label: () => t('table.friendList.joinCount')
|
||||
}),
|
||||
size: 120,
|
||||
sortingFn: sortByNumber((row) => row?.$joinCount ?? 0),
|
||||
meta: {
|
||||
class: 'text-right'
|
||||
class: 'text-right',
|
||||
label: () => t('table.friendList.joinCount')
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -319,12 +336,13 @@ export const createColumns = ({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('table.friendList.timeTogether')
|
||||
label: () => t('table.friendList.timeTogether')
|
||||
}),
|
||||
size: 140,
|
||||
sortingFn: sortByNumber((row) => row?.$timeSpent ?? 0),
|
||||
meta: {
|
||||
class: 'text-right'
|
||||
class: 'text-right',
|
||||
label: () => t('table.friendList.timeTogether')
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const time = row.original?.$timeSpent;
|
||||
@@ -337,9 +355,10 @@ export const createColumns = ({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('table.friendList.lastSeen')
|
||||
label: () => t('table.friendList.lastSeen')
|
||||
}),
|
||||
size: 170,
|
||||
meta: { label: () => t('table.friendList.lastSeen') },
|
||||
sortingFn: sortByString((row) => row?.$lastSeen ?? ''),
|
||||
cell: ({ row }) => {
|
||||
const text = formatDateFilter(row.original?.$lastSeen, 'long');
|
||||
@@ -352,12 +371,13 @@ export const createColumns = ({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('table.friendList.mutualFriends')
|
||||
label: () => t('table.friendList.mutualFriends')
|
||||
}),
|
||||
size: 120,
|
||||
sortingFn: sortByNumber((row) => row?.$mutualCount ?? 0),
|
||||
meta: {
|
||||
class: 'text-right'
|
||||
class: 'text-right',
|
||||
label: () => t('table.friendList.mutualFriends')
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const count = row.original?.$mutualCount;
|
||||
@@ -370,9 +390,10 @@ export const createColumns = ({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('table.friendList.lastActivity')
|
||||
label: () => t('table.friendList.lastActivity')
|
||||
}),
|
||||
size: 200,
|
||||
meta: { label: () => t('table.friendList.lastActivity') },
|
||||
sortingFn: sortByString((row) => row?.last_activity ?? ''),
|
||||
cell: ({ row }) => (
|
||||
<span>
|
||||
@@ -384,8 +405,12 @@ export const createColumns = ({
|
||||
id: 'lastLogin',
|
||||
accessorFn: (row) => row?.last_login,
|
||||
header: ({ column }) =>
|
||||
sortButton({ column, label: t('table.friendList.lastLogin') }),
|
||||
sortButton({
|
||||
column,
|
||||
label: () => t('table.friendList.lastLogin')
|
||||
}),
|
||||
size: 200,
|
||||
meta: { label: () => t('table.friendList.lastLogin') },
|
||||
sortingFn: sortByString((row) => row?.last_login ?? ''),
|
||||
cell: ({ row }) => (
|
||||
<span>
|
||||
@@ -399,9 +424,10 @@ export const createColumns = ({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('table.friendList.dateJoined')
|
||||
label: () => t('table.friendList.dateJoined')
|
||||
}),
|
||||
size: 120,
|
||||
meta: { label: () => t('table.friendList.dateJoined') },
|
||||
sortingFn: sortByString((row) => row?.date_joined ?? ''),
|
||||
cell: ({ row }) => <span>{row.original?.date_joined ?? ''}</span>
|
||||
},
|
||||
@@ -411,7 +437,8 @@ export const createColumns = ({
|
||||
size: 100,
|
||||
enableSorting: false,
|
||||
meta: {
|
||||
class: 'text-center'
|
||||
class: 'text-center',
|
||||
label: t('table.friendList.unfriend')
|
||||
},
|
||||
cell: ({ row }) => (
|
||||
// TODO(icon): verify unfollow icon replacement
|
||||
|
||||
@@ -31,6 +31,7 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
|
||||
{
|
||||
accessorKey: 'created_at',
|
||||
size: 120,
|
||||
meta: { label: () => t('table.friendLog.date') },
|
||||
header: ({ column }) => (
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -64,6 +65,7 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
|
||||
|
||||
size: 160,
|
||||
header: () => t('table.friendLog.type'),
|
||||
meta: { label: () => t('table.friendLog.type') },
|
||||
cell: ({ row }) => {
|
||||
const type = row.getValue('type');
|
||||
return (
|
||||
@@ -79,7 +81,8 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
|
||||
minSize: 80,
|
||||
header: () => t('table.friendLog.user'),
|
||||
meta: {
|
||||
stretch: true
|
||||
stretch: true,
|
||||
label: () => t('table.friendLog.user')
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const original = row.original;
|
||||
@@ -113,7 +116,8 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
|
||||
{
|
||||
id: 'action',
|
||||
meta: {
|
||||
class: 'w-[80px] max-w-[80px] text-right'
|
||||
class: 'w-[80px] max-w-[80px] text-right',
|
||||
label: () => t('table.friendLog.action')
|
||||
},
|
||||
size: 80,
|
||||
maxSize: 80,
|
||||
|
||||
@@ -43,6 +43,7 @@ export const createColumns = ({ getCreatedAt, onDelete, onDeletePrompt }) => {
|
||||
accessorFn: (row) => getCreatedAt(row),
|
||||
id: 'created_at',
|
||||
size: 140,
|
||||
meta: { label: () => t('table.gameLog.date') },
|
||||
header: ({ column }) => (
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -70,6 +71,7 @@ export const createColumns = ({ getCreatedAt, onDelete, onDeletePrompt }) => {
|
||||
accessorKey: 'type',
|
||||
size: 150,
|
||||
header: () => t('table.gameLog.type'),
|
||||
meta: { label: () => t('table.gameLog.type') },
|
||||
cell: ({ row }) => {
|
||||
const original = row.original;
|
||||
const label = t(`view.game_log.filters.${original.type}`);
|
||||
@@ -94,6 +96,7 @@ export const createColumns = ({ getCreatedAt, onDelete, onDeletePrompt }) => {
|
||||
accessorKey: 'displayName',
|
||||
size: 200,
|
||||
header: () => t('table.gameLog.user'),
|
||||
meta: { label: () => t('table.gameLog.user') },
|
||||
cell: ({ row }) => {
|
||||
const original = row.original;
|
||||
const isFriend = original.isFriend;
|
||||
@@ -121,7 +124,8 @@ export const createColumns = ({ getCreatedAt, onDelete, onDeletePrompt }) => {
|
||||
enableSorting: false,
|
||||
minSize: 150,
|
||||
meta: {
|
||||
stretch: true
|
||||
stretch: true,
|
||||
label: () => t('table.gameLog.detail')
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const original = row.original;
|
||||
@@ -248,7 +252,8 @@ export const createColumns = ({ getCreatedAt, onDelete, onDeletePrompt }) => {
|
||||
{
|
||||
id: 'action',
|
||||
meta: {
|
||||
class: 'text-right'
|
||||
class: 'text-right',
|
||||
label: () => t('table.gameLog.action')
|
||||
},
|
||||
size: 90,
|
||||
minSize: 90,
|
||||
|
||||
@@ -32,6 +32,7 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
|
||||
{
|
||||
accessorKey: 'created',
|
||||
size: 120,
|
||||
meta: { label: () => t('table.moderation.date') },
|
||||
header: ({ column }) => (
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -64,6 +65,7 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
|
||||
accessorKey: 'type',
|
||||
size: 140,
|
||||
header: () => t('table.moderation.type'),
|
||||
meta: { label: () => t('table.moderation.type') },
|
||||
cell: ({ row }) => {
|
||||
const type = row.getValue('type');
|
||||
const typeKey = `view.moderation.filters.${type}`;
|
||||
@@ -79,7 +81,8 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
|
||||
{
|
||||
accessorKey: 'sourceDisplayName',
|
||||
meta: {
|
||||
class: 'overflow-hidden'
|
||||
class: 'overflow-hidden',
|
||||
label: () => t('table.moderation.source')
|
||||
},
|
||||
size: 120,
|
||||
header: () => t('table.moderation.source'),
|
||||
@@ -100,7 +103,8 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
|
||||
size: 200,
|
||||
minSize: 80,
|
||||
meta: {
|
||||
stretch: true
|
||||
stretch: true,
|
||||
label: () => t('table.moderation.target')
|
||||
},
|
||||
header: () => t('table.moderation.target'),
|
||||
cell: ({ row }) => {
|
||||
@@ -118,7 +122,8 @@ export const createColumns = ({ onDelete, onDeletePrompt }) => {
|
||||
{
|
||||
id: 'action',
|
||||
meta: {
|
||||
class: 'text-right'
|
||||
class: 'text-right',
|
||||
label: () => t('table.moderation.action')
|
||||
},
|
||||
size: 80,
|
||||
minSize: 80,
|
||||
|
||||
@@ -31,24 +31,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>
|
||||
);
|
||||
};
|
||||
|
||||
export function getColumns({
|
||||
onShowAvatarDialog,
|
||||
@@ -102,8 +105,12 @@ export function getColumns({
|
||||
id: 'name',
|
||||
accessorKey: 'Name',
|
||||
header: ({ column }) =>
|
||||
sortButton({ column, label: t('dialog.avatar.info.name') }),
|
||||
sortButton({
|
||||
column,
|
||||
label: () => t('dialog.avatar.info.name')
|
||||
}),
|
||||
size: 200,
|
||||
meta: { label: () => t('dialog.avatar.info.name') },
|
||||
cell: ({ row }) => {
|
||||
const ref = row.original;
|
||||
return (
|
||||
@@ -124,6 +131,7 @@ export function getColumns({
|
||||
header: () => t('dialog.avatar.info.platform'),
|
||||
size: 120,
|
||||
enableSorting: false,
|
||||
meta: { label: () => t('dialog.avatar.info.platform') },
|
||||
cell: ({ row }) => {
|
||||
const ref = row.original;
|
||||
const platforms = getAvailablePlatforms(ref.unityPackages);
|
||||
@@ -160,6 +168,7 @@ export function getColumns({
|
||||
header: () => t('dialog.avatar.info.tags'),
|
||||
size: 150,
|
||||
enableSorting: false,
|
||||
meta: { label: () => t('dialog.avatar.info.tags') },
|
||||
cell: ({ row }) => {
|
||||
const tags = row.original.$tags || [];
|
||||
if (!tags.length) return null;
|
||||
@@ -198,6 +207,7 @@ export function getColumns({
|
||||
accessorKey: 'releaseStatus',
|
||||
header: () => t('dialog.avatar.tags.public'),
|
||||
size: 120,
|
||||
meta: { label: () => t('dialog.avatar.tags.public') },
|
||||
cell: ({ row }) => {
|
||||
const ref = row.original;
|
||||
return (
|
||||
@@ -215,12 +225,13 @@ export function getColumns({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('dialog.avatar.info.time_spent'),
|
||||
label: () => t('dialog.avatar.info.time_spent'),
|
||||
descFirst: true
|
||||
}),
|
||||
size: 140,
|
||||
meta: {
|
||||
class: 'text-right'
|
||||
class: 'text-right',
|
||||
label: () => t('dialog.avatar.info.time_spent')
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const time = row.original?.$timeSpent;
|
||||
@@ -237,12 +248,13 @@ export function getColumns({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('dialog.avatar.info.version'),
|
||||
label: () => t('dialog.avatar.info.version'),
|
||||
descFirst: true
|
||||
}),
|
||||
size: 90,
|
||||
meta: {
|
||||
class: 'text-right'
|
||||
class: 'text-right',
|
||||
label: () => t('dialog.avatar.info.version')
|
||||
},
|
||||
cell: ({ row }) => (
|
||||
<span class=" text-sm">{row.original.version ?? '-'}</span>
|
||||
@@ -255,9 +267,10 @@ export function getColumns({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('dialog.avatar.info.pc_performance')
|
||||
label: () => t('dialog.avatar.info.pc_performance')
|
||||
}),
|
||||
size: 140,
|
||||
meta: { label: () => t('dialog.avatar.info.pc_performance') },
|
||||
cell: ({ row }) => {
|
||||
const perf = getPlatformInfo(row.original.unityPackages)?.pc
|
||||
?.performanceRating;
|
||||
@@ -276,9 +289,10 @@ export function getColumns({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('dialog.avatar.info.android_performance')
|
||||
label: () => t('dialog.avatar.info.android_performance')
|
||||
}),
|
||||
size: 140,
|
||||
meta: { label: () => t('dialog.avatar.info.android_performance') },
|
||||
cell: ({ row }) => {
|
||||
const perf = getPlatformInfo(row.original.unityPackages)
|
||||
?.android?.performanceRating;
|
||||
@@ -297,9 +311,10 @@ export function getColumns({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('dialog.avatar.info.ios_performance')
|
||||
label: () => t('dialog.avatar.info.ios_performance')
|
||||
}),
|
||||
size: 140,
|
||||
meta: { label: () => t('dialog.avatar.info.ios_performance') },
|
||||
cell: ({ row }) => {
|
||||
const perf = getPlatformInfo(row.original.unityPackages)?.ios
|
||||
?.performanceRating;
|
||||
@@ -316,10 +331,11 @@ export function getColumns({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('dialog.avatar.info.last_updated'),
|
||||
label: () => t('dialog.avatar.info.last_updated'),
|
||||
descFirst: true
|
||||
}),
|
||||
size: 160,
|
||||
meta: { label: () => t('dialog.avatar.info.last_updated') },
|
||||
cell: ({ row }) => {
|
||||
const ref = row.original;
|
||||
return (
|
||||
@@ -335,10 +351,11 @@ export function getColumns({
|
||||
header: ({ column }) =>
|
||||
sortButton({
|
||||
column,
|
||||
label: t('dialog.avatar.info.created_at'),
|
||||
label: () => t('dialog.avatar.info.created_at'),
|
||||
descFirst: true
|
||||
}),
|
||||
size: 160,
|
||||
meta: { label: () => t('dialog.avatar.info.created_at') },
|
||||
cell: ({ row }) => {
|
||||
const ref = row.original;
|
||||
return (
|
||||
|
||||
@@ -102,6 +102,7 @@ export const createColumns = ({
|
||||
accessorFn: (row) => getNotificationCreatedAtTs(row),
|
||||
id: 'created_at',
|
||||
size: 120,
|
||||
meta: { label: () => t('table.notification.date') },
|
||||
header: ({ column }) => (
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -151,6 +152,7 @@ export const createColumns = ({
|
||||
accessorKey: 'type',
|
||||
size: 180,
|
||||
header: () => t('table.notification.type'),
|
||||
meta: { label: () => t('table.notification.type') },
|
||||
cell: ({ row }) => {
|
||||
const original = row.original;
|
||||
const typeKey = `view.notification.filters.${original.type}`;
|
||||
@@ -228,7 +230,8 @@ export const createColumns = ({
|
||||
{
|
||||
accessorKey: 'senderUsername',
|
||||
meta: {
|
||||
class: 'overflow-hidden'
|
||||
class: 'overflow-hidden',
|
||||
label: () => t('table.notification.user')
|
||||
},
|
||||
size: 150,
|
||||
header: () => t('table.notification.user'),
|
||||
@@ -284,7 +287,8 @@ export const createColumns = ({
|
||||
{
|
||||
accessorKey: 'groupName',
|
||||
meta: {
|
||||
class: 'overflow-hidden'
|
||||
class: 'overflow-hidden',
|
||||
label: () => t('table.notification.group')
|
||||
},
|
||||
size: 150,
|
||||
header: () => t('table.notification.group'),
|
||||
@@ -390,6 +394,7 @@ export const createColumns = ({
|
||||
accessorKey: 'photo',
|
||||
size: 80,
|
||||
header: () => t('table.notification.photo'),
|
||||
meta: { label: () => t('table.notification.photo') },
|
||||
cell: ({ row }) => {
|
||||
const original = row.original;
|
||||
if (original.type === 'boop') {
|
||||
@@ -458,7 +463,8 @@ export const createColumns = ({
|
||||
enableSorting: false,
|
||||
meta: {
|
||||
class: 'min-w-0 overflow-hidden',
|
||||
stretch: true
|
||||
stretch: true,
|
||||
label: () => t('table.notification.message')
|
||||
},
|
||||
minSize: 100,
|
||||
cell: ({ row }) => {
|
||||
@@ -548,7 +554,8 @@ export const createColumns = ({
|
||||
{
|
||||
id: 'action',
|
||||
meta: {
|
||||
class: 'text-right'
|
||||
class: 'text-right',
|
||||
label: () => t('table.notification.action')
|
||||
},
|
||||
size: 120,
|
||||
minSize: 120,
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
Reference in New Issue
Block a user