2. fallback search resulr from column sorting feature updates 3. Add selected project display in Project cash flow pagedevelop
| @@ -95,10 +95,10 @@ const MailSetting: React.FC<Props> = ({ | |||
| try { | |||
| // msg = "testEveryone" | |||
| // await testEveryone() | |||
| msg = "test7th" | |||
| await test7th() | |||
| // msg = "test15th" | |||
| // await test15th() | |||
| // msg = "test7th" | |||
| // await test7th() | |||
| msg = "test15th" | |||
| await test15th() | |||
| } catch (error) { | |||
| console.log(error) | |||
| console.log(msg) | |||
| @@ -5,7 +5,7 @@ import { useState, useEffect, useMemo } from "react"; | |||
| import Paper from "@mui/material/Paper"; | |||
| import { TFunction } from "i18next"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import { Card, CardHeader } from "@mui/material"; | |||
| import { Card, CardContent, CardHeader } from "@mui/material"; | |||
| import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; | |||
| import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; | |||
| import ReactApexChart from "react-apexcharts"; | |||
| @@ -26,6 +26,7 @@ import dayjs from 'dayjs'; | |||
| import ProjectTotalFee from "../CreateInvoice_forGen/ProjectTotalFee"; | |||
| import Typography from "@mui/material/Typography"; | |||
| import { useSearchParams } from 'next/navigation'; | |||
| import { ResetTvOutlined } from "@mui/icons-material"; | |||
| interface Props { | |||
| projects: CashFlow[]; | |||
| @@ -64,6 +65,7 @@ const ProjectCashFlow: React.FC = () => { | |||
| const [monthlyAnticipateExpenditureList, setMonthlyAnticipateExpenditureList]: any[] = React.useState([0,0,0,0,0,0,0,0,0,0,0,0]); | |||
| const [ledgerData, setLedgerData]: any[] = React.useState([]); | |||
| const [isInitializing, setIsInitializing] = useState(true); | |||
| const [projectInfo, setProjectInfo]: any[] = useState([]) | |||
| const [cashFlowYear, setCashFlowYear]: any[] = React.useState( | |||
| todayDate.getFullYear(), | |||
| ); | |||
| @@ -86,6 +88,11 @@ const ProjectCashFlow: React.FC = () => { | |||
| ); | |||
| const projectIdList = selectedRowsData.map((row: any) => row.id); | |||
| setSelectedProjectIdList(projectIdList); | |||
| console.log(projectData) | |||
| setProjectInfo(projectData.filter((result:any)=> { | |||
| // console.log("Checking ID:", result.id, "against list:", projectIdList); | |||
| return projectIdList.includes(result.id) | |||
| })) | |||
| } | |||
| }; | |||
| @@ -240,7 +247,6 @@ const ProjectCashFlow: React.FC = () => { | |||
| fetchReceivableAndExpenditureData(); | |||
| fetchAnticipateData(); | |||
| fetchProjectCashFlowLedger(); | |||
| }, [cashFlowYear,selectedProjectIdList]); | |||
| useEffect(() => { | |||
| @@ -829,6 +835,15 @@ const ProjectCashFlow: React.FC = () => { | |||
| onRowSelectionModelChange={handleSelectionChange} | |||
| rowSelectionModel={selectionModel} | |||
| /> | |||
| <Grid container> | |||
| <Grid item xs={12} md={12} lg={12}> | |||
| <Card> | |||
| <CardContent> | |||
| { projectInfo[0]?.projectCode && `${projectInfo[0]?.projectCode} - ${projectInfo[0]?.projectName}`} | |||
| </CardContent> | |||
| </Card> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item sm> | |||
| <div style={{ display: "inline-block", width: "50%" }}> | |||
| <Grid item xs={12} md={12} lg={12}> | |||
| @@ -28,7 +28,10 @@ const ProjectSearchWrapper: React.FC & SubComponents = async () => { | |||
| let filteredProjects = projects; | |||
| if (!isViewAllProjectRight) { | |||
| filteredProjects = projects.filter((project) => project.teamId === teamId || project.team === "ST"); | |||
| filteredProjects = projects.filter((project) => project.teamId === teamId ); | |||
| if (teamId == 1){ | |||
| filteredProjects = projects.filter((project) => project.teamId === teamId || project.team === "ST"); | |||
| } | |||
| } | |||
| return ( | |||
| @@ -158,50 +158,50 @@ function SearchResults<T extends ResultWithId>({ | |||
| return column.underline ?? "always"; | |||
| }; | |||
| type OrderProps = Record<keyof T, Boolean> | |||
| const [sortedItems, setSortedItems] = useState(items) | |||
| const [orderProps, setOrderProps] = useState<OrderProps>(() => { | |||
| if (items.length === 0) { | |||
| return {} as OrderProps | |||
| } | |||
| return Object.keys(sortedItems[0]).reduce((acc, key) => { | |||
| if (key === "deleted" || key === "id") return acc | |||
| acc[key as keyof T] = false; | |||
| return acc; | |||
| }, {} as OrderProps); | |||
| }); | |||
| const changeOrder = useCallback((key: keyof T) => { | |||
| // preserve all column sorting | |||
| // setOrderProps( | |||
| // (prev) => ({ | |||
| // [...prev]: false, | |||
| // [key]: !prev[key] | |||
| // }) | |||
| // ) | |||
| // only sort 1 column | |||
| setOrderProps( | |||
| (prev) => { | |||
| const newOrderProps = Object.keys(prev).reduce((acc, currKey) => { | |||
| acc[currKey as keyof T] = currKey === key ? !prev[currKey as keyof T] : false; | |||
| return acc; | |||
| }, {} as OrderProps); | |||
| return newOrderProps; | |||
| } | |||
| ) | |||
| }, []) | |||
| const sortingItems = useCallback( | |||
| (key: keyof T) => { | |||
| // true === asc | |||
| // false === desc | |||
| console.log(orderProps) | |||
| if (orderProps[key]) { | |||
| return orderBy(sortedItems, key, 'asc') | |||
| } else { | |||
| return orderBy(sortedItems, key, 'desc') | |||
| } | |||
| } | |||
| , [sortedItems, orderProps] | |||
| ) | |||
| // type OrderProps = Record<keyof T, Boolean> | |||
| // const [sortedItems, setSortedItems] = useState(items) | |||
| // const [orderProps, setOrderProps] = useState<OrderProps>(() => { | |||
| // if (items.length === 0) { | |||
| // return {} as OrderProps | |||
| // } | |||
| // return Object.keys(sortedItems[0]).reduce((acc, key) => { | |||
| // if (key === "deleted" || key === "id") return acc | |||
| // acc[key as keyof T] = false; | |||
| // return acc; | |||
| // }, {} as OrderProps); | |||
| // }); | |||
| // const changeOrder = useCallback((key: keyof T) => { | |||
| // // preserve all column sorting | |||
| // // setOrderProps( | |||
| // // (prev) => ({ | |||
| // // [...prev]: false, | |||
| // // [key]: !prev[key] | |||
| // // }) | |||
| // // ) | |||
| // // only sort 1 column | |||
| // setOrderProps( | |||
| // (prev) => { | |||
| // const newOrderProps = Object.keys(prev).reduce((acc, currKey) => { | |||
| // acc[currKey as keyof T] = currKey === key ? !prev[currKey as keyof T] : false; | |||
| // return acc; | |||
| // }, {} as OrderProps); | |||
| // return newOrderProps; | |||
| // } | |||
| // ) | |||
| // }, []) | |||
| // const sortingItems = useCallback( | |||
| // (key: keyof T) => { | |||
| // // true === asc | |||
| // // false === desc | |||
| // console.log(orderProps) | |||
| // if (orderProps[key]) { | |||
| // return orderBy(sortedItems, key, 'asc') | |||
| // } else { | |||
| // return orderBy(sortedItems, key, 'desc') | |||
| // } | |||
| // } | |||
| // , [sortedItems, orderProps] | |||
| // ) | |||
| const table = ( | |||
| <> | |||
| <TableContainer sx={{ maxHeight: 440 }}> | |||
| @@ -209,25 +209,15 @@ function SearchResults<T extends ResultWithId>({ | |||
| <TableHead> | |||
| <TableRow> | |||
| {columns.filter(item => item.isHidden !== true).map((column, idx) => ( | |||
| <TableCell | |||
| key={`${column.name.toString()}${idx}`} | |||
| onClick={() => { | |||
| changeOrder(column.name) | |||
| setSortedItems(sortingItems(column.name)) | |||
| }} | |||
| > | |||
| <TableCell key={`${column.name.toString()}${idx}`}> | |||
| {column?.type === "money" ? <div style={{display: "flex", justifyContent: "flex-end"}}>{column.label}</div> : column.label} | |||
| {(() => { | |||
| const isAscending = orderProps[column.name]; | |||
| if (isAscending === undefined) return undefined; | |||
| return isAscending ? <ArrowUp /> : <ArrowDown />; | |||
| })()} | |||
| </TableCell> | |||
| ))} | |||
| </TableRow> | |||
| </TableHead> | |||
| <TableBody> | |||
| {sortedItems | |||
| {items | |||
| .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) | |||
| .map((item) => { | |||
| return ( | |||
| @@ -280,7 +270,7 @@ function SearchResults<T extends ResultWithId>({ | |||
| <TablePagination | |||
| rowsPerPageOptions={[10, 25, 100]} | |||
| component="div" | |||
| count={sortedItems.length} | |||
| count={items.length} | |||
| rowsPerPage={rowsPerPage} | |||
| page={page} | |||
| onPageChange={handleChangePage} | |||
| @@ -25,6 +25,7 @@ interface CommonProps { | |||
| referenceDay: Dayjs; | |||
| includeLeaves?: boolean; | |||
| leaveTypes?: LeaveType[]; | |||
| isTimesheetAdmendment?: boolean; | |||
| } | |||
| interface SingleAutocompleteProps extends CommonProps { | |||
| @@ -44,7 +45,8 @@ interface MultiAutocompleteProps extends CommonProps { | |||
| includeLeaves: false; | |||
| } | |||
| type Props = SingleAutocompleteProps | MultiAutocompleteProps; | |||
| type Props = SingleAutocompleteProps | MultiAutocompleteProps ; | |||
| const getGroupName = (t: TFunction, groupName: string): string => { | |||
| switch (groupName) { | |||
| @@ -73,6 +75,7 @@ const AutocompleteProjectSelect: React.FC<Props> = ({ | |||
| multiple, | |||
| leaveTypes, | |||
| includeLeaves, | |||
| isTimesheetAdmendment | |||
| }) => { | |||
| const { t } = useTranslation("home"); | |||
| const allFilteredProjects = useMemo(() => { | |||
| @@ -97,18 +100,20 @@ console.log(assignedProjects) | |||
| label: `${p.code} - ${p.name}`, | |||
| group: "assigned", | |||
| })), | |||
| // ...(includeLeaves && leaveTypes | |||
| // ? leaveTypes.map((l) => ({ | |||
| // value: `leave-${l.id}`, | |||
| // label: t(l.name), | |||
| // group: "leaves", | |||
| // })) | |||
| // : []), | |||
| // ...nonAssignedProjects.map((p) => ({ | |||
| // value: p.id, | |||
| // label: `${p.code} - ${p.name}`, | |||
| // group: assignedProjects.length === 0 ? "all-projects" : "non-assigned", | |||
| // })), | |||
| ...(includeLeaves && leaveTypes | |||
| ? leaveTypes.map((l) => ({ | |||
| value: `leave-${l.id}`, | |||
| label: t(l.name), | |||
| group: "leaves", | |||
| })) | |||
| : []), | |||
| ...(isTimesheetAdmendment | |||
| ? nonAssignedProjects.map((p) => ({ | |||
| value: p.id, | |||
| label: `${p.code} - ${p.name}`, | |||
| group: assignedProjects.length === 0 ? "all-projects" : "non-assigned", | |||
| })) | |||
| : []), | |||
| ]; | |||
| }, [assignedProjects, includeLeaves, leaveTypes, nonAssignedProjects, t]); | |||
| @@ -177,6 +177,7 @@ const TimesheetEditModal: React.FC<Props> = ({ | |||
| setValue("taskGroupId", firstTaskGroup?.value); | |||
| setValue("taskId", undefined); | |||
| }} | |||
| isTimesheetAdmendment={true} | |||
| /> | |||
| )} | |||
| rules={{ deps: ["taskGroupId", "taskId"] }} | |||