Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: "npm"
Expand All @@ -26,9 +26,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: "npm"
Expand All @@ -43,9 +43,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: ".nvmrc"
cache: "npm"
Expand Down
51 changes: 31 additions & 20 deletions app/components/atoms/DataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,27 @@ const emit = defineEmits<{
invalidate: []
}>()

const props = defineProps<{
columns: ColumnDef<any, any>[]
data: any[]
loading: boolean
options?: Partial<TableOptions<any>>
emptyMessage?: string
permission?: boolean | ((item: any) => Promise<boolean>)
expandedMarkup?: (row: Row<any>) => VNode
}>()
const props = withDefaults(
defineProps<{
columns: ColumnDef<any, any>[]
data: any[]
loading: boolean
options?: Partial<TableOptions<any>>
emptyMessage?: string
permission?: boolean | ((item: any) => Promise<boolean>)
expandedMarkup?: (row: Row<any>) => VNode
pageSize?: number
}>(),
{
pageSize: 10,
},
)

const globalFilter = ref<string>('')
const sorting = ref<SortingState>(props.options?.initialState?.sorting || [])
const pagination = ref<PaginationState>({ pageIndex: 0, pageSize: 10 })
const pagination = ref<PaginationState>({ pageIndex: 0, pageSize: props.pageSize })
const rowSelectionPermissions = ref<Record<string, boolean>>({})
const permissionFetchVersion = ref(0)

