| @@ -8,8 +8,6 @@ import { | |||
| fetchTeamMemberTimesheets, | |||
| fetchTimesheets, | |||
| } from "@/app/api/timesheets"; | |||
| import { authOptions } from "@/config/authConfig"; | |||
| import { getServerSession } from "next-auth"; | |||
| import { | |||
| fetchAssignedProjects, | |||
| fetchProjectWithTasks, | |||
| @@ -21,22 +19,18 @@ export const metadata: Metadata = { | |||
| }; | |||
| const Home: React.FC = async () => { | |||
| const session = await getServerSession(authOptions); | |||
| // Get name for caching | |||
| const username = session!.user!.name!; | |||
| fetchTimesheets(username); | |||
| fetchAssignedProjects(username); | |||
| fetchLeaves(username); | |||
| fetchTimesheets(); | |||
| fetchAssignedProjects(); | |||
| fetchLeaves(); | |||
| fetchLeaveTypes(); | |||
| fetchProjectWithTasks(); | |||
| fetchHolidays(); | |||
| fetchTeamMemberTimesheets(username); | |||
| fetchTeamMemberLeaves(username); | |||
| fetchTeamMemberTimesheets(); | |||
| fetchTeamMemberLeaves(); | |||
| return ( | |||
| <I18nProvider namespaces={["home", "common"]}> | |||
| <UserWorkspacePage username={username} /> | |||
| <UserWorkspacePage /> | |||
| </I18nProvider> | |||
| ); | |||
| }; | |||
| @@ -170,11 +170,11 @@ export const fetchProjectWorkNatures = cache(async () => { | |||
| }); | |||
| }); | |||
| export const fetchAssignedProjects = cache(async (username: string) => { | |||
| export const fetchAssignedProjects = cache(async () => { | |||
| return serverFetchJson<AssignedProject[]>( | |||
| `${BASE_API_URL}/projects/assignedProjects`, | |||
| { | |||
| next: { tags: [`assignedProjects__${username}`] }, | |||
| next: { tags: [`assignedProjects`] }, | |||
| }, | |||
| ); | |||
| }); | |||
| @@ -31,10 +31,7 @@ export interface RecordLeaveInput { | |||
| [date: string]: LeaveEntry[]; | |||
| } | |||
| export const saveTimesheet = async ( | |||
| data: RecordTimesheetInput, | |||
| username: string, | |||
| ) => { | |||
| export const saveTimesheet = async (data: RecordTimesheetInput) => { | |||
| const savedRecords = await serverFetchJson<RecordTimesheetInput>( | |||
| `${BASE_API_URL}/timesheets/save`, | |||
| { | |||
| @@ -44,12 +41,12 @@ export const saveTimesheet = async ( | |||
| }, | |||
| ); | |||
| revalidateTag(`timesheets_${username}`); | |||
| revalidateTag(`timesheets`); | |||
| return savedRecords; | |||
| }; | |||
| export const saveLeave = async (data: RecordLeaveInput, username: string) => { | |||
| export const saveLeave = async (data: RecordLeaveInput) => { | |||
| const savedRecords = await serverFetchJson<RecordLeaveInput>( | |||
| `${BASE_API_URL}/timesheets/saveLeave`, | |||
| { | |||
| @@ -59,7 +56,7 @@ export const saveLeave = async (data: RecordLeaveInput, username: string) => { | |||
| }, | |||
| ); | |||
| revalidateTag(`leaves_${username}`); | |||
| revalidateTag(`leaves`); | |||
| return savedRecords; | |||
| }; | |||
| @@ -24,17 +24,17 @@ export type TeamLeaves = { | |||
| }; | |||
| }; | |||
| export const fetchTimesheets = cache(async (username: string) => { | |||
| export const fetchTimesheets = cache(async () => { | |||
| return serverFetchJson<RecordTimesheetInput>(`${BASE_API_URL}/timesheets`, { | |||
| next: { tags: [`timesheets_${username}`] }, | |||
| next: { tags: [`timesheets`] }, | |||
| }); | |||
| }); | |||
| export const fetchLeaves = cache(async (username: string) => { | |||
| export const fetchLeaves = cache(async () => { | |||
| return serverFetchJson<RecordLeaveInput>( | |||
| `${BASE_API_URL}/timesheets/leaves`, | |||
| { | |||
| next: { tags: [`leaves_${username}`] }, | |||
| next: { tags: [`leaves`] }, | |||
| }, | |||
| ); | |||
| }); | |||
| @@ -45,17 +45,17 @@ export const fetchLeaveTypes = cache(async () => { | |||
| }); | |||
| }); | |||
| export const fetchTeamMemberTimesheets = cache(async (username: string) => { | |||
| export const fetchTeamMemberTimesheets = cache(async () => { | |||
| return serverFetchJson<TeamTimeSheets>( | |||
| `${BASE_API_URL}/timesheets/teamTimesheets`, | |||
| { | |||
| next: { tags: [`team_timesheets_${username}`] }, | |||
| next: { tags: [`team_timesheets`] }, | |||
| }, | |||
| ); | |||
| }); | |||
| export const fetchTeamMemberLeaves = cache(async (username: string) => { | |||
| export const fetchTeamMemberLeaves = cache(async () => { | |||
| return serverFetchJson<TeamLeaves>(`${BASE_API_URL}/timesheets/teamLeaves`, { | |||
| next: { tags: [`team_leaves_${username}`] }, | |||
| next: { tags: [`team_leaves`] }, | |||
| }); | |||
| }); | |||
| @@ -36,7 +36,6 @@ import ErrorAlert from "../ErrorAlert"; | |||
| interface Props { | |||
| isOpen: boolean; | |||
| onClose: () => void; | |||
| username: string; | |||
| defaultLeaveRecords?: RecordLeaveInput; | |||
| leaveTypes: LeaveType[]; | |||
| timesheetRecords: RecordTimesheetInput; | |||
| @@ -56,7 +55,6 @@ const modalSx: SxProps = { | |||
| const LeaveModal: React.FC<Props> = ({ | |||
| isOpen, | |||
| onClose, | |||
| username, | |||
| defaultLeaveRecords, | |||
| timesheetRecords, | |||
| leaveTypes, | |||
| @@ -97,7 +95,7 @@ const LeaveModal: React.FC<Props> = ({ | |||
| ); | |||
| return; | |||
| } | |||
| const savedRecords = await saveLeave(data, username); | |||
| const savedRecords = await saveLeave(data); | |||
| const today = dayjs(); | |||
| const newFormValues = Array(7) | |||
| @@ -113,7 +111,7 @@ const LeaveModal: React.FC<Props> = ({ | |||
| formProps.reset(newFormValues); | |||
| onClose(); | |||
| }, | |||
| [companyHolidays, formProps, onClose, timesheetRecords, username], | |||
| [companyHolidays, formProps, onClose, timesheetRecords], | |||
| ); | |||
| const onCancel = useCallback(() => { | |||
| @@ -1,6 +1,9 @@ | |||
| import { LeaveType } from "@/app/api/timesheets"; | |||
| import { LeaveEntry } from "@/app/api/timesheets/actions"; | |||
| import { DAILY_NORMAL_MAX_HOURS } from "@/app/api/timesheets/utils"; | |||
| import { | |||
| DAILY_NORMAL_MAX_HOURS, | |||
| TIMESHEET_DAILY_MAX_HOURS, | |||
| } from "@/app/api/timesheets/utils"; | |||
| import { shortDateFormatter } from "@/app/utils/formatUtil"; | |||
| import { roundToNearestQuarter } from "@/app/utils/manhourUtils"; | |||
| import { Check, Delete } from "@mui/icons-material"; | |||
| @@ -153,7 +156,10 @@ const LeaveEditModal: React.FC<Props> = ({ | |||
| /> | |||
| {formState.errors.root?.message && ( | |||
| <Typography variant="caption" color="error"> | |||
| {t(formState.errors.root.message, { DAILY_NORMAL_MAX_HOURS })} | |||
| {t(formState.errors.root.message, { | |||
| DAILY_NORMAL_MAX_HOURS, | |||
| TIMESHEET_DAILY_MAX_HOURS, | |||
| })} | |||
| </Typography> | |||
| )} | |||
| <Box display="flex" justifyContent="flex-end" gap={1}> | |||
| @@ -38,7 +38,6 @@ interface Props { | |||
| onClose: () => void; | |||
| allProjects: ProjectWithTasks[]; | |||
| assignedProjects: AssignedProject[]; | |||
| username: string; | |||
| defaultTimesheets?: RecordTimesheetInput; | |||
| leaveRecords: RecordLeaveInput; | |||
| companyHolidays: HolidaysResult[]; | |||
| @@ -60,7 +59,6 @@ const TimesheetModal: React.FC<Props> = ({ | |||
| onClose, | |||
| allProjects, | |||
| assignedProjects, | |||
| username, | |||
| defaultTimesheets, | |||
| leaveRecords, | |||
| companyHolidays, | |||
| @@ -97,7 +95,7 @@ const TimesheetModal: React.FC<Props> = ({ | |||
| ); | |||
| return; | |||
| } | |||
| const savedRecords = await saveTimesheet(data, username); | |||
| const savedRecords = await saveTimesheet(data); | |||
| const today = dayjs(); | |||
| const newFormValues = Array(7) | |||
| @@ -113,7 +111,7 @@ const TimesheetModal: React.FC<Props> = ({ | |||
| formProps.reset(newFormValues); | |||
| onClose(); | |||
| }, | |||
| [companyHolidays, formProps, leaveRecords, onClose, username], | |||
| [companyHolidays, formProps, leaveRecords, onClose], | |||
| ); | |||
| const onCancel = useCallback(() => { | |||
| @@ -23,7 +23,10 @@ import { TaskGroup } from "@/app/api/tasks"; | |||
| import uniqBy from "lodash/uniqBy"; | |||
| import { roundToNearestQuarter } from "@/app/utils/manhourUtils"; | |||
| import { shortDateFormatter } from "@/app/utils/formatUtil"; | |||
| import { DAILY_NORMAL_MAX_HOURS } from "@/app/api/timesheets/utils"; | |||
| import { | |||
| DAILY_NORMAL_MAX_HOURS, | |||
| TIMESHEET_DAILY_MAX_HOURS, | |||
| } from "@/app/api/timesheets/utils"; | |||
| export interface Props extends Omit<ModalProps, "children"> { | |||
| onSave: (timeEntry: TimeEntry, recordDate?: string) => Promise<void>; | |||
| @@ -277,7 +280,10 @@ const TimesheetEditModal: React.FC<Props> = ({ | |||
| /> | |||
| {formState.errors.root?.message && ( | |||
| <Typography variant="caption" color="error"> | |||
| {t(formState.errors.root.message, { DAILY_NORMAL_MAX_HOURS })} | |||
| {t(formState.errors.root.message, { | |||
| DAILY_NORMAL_MAX_HOURS, | |||
| TIMESHEET_DAILY_MAX_HOURS, | |||
| })} | |||
| </Typography> | |||
| )} | |||
| <Box display="flex" justifyContent="flex-end" gap={1}> | |||
| @@ -30,7 +30,6 @@ export interface Props { | |||
| leaveTypes: LeaveType[]; | |||
| allProjects: ProjectWithTasks[]; | |||
| assignedProjects: AssignedProject[]; | |||
| username: string; | |||
| defaultLeaveRecords: RecordLeaveInput; | |||
| defaultTimesheets: RecordTimesheetInput; | |||
| holidays: HolidaysResult[]; | |||
| @@ -48,7 +47,6 @@ const UserWorkspacePage: React.FC<Props> = ({ | |||
| leaveTypes, | |||
| allProjects, | |||
| assignedProjects, | |||
| username, | |||
| defaultLeaveRecords, | |||
| defaultTimesheets, | |||
| holidays, | |||
| @@ -180,7 +178,6 @@ const UserWorkspacePage: React.FC<Props> = ({ | |||
| onClose={handleCloseTimesheetModal} | |||
| allProjects={allProjects} | |||
| assignedProjects={assignedProjects} | |||
| username={username} | |||
| defaultTimesheets={defaultTimesheets} | |||
| leaveRecords={defaultLeaveRecords} | |||
| /> | |||
| @@ -191,7 +188,6 @@ const UserWorkspacePage: React.FC<Props> = ({ | |||
| onClose={handleCloseLeaveModal} | |||
| defaultLeaveRecords={defaultLeaveRecords} | |||
| timesheetRecords={defaultTimesheets} | |||
| username={username} | |||
| /> | |||
| {assignedProjects.length > 0 ? ( | |||
| <AssignedProjects assignedProjects={assignedProjects} /> | |||
| @@ -12,11 +12,7 @@ import { | |||
| } from "@/app/api/timesheets"; | |||
| import { fetchHolidays } from "@/app/api/holidays"; | |||
| interface Props { | |||
| username: string; | |||
| } | |||
| const UserWorkspaceWrapper: React.FC<Props> = async ({ username }) => { | |||
| const UserWorkspaceWrapper: React.FC = async () => { | |||
| const [ | |||
| teamLeaves, | |||
| teamTimesheets, | |||
| @@ -27,12 +23,12 @@ const UserWorkspaceWrapper: React.FC<Props> = async ({ username }) => { | |||
| leaveTypes, | |||
| holidays, | |||
| ] = await Promise.all([ | |||
| fetchTeamMemberLeaves(username), | |||
| fetchTeamMemberTimesheets(username), | |||
| fetchAssignedProjects(username), | |||
| fetchTeamMemberLeaves(), | |||
| fetchTeamMemberTimesheets(), | |||
| fetchAssignedProjects(), | |||
| fetchProjectWithTasks(), | |||
| fetchTimesheets(username), | |||
| fetchLeaves(username), | |||
| fetchTimesheets(), | |||
| fetchLeaves(), | |||
| fetchLeaveTypes(), | |||
| fetchHolidays(), | |||
| ]); | |||
| @@ -43,7 +39,6 @@ const UserWorkspaceWrapper: React.FC<Props> = async ({ username }) => { | |||
| teamTimesheets={teamTimesheets} | |||
| allProjects={allProjects} | |||
| assignedProjects={assignedProjects} | |||
| username={username} | |||
| defaultTimesheets={timesheets} | |||
| defaultLeaveRecords={leaves} | |||
| leaveTypes={leaveTypes} | |||