浏览代码

[Project & Customer] Add sub-teamlead (project) and rename "confirm" -> "save" (customer)

main
cyril.tsui 2 周前
父节点
当前提交
f1004e6a9a
共有 8 个文件被更改,包括 40 次插入2 次删除
  1. +1
    -0
      src/app/api/projects/actions.ts
  2. +1
    -0
      src/app/api/projects/index.ts
  3. +5
    -0
      src/components/ControlledAutoComplete/ControlledAutoComplete.tsx
  4. +1
    -0
      src/components/CreateProject/CreateProject.tsx
  5. +25
    -1
      src/components/CreateProject/ProjectClientDetails.tsx
  6. +1
    -1
      src/components/CustomerSave/CustomerSave.tsx
  7. +3
    -0
      src/i18n/en/customer.json
  8. +3
    -0
      src/i18n/zh/customer.json

+ 1
- 0
src/app/api/projects/actions.ts 查看文件

@@ -19,6 +19,7 @@ export interface CreateProjectInputs {
projectCategoryId: number; projectCategoryId: number;
projectDescription: string; projectDescription: string;
projectLeadId: number; projectLeadId: number;
projectSubLeadId: number;
projectActualStart: string; projectActualStart: string;
projectActualEnd: string; projectActualEnd: string;
projectPlanStart: string; projectPlanStart: string;


+ 1
- 0
src/app/api/projects/index.ts 查看文件

@@ -25,6 +25,7 @@ export interface MainProject {
projectCategoryId: number; projectCategoryId: number;
projectDescription: string; projectDescription: string;
projectLeadId: number; projectLeadId: number;
projectSubLeadId: number;
projectStatus: string; projectStatus: string;
isClpProject: boolean; isClpProject: boolean;
serviceTypeId: number; serviceTypeId: number;


+ 5
- 0
src/components/ControlledAutoComplete/ControlledAutoComplete.tsx 查看文件

@@ -57,6 +57,11 @@ function ControlledAutoComplete<
control._formValues[name] = options[0]?.id ?? undefined; control._formValues[name] = options[0]?.id ?? undefined;
} else if (Boolean(isMultiple) && !Boolean(control._formValues[name])) { } else if (Boolean(isMultiple) && !Boolean(control._formValues[name])) {
control._formValues[name] = []; control._formValues[name] = [];
} else if (!Boolean(isMultiple)) {
const ids = options.map((opt) => opt.id)
if (!ids.includes(control._formValues[name])) {
control._formValues[name] = options[0]?.id ?? undefined;
}
} }


