| @@ -1,7 +1,7 @@ | |||||
| import React, { useCallback, useMemo, useState, useEffect, SyntheticEvent } from "react"; | import React, { useCallback, useMemo, useState, useEffect, SyntheticEvent } from "react"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import { Button, TextField, CardContent, Typography, Divider, Card, Box, Autocomplete, MenuItem, AutocompleteChangeReason, AutocompleteChangeDetails } from "@mui/material"; | import { Button, TextField, CardContent, Typography, Divider, Card, Box, Autocomplete, MenuItem, AutocompleteChangeReason, AutocompleteChangeDetails } from "@mui/material"; | ||||
| import { Add, Check, Close, Delete} from "@mui/icons-material"; | |||||
| import { Add, Check, Close, ControlPointSharp, Delete} from "@mui/icons-material"; | |||||
| import { invoiceList } from "@/app/api/invoices"; | import { invoiceList } from "@/app/api/invoices"; | ||||
| import { | import { | ||||
| GridCellParams, | GridCellParams, | ||||
| @@ -23,7 +23,6 @@ import { GridToolbarContainer } from "@mui/x-data-grid"; | |||||
| import { FooterPropsOverrides } from "@mui/x-data-grid"; | import { FooterPropsOverrides } from "@mui/x-data-grid"; | ||||
| import { useFormContext } from "react-hook-form"; | import { useFormContext } from "react-hook-form"; | ||||
| import { ProjectResult } from "@/app/api/projects"; | import { ProjectResult } from "@/app/api/projects"; | ||||
| import useEnhancedEffect from "@mui/material/utils/useEnhancedEffect"; | |||||
| type InvoiceListError = { | type InvoiceListError = { | ||||
| [field in keyof invoiceList]?: string; | [field in keyof invoiceList]?: string; | ||||
| @@ -81,8 +80,7 @@ const InvoiceTable: React.FC<Props> = ({ projects, invoices }) => { | |||||
| ): InvoiceListError | undefined => { | ): InvoiceListError | undefined => { | ||||
| // Test for errors | // Test for errors | ||||
| const error: any = {}; | const error: any = {}; | ||||
| console.log(entry) | |||||
| if (!entry.issuedAmount) { | if (!entry.issuedAmount) { | ||||
| error.issuedAmount = true | error.issuedAmount = true | ||||
| error.message = t("Please input issued amount ") | error.message = t("Please input issued amount ") | ||||
| @@ -98,7 +96,7 @@ const InvoiceTable: React.FC<Props> = ({ projects, invoices }) => { | |||||
| } else if(!entry.invoiceNo){ | } else if(!entry.invoiceNo){ | ||||
| error.invoiceNo = true | error.invoiceNo = true | ||||
| error.message = t("Please input invoice No") | error.message = t("Please input invoice No") | ||||
| }else if(isInvoiceNoExists(entry.invoiceNo)){ | |||||
| }else if(isInvoiceExists(entry.invoiceNo)){ | |||||
| error.invoiceNo = true | error.invoiceNo = true | ||||
| error.message = t("Duplicate Invoice No") | error.message = t("Duplicate Invoice No") | ||||
| } | } | ||||
| @@ -106,12 +104,12 @@ const InvoiceTable: React.FC<Props> = ({ projects, invoices }) => { | |||||
| return Object.keys(error).length > 0 ? error : undefined; | return Object.keys(error).length > 0 ? error : undefined; | ||||
| } | } | ||||
| const isInvoiceNoExists = (invoiceNo: string): boolean => { | |||||
| // console.log(invoices.some(i => i.invoiceNo === invoiceNo)) | |||||
| const isInvoiceExists = (invoiceNo: string): boolean => { | |||||
| const result = invoices.some(i => i.invoiceNo === invoiceNo) | const result = invoices.some(i => i.invoiceNo === invoiceNo) | ||||
| return result | return result | ||||
| } | } | ||||
| const validateRow = useCallback( | const validateRow = useCallback( | ||||
| (id: GridRowId) => { | (id: GridRowId) => { | ||||
| const row = apiRef.current.getRowWithUpdatedValues( | const row = apiRef.current.getRowWithUpdatedValues( | ||||
| @@ -127,7 +125,7 @@ const InvoiceTable: React.FC<Props> = ({ projects, invoices }) => { | |||||
| return error; | return error; | ||||
| }, | }, | ||||
| [], | [], | ||||
| ); | |||||
| ); | |||||
| const handleEditStop = useCallback<GridEventListener<"rowEditStop">>( | const handleEditStop = useCallback<GridEventListener<"rowEditStop">>( | ||||
| (params, event) => { | (params, event) => { | ||||
| @@ -162,8 +160,6 @@ const InvoiceTable: React.FC<Props> = ({ projects, invoices }) => { | |||||
| [validateRow], | [validateRow], | ||||
| ); | ); | ||||
| const addRow = useCallback(() => { | const addRow = useCallback(() => { | ||||
| const newEntry = { id: Date.now(), _isNew: true }; | const newEntry = { id: Date.now(), _isNew: true }; | ||||
| setSelectedRow((e) => [...e, newEntry]); | setSelectedRow((e) => [...e, newEntry]); | ||||
| @@ -189,8 +185,20 @@ const InvoiceTable: React.FC<Props> = ({ projects, invoices }) => { | |||||
| ...model, | ...model, | ||||
| [id]: { mode: GridRowModes.View, ignoreModifications: true }, | [id]: { mode: GridRowModes.View, ignoreModifications: true }, | ||||
| })); | })); | ||||
| const editRow = selectedRow.find(row => getRowId(row) === id) | |||||
| if (editRow?._isNew) { | |||||
| setSelectedRow((row => row.filter(r => getRowId(r) !== id))) | |||||
| }else{ | |||||
| setSelectedRow((row) => | |||||
| row.map((r) => | |||||
| getRowId(r) === id | |||||
| ? { ...r, _error: undefined} | |||||
| : r | |||||
| ) | |||||
| ) | |||||
| } | |||||
| }, | }, | ||||
| [], | |||||
| [selectedRow, getRowId], | |||||
| ); | ); | ||||
| const handleDelete = useCallback( | const handleDelete = useCallback( | ||||
| @@ -256,12 +264,13 @@ const InvoiceTable: React.FC<Props> = ({ projects, invoices }) => { | |||||
| }, [selectedRow, setValue]); | }, [selectedRow, setValue]); | ||||
| function renderAutocomplete(params: GridRenderCellParams<any, number>) { | function renderAutocomplete(params: GridRenderCellParams<any, number>) { | ||||
| console.log(params) | |||||
| return( | return( | ||||
| <Box sx={{ display: 'flex', alignItems: 'center', pr: 2, }}> | <Box sx={{ display: 'flex', alignItems: 'center', pr: 2, }}> | ||||
| <Autocomplete | <Autocomplete | ||||
| readOnly | readOnly | ||||
| sx={{ width: 300 }} | sx={{ width: 300 }} | ||||
| value={params.row.projectCode} | |||||
| value={params.row.projectCode} | |||||
| options={projectCombos} | options={projectCombos} | ||||
| renderInput={(params) => <TextField {...params} />} | renderInput={(params) => <TextField {...params} />} | ||||
| /> | /> | ||||
| @@ -273,15 +282,20 @@ const InvoiceTable: React.FC<Props> = ({ projects, invoices }) => { | |||||
| const { id, value, field, hasFocus } = props; | const { id, value, field, hasFocus } = props; | ||||
| const apiRef = useGridApiContext(); | const apiRef = useGridApiContext(); | ||||
| const handleValueChange = useCallback((newValue: any) => { | |||||
| console.log(newValue) | |||||
| console.log(value) | |||||
| const handleValueChange = useCallback((newValue: any) => { | |||||
| // console.log(id, field, newValue) | |||||
| apiRef.current.setEditCellValue({ id, field, value: newValue }) | apiRef.current.setEditCellValue({ id, field, value: newValue }) | ||||
| }, []); | }, []); | ||||
| // console.log(projectCombos.find(o => o?.toString() === value?.toString())) | |||||
| return ( | return ( | ||||
| <Box sx={{ display: 'flex', alignItems: 'center', pr: 2 }}> | <Box sx={{ display: 'flex', alignItems: 'center', pr: 2 }}> | ||||
| <Autocomplete | <Autocomplete | ||||
| disablePortal | disablePortal | ||||
| value={props.row.projectCode} | |||||
| options={projectCombos} | options={projectCombos} | ||||
| sx={{ width: 300 }} | sx={{ width: 300 }} | ||||
| onChange={(event: React.SyntheticEvent<Element, Event>, value: string | null, ) => handleValueChange(value)} | onChange={(event: React.SyntheticEvent<Element, Event>, value: string | null, ) => handleValueChange(value)} | ||||
| @@ -340,7 +354,7 @@ const editCombinedColumns = useMemo<GridColDef[]>( | |||||
| field: "actions", | field: "actions", | ||||
| headerName: t("Actions"), | headerName: t("Actions"), | ||||
| getActions: ({ id }) => { | getActions: ({ id }) => { | ||||
| console.log(rowModesModel[id]?.mode === GridRowModes.Edit) | |||||
| console.log(rowModesModel[id]?.mode) | |||||
| if (rowModesModel[id]?.mode === GridRowModes.Edit) { | if (rowModesModel[id]?.mode === GridRowModes.Edit) { | ||||
| return [ | return [ | ||||
| <GridActionsCellItem | <GridActionsCellItem | ||||
| @@ -369,7 +383,7 @@ const editCombinedColumns = useMemo<GridColDef[]>( | |||||
| }, | }, | ||||
| }, | }, | ||||
| ], | ], | ||||
| [t] | |||||
| [t, rowModesModel, handleSave, handleCancel, handleDelete] | |||||
| ) | ) | ||||
| const footer = ( | const footer = ( | ||||