소스 검색

[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;
projectDescription: string;
projectLeadId: number;
projectSubLeadId: number;
projectActualStart: string;
projectActualEnd: string;
projectPlanStart: string;


+ 1
- 0
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;


+ 5
- 0
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 (


+ 1
- 0
src/components/CreateProject/CreateProject.tsx 파일 보기

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


+ 25
- 1
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<Props> = ({
mainProjects,
projectCategories,
teamLeads,
allStaffs,
allCustomers,
allSubsidiaries,
serviceTypes,
@@ -195,6 +197,13 @@ const ProjectClientDetails: React.FC<Props> = ({
}
}, [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
const mainProjectId = watch("mainProjectId");
useEffect(() => {
@@ -210,11 +219,13 @@ const ProjectClientDetails: React.FC<Props> = ({
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<Props> = ({
}
},[planStart, planEnd])

return (
<Card sx={{ display: isActive ? "block" : "none" }}>
<CardContent component={Stack} spacing={4}>
@@ -401,6 +411,20 @@ const ProjectClientDetails: React.FC<Props> = ({
noOptionsText={t("No Team Lead")}
/>
</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}>
<ControlledAutoComplete
control={control}


+ 1
- 1
src/components/CustomerSave/CustomerSave.tsx 파일 보기

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


+ 3
- 0
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",


+ 3
- 0
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": "刪除",


불러오는 중...
취소
저장