// Convert 0-based to 1-based for Radix
const internalPage = computed({
Expand All @@ -31,18 +38,19 @@ const internalPage = computed({
const selectedRowLength = computed(() => table.getSelectedRowModel().rows.length)

watch(
() => props.data?.length,
async (length) => {
if (length) await fetchPermissions()
},
{ immediate: true },
)
() => ({
permission: props.permission,
ids: (props.data || []).map(item => String(item.id)),
}),
async ({ ids }) => {
if (!ids.length) {
rowSelectionPermissions.value = {}
return
}

watch(
() => props.permission,
async () => {
if (props.data?.length) await fetchPermissions()
await fetchPermissions()
},
{ immediate: true },
)

const table = useVueTable({
Expand Down Expand Up @@ -79,6 +87,7 @@ const search = ref(table.getState().globalFilter)
watch(search, newValue => table.setGlobalFilter(newValue))

async function fetchPermissions() {
const currentFetchVersion = ++permissionFetchVersion.value
const permissions: Record<string, boolean> = {}

for (const item of props.data) {
Expand All @@ -87,6 +96,8 @@ async function fetchPermissions() {
else permissions[item.id] = true
}

if (currentFetchVersion !== permissionFetchVersion.value) return

rowSelectionPermissions.value = permissions
}
</script>
Expand Down
2 changes: 1 addition & 1 deletion app/components/ui/alert-dialog/AlertDialogAction.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const delegatedProps = computed(() => {
<template>
<AlertDialogAction
v-bind="delegatedProps"
:class="cn(buttonVariants({ variant: 'foreground' }), props.class)"
:class="cn(buttonVariants({ variant: 'destructive' }), props.class)"
>
<slot />
</AlertDialogAction>
Expand Down
2 changes: 1 addition & 1 deletion app/components/ui/alert-dialog/AlertDialogCancel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const delegatedProps = computed(() => {
<AlertDialogCancel
v-bind="delegatedProps"
:class="cn(
buttonVariants({ variant: 'destructive' }),
buttonVariants({ variant: 'foreground' }),
props.class,
)"
>
Expand Down
32 changes: 19 additions & 13 deletions app/pages/campaigns/[id]-[title]/homebrews.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const queryClient = useQueryClient()

const table = ref<InstanceType<typeof DataTable>>()
const limitCta = ref<InstanceType<typeof LimitCta>>()
const pageSize = 20
const max = 100

const hasRights = computed(() => props.isOwner || props.isAdmin)
Expand All @@ -29,19 +30,23 @@ const enableDateFetching = computed(() => props.fetchReady)
const { mutateAsync: removeHomebrew } = useHomebrewRemove()
const { data: count } = useHomebrewCount(props.campaignId, enableDateFetching)

const { data, status } = useHomebrewListing(computed(() => {
const pagination = table.value?.vueTable.getState().pagination
const sorting = table.value?.vueTable.getState().sorting
const search = table.value?.vueTable.getState().globalFilter

return {
search,
sortBy: sorting?.[0]?.id ?? initialState.sorting?.[0]?.id,
sortDesc: sorting?.[0]?.desc ?? initialState.sorting?.[0]?.desc,
page: pagination?.pageIndex ?? 0,
eq: { field: 'campaign', value: props.campaignId },
}
}), enableDateFetching)
const { data, status } = useHomebrewListing(
computed(() => {
const pagination = table.value?.vueTable.getState().pagination
const sorting = table.value?.vueTable.getState().sorting
const search = table.value?.vueTable.getState().globalFilter

return {
search,
sortBy: sorting?.[0]?.id ?? initialState.sorting?.[0]?.id,
sortDesc: sorting?.[0]?.desc ?? initialState.sorting?.[0]?.desc,
page: pagination?.pageIndex ?? 0,
eq: { field: 'campaign', value: props.campaignId },
}
}),
enableDateFetching,
pageSize,
)

const columns = generateColumns({
onUpdate: (item: HomebrewItemRow) => openModal(item),
Expand Down Expand Up @@ -97,6 +102,7 @@ function invalidateQueries(): void {
:columns="columns"
:data="data?.homebrews || []"
:total="data?.amount || 0"
:page-size="pageSize"
:loading="status === 'pending'"
:options="{
pageCount: data?.pages ?? -1,
Expand Down
32 changes: 19 additions & 13 deletions app/pages/campaigns/[id]-[title]/notes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const { startCoolDown, isInCoolDown, getRemainingTime } = useCoolDown()
const queryClient = useQueryClient()

const table = ref<InstanceType<typeof DataTable>>()
const pageSize = 20
const max = 100

const hasRights = computed(() => props.isOwner || props.isAdmin)
Expand All @@ -32,19 +33,23 @@ const enableDateFetching = computed(() => props.fetchReady)
const { data: count } = useNoteCount(props.campaignId, enableDateFetching)
const { mutateAsync: removeNote } = useNoteRemove()

const { data, status } = useNoteListing(computed(() => {
const pagination = table.value?.vueTable.getState().pagination
const sorting = table.value?.vueTable.getState().sorting
const search = table.value?.vueTable.getState().globalFilter

return {
search,
sortBy: sorting?.[0]?.id ?? initialState.sorting?.[0]?.id,
sortDesc: sorting?.[0]?.desc ?? initialState.sorting?.[0]?.desc,
page: pagination?.pageIndex ?? 0,
eq: { field: 'campaign', value: props.campaignId },
}
}), enableDateFetching)
const { data, status } = useNoteListing(
computed(() => {
const pagination = table.value?.vueTable.getState().pagination
const sorting = table.value?.vueTable.getState().sorting
const search = table.value?.vueTable.getState().globalFilter

return {
search,
sortBy: sorting?.[0]?.id ?? initialState.sorting?.[0]?.id,
sortDesc: sorting?.[0]?.desc ?? initialState.sorting?.[0]?.desc,
page: pagination?.pageIndex ?? 0,
eq: { field: 'campaign', value: props.campaignId },
}
}),
enableDateFetching,
pageSize,
)

const columns = generateColumns({
onUpdate: (item: NoteRow) => openModal(item),
Expand Down Expand Up @@ -135,6 +140,7 @@ async function sendNoteAsMail(note: NoteRow, addresses: string[]): Promise<void>
:columns="columns"
:data="data?.notes || []"
:total="data?.amount || 0"
:page-size="pageSize"
:loading="status === 'pending'"
:options="{
pageCount: data?.pages ?? -1,
Expand Down
25 changes: 25 additions & 0 deletions constants/changelogs/v2-1-4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"version": "v2.1.4",
"date": "2026-04-07",
"features": [
{
"title": "Improvements",
"items": [
{
"text": "Updated page size to 20 items for campaign homebrew and notes"
}
]
},
{
"title": "Bug fixes",
"items": [
{
"text": "Permission check wasn't redone when a item was removed from the table and another item was added, causing the new item to have incorrect permissions until the page was refreshed"
},
{
"text": "Alert dialog action and cancel buttons had the wrong color variants, making the cancel button look like a destructive action"
}
]
}
]
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dnd-tracker",
"version": "2.1.3",
"version": "2.1.4",
"private": true,
"type": "module",
"scripts": {
Expand Down Expand Up @@ -111,4 +111,4 @@
"lint-staged": {
"*.{js,ts,vue}": "eslint --fix"
}
}
}