From 0d1788500b0c1a5035abef05b13b0e0640e09762 Mon Sep 17 00:00:00 2001 From: EagleTrooper Date: Mon, 24 Nov 2025 22:35:47 -0600 Subject: [PATCH 1/9] Update ui/src/components/trainingReport/trainingReportForm.vue Added a Watcher Code to clear checkboxes when a different training report is picked. --- ui/src/components/trainingReport/trainingReportForm.vue | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ui/src/components/trainingReport/trainingReportForm.vue b/ui/src/components/trainingReport/trainingReportForm.vue index 06c529b..dae28db 100644 --- a/ui/src/components/trainingReport/trainingReportForm.vue +++ b/ui/src/components/trainingReport/trainingReportForm.vue @@ -36,6 +36,15 @@ watch(values, (newErrors) => { console.log(newErrors.attendees) }, { deep: true }) +watch(() => values.course_id, (newCourseId, oldCourseId) => { + if (!oldCourseId) return; + + values.attendees.forEach(a => { + a.passed_bookwork = false; + a.passed_qual = false; + }); +}); + const submitForm = handleSubmit(onSubmit); function toMySQLDateTime(date: Date): string { From f4fae1f84c80fa6e0db01272f682cb769b82ac50 Mon Sep 17 00:00:00 2001 From: EagleTrooper Date: Tue, 25 Nov 2025 21:23:13 -0600 Subject: [PATCH 2/9] Modified Checkbox Updates on Course re-select --- .../components/trainingReport/trainingReportForm.vue | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ui/src/components/trainingReport/trainingReportForm.vue b/ui/src/components/trainingReport/trainingReportForm.vue index dae28db..e224edf 100644 --- a/ui/src/components/trainingReport/trainingReportForm.vue +++ b/ui/src/components/trainingReport/trainingReportForm.vue @@ -6,6 +6,7 @@ import { toTypedSchema } from '@vee-validate/zod' import { computed, onMounted, ref, watch } from 'vue' import { getAllAttendeeRoles, getAllTrainings, postTrainingReport } from '@/api/trainingReport' import { getMembers, Member } from '@/api/member' + import FieldGroup from '../ui/field/FieldGroup.vue' import Field from '../ui/field/Field.vue' import FieldLabel from '../ui/field/FieldLabel.vue' @@ -18,7 +19,8 @@ import FieldLegend from '../ui/field/FieldLegend.vue' import FieldDescription from '../ui/field/FieldDescription.vue' import Checkbox from '../ui/checkbox/Checkbox.vue' -const { handleSubmit, resetForm, errors, values } = useForm({ + +const { handleSubmit, resetForm, errors, values, setFieldValue } = useForm({ validationSchema: toTypedSchema(trainingReportSchema), initialValues: { course_id: null, @@ -39,10 +41,10 @@ watch(values, (newErrors) => { watch(() => values.course_id, (newCourseId, oldCourseId) => { if (!oldCourseId) return; - values.attendees.forEach(a => { - a.passed_bookwork = false; - a.passed_qual = false; - }); + values.attendees.forEach((a, index) => { + setFieldValue(`attendees[${index}].passed_bookwork`, false); + setFieldValue(`attendees[${index}].passed_qual`, false); + }); }); const submitForm = handleSubmit(onSubmit); From 104946b2d18ce5cc934fb8157f7f2f5534532bd5 Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Fri, 28 Nov 2025 14:41:06 -0500 Subject: [PATCH 3/9] Fixed checkbox reset not updating visually --- .../trainingReport/trainingReportForm.vue | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/ui/src/components/trainingReport/trainingReportForm.vue b/ui/src/components/trainingReport/trainingReportForm.vue index e224edf..fe11b8b 100644 --- a/ui/src/components/trainingReport/trainingReportForm.vue +++ b/ui/src/components/trainingReport/trainingReportForm.vue @@ -31,20 +31,20 @@ const { handleSubmit, resetForm, errors, values, setFieldValue } = useForm({ }) watch(errors, (newErrors) => { - console.log(newErrors) + console.log(newErrors) }, { deep: true }) watch(values, (newErrors) => { - console.log(newErrors.attendees) + console.log(newErrors.attendees) }, { deep: true }) watch(() => values.course_id, (newCourseId, oldCourseId) => { if (!oldCourseId) return; - values.attendees.forEach((a, index) => { - setFieldValue(`attendees[${index}].passed_bookwork`, false); - setFieldValue(`attendees[${index}].passed_qual`, false); - }); + values.attendees.forEach((a, index) => { + setFieldValue(`attendees[${index}].passed_bookwork`, false); + setFieldValue(`attendees[${index}].passed_qual`, false); + }); }); const submitForm = handleSubmit(onSubmit); @@ -189,7 +189,8 @@ onMounted(async () => {
+ :name="`attendees[${index}].passed_bookwork`" :model-value="!field.checked" + @update:model-value="field['onUpdate:modelValue']">
+ :name="`attendees[${index}].passed_qual`" :model-value="!field.checked" + @update:model-value="field['onUpdate:modelValue']">
Date: Fri, 28 Nov 2025 15:14:23 -0500 Subject: [PATCH 5/9] Modified header to address pass/fail confusions --- .../trainingReport/trainingReportForm.vue | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/ui/src/components/trainingReport/trainingReportForm.vue b/ui/src/components/trainingReport/trainingReportForm.vue index cad4817..5e4d02f 100644 --- a/ui/src/components/trainingReport/trainingReportForm.vue +++ b/ui/src/components/trainingReport/trainingReportForm.vue @@ -134,14 +134,29 @@ onMounted(async () => { -
-
Member
-
Role
-
Bookwork
-
Qual
-
Remarks
-
+
+
+ +
Member
+
Role
+ + +
Bookwork
+ + +
Qual
+ +
Remarks
+
+
+ + +
+ ─── Pass ──── +
From bfcd7d4c7ab1265b0a628e7e4c53cc5838aa4d86 Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Fri, 28 Nov 2025 15:14:56 -0500 Subject: [PATCH 6/9] fixed header unbalance --- ui/src/components/trainingReport/trainingReportForm.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/components/trainingReport/trainingReportForm.vue b/ui/src/components/trainingReport/trainingReportForm.vue index 5e4d02f..b33c900 100644 --- a/ui/src/components/trainingReport/trainingReportForm.vue +++ b/ui/src/components/trainingReport/trainingReportForm.vue @@ -155,7 +155,7 @@ onMounted(async () => {
- ─── Pass ──── + ──── Pass ────
From d24a01db8c0032828e0e7103e7708f80ed0a9d46 Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Fri, 28 Nov 2025 15:31:35 -0500 Subject: [PATCH 7/9] Integrated new time handling system --- api/src/routes/course.ts | 1 + api/src/services/CourseSerivce.ts | 12 ++++++------ shared/types/course.ts | 18 +++++++++--------- shared/utils/time.ts | 1 + .../trainingReport/trainingReportForm.vue | 3 ++- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/api/src/routes/course.ts b/api/src/routes/course.ts index 38bd053..046b9bb 100644 --- a/api/src/routes/course.ts +++ b/api/src/routes/course.ts @@ -76,6 +76,7 @@ eventRouter.post('/', async (req: Request, res: Response) => { console.log(); let data: CourseEventDetails = req.body; data.created_by = posterID; + data.event_date = new Date(data.event_date); const id = await insertCourseEvent(data); res.status(201).json(id); } catch (error) { diff --git a/api/src/services/CourseSerivce.ts b/api/src/services/CourseSerivce.ts index 6b43c32..fe989b8 100644 --- a/api/src/services/CourseSerivce.ts +++ b/api/src/services/CourseSerivce.ts @@ -1,6 +1,6 @@ import pool from "../db" import { Course, CourseAttendee, CourseAttendeeRole, CourseEventDetails, CourseEventSummary, RawAttendeeRow } from "@app/shared/types/course" - +import { toDateTime } from "@app/shared/utils/time"; export async function getAllCourses(): Promise { const sql = "SELECT * FROM courses WHERE deleted = false;" @@ -21,8 +21,8 @@ function buildAttendee(row: RawAttendeeRow): CourseAttendee { passed_qual: !!row.passed_qual, attendee_id: row.attendee_id, course_event_id: row.course_event_id, - created_at: row.created_at, - updated_at: row.updated_at, + created_at: new Date(row.created_at), + updated_at: new Date(row.updated_at), remarks: row.remarks, attendee_role_id: row.attendee_role_id, attendee_name: row.attendee_name, @@ -32,8 +32,8 @@ function buildAttendee(row: RawAttendeeRow): CourseAttendee { name: row.role_name, description: row.role_description, deleted: !!row.role_deleted, - created_at: row.role_created_at, - updated_at: row.role_updated_at, + created_at: new Date(row.role_created_at), + updated_at: new Date(row.role_updated_at), } : null }; @@ -83,7 +83,7 @@ export async function insertCourseEvent(event: CourseEventDetails): Promise { emit("submit", newID); }); From e5806e275ff92c44748e13bb98680959a203e146 Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Fri, 28 Nov 2025 16:47:42 -0500 Subject: [PATCH 8/9] cleaned up date formats a bit --- ui/src/pages/TrainingReport.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/pages/TrainingReport.vue b/ui/src/pages/TrainingReport.vue index b4b062b..648d7a4 100644 --- a/ui/src/pages/TrainingReport.vue +++ b/ui/src/pages/TrainingReport.vue @@ -151,7 +151,7 @@ onMounted(async () => { @click="router.push(`/trainingReport/${report.event_id}`)"> {{ report.course_name.length > 30 ? report.course_shortname : report.course_name }} - {{ report.date }} + {{ report.date.split('T')[0] }} {{ report.created_by_name === null ? "Unknown User" : report.created_by_name }} @@ -173,7 +173,7 @@ onMounted(async () => {

{{ focusedTrainingReport.course_name }}

-

{{ focusedTrainingReport.event_date }}

+

{{ focusedTrainingReport.event_date.split('T')[0] }}

Created by {{ focusedTrainingReport.created_by_name === null ? "Unknown User" : focusedTrainingReport.created_by_name }} From c935a9950c1b4a5c55441fdd1092a5c965bb9bd9 Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Fri, 28 Nov 2025 17:00:07 -0500 Subject: [PATCH 9/9] sorted possible training options by name --- api/src/services/CourseSerivce.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/services/CourseSerivce.ts b/api/src/services/CourseSerivce.ts index fe989b8..1cadc31 100644 --- a/api/src/services/CourseSerivce.ts +++ b/api/src/services/CourseSerivce.ts @@ -2,7 +2,7 @@ import pool from "../db" import { Course, CourseAttendee, CourseAttendeeRole, CourseEventDetails, CourseEventSummary, RawAttendeeRow } from "@app/shared/types/course" import { toDateTime } from "@app/shared/utils/time"; export async function getAllCourses(): Promise { - const sql = "SELECT * FROM courses WHERE deleted = false;" + const sql = "SELECT * FROM courses WHERE deleted = false ORDER BY name ASC;" const res: Course[] = await pool.query(sql);