Skip to content
Draft
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
2 changes: 1 addition & 1 deletion src/app/configure-tasks-app/ui/TemplateSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const TemplateSidebar = ({
const currentWorkflowState = workflowStates.find((el) => el?.id === currentTask?.workflowStateId)
updateStatusValue(currentWorkflowState)
}
}, [activeTemplate, workflowStates])
}, [activeTemplate, workflowStates, updateStatusValue])

const windowWidth = useWindowWidth()
const isMobile = windowWidth < 800 && windowWidth !== 0
Expand Down
71 changes: 71 additions & 0 deletions src/hooks/useHandleSelectorComponent.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { act } from 'react'
import { useEffect } from 'react'
import { JSDOM } from 'jsdom'
import type { SelectorType } from '@/components/inputs/Selector'
import { useHandleSelectorComponent } from '@/hooks/useHandleSelectorComponent'

const initialItem = { id: 'initial' }
const updatedItem = { id: 'updated' }
const templateSelector = 'templateSelected' as SelectorType

const setupDom = () => {
const dom = new JSDOM('<!doctype html><html><body></body></html>', { url: 'http://localhost' })
const previousWindow = globalThis.window
const previousDocument = globalThis.document
const previousNavigator = globalThis.navigator
const previousActEnvironment = Object.getOwnPropertyDescriptor(globalThis, 'IS_REACT_ACT_ENVIRONMENT')

Object.defineProperty(globalThis, 'window', { configurable: true, value: dom.window })
Object.defineProperty(globalThis, 'document', { configurable: true, value: dom.window.document })
Object.defineProperty(globalThis, 'navigator', { configurable: true, value: dom.window.navigator })
Object.defineProperty(globalThis, 'IS_REACT_ACT_ENVIRONMENT', { configurable: true, value: true })

return () => {
Object.defineProperty(globalThis, 'window', { configurable: true, value: previousWindow })
Object.defineProperty(globalThis, 'document', { configurable: true, value: previousDocument })
Object.defineProperty(globalThis, 'navigator', { configurable: true, value: previousNavigator })
if (previousActEnvironment) {
Object.defineProperty(globalThis, 'IS_REACT_ACT_ENVIRONMENT', previousActEnvironment)
} else {
Reflect.deleteProperty(globalThis, 'IS_REACT_ACT_ENVIRONMENT')
}
dom.window.close()
}
}

describe('useHandleSelectorComponent', () => {
it('keeps the imperative updater stable after local selector state changes', async () => {
const cleanupDom = setupDom()
const { createRoot } = await import('react-dom/client')
const container = document.createElement('div')
document.body.appendChild(container)
const root = createRoot(container)
const effectRuns = jest.fn()

const Probe = () => {
const { updateRenderingItem } = useHandleSelectorComponent({
item: initialItem,
type: templateSelector,
})

useEffect(() => {
effectRuns()
updateRenderingItem(updatedItem)
}, [updateRenderingItem])

return null
}

await act(async () => {
root.render(<Probe />)
})

expect(effectRuns).toHaveBeenCalledTimes(1)

act(() => {
root.unmount()
})
container.remove()
cleanupDom()
})
})
6 changes: 3 additions & 3 deletions src/hooks/useHandleSelectorComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { setCreateTemplateFields } from '@/redux/features/templateSlice'
import store from '@/redux/store'
import { WorkflowStateResponse } from '@/types/dto/workflowStates.dto'
import { HandleSelectorComponentModes } from '@/types/interfaces'
import { useEffect, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'

export const useHandleSelectorComponent = ({
item,
Expand All @@ -17,9 +17,9 @@ export const useHandleSelectorComponent = ({
}) => {
const [renderingItem, setRenderingItem] = useState<unknown>(item)

const updateRenderingItem = (newValue: unknown) => {
const updateRenderingItem = useCallback((newValue: unknown) => {
setRenderingItem(newValue)
}
}, [])

useEffect(() => {
//item can be null and we don't want this block to run if item is null, thus we are doing the below check for item
Expand Down
Loading