diff --git a/CHANGELOG.md b/CHANGELOG.md index fb4833b14..d3c1dcd2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/components/formStore/table/getVersionedState.ts b/src/components/formStore/table/getVersionedState.ts index e1ed56972..e04ac82dd 100644 --- a/src/components/formStore/table/getVersionedState.ts +++ b/src/components/formStore/table/getVersionedState.ts @@ -1,4 +1,5 @@ import { TableState, VisibilityState } from '@tanstack/react-table' +import { FormTypes } from '@oneblink/types' const defaultHiddenColumns = [ { @@ -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 = @@ -25,9 +48,13 @@ export type FormTableState = Partial & { 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 @@ -44,7 +71,12 @@ export const getVersionedFormTableState = ( if (!state.columnVisibility) { state.columnVisibility = defaultHiddenColumns.reduce( (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 @@ -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) } } diff --git a/src/components/formStore/table/useFormStoreTable.tsx b/src/components/formStore/table/useFormStoreTable.tsx index 99c8306ec..cf5bbf969 100644 --- a/src/components/formStore/table/useFormStoreTable.tsx +++ b/src/components/formStore/table/useFormStoreTable.tsx @@ -822,13 +822,12 @@ export default function useFormStoreTable({ const [initialState] = React.useState(() => { 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(() => { diff --git a/tests/components/form-store/table.test.ts b/tests/components/form-store/table.test.ts index 2b290ea63..3c1157798 100644 --- a/tests/components/form-store/table.test.ts +++ b/tests/components/form-store/table.test.ts @@ -1,9 +1,43 @@ +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 = { @@ -11,7 +45,10 @@ describe('getVersionedFormTableState', () => { hiddenColumns: ['FORM_COLUMN'], defaultHiddenColumnsVersion: latestStateVersion, } - const updatedState = getVersionedFormTableState(initialState) + const updatedState = getVersionedFormTableState({ + form: formWithoutEvents, + initialState, + }) expect(updatedState).toEqual({ ...initialState, columnVisibility: { FORM_COLUMN: false }, @@ -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: { @@ -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'], @@ -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'], @@ -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 }, + }) + }) + }) })