浏览代码

1. Add isTimesheetAdmendment props to project select component, to show all projects when using timesheet admendment, to limit the projects when using timesheet input

2. fallback search resulr from column sorting feature updates
3. Add selected project display in Project cash flow page
develop
MSI\2Fi 4 个月前
父节点
当前提交
938f128271
共有 6 个文件被更改,包括 92 次插入78 次删除
  1. +4
    -4
      src/components/MailSetting/MailSetting.tsx
  2. +17
    -2
      src/components/ProjectCashFlow/ProjectCashFlow.tsx
  3. +4
    -1
      src/components/ProjectSearch/ProjectSearchWrapper.tsx
  4. +48
    -58
      src/components/SearchResults/SearchResults.tsx
  5. +18
    -13
      src/components/TimesheetTable/ProjectSelect.tsx
  6. +1
    -0
      src/components/TimesheetTable/TimesheetEditModal.tsx

+ 4
- 4
src/components/MailSetting/MailSetting.tsx 查看文件

@@ -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)


+ 17
- 2
src/components/ProjectCashFlow/ProjectCashFlow.tsx 查看文件

@@ -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}>


+ 4
- 1
src/components/ProjectSearch/ProjectSearchWrapper.tsx 查看文件

@@ -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 (


+ 48
- 58
src/components/SearchResults/SearchResults.tsx 查看文件

@@ -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}


+ 18
- 13
src/components/TimesheetTable/ProjectSelect.tsx 查看文件

@@ -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]);



+ 1
- 0
src/components/TimesheetTable/TimesheetEditModal.tsx 查看文件

@@ -177,6 +177,7 @@ const TimesheetEditModal: React.FC<Props> = ({
setValue("taskGroupId", firstTaskGroup?.value);
setValue("taskId", undefined);
}}
isTimesheetAdmendment={true}
/>
)}
rules={{ deps: ["taskGroupId", "taskId"] }}


正在加载...
取消
保存