Skip to content

Commit c031b4f

Browse files
authored
feat(ui): DOMA-12305 add table component (#6658)
* feat(condo): DOMA-12250 add new compoent * feat(condo): DOMA-12250 add context menu 1.1 * feat(condo): DOMA-12250 before last verstion * feat(condo): DOMA-12250 before last 2 * feat(condo): DOMA-12250 delete other files * feat(condo): DOMA-12250 replace depends * feat(condo): DOMA-12250 fix stylelint * feat(condo): DOMA-12305 add table component * feat(condo): DOMA-12305 add TableColumnMenuLabels * feat(condo): DOMA-12305 fix after review * feat(condo): DOMA-12305 fix sonarCloud * feat(condo): DOMA-12305 fix stylelint * feat(condo): DOMA-12305 update after review * feat(condo): DOMA-12305 lint and shema updates * feat(condo): DOMA-12305 add ability use record in render column function * feat(condo): DOMA-12305 add server data in table * feat(condo): DOMA-12305 update news table * feat(condo): DOMA-12305 update syncUrlCallback * feat(condo): DOMA-12305 change table interface * feat(condo): DOMA-12305 fix ci * feat(condo): DOMA-12305 add columnOptions * feat(condo): DOMA-12305 add rowSelection * feat(condo): DOMA-12305 add ref in table * feat(condo): DOMA-12305 try to add column resize * feat(condo): DOMA-12305 fix builds * feat(condo): DOMA-12305 fix styles * feat(condo): DOMA-12305 yarn lock update * fix(condo): DOMA-12305 remove table from news page * feat(condo): DOMA-12305 add intitialSize to column * feat(condo): DOMA-12305 small ui fixes * feat(condo): DOMA-12305 fix comments after review * feat(condo): DOMA-12305 add comment for onTableStateChange * feat(ui): DOMA-12305 add changes from contact page * feat(condo): DOMA-12305 fix ci and column resize * feat(condo): DOMA-12305 fix types * feat(condo): DOMA-12305 fix sonarCloud * feat(condo): DOMA-12305 fix semgrep * feat(ui): DOMA-12305 fix number filter * feat(ui): DOMA-12305 update table component styles, improve pagination, and refactor column settings * feat(ui): DOMA-12305 update table component styles and fix icon class names * feat(ui): DOMA-12305 reorganize dropdown menu styles and enhance icon transition * feat(ui): DOMA-12305 update ColumnSettings and TableBody components for better clarity and default handling
1 parent 89e92fa commit c031b4f

29 files changed

+3338
-0
lines changed

apps/condo/lang/en/en.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,13 @@
297297
"WillBeReadySoon": "Everything will be ready soon",
298298
"Yes": "Yes",
299299
"You": "you",
300+
"Table.Sort": "Sort",
301+
"Table.Filter": "Filter",
302+
"Table.Settings": "Configure columns",
303+
"Table.Sorted": "Sorted",
304+
"Table.Filtered": "Filtered",
305+
"Table.NoData": "No Data",
306+
"Table.DefaultSettingsLabel": "Restore default settings",
300307
"accrualsAndPayments.billing.noReceiptsYet": "Connected, but no receipt yet",
301308
"accrualsAndPayments.billing.statusTag.connected": "{name}: connected",
302309
"accrualsAndPayments.billing.statusTag.error": "{name}: error",

apps/condo/lang/es/es.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,13 @@
297297
"WillBeReadySoon": "Estará listo pronto",
298298
"Yes": "",
299299
"You": "",
300+
"Table.Sort": "Ordenar",
301+
"Table.Filter": "Filtrar",
302+
"Table.Settings": "Configurar columnas",
303+
"Table.Sorted": "Ordenado",
304+
"Table.Filtered": "Filtrado",
305+
"Table.NoData": "No hay datos",
306+
"Table.DefaultSettingsLabel": "Restaurar configuración predeterminada",
300307
"accrualsAndPayments.billing.noReceiptsYet": "Conectado, pero aún no hay recibos",
301308
"accrualsAndPayments.billing.statusTag.connected": "{name}: conectado",
302309
"accrualsAndPayments.billing.statusTag.error": "{name}: error",

apps/condo/lang/ru/ru.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,13 @@
297297
"WillBeReadySoon": "Скоро всё будет готово",
298298
"Yes": "Да",
299299
"You": "вы",
300+
"Table.Sort": "Сортировать",
301+
"Table.Filter": "Фильтровать",
302+
"Table.Settings": "Настроить колонки",
303+
"Table.Sorted": "Отсортировано",
304+
"Table.Filtered": "Отфильтровано",
305+
"Table.NoData": "Нет данных",
306+
"Table.DefaultSettingsLabel": "Вернуть настройки по умолчанию",
300307
"accrualsAndPayments.billing.noReceiptsYet": "Подключено, но квитанций пока нет",
301308
"accrualsAndPayments.billing.statusTag.connected": "{name}: подключено",
302309
"accrualsAndPayments.billing.statusTag.error": "{name}: ошибка",

apps/condo/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69325,6 +69325,7 @@ enum B2BAppIconType {
6932569325
FloorParking
6932669326
Frown
6932769327
Globe
69328+
GripHorizontal
6932869329
Guide
6932969330
History
6933069331
Home

apps/condo/schema.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5049,6 +5049,7 @@ export enum B2BAppIconType {
50495049
FloorParking = 'FloorParking',
50505050
Frown = 'Frown',
50515051
Globe = 'Globe',
5052+
GripHorizontal = 'GripHorizontal',
50525053
Guide = 'Guide',
50535054
History = 'History',
50545055
Home = 'Home',
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/** This file is auto-generated, do not edit it manually **/
2+
import React from 'react'
3+
4+
import { IconWrapper, IconProps } from '../wrappers'
5+
6+
export const GripHorizontal: React.FC<IconProps> = ({ svgProps: props, ...restProps }) => {
7+
return (
8+
<IconWrapper
9+
icon={
10+
<svg
11+
width='inherit'
12+
height='inherit'
13+
fill='none'
14+
xmlns='http://www.w3.org/2000/svg'
15+
viewBox='0 0 24 24'
16+
{...props}
17+
>
18+
<path
19+
d='M12 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2ZM19 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2ZM5 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2ZM12 16a1 1 0 1 0 0-2 1 1 0 0 0 0 2ZM19 16a1 1 0 1 0 0-2 1 1 0 0 0 0 2ZM5 16a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z'
20+
stroke='currentColor'
21+
strokeWidth={2}
22+
strokeLinecap='round'
23+
strokeLinejoin='round'
24+
/>
25+
</svg>
26+
}
27+
{...restProps}
28+
/>
29+
)
30+
}

packages/icons/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export { Floor } from './components/Floor'
4545
export { FloorParking } from './components/FloorParking'
4646
export { Frown } from './components/Frown'
4747
export { Globe } from './components/Globe'
48+
export { GripHorizontal } from './components/GripHorizontal'
4849
export { Guide } from './components/Guide'
4950
export { History } from './components/History'
5051
export { Home } from './components/Home'

packages/ui/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@
124124
"access": "public"
125125
},
126126
"dependencies": {
127+
"@dnd-kit/core": "^6.3.1",
128+
"@dnd-kit/sortable": "^10.0.0",
129+
"@dnd-kit/utilities": "^3.2.2",
127130
"@open-condo/icons": "workspace:^",
131+
"@tanstack/react-table": "^8.1.6",
128132
"antd": "^4.24.12",
129133
"classnames": "^2.5.1",
130134
"react-markdown": "^6",
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import {
2+
DndContext,
3+
closestCenter,
4+
KeyboardSensor,
5+
PointerSensor,
6+
useSensor,
7+
useSensors,
8+
DragEndEvent,
9+
} from '@dnd-kit/core'
10+
import {
11+
arrayMove,
12+
SortableContext,
13+
sortableKeyboardCoordinates,
14+
verticalListSortingStrategy,
15+
} from '@dnd-kit/sortable'
16+
import { RowData, Table } from '@tanstack/react-table'
17+
import React, { useCallback, useRef } from 'react'
18+
19+
import { ColumnSettingsItem } from '@open-condo/ui/src/components/Table/components/ColumnSettingsItem'
20+
import type { ColumnDefWithId } from '@open-condo/ui/src/components/Table/types'
21+
22+
interface ColumnSettingsProps<TData extends RowData = RowData> {
23+
columns: ColumnDefWithId<TData>[]
24+
table: Table<TData>
25+
}
26+
27+
export const ColumnSettings = <TData extends RowData = RowData>({ columns, table }: ColumnSettingsProps<TData>) => {
28+
const columnWithoutToggleVisibility = useRef<number>(
29+
table.getVisibleLeafColumns().reduce((acc, column) => acc + (column.columnDef.meta?.enableColumnSettings ? 0 : 1), 0)
30+
)
31+
32+
const sensors = useSensors(
33+
useSensor(PointerSensor),
34+
useSensor(KeyboardSensor, {
35+
coordinateGetter: sortableKeyboardCoordinates,
36+
})
37+
)
38+
39+
const handleDragEnd = useCallback((event: DragEndEvent) => {
40+
const { active, over } = event
41+
42+
if (active.id !== over?.id && table.setColumnOrder) {
43+
const oldIndex = columns.findIndex(column => column.id === active.id)
44+
const newIndex = columns.findIndex(column => column.id === over?.id)
45+
46+
const newOrder = arrayMove(columns, oldIndex, newIndex).map(col => col.id)
47+
table.setColumnOrder(newOrder)
48+
}
49+
}, [columns, table])
50+
51+
const handleToggleVisibility = useCallback((columnKey: string, checked: boolean) => {
52+
const column = table.getColumn(columnKey)
53+
54+
// NOTE: If column is hidden - reset filter and sorting state
55+
if (!checked && column) {
56+
column.clearSorting()
57+
column.setFilterValue(undefined)
58+
}
59+
60+
column?.toggleVisibility(checked)
61+
}, [table])
62+
63+
return (
64+
<DndContext
65+
sensors={sensors}
66+
collisionDetection={closestCenter}
67+
onDragEnd={handleDragEnd}
68+
>
69+
<SortableContext items={columns.map(c => c.id)} strategy={verticalListSortingStrategy}>
70+
<div className='condo-table-column-settings-dropdown'>
71+
{columns.map((column) => {
72+
if (!table.getColumn(column.id)?.columnDef?.meta?.enableColumnSettings) return
73+
const isVisible = table.getColumn(column.id)?.getIsVisible()
74+
const isLastVisibleColumn = isVisible && table.getVisibleLeafColumns().length === columnWithoutToggleVisibility.current + 1
75+
76+
return (
77+
<ColumnSettingsItem
78+
key={column.id}
79+
column={column}
80+
table={table}
81+
isVisible={isVisible || false}
82+
isLastVisibleColumn={isLastVisibleColumn || false}
83+
onToggleVisibility={(checked: boolean) => handleToggleVisibility(column.id, checked)}
84+
/>
85+
)
86+
})}
87+
</div>
88+
</SortableContext>
89+
</DndContext>
90+
)
91+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { useSortable } from '@dnd-kit/sortable'
2+
import { CSS } from '@dnd-kit/utilities'
3+
import { flexRender, RowData, Table } from '@tanstack/react-table'
4+
import classNames from 'classnames'
5+
import React, { useMemo } from 'react'
6+
7+
import { GripHorizontal } from '@open-condo/icons'
8+
import { Space, Switch, Typography } from '@open-condo/ui/src'
9+
import type { ColumnDefWithId } from '@open-condo/ui/src/components/Table/types'
10+
11+
12+
interface ColumnSettingsItemProps<TData extends RowData = RowData> {
13+
column: ColumnDefWithId<TData>
14+
table: Table<TData>
15+
isVisible: boolean
16+
isLastVisibleColumn: boolean
17+
onToggleVisibility: (checked: boolean) => void
18+
}
19+
20+
export const ColumnSettingsItem = <TData extends RowData = RowData> ({
21+
column,
22+
table,
23+
isVisible,
24+
isLastVisibleColumn,
25+
onToggleVisibility,
26+
}: ColumnSettingsItemProps<TData>) => {
27+
28+
const {
29+
attributes,
30+
listeners,
31+
setNodeRef,
32+
transform,
33+
transition,
34+
isDragging,
35+
} = useSortable({
36+
id: column.id,
37+
disabled: false,
38+
})
39+
40+
const style = {
41+
transform: CSS.Transform.toString(transform),
42+
transition,
43+
}
44+
45+
const text = useMemo(() =>
46+
flexRender(column.header, {
47+
column: table.getColumn(column.id)!,
48+
table: table,
49+
header: table
50+
.getFlatHeaders()
51+
.find(header => header.id === column.id)!,
52+
})
53+
, [column.header, column.id, table])
54+
55+
return (
56+
<div
57+
ref={setNodeRef}
58+
className={classNames(
59+
'condo-table-column-settings-item',
60+
isDragging && 'is-dragging',
61+
)}
62+
style={style}
63+
{...attributes}
64+
>
65+
<Space size={12}>
66+
<div className='condo-table-switch-container'>
67+
<Switch
68+
checked={isVisible}
69+
disabled={isLastVisibleColumn}
70+
onChange={(checked) => onToggleVisibility(checked)}
71+
size='small'
72+
/>
73+
</div>
74+
<div
75+
className='condo-table-grip-container'
76+
{...listeners}
77+
>
78+
<GripHorizontal size='small'/>
79+
</div>
80+
<Typography.Text type='primary' size='medium'>
81+
{text}
82+
</Typography.Text>
83+
</Space>
84+
</div>
85+
)
86+
}

0 commit comments

Comments
 (0)