Preview.tsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import { FC, useCallback, useMemo } from 'react';
  2. import { makeStyles, Theme, Typography } from '@material-ui/core';
  3. import { useTranslation } from 'react-i18next';
  4. import { InsertPreviewProps } from './Types';
  5. import { Option } from '@/components/customSelector/Types';
  6. import CustomSelector from '@/components/customSelector/CustomSelector';
  7. import AttuGrid from '@/components/grid/Grid';
  8. import { transferCsvArrayToTableData } from '@/utils/Insert';
  9. import { ColDefinitionsType } from '@/components/grid/Types';
  10. import SimpleMenu from '@/components/menu/SimpleMenu';
  11. import icons from '@/components/icons/Icons';
  12. const getStyles = makeStyles((theme: Theme) => ({
  13. wrapper: {
  14. width: '75vw',
  15. },
  16. selectorTip: {
  17. color: theme.palette.attuGrey.dark,
  18. fontWeight: 500,
  19. marginBottom: theme.spacing(1),
  20. },
  21. selectorWrapper: {
  22. '& .selector': {
  23. flexBasis: '40%',
  24. minWidth: '256px',
  25. },
  26. '& .isContainSelect': {
  27. paddingTop: theme.spacing(2),
  28. paddingBottom: theme.spacing(2),
  29. },
  30. },
  31. gridWrapper: {
  32. height: '320px',
  33. },
  34. tableTip: {
  35. display: 'flex',
  36. justifyContent: 'space-between',
  37. alignItems: 'center',
  38. marginTop: theme.spacing(3),
  39. marginBottom: theme.spacing(1),
  40. '& .text': {
  41. color: theme.palette.attuGrey.dark,
  42. fontWeight: 500,
  43. },
  44. },
  45. menuLabel: {
  46. display: 'flex',
  47. justifyContent: 'space-between',
  48. minWidth: '160px',
  49. color: theme.palette.attuGrey.dark,
  50. backgroundColor: '#fff',
  51. '&:hover': {
  52. backgroundColor: '#fff',
  53. },
  54. },
  55. menuIcon: {
  56. color: theme.palette.attuGrey.dark,
  57. },
  58. menuItem: {
  59. fontWeight: 500,
  60. fontSize: '12px',
  61. lineHeight: '16px',
  62. color: theme.palette.attuGrey.dark,
  63. },
  64. menuActive: {
  65. color: theme.palette.primary.main,
  66. },
  67. }));
  68. const getTableData = (
  69. data: any[],
  70. isContainFieldNames: number
  71. ): { [key in string]: any }[] => {
  72. const csvData = isContainFieldNames ? data.slice(1) : data;
  73. return transferCsvArrayToTableData(csvData);
  74. };
  75. const InsertPreview: FC<InsertPreviewProps> = ({
  76. schemaOptions,
  77. data,
  78. isContainFieldNames,
  79. handleIsContainedChange,
  80. tableHeads,
  81. setTableHeads,
  82. file,
  83. }) => {
  84. const classes = getStyles();
  85. const { t: insertTrans } = useTranslation('insert');
  86. const ArrowIcon = icons.dropdown;
  87. // table needed table structure, metadata from csv
  88. const tableData = getTableData(data, isContainFieldNames);
  89. const handleTableHeadChange = useCallback(
  90. (index: number, label: string) => {
  91. const newHeads = [...tableHeads];
  92. newHeads[index] = label;
  93. setTableHeads(newHeads);
  94. },
  95. [tableHeads, setTableHeads]
  96. );
  97. const editHeads = useMemo(
  98. () =>
  99. tableHeads.map((head: string, index: number) => ({
  100. value: head,
  101. component: (
  102. <SimpleMenu
  103. label={head || insertTrans('requiredFieldName')}
  104. menuItems={schemaOptions.map(schema => ({
  105. label: schema.label,
  106. callback: () => handleTableHeadChange(index, schema.label),
  107. wrapperClass: `${classes.menuItem} ${head === schema.label ? classes.menuActive : ''
  108. }`,
  109. }))}
  110. buttonProps={{
  111. className: classes.menuLabel,
  112. endIcon: <ArrowIcon classes={{ root: classes.menuIcon }} />,
  113. }}
  114. ></SimpleMenu>
  115. ),
  116. })),
  117. [
  118. tableHeads,
  119. classes.menuLabel,
  120. classes.menuIcon,
  121. classes.menuItem,
  122. classes.menuActive,
  123. ArrowIcon,
  124. schemaOptions,
  125. insertTrans,
  126. handleTableHeadChange,
  127. ]
  128. );
  129. const isContainedOptions: Option[] = [
  130. {
  131. label: 'Yes',
  132. value: 1,
  133. },
  134. { label: 'No', value: 0 },
  135. ];
  136. // use table row first item to get value
  137. const colDefinitions: ColDefinitionsType[] = Object.keys(tableData[0])
  138. // filter id since we don't want to show it in the table
  139. .filter(item => item !== 'id')
  140. .map(key => ({
  141. id: key,
  142. align: 'left',
  143. disablePadding: false,
  144. label: '',
  145. }));
  146. return (
  147. <section className={classes.wrapper}>
  148. <form className={classes.selectorWrapper}>
  149. <label>
  150. <Typography className={classes.selectorTip}>
  151. {insertTrans('isContainFieldNames')}
  152. </Typography>
  153. </label>
  154. <CustomSelector
  155. options={isContainedOptions}
  156. wrapperClass="selector"
  157. classes={{ filled: 'isContainSelect' }}
  158. value={isContainFieldNames}
  159. variant="filled"
  160. onChange={(e: { target: { value: unknown } }) => {
  161. const isContainedValue = e.target.value;
  162. handleIsContainedChange(isContainedValue as number);
  163. }}
  164. />
  165. </form>
  166. <div className={classes.tableTip}>
  167. <Typography className="text">
  168. {insertTrans('previewTipData')}
  169. </Typography>
  170. <Typography className="text">
  171. {insertTrans('previewTipAction')}
  172. </Typography>
  173. </div>
  174. {tableData.length > 0 && (
  175. <div className={classes.gridWrapper}>
  176. <AttuGrid
  177. toolbarConfigs={[]}
  178. colDefinitions={colDefinitions}
  179. rows={tableData}
  180. rowCount={0}
  181. primaryKey="id"
  182. openCheckBox={false}
  183. showHoverStyle={false}
  184. headEditable={true}
  185. editHeads={editHeads}
  186. tableCellMaxWidth="120px"
  187. />
  188. </div>
  189. )}
  190. </section>
  191. );
  192. };
  193. export default InsertPreview;