129 行
3.6 KiB
TypeScript
129 行
3.6 KiB
TypeScript
import { apiRequestData } from "./http";
|
|
import type { EmployeeDepartmentSummary, EmployeeStatus } from "./employees";
|
|
|
|
export type PerformanceReviewCycleType = "monthly" | "quarterly" | "semi_annual" | "annual";
|
|
export type PerformanceReviewCycleStatus = "draft" | "active" | "completed";
|
|
export type PerformanceReviewDimensionType =
|
|
| "work_quality"
|
|
| "work_efficiency"
|
|
| "teamwork"
|
|
| "initiative"
|
|
| "professional_skill";
|
|
|
|
export type PerformanceEmployeeSummary = {
|
|
id: string;
|
|
employeeNo: string;
|
|
name: string;
|
|
title: string;
|
|
status: EmployeeStatus;
|
|
avatarUrl: string | null;
|
|
department: EmployeeDepartmentSummary | null;
|
|
};
|
|
|
|
export type PerformanceReviewCycle = {
|
|
id: string;
|
|
name: string;
|
|
cycleType: PerformanceReviewCycleType;
|
|
status: PerformanceReviewCycleStatus;
|
|
startDate: string | null;
|
|
endDate: string | null;
|
|
activatedAt: string | null;
|
|
completedAt: string | null;
|
|
createdAt: string | null;
|
|
createdBy: string | null;
|
|
updatedAt: string | null;
|
|
updatedBy: string | null;
|
|
};
|
|
|
|
export type PerformanceReviewDimension = {
|
|
dimensionType: PerformanceReviewDimensionType;
|
|
score: number;
|
|
};
|
|
|
|
export type PerformanceReview = {
|
|
id: string;
|
|
cycleId: string;
|
|
employeeId: string;
|
|
reviewerEmployeeId: string;
|
|
overallScore: number;
|
|
comment: string | null;
|
|
reviewer: {
|
|
id: string;
|
|
employeeNo: string;
|
|
name: string;
|
|
} | null;
|
|
dimensions: PerformanceReviewDimension[];
|
|
createdAt: string | null;
|
|
createdBy: string | null;
|
|
updatedAt: string | null;
|
|
updatedBy: string | null;
|
|
};
|
|
|
|
export type PerformanceCycleOverview = {
|
|
cycle: PerformanceReviewCycle;
|
|
items: Array<{
|
|
employee: PerformanceEmployeeSummary;
|
|
review: PerformanceReview | null;
|
|
}>;
|
|
};
|
|
|
|
export type PerformanceEmployeeReviewTimeline = {
|
|
employee: PerformanceEmployeeSummary;
|
|
viewerRole: "self" | "manager" | "admin";
|
|
items: Array<{
|
|
cycle: PerformanceReviewCycle;
|
|
review: PerformanceReview | null;
|
|
canEdit: boolean;
|
|
}>;
|
|
};
|
|
|
|
export type CreatePerformanceCyclePayload = {
|
|
name: string;
|
|
cycleType: PerformanceReviewCycleType;
|
|
startDate: string;
|
|
endDate: string;
|
|
};
|
|
|
|
export type PatchPerformanceCyclePayload = Partial<CreatePerformanceCyclePayload> & {
|
|
status?: PerformanceReviewCycleStatus;
|
|
};
|
|
|
|
export type UpsertPerformanceReviewPayload = {
|
|
overallScore: number;
|
|
comment?: string | null;
|
|
dimensions?: PerformanceReviewDimension[];
|
|
};
|
|
|
|
export async function fetchPerformanceCycles() {
|
|
return apiRequestData<{ items: PerformanceReviewCycle[] }>("/api/performance/cycles");
|
|
}
|
|
|
|
export async function createPerformanceCycle(payload: CreatePerformanceCyclePayload) {
|
|
return apiRequestData<PerformanceReviewCycle>("/api/performance/cycles", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function patchPerformanceCycle(cycleId: string, payload: PatchPerformanceCyclePayload) {
|
|
return apiRequestData<PerformanceReviewCycle>(`/api/performance/cycles/${cycleId}`, {
|
|
method: "PATCH",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|
|
|
|
export async function fetchPerformanceCycleOverview(cycleId: string) {
|
|
return apiRequestData<PerformanceCycleOverview>(`/api/performance/cycles/${cycleId}/reviews`);
|
|
}
|
|
|
|
export async function fetchEmployeePerformanceTimeline(employeeId: string) {
|
|
return apiRequestData<PerformanceEmployeeReviewTimeline>(`/api/performance/employees/${employeeId}/reviews`);
|
|
}
|
|
|
|
export async function upsertPerformanceReview(cycleId: string, employeeId: string, payload: UpsertPerformanceReviewPayload) {
|
|
return apiRequestData<PerformanceReview>(`/api/performance/cycles/${cycleId}/reviews/${employeeId}`, {
|
|
method: "PUT",
|
|
body: JSON.stringify(payload),
|
|
});
|
|
}
|