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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- hide calendar booking and payment columns in form store if no corresponding events exist

## [13.0.0] - 2026-09-15

### Added
Expand Down
47 changes: 42 additions & 5 deletions src/components/formStore/table/getVersionedState.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { TableState, VisibilityState } from '@tanstack/react-table'
import { FormTypes } from '@oneblink/types'

const defaultHiddenColumns = [
{
Expand All @@ -13,6 +14,28 @@ const defaultHiddenColumns = [
version: 'V2',
hiddenColumns: ['COMPLETED_AT'],
},
{
version: 'V3',
hiddenColumns: (form: FormTypes.Form) => {
const columns = []
if (!form.schedulingEvents?.length) {
columns.push(
'CALENDAR_EVENT_TITLE',
'CALENDAR_EVENT_CALENDAR_NAME',
'CALENDAR_EVENT_DATE_TIME',
'CALENDAR_EVENT_CANCELLED_REASON',
)
}
if (!form.paymentEvents?.length) {
columns.push(
'PAYMENT_STATUS',
'PAYMENT_PROVIDER_TRANSACTION_ID',
'PAYMENT_PROVIDER_RECEIPT_NUMBER',
)
}
return columns
},
},
]

export const latestStateVersion =
Expand All @@ -25,9 +48,13 @@ export type FormTableState = Partial<TableState> & {
formId: number
}

export const getVersionedFormTableState = (
initialState: FormTableState,
): FormTableState => {
export const getVersionedFormTableState = ({
form,
initialState,
}: {
form: FormTypes.Form
initialState: FormTableState
}): FormTableState => {
const state = { ...initialState }

// carry over deprecated hiddenColumns to columnVisibility
Expand All @@ -44,7 +71,12 @@ export const getVersionedFormTableState = (
if (!state.columnVisibility) {
state.columnVisibility = defaultHiddenColumns.reduce<VisibilityState>(
(memo, defaultHiddenColumn) => {
defaultHiddenColumn.hiddenColumns.forEach((column) => {
const hiddenColumns =
typeof defaultHiddenColumn.hiddenColumns === 'function'
? defaultHiddenColumn.hiddenColumns(form)
: defaultHiddenColumn.hiddenColumns

hiddenColumns.forEach((column) => {
memo[column] = false
})
return memo
Expand All @@ -62,8 +94,13 @@ export const getVersionedFormTableState = (
continue
}

const hiddenColumns =
typeof defaultHiddenColumn.hiddenColumns === 'function'
? defaultHiddenColumn.hiddenColumns(form)
: defaultHiddenColumn.hiddenColumns

if (foundVersion) {
for (const hiddenColumn of defaultHiddenColumn.hiddenColumns) {
for (const hiddenColumn of hiddenColumns) {
columnsSet.add(hiddenColumn)
}
}
Expand Down
13 changes: 6 additions & 7 deletions src/components/formStore/table/useFormStoreTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -822,13 +822,12 @@ export default function useFormStoreTable({

const [initialState] = React.useState<FormTableState | undefined>(() => {
const text = localStorage.getItem(localStorageKey(form.id))
return getVersionedFormTableState(
text
? JSON.parse(text)
: {
formId: form.id,
},
)
const initialState = text
? JSON.parse(text)
: {
formId: form.id,
}
return getVersionedFormTableState({ form, initialState })
})

const transformedSorting = React.useMemo(() => {
Expand Down
173 changes: 169 additions & 4 deletions tests/components/form-store/table.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,54 @@
import { FormTypes } from '@oneblink/types'
import { expect, it, describe } from 'vitest'
import getVersionedFormTableState, {
FormTableState,
latestStateVersion,
} from '../../../src/components/formStore/table/getVersionedState'

const createForm = ({
hasSchedulingEvents = false,
hasPaymentEvents = false,
}: {
hasSchedulingEvents?: boolean
hasPaymentEvents?: boolean
} = {}) =>
({
id: 1,
schedulingEvents: hasSchedulingEvents ? [{}] : [],
paymentEvents: hasPaymentEvents ? [{}] : [],
}) as FormTypes.Form

const formWithEvents = createForm({
hasSchedulingEvents: true,
hasPaymentEvents: true,
})

const formWithoutEvents = createForm()

const calendarEventHiddenColumnVisibility = {
CALENDAR_EVENT_TITLE: false,
CALENDAR_EVENT_CALENDAR_NAME: false,
CALENDAR_EVENT_DATE_TIME: false,
CALENDAR_EVENT_CANCELLED_REASON: false,
}

const paymentHiddenColumnVisibility = {
PAYMENT_STATUS: false,
PAYMENT_PROVIDER_TRANSACTION_ID: false,
PAYMENT_PROVIDER_RECEIPT_NUMBER: false,
}

describe('getVersionedFormTableState', () => {
it('should return the same state if defaultHiddenColumnsVersion is the latest', () => {
const initialState: FormTableState = {
formId: 1,
hiddenColumns: ['FORM_COLUMN'],
defaultHiddenColumnsVersion: latestStateVersion,
}
const updatedState = getVersionedFormTableState(initialState)
const updatedState = getVersionedFormTableState({
form: formWithoutEvents,
initialState,
})
expect(updatedState).toEqual({
...initialState,
columnVisibility: { FORM_COLUMN: false },
Expand All @@ -22,7 +59,10 @@ describe('getVersionedFormTableState', () => {
const initialState: FormTableState = {
formId: 1,
}
const updatedState = getVersionedFormTableState(initialState)
const updatedState = getVersionedFormTableState({
form: formWithEvents,
initialState,
})
expect(updatedState).toEqual({
...initialState,
columnVisibility: {
Expand All @@ -43,7 +83,10 @@ describe('getVersionedFormTableState', () => {
formId: 1,
hiddenColumns: ['EXTERNAL_ID'],
}
const updatedState = getVersionedFormTableState(initialState)
const updatedState = getVersionedFormTableState({
form: formWithEvents,
initialState,
})
expect(updatedState).toEqual({
...initialState,
hiddenColumns: ['EXTERNAL_ID'],
Expand All @@ -65,7 +108,10 @@ describe('getVersionedFormTableState', () => {
hiddenColumns: ['SUBMISSION_ID', 'EXTERNAL_ID', 'TASK', 'FORM_COLUMN'],
defaultHiddenColumnsVersion: 'V1',
}
const updatedState = getVersionedFormTableState(initialState)
const updatedState = getVersionedFormTableState({
form: formWithEvents,
initialState,
})
expect(updatedState).toEqual({
...initialState,
hiddenColumns: ['SUBMISSION_ID', 'EXTERNAL_ID', 'TASK', 'FORM_COLUMN'],
Expand All @@ -79,4 +125,123 @@ describe('getVersionedFormTableState', () => {
},
})
})

describe('V3 dynamic hidden columns', () => {
it('should hide calendar and payment columns for a brand new state when the form does not have those events', () => {
const initialState: FormTableState = {
formId: 1,
}
const updatedState = getVersionedFormTableState({
form: formWithoutEvents,
initialState,
})
expect(updatedState).toEqual({
...initialState,
columnVisibility: {
SUBMISSION_ID: false,
EXTERNAL_ID: false,
TASK: false,
TASK_ACTION: false,
TASK_GROUP: false,
TASK_GROUP_INSTANCE: false,
COMPLETED_AT: false,
...calendarEventHiddenColumnVisibility,
...paymentHiddenColumnVisibility,
},
defaultHiddenColumnsVersion: latestStateVersion,
})
})

it('should only hide the dynamic columns that the form does not support for a brand new state', () => {
const initialState: FormTableState = {
formId: 1,
}
const updatedState = getVersionedFormTableState({
form: createForm({
hasSchedulingEvents: true,
hasPaymentEvents: false,
}),
initialState,
})
expect(updatedState).toEqual({
...initialState,
columnVisibility: {
SUBMISSION_ID: false,
EXTERNAL_ID: false,
TASK: false,
TASK_ACTION: false,
TASK_GROUP: false,
TASK_GROUP_INSTANCE: false,
COMPLETED_AT: false,
...paymentHiddenColumnVisibility,
},
defaultHiddenColumnsVersion: latestStateVersion,
})
})

it('should add dynamic hidden columns when upgrading from V2 if the form does not have those events', () => {
const initialState: FormTableState = {
formId: 1,
hiddenColumns: ['SUBMISSION_ID', 'EXTERNAL_ID', 'TASK', 'COMPLETED_AT'],
defaultHiddenColumnsVersion: 'V2',
}
const updatedState = getVersionedFormTableState({
form: formWithoutEvents,
initialState,
})
expect(updatedState).toEqual({
...initialState,
hiddenColumns: ['SUBMISSION_ID', 'EXTERNAL_ID', 'TASK', 'COMPLETED_AT'],
defaultHiddenColumnsVersion: latestStateVersion,
columnVisibility: {
SUBMISSION_ID: false,
EXTERNAL_ID: false,
TASK: false,
COMPLETED_AT: false,
...calendarEventHiddenColumnVisibility,
...paymentHiddenColumnVisibility,
},
})
})

it('should only hide the dynamic columns that the form does not support when upgrading from V2', () => {
const initialState: FormTableState = {
formId: 1,
hiddenColumns: ['SUBMISSION_ID'],
defaultHiddenColumnsVersion: 'V2',
}
const updatedState = getVersionedFormTableState({
form: createForm({
hasSchedulingEvents: true,
hasPaymentEvents: false,
}),
initialState,
})
expect(updatedState).toEqual({
...initialState,
hiddenColumns: ['SUBMISSION_ID'],
defaultHiddenColumnsVersion: latestStateVersion,
columnVisibility: {
SUBMISSION_ID: false,
...paymentHiddenColumnVisibility,
},
})
})

it('should not re-apply dynamic hidden columns if the state is already on V3', () => {
const initialState: FormTableState = {
formId: 1,
hiddenColumns: ['FORM_COLUMN'],
defaultHiddenColumnsVersion: 'V3',
}
const updatedState = getVersionedFormTableState({
form: formWithoutEvents,
initialState,
})
expect(updatedState).toEqual({
...initialState,
columnVisibility: { FORM_COLUMN: false },
})
})
})
})
Loading