Merge pull request 'main' (#11) from main into testing
Reviewed-on: #11
This commit is contained in:
@@ -42,7 +42,6 @@ import {
|
||||
useBulkAssignProgrammeMutation,
|
||||
useBulkRevokeCourseMutation,
|
||||
useBulkCreateLearnersForHrMutation,
|
||||
useGetCoursesForHrQuery,
|
||||
useGetAssignedCoursesForOrganizationQuery,
|
||||
useGetLearnerCoursesQuery,
|
||||
useGetProgrammesForHrQuery,
|
||||
@@ -91,6 +90,8 @@ const LearnersPage: React.FC = () => {
|
||||
const [showEditDrawer, setShowEditDrawer] = useState(false);
|
||||
const [selectedProgrammeId, setSelectedProgrammeId] = useState('');
|
||||
const [selectedCourseId, setSelectedCourseId] = useState('');
|
||||
const [courseStartDate, setCourseStartDate] = useState('');
|
||||
const [courseEndDate, setCourseEndDate] = useState('');
|
||||
const [assignError, setAssignError] = useState('');
|
||||
const [assignCourseError, setAssignCourseError] = useState('');
|
||||
const [editingEmployee, setEditingEmployee] = useState<Employee | null>(null);
|
||||
@@ -169,14 +170,13 @@ const LearnersPage: React.FC = () => {
|
||||
offset: 0,
|
||||
});
|
||||
const {
|
||||
data: coursesResponse,
|
||||
isLoading: coursesLoading,
|
||||
refetch: refetchCourses
|
||||
} = useGetCoursesForHrQuery({
|
||||
limit: 100,
|
||||
offset: 0,
|
||||
});
|
||||
|
||||
data: bulkAssignCoursesResponse,
|
||||
isLoading: bulkAssignCoursesLoading,
|
||||
} = useGetAssignedCoursesForOrganizationQuery(
|
||||
{ limit: 100, offset: 0 },
|
||||
{ skip: !showAssignCourseModal }
|
||||
);
|
||||
|
||||
const { data: learnerCoursesResponse, refetch: refetchLearnerCourses, isLoading: learnerCoursesLoading } =
|
||||
useGetLearnerCoursesQuery(editingEmployee?.id ?? '', {
|
||||
skip: !editingEmployee?.id,
|
||||
@@ -454,6 +454,8 @@ const LearnersPage: React.FC = () => {
|
||||
const response = await bulkAssignCourse({
|
||||
principal_xids: [editingEmployee.id],
|
||||
course_xids: [courseId],
|
||||
start_date: courseStartDate,
|
||||
end_date: courseEndDate,
|
||||
}).unwrap();
|
||||
|
||||
await refetchLearnerCourses();
|
||||
@@ -737,11 +739,21 @@ const LearnersPage: React.FC = () => {
|
||||
setAssignCourseError('Please select a course.');
|
||||
return;
|
||||
}
|
||||
if (!courseStartDate || !courseEndDate) {
|
||||
setAssignCourseError('Please select start date and end date.');
|
||||
return;
|
||||
}
|
||||
if (new Date(courseEndDate) < new Date(courseStartDate)) {
|
||||
setAssignCourseError('End date cannot be before start date.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await bulkAssignCourse({
|
||||
principal_xids: selectedEmployees,
|
||||
course_xids: [selectedCourseId],
|
||||
start_date: courseStartDate,
|
||||
end_date: courseEndDate,
|
||||
}).unwrap();
|
||||
|
||||
showToast(
|
||||
@@ -751,6 +763,8 @@ const LearnersPage: React.FC = () => {
|
||||
);
|
||||
setShowAssignCourseModal(false);
|
||||
setSelectedCourseId('');
|
||||
setCourseStartDate('');
|
||||
setCourseEndDate('');
|
||||
setSelectedEmployees([]);
|
||||
} catch (error: any) {
|
||||
const message = error?.data?.message || 'Failed to assign course.';
|
||||
@@ -1446,7 +1460,7 @@ const LearnersPage: React.FC = () => {
|
||||
<SelectValue placeholder={programmesLoading ? 'Loading programmes...' : 'Choose programme'} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(programmesResponse?.data?.items ?? []).map((programme) => (
|
||||
{(programmesResponse?.data ?? []).map((programme) => (
|
||||
<SelectItem key={programme.id} value={programme.id}>
|
||||
{programme.programme_title}
|
||||
</SelectItem>
|
||||
@@ -1501,10 +1515,12 @@ const LearnersPage: React.FC = () => {
|
||||
</label>
|
||||
<Select value={selectedCourseId} onValueChange={setSelectedCourseId}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={coursesLoading ? 'Loading courses...' : 'Choose course'} />
|
||||
<SelectValue
|
||||
placeholder={bulkAssignCoursesLoading ? 'Loading courses...' : 'Choose course'}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(coursesResponse?.data?.items ?? []).map((course) => (
|
||||
{(bulkAssignCoursesResponse?.data ?? []).map((course) => (
|
||||
<SelectItem key={course.id} value={course.id}>
|
||||
{course.course_name}
|
||||
</SelectItem>
|
||||
@@ -1512,6 +1528,24 @@ const LearnersPage: React.FC = () => {
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">Start Date</label>
|
||||
<Input
|
||||
type="date"
|
||||
value={courseStartDate}
|
||||
onChange={(e) => setCourseStartDate(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">End Date</label>
|
||||
<Input
|
||||
type="date"
|
||||
value={courseEndDate}
|
||||
onChange={(e) => setCourseEndDate(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2 pt-4">
|
||||
<Button
|
||||
className="flex-1"
|
||||
@@ -1526,6 +1560,8 @@ const LearnersPage: React.FC = () => {
|
||||
setShowAssignCourseModal(false);
|
||||
setAssignCourseError('');
|
||||
setSelectedCourseId('');
|
||||
setCourseStartDate('');
|
||||
setCourseEndDate('');
|
||||
}}
|
||||
className="flex-1"
|
||||
disabled={isAssigningCourse}
|
||||
@@ -1615,11 +1651,13 @@ const LearnersPage: React.FC = () => {
|
||||
type="button"
|
||||
variant="default"
|
||||
onClick={() => {
|
||||
if (showOrgCoursesCatalog) {
|
||||
void refetchOrgCourses();
|
||||
} else {
|
||||
setShowOrgCoursesCatalog(true);
|
||||
}
|
||||
if (!editingEmployee) return;
|
||||
setSelectedEmployees([editingEmployee.id]);
|
||||
setAssignCourseError('');
|
||||
setSelectedCourseId('');
|
||||
setCourseStartDate('');
|
||||
setCourseEndDate('');
|
||||
setShowAssignCourseModal(true);
|
||||
}}
|
||||
disabled={!editingEmployee}
|
||||
className="h-9 shrink-0 rounded-md"
|
||||
|
||||
@@ -127,12 +127,7 @@ interface ProgrammeListResponse {
|
||||
success: boolean;
|
||||
status: number;
|
||||
message: string;
|
||||
data: {
|
||||
total_count: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
items: ProgrammeItem[];
|
||||
};
|
||||
data: ProgrammeItem[];
|
||||
errors: unknown;
|
||||
correlation_id: string;
|
||||
}
|
||||
@@ -214,6 +209,8 @@ interface CourseListResponse {
|
||||
interface BulkAssignCourseRequest {
|
||||
principal_xids: string[];
|
||||
course_xids: string[];
|
||||
start_date: string;
|
||||
end_date: string;
|
||||
principal_organization_course_link_xid?: string;
|
||||
}
|
||||
|
||||
@@ -358,7 +355,7 @@ export const learnersApi = createApi({
|
||||
}),
|
||||
getProgrammesForHr: builder.query<ProgrammeListResponse, ProgrammeListQueryParams>({
|
||||
query: (params) => ({
|
||||
url: '/hr/programme-course/programme/list',
|
||||
url: '/hr/organization/list/assigned-programmes',
|
||||
method: 'GET',
|
||||
params: {
|
||||
limit: params.limit,
|
||||
|
||||
Reference in New Issue
Block a user