diff --git a/src/app/api/projects/actions.ts b/src/app/api/projects/actions.ts index 96d79b9..5d8a178 100644 --- a/src/app/api/projects/actions.ts +++ b/src/app/api/projects/actions.ts @@ -19,6 +19,7 @@ export interface CreateProjectInputs { projectCategoryId: number; projectDescription: string; projectLeadId: number; + projectSubLeadId: number; projectActualStart: string; projectActualEnd: string; projectPlanStart: string; diff --git a/src/app/api/projects/index.ts b/src/app/api/projects/index.ts index c8e77e4..e9b6f7c 100644 --- a/src/app/api/projects/index.ts +++ b/src/app/api/projects/index.ts @@ -25,6 +25,7 @@ export interface MainProject { projectCategoryId: number; projectDescription: string; projectLeadId: number; + projectSubLeadId: number; projectStatus: string; isClpProject: boolean; serviceTypeId: number; diff --git a/src/components/ControlledAutoComplete/ControlledAutoComplete.tsx b/src/components/ControlledAutoComplete/ControlledAutoComplete.tsx index c2a2044..037df88 100644 --- a/src/components/ControlledAutoComplete/ControlledAutoComplete.tsx +++ b/src/components/ControlledAutoComplete/ControlledAutoComplete.tsx @@ -57,6 +57,11 @@ function ControlledAutoComplete< control._formValues[name] = options[0]?.id ?? undefined; } else if (Boolean(isMultiple) && !Boolean(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 ( diff --git a/src/components/CreateProject/CreateProject.tsx b/src/components/CreateProject/CreateProject.tsx index a7ada1b..4fc78ce 100644 --- a/src/components/CreateProject/CreateProject.tsx +++ b/src/components/CreateProject/CreateProject.tsx @@ -760,6 +760,7 @@ const CreateProject: React.FC = ({ projectCategories={projectCategories} customerTypes={customerTypes} teamLeads={teamLeads} + allStaffs={allStaffs} isActive={tabIndex === 0} isEditMode={isEditMode} /> diff --git a/src/components/CreateProject/ProjectClientDetails.tsx b/src/components/CreateProject/ProjectClientDetails.tsx index 5e86694..5b97e60 100644 --- a/src/components/CreateProject/ProjectClientDetails.tsx +++ b/src/components/CreateProject/ProjectClientDetails.tsx @@ -46,6 +46,7 @@ interface Props { mainProjects?: MainProject[]; projectCategories: ProjectCategory[]; teamLeads: StaffResult[]; + allStaffs: StaffResult[]; allCustomers: Customer[]; allSubsidiaries: Subsidiary[]; serviceTypes: ServiceType[]; @@ -64,6 +65,7 @@ const ProjectClientDetails: React.FC = ({ mainProjects, projectCategories, teamLeads, + allStaffs, allCustomers, allSubsidiaries, serviceTypes, @@ -195,6 +197,13 @@ const ProjectClientDetails: React.FC = ({ } }, [getValues, selectedTeamLeadId, setValue]); + // List of possible sub team lead (staffs by team) + const subTeamLeads = useMemo(() => { + 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 const mainProjectId = watch("mainProjectId"); useEffect(() => { @@ -210,11 +219,13 @@ const ProjectClientDetails: React.FC = ({ if (mainProject !== undefined) { const teamLeadIds = teamLeads.map((teamLead) => teamLead.id) + const subTeamLeadIds = subTeamLeads.map((_subTeamLead) => _subTeamLead.id) setValue("projectName", mainProject.projectName); 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 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("fundingTypeId", mainProject.fundingTypeId); @@ -272,7 +283,6 @@ const ProjectClientDetails: React.FC = ({ } },[planStart, planEnd]) - return ( @@ -401,6 +411,20 @@ const ProjectClientDetails: React.FC = ({ noOptionsText={t("No Team Lead")} /> + {subTeamLeads.length > 0 && + 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")} + /> + } = ({ {t("Cancel")} } diff --git a/src/i18n/en/customer.json b/src/i18n/en/customer.json index 0f828fc..4a6b3e0 100644 --- a/src/i18n/en/customer.json +++ b/src/i18n/en/customer.json @@ -13,6 +13,8 @@ "Customer Details": "Client Details", "Customer Info": "Client Info", "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 name": "Please input correct client name", @@ -59,6 +61,7 @@ "Search Criteria": "Search Criteria", "Cancel": "Cancel", "Confirm": "Confirm", + "Save": "Save", "Submit": "Submit", "Reset": "Reset", "Delete": "Delete", diff --git a/src/i18n/zh/customer.json b/src/i18n/zh/customer.json index 31a61ac..a70e381 100644 --- a/src/i18n/zh/customer.json +++ b/src/i18n/zh/customer.json @@ -13,6 +13,8 @@ "Customer Details": "客戶詳請", "Customer Info": "客戶資料", "Customer Type": "客戶類型", + "Created By": "創建者", + "Modified By": "修改者", "Please input correct customer code": "請輸入客戶編號", "Please input correct customer name": "請輸入客戶編號", @@ -59,6 +61,7 @@ "Search Criteria": "搜尋條件", "Cancel": "取消", "Confirm": "確認", + "Save": "儲存", "Submit": "提交", "Reset": "重置", "Delete": "刪除",