return ( return (


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

@@ -760,6 +760,7 @@ const CreateProject: React.FC<Props> = ({
projectCategories={projectCategories} projectCategories={projectCategories}
customerTypes={customerTypes} customerTypes={customerTypes}
teamLeads={teamLeads} teamLeads={teamLeads}
allStaffs={allStaffs}
isActive={tabIndex === 0} isActive={tabIndex === 0}
isEditMode={isEditMode} isEditMode={isEditMode}
/> />


+ 25
- 1
src/components/CreateProject/ProjectClientDetails.tsx 查看文件

@@ -46,6 +46,7 @@ interface Props {
mainProjects?: MainProject[]; mainProjects?: MainProject[];
projectCategories: ProjectCategory[]; projectCategories: ProjectCategory[];
teamLeads: StaffResult[]; teamLeads: StaffResult[];
allStaffs: StaffResult[];
allCustomers: Customer[]; allCustomers: Customer[];
allSubsidiaries: Subsidiary[]; allSubsidiaries: Subsidiary[];
serviceTypes: ServiceType[]; serviceTypes: ServiceType[];
@@ -64,6 +65,7 @@ const ProjectClientDetails: React.FC<Props> = ({
mainProjects, mainProjects,
projectCategories, projectCategories,
teamLeads, teamLeads,
allStaffs,
allCustomers, allCustomers,
allSubsidiaries, allSubsidiaries,
serviceTypes, serviceTypes,
@@ -195,6 +197,13 @@ const ProjectClientDetails: React.FC<Props> = ({
} }
}, [getValues, selectedTeamLeadId, setValue]); }, [getValues, selectedTeamLeadId, setValue]);


// List of possible sub team lead (staffs by team)
const subTeamLeads = useMemo<StaffResult[]>(() => {
if (!selectedTeamLeadId) return [];
const teamLead = teamLeads.find(tl => tl.id === selectedTeamLeadId);
return teamLead ? allStaffs.filter(staff => staff.team === teamLead.team) : [];
}, [selectedTeamLeadId, teamLeads, allStaffs]);

// Automatically update the project & client details whene select a main project // Automatically update the project & client details whene select a main project
const mainProjectId = watch("mainProjectId"); const mainProjectId = watch("mainProjectId");
useEffect(() => { useEffect(() => {
@@ -210,11 +219,13 @@ const ProjectClientDetails: React.FC<Props> = ({
if (mainProject !== undefined) { if (mainProject !== undefined) {


const teamLeadIds = teamLeads.map((teamLead) => teamLead.id) const teamLeadIds = teamLeads.map((teamLead) => teamLead.id)
const subTeamLeadIds = subTeamLeads.map((_subTeamLead) => _subTeamLead.id)
setValue("projectName", mainProject.projectName); setValue("projectName", mainProject.projectName);
setValue("projectCategoryId", mainProject.projectCategoryId); setValue("projectCategoryId", mainProject.projectCategoryId);


// set project lead id to the first team lead id if the main project lead id is not in the team lead list // set project lead id to the first team lead id if the main project lead id is not in the team lead list
setValue("projectLeadId", teamLeadIds.find((id) => id === mainProject.projectLeadId) ? mainProject.projectLeadId : teamLeadIds[0] ?? mainProject.projectLeadId); setValue("projectLeadId", teamLeadIds.find((id) => id === mainProject.projectLeadId) ? mainProject.projectLeadId : teamLeadIds[0] ?? mainProject.projectLeadId);
setValue("projectSubLeadId", subTeamLeadIds.find((id) => id === mainProject.projectSubLeadId) ? mainProject.projectSubLeadId : subTeamLeadIds[0] ?? mainProject.projectSubLeadId);
setValue("serviceTypeId", mainProject.serviceTypeId); setValue("serviceTypeId", mainProject.serviceTypeId);
setValue("fundingTypeId", mainProject.fundingTypeId); setValue("fundingTypeId", mainProject.fundingTypeId);
@@ -272,7 +283,6 @@ const ProjectClientDetails: React.FC<Props> = ({
} }
},[planStart, planEnd]) },[planStart, planEnd])

return ( return (
<Card sx={{ display: isActive ? "block" : "none" }}> <Card sx={{ display: isActive ? "block" : "none" }}>
<CardContent component={Stack} spacing={4}> <CardContent component={Stack} spacing={4}>
@@ -401,6 +411,20 @@ const ProjectClientDetails: React.FC<Props> = ({
noOptionsText={t("No Team Lead")} noOptionsText={t("No Team Lead")}
/> />
</Grid> </Grid>
{subTeamLeads.length > 0 && <Grid item xs={6}>
<ControlledAutoComplete
control={control}
options={subTeamLeads
// .filter(staff => staff.team === teamLeads.find(teamLead => teamLead.id === selectedTeamLeadId)?.team)
.map((staff) => ({
...staff,
label: `${staff.staffId} - ${staff.name} (${staff.team})`,
}))}
name="projectSubLeadId"
label={t("Sub Team Lead")}
noOptionsText={t("No Sub Team Lead")}
/>
</Grid>}
<Grid item xs={6}> <Grid item xs={6}>
<ControlledAutoComplete <ControlledAutoComplete
control={control} control={control}


+ 1
- 1
src/components/CustomerSave/CustomerSave.tsx 查看文件

@@ -273,7 +273,7 @@ const CustomerSave: React.FC<Props> = ({
{t("Cancel")} {t("Cancel")}
</Button> </Button>
<Button variant="contained" startIcon={<Check />} type="submit" disabled={Boolean(formProps.watch("isGridEditing"))}> <Button variant="contained" startIcon={<Check />} type="submit" disabled={Boolean(formProps.watch("isGridEditing"))}>
{t("Confirm")}
{t("Save")}
</Button> </Button>
</Stack> </Stack>
</Stack>} </Stack>}


+ 3
- 0
src/i18n/en/customer.json 查看文件

@@ -13,6 +13,8 @@
"Customer Details": "Client Details", "Customer Details": "Client Details",
"Customer Info": "Client Info", "Customer Info": "Client Info",
"Customer Type": "Client Type", "Customer Type": "Client Type",
"Created By": "Created By",
"Modified By": "Modified By",


"Please input correct customer code": "Please input correct client code", "Please input correct customer code": "Please input correct client code",
"Please input correct customer name": "Please input correct client name", "Please input correct customer name": "Please input correct client name",
@@ -59,6 +61,7 @@
"Search Criteria": "Search Criteria", "Search Criteria": "Search Criteria",
"Cancel": "Cancel", "Cancel": "Cancel",
"Confirm": "Confirm", "Confirm": "Confirm",
"Save": "Save",
"Submit": "Submit", "Submit": "Submit",
"Reset": "Reset", "Reset": "Reset",
"Delete": "Delete", "Delete": "Delete",


+ 3
- 0
src/i18n/zh/customer.json 查看文件

@@ -13,6 +13,8 @@
"Customer Details": "客戶詳請", "Customer Details": "客戶詳請",
"Customer Info": "客戶資料", "Customer Info": "客戶資料",
"Customer Type": "客戶類型", "Customer Type": "客戶類型",
"Created By": "創建者",
"Modified By": "修改者",


"Please input correct customer code": "請輸入客戶編號", "Please input correct customer code": "請輸入客戶編號",
"Please input correct customer name": "請輸入客戶編號", "Please input correct customer name": "請輸入客戶編號",
@@ -59,6 +61,7 @@
"Search Criteria": "搜尋條件", "Search Criteria": "搜尋條件",
"Cancel": "取消", "Cancel": "取消",
"Confirm": "確認", "Confirm": "確認",
"Save": "儲存",
"Submit": "提交", "Submit": "提交",
"Reset": "重置", "Reset": "重置",
"Delete": "刪除", "Delete": "刪除",


正在加载...
取消
保存