@startsimpli/ui 0.4.6 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/__mocks__/next/link.js +11 -0
- package/src/components/ActivityTimeline.tsx +173 -0
- package/src/components/LogActivityDialog.tsx +303 -0
- package/src/components/QuickLogButtons.tsx +32 -0
- package/src/components/account/__tests__/account.test.tsx +315 -0
- package/src/components/badge/StageBadge.tsx +31 -0
- package/src/components/badge/index.ts +3 -0
- package/src/components/command-palette/CommandGroup.tsx +23 -0
- package/src/components/command-palette/CommandPalette.tsx +327 -0
- package/src/components/command-palette/CommandResultItem.tsx +59 -0
- package/src/components/command-palette/__tests__/CommandGroup.test.tsx +81 -0
- package/src/components/command-palette/__tests__/CommandResultItem.test.tsx +166 -0
- package/src/components/command-palette/__tests__/command-palette-context.test.tsx +166 -0
- package/src/components/command-palette/__tests__/useCommandPaletteSearch.test.ts +271 -0
- package/src/components/command-palette/command-palette-context.tsx +51 -0
- package/src/components/command-palette/index.ts +9 -0
- package/src/components/command-palette/useCommandPaletteSearch.ts +114 -0
- package/src/components/compose/__tests__/compose.test.tsx +656 -0
- package/src/components/compose/compose-header.tsx +72 -0
- package/src/components/compose/compose-loading.tsx +13 -0
- package/src/components/compose/index.ts +6 -0
- package/src/components/compose/save-status-indicator.tsx +57 -0
- package/src/components/compose/send-confirmation-dialog.tsx +87 -0
- package/src/components/compose/subject-input.tsx +25 -0
- package/src/components/compose/useAutoSave.ts +93 -0
- package/src/components/dashboard/DashboardGrid.tsx +32 -0
- package/src/components/dashboard/DashboardSection.tsx +32 -0
- package/src/components/dashboard/MetricCard.tsx +129 -0
- package/src/components/dashboard/PeriodSelector.tsx +55 -0
- package/src/components/dashboard/PipelineFunnel.tsx +126 -0
- package/src/components/dashboard/SparklineTrend.tsx +102 -0
- package/src/components/dashboard/TopCampaigns.tsx +132 -0
- package/src/components/dashboard/__tests__/dashboard.test.tsx +785 -0
- package/src/components/dashboard/index.ts +20 -0
- package/src/components/dialog/ConfirmDialog.tsx +72 -0
- package/src/components/dialog/__tests__/ConfirmDialog.test.tsx +126 -0
- package/src/components/dialog/index.ts +3 -0
- package/src/components/email-dialogs/__tests__/email-dialogs.test.tsx +982 -0
- package/src/components/email-dialogs/index.ts +14 -0
- package/src/components/email-dialogs/merge-fields.tsx +196 -0
- package/src/components/email-dialogs/preview-dialog.tsx +194 -0
- package/src/components/email-dialogs/schedule-dialog.tsx +297 -0
- package/src/components/email-dialogs/template-picker.tsx +225 -0
- package/src/components/email-dialogs/test-send-dialog.tsx +188 -0
- package/src/components/email-editor/BlockRenderer.tsx +120 -0
- package/src/components/email-editor/__tests__/BlockRenderer.test.tsx +332 -0
- package/src/components/email-editor/__tests__/block-renderers.test.ts +624 -0
- package/src/components/email-editor/__tests__/email-html-renderer.test.ts +376 -0
- package/src/components/email-editor/add-block-menu.tsx +151 -0
- package/src/components/email-editor/block-toolbar.tsx +73 -0
- package/src/components/email-editor/blocks/__tests__/blocks.test.tsx +818 -0
- package/src/components/email-editor/blocks/button-block.tsx +44 -0
- package/src/components/email-editor/blocks/divider-block.tsx +43 -0
- package/src/components/email-editor/blocks/footer-block.tsx +39 -0
- package/src/components/email-editor/blocks/header-block.tsx +39 -0
- package/src/components/email-editor/blocks/image-block.tsx +61 -0
- package/src/components/email-editor/blocks/index.ts +9 -0
- package/src/components/email-editor/blocks/metrics-block.tsx +198 -0
- package/src/components/email-editor/blocks/social-block.tsx +75 -0
- package/src/components/email-editor/blocks/spacer-block.tsx +26 -0
- package/src/components/email-editor/blocks/text-block.tsx +75 -0
- package/src/components/email-editor/editor-sidebar.tsx +66 -0
- package/src/components/email-editor/email-editor.tsx +497 -0
- package/src/components/email-editor/hooks/__tests__/useDragDrop.test.ts +355 -0
- package/src/components/email-editor/hooks/__tests__/useEmailEditorState.test.ts +551 -0
- package/src/components/email-editor/hooks/useDragDrop.ts +181 -0
- package/src/components/email-editor/hooks/useEmailEditorState.ts +426 -0
- package/src/components/email-editor/index.ts +51 -0
- package/src/components/email-editor/panels/BlockPropertyPanel.tsx +637 -0
- package/src/components/email-editor/panels/GlobalStylesPanel.tsx +108 -0
- package/src/components/email-editor/panels/SectionSettingsPanel.tsx +80 -0
- package/src/components/email-editor/panels/__tests__/BlockPropertyPanel.test.tsx +707 -0
- package/src/components/email-editor/panels/__tests__/GlobalStylesPanel.test.tsx +226 -0
- package/src/components/email-editor/panels/index.ts +3 -0
- package/src/components/email-editor/renderer/block-renderers.ts +209 -0
- package/src/components/email-editor/renderer/email-html-renderer.ts +128 -0
- package/src/components/email-editor/types.ts +413 -0
- package/src/components/email-editor/utils/defaults.ts +116 -0
- package/src/components/email-editor/utils/undo-redo.ts +59 -0
- package/src/components/enrichment/EnrichButton.tsx +33 -0
- package/src/components/enrichment/EnrichmentProgress.tsx +66 -0
- package/src/components/enrichment/QualityBadge.tsx +43 -0
- package/src/components/enrichment/__tests__/enrichment.test.tsx +184 -0
- package/src/components/enrichment/index.ts +8 -0
- package/src/components/gantt/GanttBoardView.tsx +71 -0
- package/src/components/gantt/GanttChart.tsx +140 -887
- package/src/components/gantt/GanttFilterBar.tsx +100 -0
- package/src/components/gantt/GanttListView.tsx +63 -0
- package/src/components/gantt/GanttTimelineView.tsx +215 -0
- package/src/components/gantt/__tests__/GanttBoardView.test.tsx +305 -0
- package/src/components/gantt/__tests__/GanttFilterBar.test.tsx +544 -0
- package/src/components/gantt/__tests__/GanttListView.test.tsx +337 -0
- package/src/components/gantt/__tests__/GanttTimelineView.test.tsx +375 -0
- package/src/components/gantt/__tests__/gantt-utils.test.ts +341 -0
- package/src/components/gantt/__tests__/useGanttState.test.ts +535 -0
- package/src/components/gantt/hooks/useGanttState.ts +644 -0
- package/src/components/gantt/index.ts +10 -0
- package/src/components/gantt/types.ts +5 -5
- package/src/components/index.ts +46 -0
- package/src/components/integrations/ConnectionStatus.tsx +77 -0
- package/src/components/integrations/IntegrationCard.tsx +92 -0
- package/src/components/integrations/__tests__/integrations.test.tsx +191 -0
- package/src/components/integrations/index.ts +5 -0
- package/src/components/kanban/KanbanBoard.tsx +103 -0
- package/src/components/kanban/__tests__/kanban.test.tsx +157 -0
- package/src/components/kanban/index.ts +2 -0
- package/src/components/lists/CreateListDialog.tsx +158 -0
- package/src/components/lists/ListCard.tsx +77 -0
- package/src/components/lists/__tests__/lists.test.tsx +263 -0
- package/src/components/lists/index.ts +5 -0
- package/src/components/loading/__tests__/loading.test.tsx +114 -0
- package/src/components/navigation/__tests__/navigation.test.tsx +194 -0
- package/src/components/pipeline/StageTransitionModal.tsx +146 -0
- package/src/components/pipeline/__tests__/pipeline.test.tsx +169 -0
- package/src/components/pipeline/index.ts +2 -0
- package/src/components/settings/SettingsCard.tsx +33 -0
- package/src/components/settings/SettingsLayout.tsx +28 -0
- package/src/components/settings/SettingsNav.tsx +42 -0
- package/src/components/settings/__tests__/settings.test.tsx +181 -0
- package/src/components/settings/index.ts +6 -0
- package/src/components/wizard/__tests__/wizard.test.tsx +97 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { render, screen, fireEvent } from '@testing-library/react'
|
|
2
|
+
import { GanttBoardView } from '../GanttBoardView'
|
|
3
|
+
import type { GanttBoardViewProps } from '../GanttBoardView'
|
|
4
|
+
import type { TimelineItem } from '../types'
|
|
5
|
+
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Helpers
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
function makeItem(overrides: Partial<TimelineItem> & { id: string; title: string; status: string }): TimelineItem {
|
|
11
|
+
return { startDate: '2025-01-01', endDate: '2025-03-31', ...overrides }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const CATEGORY_COLORS: Record<string, string> = {
|
|
15
|
+
product: '#3b82f6',
|
|
16
|
+
team: '#a855f7',
|
|
17
|
+
other: '#6b7280',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function defaultProps(overrides: Partial<GanttBoardViewProps> = {}): GanttBoardViewProps {
|
|
21
|
+
return {
|
|
22
|
+
boardColumns: [],
|
|
23
|
+
boardDragItem: null,
|
|
24
|
+
setBoardDragItem: jest.fn(),
|
|
25
|
+
onStatusChange: undefined,
|
|
26
|
+
categoryColors: CATEGORY_COLORS,
|
|
27
|
+
handleItemClick: jest.fn(),
|
|
28
|
+
...overrides,
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Column rendering
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
describe('GanttBoardView — column rendering', () => {
|
|
37
|
+
it('renders nothing when boardColumns is empty', () => {
|
|
38
|
+
const { container } = render(<GanttBoardView {...defaultProps()} />)
|
|
39
|
+
// The board wrapper div is rendered but contains no column children
|
|
40
|
+
expect(container.querySelector('.gantt-board-column')).not.toBeInTheDocument()
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('renders one column per status', () => {
|
|
44
|
+
const columns = [
|
|
45
|
+
{ status: 'not_started', items: [] },
|
|
46
|
+
{ status: 'in_progress', items: [] },
|
|
47
|
+
{ status: 'completed', items: [] },
|
|
48
|
+
]
|
|
49
|
+
const { container } = render(<GanttBoardView {...defaultProps({ boardColumns: columns })} />)
|
|
50
|
+
expect(container.querySelectorAll('.gantt-board-column')).toHaveLength(3)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('renders a status badge in each column header', () => {
|
|
54
|
+
const columns = [
|
|
55
|
+
{ status: 'not_started', items: [] },
|
|
56
|
+
{ status: 'in_progress', items: [] },
|
|
57
|
+
]
|
|
58
|
+
render(<GanttBoardView {...defaultProps({ boardColumns: columns })} />)
|
|
59
|
+
// Underscores are replaced with spaces in the badge
|
|
60
|
+
expect(screen.getByText('not started')).toBeInTheDocument()
|
|
61
|
+
expect(screen.getByText('in progress')).toBeInTheDocument()
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('displays the item count in each column header', () => {
|
|
65
|
+
const columns = [
|
|
66
|
+
{ status: 'not_started', items: [makeItem({ id: 'a', title: 'Task A', status: 'not_started' })] },
|
|
67
|
+
{ status: 'in_progress', items: [] },
|
|
68
|
+
]
|
|
69
|
+
render(<GanttBoardView {...defaultProps({ boardColumns: columns })} />)
|
|
70
|
+
// Count badges: '1' for the first column, '0' for the second
|
|
71
|
+
const counts = screen.getAllByText('1')
|
|
72
|
+
expect(counts.length).toBeGreaterThanOrEqual(1)
|
|
73
|
+
expect(screen.getByText('0')).toBeInTheDocument()
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Card rendering
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
|
|
81
|
+
describe('GanttBoardView — card rendering', () => {
|
|
82
|
+
it('renders a card for each item in a column', () => {
|
|
83
|
+
const columns = [
|
|
84
|
+
{
|
|
85
|
+
status: 'in_progress',
|
|
86
|
+
items: [
|
|
87
|
+
makeItem({ id: 'a', title: 'Alpha Task', status: 'in_progress' }),
|
|
88
|
+
makeItem({ id: 'b', title: 'Beta Task', status: 'in_progress' }),
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
]
|
|
92
|
+
render(<GanttBoardView {...defaultProps({ boardColumns: columns })} />)
|
|
93
|
+
expect(screen.getByText('Alpha Task')).toBeInTheDocument()
|
|
94
|
+
expect(screen.getByText('Beta Task')).toBeInTheDocument()
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('renders a category badge on cards that have a category', () => {
|
|
98
|
+
const columns = [
|
|
99
|
+
{
|
|
100
|
+
status: 'in_progress',
|
|
101
|
+
items: [makeItem({ id: 'a', title: 'Task A', status: 'in_progress', category: 'product' })],
|
|
102
|
+
},
|
|
103
|
+
]
|
|
104
|
+
render(<GanttBoardView {...defaultProps({ boardColumns: columns })} />)
|
|
105
|
+
expect(screen.getByText('product')).toBeInTheDocument()
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it('does not render a category badge when the item has no category', () => {
|
|
109
|
+
const columns = [
|
|
110
|
+
{
|
|
111
|
+
status: 'in_progress',
|
|
112
|
+
items: [makeItem({ id: 'a', title: 'Task A', status: 'in_progress' })],
|
|
113
|
+
},
|
|
114
|
+
]
|
|
115
|
+
const { container } = render(<GanttBoardView {...defaultProps({ boardColumns: columns })} />)
|
|
116
|
+
expect(container.querySelector('.gantt-category-badge')).not.toBeInTheDocument()
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('renders the end date on a card when the item has an endDate', () => {
|
|
120
|
+
// Use local-time ISO string to avoid UTC→local timezone shift
|
|
121
|
+
const columns = [
|
|
122
|
+
{
|
|
123
|
+
status: 'in_progress',
|
|
124
|
+
items: [makeItem({ id: 'a', title: 'Task A', status: 'in_progress', endDate: '2025-03-15T00:00:00' })],
|
|
125
|
+
},
|
|
126
|
+
]
|
|
127
|
+
render(<GanttBoardView {...defaultProps({ boardColumns: columns })} />)
|
|
128
|
+
// date-fns format(new Date('2025-03-15T00:00:00'), 'MMM d') === 'Mar 15'
|
|
129
|
+
expect(screen.getByText('Mar 15')).toBeInTheDocument()
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
it('does not render an end date when the item has no endDate', () => {
|
|
133
|
+
const columns = [
|
|
134
|
+
{
|
|
135
|
+
status: 'in_progress',
|
|
136
|
+
items: [{ id: 'a', title: 'No Date Task', status: 'in_progress' }],
|
|
137
|
+
},
|
|
138
|
+
]
|
|
139
|
+
const { container } = render(<GanttBoardView {...defaultProps({ boardColumns: columns })} />)
|
|
140
|
+
expect(container.querySelector('.gantt-board-card-date')).not.toBeInTheDocument()
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it('uses the fallback "other" color when the item category is not in categoryColors', () => {
|
|
144
|
+
const columns = [
|
|
145
|
+
{
|
|
146
|
+
status: 'in_progress',
|
|
147
|
+
items: [makeItem({ id: 'a', title: 'Task A', status: 'in_progress', category: 'unknown' })],
|
|
148
|
+
},
|
|
149
|
+
]
|
|
150
|
+
const { container } = render(<GanttBoardView {...defaultProps({ boardColumns: columns })} />)
|
|
151
|
+
const badge = container.querySelector('.gantt-category-badge') as HTMLElement | null
|
|
152
|
+
expect(badge).toBeInTheDocument()
|
|
153
|
+
expect(badge?.style.backgroundColor).toBe('rgb(107, 114, 128)') // #6b7280 in rgb
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
// Item click
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
|
|
161
|
+
describe('GanttBoardView — item click', () => {
|
|
162
|
+
it('calls handleItemClick when a card is clicked', () => {
|
|
163
|
+
const handleItemClick = jest.fn()
|
|
164
|
+
const item = makeItem({ id: 'a', title: 'Clickable', status: 'in_progress' })
|
|
165
|
+
const columns = [{ status: 'in_progress', items: [item] }]
|
|
166
|
+
render(<GanttBoardView {...defaultProps({ boardColumns: columns, handleItemClick })} />)
|
|
167
|
+
fireEvent.click(screen.getByText('Clickable'))
|
|
168
|
+
expect(handleItemClick).toHaveBeenCalledWith(item)
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
it('calls handleItemClick with the correct item when multiple cards are present', () => {
|
|
172
|
+
const handleItemClick = jest.fn()
|
|
173
|
+
const itemA = makeItem({ id: 'a', title: 'Task A', status: 'in_progress' })
|
|
174
|
+
const itemB = makeItem({ id: 'b', title: 'Task B', status: 'in_progress' })
|
|
175
|
+
const columns = [{ status: 'in_progress', items: [itemA, itemB] }]
|
|
176
|
+
render(<GanttBoardView {...defaultProps({ boardColumns: columns, handleItemClick })} />)
|
|
177
|
+
fireEvent.click(screen.getByText('Task B'))
|
|
178
|
+
expect(handleItemClick).toHaveBeenCalledWith(itemB)
|
|
179
|
+
})
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
// Drag and drop
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
|
|
186
|
+
describe('GanttBoardView — drag and drop', () => {
|
|
187
|
+
it('sets boardDragItem when drag starts on a card', () => {
|
|
188
|
+
const setBoardDragItem = jest.fn()
|
|
189
|
+
const onStatusChange = jest.fn()
|
|
190
|
+
const item = makeItem({ id: 'a', title: 'Draggable', status: 'not_started' })
|
|
191
|
+
const columns = [{ status: 'not_started', items: [item] }]
|
|
192
|
+
const { container } = render(
|
|
193
|
+
<GanttBoardView
|
|
194
|
+
{...defaultProps({ boardColumns: columns, setBoardDragItem, onStatusChange })}
|
|
195
|
+
/>
|
|
196
|
+
)
|
|
197
|
+
const card = container.querySelector('.gantt-board-card') as HTMLElement
|
|
198
|
+
fireEvent.dragStart(card)
|
|
199
|
+
expect(setBoardDragItem).toHaveBeenCalledWith('a')
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('clears boardDragItem when drag ends', () => {
|
|
203
|
+
const setBoardDragItem = jest.fn()
|
|
204
|
+
const onStatusChange = jest.fn()
|
|
205
|
+
const item = makeItem({ id: 'a', title: 'Draggable', status: 'not_started' })
|
|
206
|
+
const columns = [{ status: 'not_started', items: [item] }]
|
|
207
|
+
const { container } = render(
|
|
208
|
+
<GanttBoardView
|
|
209
|
+
{...defaultProps({ boardColumns: columns, setBoardDragItem, onStatusChange })}
|
|
210
|
+
/>
|
|
211
|
+
)
|
|
212
|
+
const card = container.querySelector('.gantt-board-card') as HTMLElement
|
|
213
|
+
fireEvent.dragEnd(card)
|
|
214
|
+
expect(setBoardDragItem).toHaveBeenCalledWith(null)
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
it('calls onStatusChange with the new status on drop', () => {
|
|
218
|
+
const setBoardDragItem = jest.fn()
|
|
219
|
+
const onStatusChange = jest.fn()
|
|
220
|
+
const item = makeItem({ id: 'a', title: 'Draggable', status: 'not_started' })
|
|
221
|
+
const columns = [
|
|
222
|
+
{ status: 'not_started', items: [item] },
|
|
223
|
+
{ status: 'completed', items: [] },
|
|
224
|
+
]
|
|
225
|
+
const { container } = render(
|
|
226
|
+
<GanttBoardView
|
|
227
|
+
{...defaultProps({ boardColumns: columns, boardDragItem: 'a', setBoardDragItem, onStatusChange })}
|
|
228
|
+
/>
|
|
229
|
+
)
|
|
230
|
+
const targetColumn = container.querySelectorAll('.gantt-board-column')[1] as HTMLElement
|
|
231
|
+
fireEvent.drop(targetColumn)
|
|
232
|
+
expect(onStatusChange).toHaveBeenCalledWith('a', 'completed')
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
it('does not call onStatusChange when onStatusChange is not provided', () => {
|
|
236
|
+
const setBoardDragItem = jest.fn()
|
|
237
|
+
const item = makeItem({ id: 'a', title: 'Draggable', status: 'not_started' })
|
|
238
|
+
const columns = [
|
|
239
|
+
{ status: 'not_started', items: [item] },
|
|
240
|
+
{ status: 'completed', items: [] },
|
|
241
|
+
]
|
|
242
|
+
// Should not throw even without onStatusChange
|
|
243
|
+
const { container } = render(
|
|
244
|
+
<GanttBoardView
|
|
245
|
+
{...defaultProps({
|
|
246
|
+
boardColumns: columns,
|
|
247
|
+
boardDragItem: 'a',
|
|
248
|
+
setBoardDragItem,
|
|
249
|
+
onStatusChange: undefined,
|
|
250
|
+
})}
|
|
251
|
+
/>
|
|
252
|
+
)
|
|
253
|
+
const targetColumn = container.querySelectorAll('.gantt-board-column')[1] as HTMLElement
|
|
254
|
+
expect(() => fireEvent.drop(targetColumn)).not.toThrow()
|
|
255
|
+
expect(setBoardDragItem).toHaveBeenCalledWith(null)
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it('cards are not draggable when onStatusChange is undefined', () => {
|
|
259
|
+
const item = makeItem({ id: 'a', title: 'Static', status: 'not_started' })
|
|
260
|
+
const columns = [{ status: 'not_started', items: [item] }]
|
|
261
|
+
const { container } = render(
|
|
262
|
+
<GanttBoardView {...defaultProps({ boardColumns: columns, onStatusChange: undefined })} />
|
|
263
|
+
)
|
|
264
|
+
const card = container.querySelector('.gantt-board-card') as HTMLElement
|
|
265
|
+
// draggable attribute should be false (falsy) when onStatusChange is absent
|
|
266
|
+
expect(card.draggable).toBe(false)
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
it('cards are draggable when onStatusChange is provided', () => {
|
|
270
|
+
const onStatusChange = jest.fn()
|
|
271
|
+
const item = makeItem({ id: 'a', title: 'Draggable', status: 'not_started' })
|
|
272
|
+
const columns = [{ status: 'not_started', items: [item] }]
|
|
273
|
+
const { container } = render(
|
|
274
|
+
<GanttBoardView {...defaultProps({ boardColumns: columns, onStatusChange })} />
|
|
275
|
+
)
|
|
276
|
+
const card = container.querySelector('.gantt-board-card') as HTMLElement
|
|
277
|
+
expect(card.draggable).toBe(true)
|
|
278
|
+
})
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
// ---------------------------------------------------------------------------
|
|
282
|
+
// Drag-over visual state
|
|
283
|
+
// ---------------------------------------------------------------------------
|
|
284
|
+
|
|
285
|
+
describe('GanttBoardView — drop-target styling', () => {
|
|
286
|
+
it('applies gantt-board-drop-target class to all columns when boardDragItem is set', () => {
|
|
287
|
+
const columns = [
|
|
288
|
+
{ status: 'not_started', items: [] },
|
|
289
|
+
{ status: 'completed', items: [] },
|
|
290
|
+
]
|
|
291
|
+
const { container } = render(
|
|
292
|
+
<GanttBoardView {...defaultProps({ boardColumns: columns, boardDragItem: 'some-id' })} />
|
|
293
|
+
)
|
|
294
|
+
const dropTargets = container.querySelectorAll('.gantt-board-drop-target')
|
|
295
|
+
expect(dropTargets).toHaveLength(2)
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
it('does not apply gantt-board-drop-target when boardDragItem is null', () => {
|
|
299
|
+
const columns = [{ status: 'not_started', items: [] }]
|
|
300
|
+
const { container } = render(
|
|
301
|
+
<GanttBoardView {...defaultProps({ boardColumns: columns, boardDragItem: null })} />
|
|
302
|
+
)
|
|
303
|
+
expect(container.querySelector('.gantt-board-drop-target')).not.toBeInTheDocument()
|
|
304
|
+
})
|
|
305
|
+
})
|