-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* use new dnd library * upped react table * implement alternative dnd handler * implement on change * enable selection and dnd * basic and a11y test * small test refactor * basic checkbox testing * dnd sorting + checkbox tests * enable groups * custom sorter for dnd * dnd children * handle all dnd cases * comments * enabled more cy component tests * dnd sort of children cy test * better state management * fixed types * sort by headers * better types * internal state tracking + better header sorting + reset selections * color code rows * refactor helpers * dnd helpers refactor + avoid nesting groups * dnd dropzone helpter test * better group handling * add id to form element * correctly telegraph drop target * added dynamic styles * remove rotation * stylings * more dnd styles + hover states * embeded button adjustments * refactor + testing * preserve original state * fixed test * initial sorting * refactor & sorting+dnd * refactored state sharing + real dnd for test * remove duplicate id in story * fold group with effect when dragging * Better handling of selections * more test + use realClick * external sorting controll * allow disable editing groups with dnd * refactor helper to reduce iterations * cleanup * simplify + adjust styles * more style adjustments * adjusted ambeded button paddings * fixed col table * adjust children style marker * visual adjustments and tests * improved dnd-hover and children indicators * refactor + customization test * type fix * removed unneeded dep from effect * migrate ix dashboard * tableV2 for suggestion + simple refactor * reset selections on data changing * sorting and selecting suggestions * update test * conditionally disable row selection * fixed type issues * adjusted table styles * fix child shadow * better group selections * update suggestions with new table * update children as subRows * styles + type fixes * e2e adjustments * update translations * fix button style
- Loading branch information
Showing
56 changed files
with
2,707 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/* eslint-disable react/no-multi-comp */ | ||
/* eslint-disable react/jsx-props-no-spreading */ | ||
import React, { CSSProperties, useEffect, useState } from 'react'; | ||
import { useSortable } from '@dnd-kit/sortable'; | ||
import { CSS } from '@dnd-kit/utilities'; | ||
import { flexRender, Row } from '@tanstack/react-table'; | ||
import { Translate } from 'app/I18N'; | ||
import { TableRow } from './Table'; | ||
|
||
const dndHoverClass = 'shadow-[inset_0_-4px_#3949AB]'; | ||
const childIndicatorClass = 'shadow-[inset_5px_0px_0px_-1px_#3949AB]'; | ||
|
||
const inactiveGradientStyle: CSSProperties = { | ||
position: 'absolute', | ||
left: '50%', | ||
top: '50%', | ||
transform: 'translate(-50%,-50%)', | ||
width: '16px', | ||
height: '80%', | ||
background: 'radial-gradient(circle, #c5cae9 25%, transparent 26%) 0% 0% / 8px 10px', | ||
}; | ||
|
||
const activeGradientStyle: CSSProperties = { | ||
...inactiveGradientStyle, | ||
background: 'radial-gradient(circle, #303f9f 25%, transparent 26%) 0% 0% / 8px 10px', | ||
}; | ||
|
||
const getSytles = (expanded: boolean, isOver: boolean) => { | ||
const expandedGroupStyles = expanded | ||
? 'bg-indigo-100 border-indigo-100 hover:bg-indigo-200 hover:border-indigo-200' | ||
: ''; | ||
const dndHoverStyles = isOver ? dndHoverClass : ''; | ||
return `${expandedGroupStyles} ${dndHoverStyles}`; | ||
}; | ||
|
||
const RowDragHandleCell = <T extends TableRow<T>>({ row }: { row: Row<T> }) => { | ||
const { attributes, listeners, isDragging } = useSortable({ | ||
id: row.id, | ||
}); | ||
const [handlerStyle, setHandlerStyle] = useState(inactiveGradientStyle); | ||
|
||
const canExpand = row.originalSubRows; | ||
const expanded = row.getIsExpanded(); | ||
|
||
useEffect(() => { | ||
if (canExpand && expanded && isDragging) { | ||
row.toggleExpanded(); | ||
} | ||
}, [isDragging]); | ||
|
||
return ( | ||
<button | ||
{...attributes} | ||
{...listeners} | ||
onMouseEnter={() => { | ||
setHandlerStyle(activeGradientStyle); | ||
}} | ||
onMouseLeave={() => { | ||
setHandlerStyle(inactiveGradientStyle); | ||
}} | ||
type="button" | ||
style={isDragging ? activeGradientStyle : handlerStyle} | ||
> | ||
<span className="sr-only"> | ||
<Translate>Drag row</Translate> | ||
</span> | ||
</button> | ||
); | ||
}; | ||
|
||
const DraggableRow = <T extends TableRow<T>>({ | ||
row, | ||
colSpan, | ||
groupColumnIndex, | ||
dndEnabled, | ||
}: { | ||
row: Row<T>; | ||
colSpan: number; | ||
groupColumnIndex: number; | ||
dndEnabled: boolean; | ||
}) => { | ||
const expanded = row.getIsExpanded(); | ||
const isEmpty = row.originalSubRows?.length === 0; | ||
const isChild = row.depth > 0; | ||
|
||
const { transform, setNodeRef, isDragging, isOver } = useSortable({ | ||
id: row.id, | ||
}); | ||
|
||
const { setNodeRef: dropNoderef, isOver: isOverDropzone } = useSortable({ | ||
id: `${row.id}-dropzone`, | ||
}); | ||
|
||
const draggingStyles: CSSProperties = { | ||
transformOrigin: 'left', | ||
transform: CSS.Transform.toString({ | ||
x: 0, | ||
y: transform?.y || 0, | ||
scaleX: 0.7, | ||
scaleY: 0.7, | ||
}), | ||
cursor: 'grabbing', | ||
zIndex: 1, | ||
position: 'relative', | ||
opacity: 0.9, | ||
outline: 'rgb(81 69 205) solid 4px', | ||
backgroundColor: 'white', | ||
}; | ||
|
||
const rowStyles = getSytles(expanded, isOver); | ||
|
||
return ( | ||
<> | ||
<tr | ||
style={isDragging ? draggingStyles : undefined} | ||
ref={setNodeRef} | ||
className={`text-gray-900 border-b transition-colors hover:bg-gray-50 ${rowStyles}`} | ||
> | ||
{row.getVisibleCells().map((cell, index) => ( | ||
<td | ||
key={cell.id} | ||
className={`relative px-4 py-2 ${cell.column.columnDef.meta?.contentClassName} ${isChild && groupColumnIndex === index ? childIndicatorClass : ''}`} | ||
> | ||
{flexRender(cell.column.columnDef.cell, cell.getContext())} | ||
</td> | ||
))} | ||
</tr> | ||
|
||
{isEmpty && expanded && ( | ||
<tr | ||
ref={dropNoderef} | ||
className={`border-b text-gray-900 transition-colors ${isOverDropzone ? dndHoverClass : ''}`} | ||
> | ||
<td className="px-4 py-3 text-sm italic text-gray-600" colSpan={colSpan}> | ||
{dndEnabled ? ( | ||
<Translate>Empty group. Drop here to add</Translate> | ||
) : ( | ||
<Translate>This group is empty</Translate> | ||
)} | ||
</td> | ||
</tr> | ||
)} | ||
</> | ||
); | ||
}; | ||
|
||
const DnDHeader = () => <Translate className="sr-only">Empty</Translate>; | ||
|
||
export { RowDragHandleCell, DraggableRow, DnDHeader }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* eslint-disable react/no-multi-comp */ | ||
import React from 'react'; | ||
import { Row } from '@tanstack/react-table'; | ||
import { ChevronUpIcon, ChevronDownIcon } from '@heroicons/react/20/solid'; | ||
import { Translate } from 'app/I18N'; | ||
import { EmbededButton } from '../EmbededButton'; | ||
import { TableRow } from './Table'; | ||
|
||
const GroupHeader = () => <Translate className="sr-only">Empty</Translate>; | ||
|
||
const GroupCell = <T extends TableRow<T>>({ row }: { row: Row<T> }) => { | ||
const canExpand = row.originalSubRows; | ||
const expanded = row.getIsExpanded(); | ||
|
||
return canExpand ? ( | ||
<EmbededButton | ||
icon={expanded ? <ChevronUpIcon /> : <ChevronDownIcon />} | ||
onClick={() => row.toggleExpanded()} | ||
color="indigo" | ||
className={`${expanded ? 'bg-indigo-300' : 'bg-indigo-100'} rounded-md border-none drop-shadow-none`} | ||
> | ||
<Translate className={`${expanded ? 'text-indigo-800' : 'text-indigo-700'}`}>Group</Translate> | ||
<Translate className="sr-only">Open group</Translate> | ||
</EmbededButton> | ||
) : null; | ||
}; | ||
|
||
export { GroupCell, GroupHeader }; |
Oops, something went wrong.