• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

alkem-io / client-web / #6263

16 Nov 2023 11:59AM UTC coverage: 5.91%. First build
#6263

Pull #5203

travis-ci

Pull Request #5203: IconButton Labels

184 of 8743 branches covered (0.0%)

Branch coverage included in aggregate %.

1 of 43 new or added lines in 37 files covered. (2.33%)

1281 of 16046 relevant lines covered (7.98%)

0.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/core/ui/table/DataGridTable.tsx
1
import { Box, styled } from '@mui/material';
2
import { DataGrid, DataGridProps, GridColDef, GridRenderCellParams } from '@mui/x-data-grid';
3
import { Identifiable } from '@/core/utils/Identifiable';
4
import { ReactNode, useMemo } from 'react';
5
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
6
import { useTranslation } from 'react-i18next';
7
import TranslationKey from '@/core/i18n/utils/TranslationKey';
8
import { GUTTER_PX } from '../grid/constants';
9
import DataGridActionButton from './DataGridActionButton';
10
import React from 'react';
11

12
export const StyledDataGrid = styled(DataGrid)(({ theme }) => ({
×
13
  '.MuiDataGrid-columnHeaders': {
14
    color: theme.palette.primary.contrastText,
15
    background: theme.palette.primary.main,
16
    '.MuiDataGrid-row--borderBottom': {
17
      background: theme.palette.primary.main,
18
    },
19
    '.MuiIconButton-root': {
20
      color: theme.palette.primary.contrastText,
21
    },
22
  },
23
  '.MuiDataGrid-row:nth-of-type(odd)': {
24
    background: theme.palette.background.default,
25
  },
26
  '.MuiDataGrid-row:nth-of-type(even)': {
27
    background: theme.palette.background.paper,
28
  },
29
  '.MuiDataGrid-columnSeparator': {
30
    color: 'transparent',
31
  },
32
  '.MuiDataGrid-cell': {
33
    display: 'flex',
34
    alignItems: 'center',
35
    flexDirection: 'row',
36
  },
37
  '.MuiDataGrid-cell:focus-within, & .MuiDataGrid-cell:focus': {
38
    outline: 'none',
39
  },
40
})) as typeof DataGrid;
×
41

42
interface Action<Item extends Identifiable> {
43
  name: string;
44
  render: (params: GridRenderCellParams<Item>) => ReactNode;
45
}
46

47
interface DataGridTableProps<Item extends Identifiable> extends Omit<DataGridProps<Item>, 'columns'> {
48
  rows: Item[];
49
  columns: GridColDef<Item>[];
50
  actions?: Action<Item>[];
51
  canDelete?: (item: Item) => boolean;
52
  disableDelete?: (item: Item) => boolean;
53
  onDelete?: (item: Item) => void;
54
  dependencies?: unknown[];
55
}
56

57
const alwaysTrue = () => true;
58

59
const alwaysFalse = () => false;
60

61
const getRowHeight = () => GUTTER_PX * 2;
62

63
const DataGridTable = <Item extends Identifiable>({
64
  rows,
65
  columns,
66
  actions,
×
67
  onDelete,
68
  canDelete = alwaysTrue,
×
69
  disableDelete = alwaysFalse,
70
  dependencies = [],
×
71
  ...props
72
}: DataGridTableProps<Item>) => {
×
73
  const { t } = useTranslation();
74

75
  const columnDefinitions = useMemo<GridColDef<Item>[]>(
76
    () =>
77
      columns.map(column => {
78
        return {
79
          headerName: t(`fields.${column.field}` as TranslationKey) as string,
×
80
          renderHeader: ({ colDef }) => <>{colDef.headerName}</>,
×
81
          ...column,
×
82
        };
83
      }),
84
    [t, columns, dependencies]
×
85
  );
86

×
87
  const actionsColumnDefinition = useMemo<GridColDef<Item> | undefined>(() => {
88
    const actionDefinitions = [...(actions ?? [])];
×
89
    if (!onDelete && actionDefinitions.length === 0) {
×
90
      return undefined;
91
    }
×
92
    if (onDelete) {
93
      actionDefinitions.push({
×
94
        name: 'delete',
95
        render: ({ row }: { row: Item }) =>
96
          canDelete(row) && (
×
97
            <DataGridActionButton
98
              item={row}
99
              tooltip={t('buttons.delete')}
100
              icon={DeleteOutlineIcon}
×
101
              iconColor="warning"
102
              isDisabled={disableDelete}
×
103
              onClick={onDelete}
104
            />
105
          ),
106
      });
107
    }
108

109
    return {
×
110
      headerName: actionDefinitions.length > 1 ? t('common.actions') : '',
×
111
      width: actionDefinitions.length * GUTTER_PX * 2.5,
112
      resizable: false,
×
113
      sortable: false,
×
114
      filterable: false,
115
      disableColumnMenu: true,
116
      field: 'actions',
×
NEW
117
      renderCell: (...renderParams) => {
×
118
        return (
119
          <Box marginLeft="auto">
120
            {actionDefinitions.map(({ name, render }) => (
121
              <React.Fragment key={name}>{render(...renderParams)}</React.Fragment>
122
            ))}
123
          </Box>
124
        );
×
125
      },
×
126
    };
127
  }, [actions, onDelete, canDelete, disableDelete, t, dependencies]);
128

129
  const mergedColumnDefinitions = useMemo(
130
    () => (actionsColumnDefinition ? [...columnDefinitions, actionsColumnDefinition] : columnDefinitions),
131
    [columnDefinitions, actionsColumnDefinition]
132
  );
133

×
134
  return (
×
135
    <StyledDataGrid
136
      isRowSelectable={alwaysFalse}
137
      rows={rows}
138
      columns={mergedColumnDefinitions}
×
139
      columnHeaderHeight={getRowHeight()}
140
      getRowHeight={getRowHeight}
141
      {...props}
142
    />
143
  );
144
};
145

146
export default DataGridTable;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc