Skip to main content

Service Report #006 New

Date: 2026-01-08 (Updated: 2026-01-10)


Feature Overview

Features originate from the following Minutes of Meetings:

  • MoM 2026-01-06 - Items 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 14, 15, 16, 17
#FeatureIssueMoM ReferenceTypeStatus
1Training NoShow Status#223MoM 2026-01-06, Item 1Enhancement🔍 In Review
2Rename Training Schedule to Plan#224MoM 2026-01-06, Item 2Enhancement🔍 In Review
3Non-repeat Training Plan Fix#225MoM 2026-01-06, Item 3Bug Fix🔍 In Review
4Show Session Count#226MoM 2026-01-06, Item 4Enhancement🔍 In Review
5First Day of Week Configuration#227MoM 2026-01-06, Item 5Enhancement🔍 In Review
6Date Picker Off-by-One Fix#228MoM 2026-01-06, Item 6Bug Fix🔍 In Review
7Back Button with Unsaved Changes Confirm#229MoM 2026-01-06, Item 7Enhancement🔍 In Review
8Move Search to Training Sessions#230MoM 2026-01-06, Item 8Enhancement🔍 In Review
9Work Owner Send Actions (Deferred)#231MoM 2026-01-06, Item 9Bug Fix Deferred
10Contractor No Projects (Deferred)#232MoM 2026-01-06, Item 10Bug Fix Deferred
11Hide Disabled JSA Templates#233MoM 2026-01-06, Item 11Bug Fix🔍 In Review
12Hide System JSA Listing Until Imported#234MoM 2026-01-06, Item 12Enhancement🔍 In Review
13Contractor Flow Blocked (Deferred)#235MoM 2026-01-06, Item 13Bug Fix Deferred
14Reports Menu Structure#236MoM 2026-01-06, Item 14New Feature🔍 In Review
15Dashboard WP Status Chart#237MoM 2026-01-06, Item 15New Feature🔍 In Review
16Monthly Summary Chart#238MoM 2026-01-06, Item 16New Feature🔍 In Review
17Capacity Dropdown#239MoM 2026-01-06, Item 17Enhancement🔍 In Review
18Training Info for ContractorsInternalInternalNew Feature🔍 In Review
19Status Column i18n FixInternalInternalBug Fix🔍 In Review

1. Training NoShow Status

Issue: #223 Thai Name: เพิ่มสถานะ "ไม่มา" สำหรับการอบรม

Description: Add "Did not attend" (NoShow) status to training management. Safety Officers can mark workers who were enrolled in training sessions but did not attend. This status differs from "Cancelled" which indicates the enrollment was withdrawn before the training date.

Location: Tools > กำหนดค่า > จัดการการอบรม > อนุมัติผลการอบรม

MoM 2026-01-06, Item 1:

MoM Screenshot

Attendance Status Flow

Status Definitions

StatusThai NameDescription
Enrolledลงทะเบียนแล้วInitial state after enrollment
Confirmedยืนยันแล้วSafety Officer confirmed attendance
Attendedเข้าอบรมแล้วWorker checked in on training day
Passedผ่านCompleted training successfully
Failedไม่ผ่านDid not pass training
NoShowไม่มาDid not attend (new status)
CancelledยกเลิกEnrollment cancelled before training

Role Matrix

ActionAdminSafety OfficerContractor
View attendance status (readonly)Own workers
Mark as NoShow
Filter by NoShow status

What to Test

#Test CaseStatus
1Safety Officer: Mark enrolled worker as "ไม่มา" (NoShow) Tested
2Safety Officer: Filter attendances by "ไม่มา" status (without selecting session) Tested
3Safety Officer: Filter attendances by "ไม่มา" status (with session selected) Tested
4Worker re-enrollment: NoShow workers can be enrolled in new sessions Pending
5Person status unchanged: NoShow does not update Person.TrainingStatus Pending

Technical Implementation

Backend Changes

New Endpoint: POST /api/training-approvals/search

  • Search attendances with optional filters: status, sessionId, contractorId
  • Supports "Pending" filter (Enrolled, Confirmed, Attended)
  • Supports status-specific filters (Passed, Failed, NoShow)

Files Modified:

FileChange
ITrainingApprovalService.csAdded SearchAttendancesAsync method
TrainingApprovalService.csImplemented search with multi-filter support
SearchAttendancesEndpoint.csNew endpoint for search functionality

Frontend Changes

Filter Enhancement:

  • Status dropdown now triggers search endpoint for all status types
  • Session and Contractor dropdowns show "ทั้งหมด" when All is selected
  • Date format follows Thai Buddhist calendar pattern

Files Modified:

FileChange
training-setting.contract.tsAdded SearchAttendancesRequest/Response types
training-setting.service.tsAdded searchAttendances method with rxResource
training-approval-dashboard.component.tsUpdated filter logic to use search endpoint

Bug Fixes Included

IssueDescriptionFix
Empty results on NoShow filterFiltering by "ไม่มา" showed empty even when records existCreated search endpoint that doesn't require session selection
Dropdown blank displaySession/Contractor dropdowns showed blank for "All"Changed to show "ทั้งหมด" like status dropdown
Date format inconsistencySession dropdown showed ISO format (2026-01-06)Applied ThaiDatePipe for Buddhist calendar format
Empty string GUID errorEmpty sessionId string caused 400 Bad RequestConvert empty strings to undefined before API call

2. Rename Training Schedule to Plan

Issue: #224 Thai Name: เปลี่ยนชื่อ "ตารางอบรม" เป็น "แผนการอบรม"

Description: Rename "Training Schedule" to "Training Plan" throughout the training management interface. This is a terminology change to better reflect the nature of training plans.

Location: Tools > กำหนดค่า > จัดการการอบรม

MoM 2026-01-06, Item 2:

MoM Screenshot 1

MoM Screenshot 2

Terminology Changes

Original (TH)New (TH)Original (EN)New (EN)
ตารางอบรมแผนการอบรมTraining ScheduleTraining Plan
เพิ่มตารางอบรมเพิ่มแผนการอบรมAdd ScheduleAdd Plan
ชื่อตารางอบรมชื่อแผนการอบรมSchedule NamePlan Name
ข้อมูลตารางอบรมข้อมูลแผนการอบรมSchedule InformationPlan Information

What to Test

#Test CaseStatus
1First tab shows "แผนการอบรม" instead of "ตารางอบรม" Pending
2Add button shows "เพิ่มแผนการอบรม" Pending
3Form title shows "ข้อมูลแผนการอบรม" Pending
4Delete confirmation shows "ยืนยันการลบแผนการอบรม" Pending
5Session list "Plan" column header updated Pending

Files Modified

FileChange
training-schedule-list-toolbar.component.tsUpdated add button text
training-schedule-list.component.tsUpdated table header
training-schedule-form.component.tsUpdated form title and field labels
training-session-list.component.tsUpdated schedule column header
training-setting.component.tsUpdated tab label and delete confirmation
messages.jsonUpdated 7 Thai locale entries
messages.en.jsonUpdated 7 English locale entries

3. Non-repeat Training Plan Fix

Issue: #225 Thai Name: แผนการอบรมแบบ "ไม่ซ้ำ" ไม่สร้างรอบอบรม

Description: Bug fix for training plans with "None" recurrence type. When creating sessions for a non-repeating training plan, no sessions were generated.

Location: Tools > กำหนดค่า > จัดการการอบรม > แผนการอบรม

MoM 2026-01-06, Item 3:

MoM Screenshot

Root Cause

  1. Backend: GenerateDates() method returned empty list for "None" recurrence type
  2. Frontend: rxResource status overwrites caused form view to reset during background data fetches

Fix Applied

LayerFileChange
BackendTrainingScheduleService.csFixed GenerateDates() to return single date for "None" recurrence
Frontendtraining-setting.service.tsAdded _isEditingMode signal to prevent rxResource status overwrites
Frontendtraining-setting.service.tsAdded guards in rxResource streams to preserve edit state

What to Test

#Test CaseStatus
1Create Training Plan with recurrence = "ไม่ซ้ำ" (None) Pending
2Save the plan and click "สร้างรอบอบรม" Pending
3Select date range and verify sessions are created Pending
4Verify snackbar shows session count Pending

4. Show Session Count

Issue: #226 Thai Name: แสดงจำนวนรอบอบรมที่สร้างหลังจากสร้างเสร็จ

Description: Show the number of training sessions created in a snackbar message after generating sessions from a training plan. Previously showed generic "บันทึกสำเร็จ" message.

Location: Tools > กำหนดค่า > จัดการการอบรม > แผนการอบรม > สร้างรอบอบรม

Before/After

BeforeAfter
Generic "บันทึกสำเร็จ" message"สร้างรอบอบรมจำนวน X รายการ"

What to Test

#Test CaseStatus
1Generate sessions → verify count shown in snackbar Tested
2Generate 0 sessions → verify "0 รายการ" shown Pending

Files Modified

FileChange
training-setting.service.tsAdded _sessionsCreatedCount signal, capture from response
training-setting.component.tsDisplay count in snackbar using $localize
messages.jsonAdded settings.training.sessionsCreatedMessage
messages.en.jsonAdded English translation

5. First Day of Week Configuration

Issue: #227 Thai Name: กำหนดวันเริ่มต้นสัปดาห์ (จันทร์/อาทิตย์)

Description: Make the first day of week configurable between Sunday and Monday. This setting is controlled by System Administrators through a new System Settings page.

Location: Tools > กำหนดค่า > ตั้งค่าระบบ

Changes Summary

ChangeDescription
System SettingsNew settings page (ตั้งค่าระบบ) for system-wide configuration
Business SettingsRenamed from Employer Settings (ตั้งค่าบริษัทตั้งค่าธุรกิจ)
Regional SettingsMoved from Business Settings to System Settings
First day of weekRadio buttons to select Sunday (0) or Monday (1)
Toast positionMoved to bottom center for better visibility

First Day of Week Options

ValueThaiEnglishDescription
0วันอาทิตย์SundayWeek starts on Sunday (default)
1วันจันทร์MondayWeek starts on Monday

Components Affected

ComponentBehavior
DatePickerCalendar shows week starting on configured day
Training CalendarWeek view starts on configured day
All date range pickersRespects the setting

What to Test

#Test CaseStatus
1Open System Settings and verify radio buttons for first day of week Pending
2Select "วันจันทร์" (Monday) and save Pending
3Open any DatePicker and verify calendar starts on Monday Pending
4Open Training Calendar and verify week starts on Monday Pending
5Verify Business Settings has 3 tabs (no Regional) Pending
6Verify toast notifications appear at bottom center Pending

Files Modified

Backend

FileChange
GlobalSetting.csAdded FirstDayOfWeek property (int)
GlobalSettingDto.csAdded FirstDayOfWeek property
GetGlobalSettingEndpoint.csNew endpoint: GET /api/settings/global
SaveGlobalSettingEndpoint.csNew endpoint: POST /api/settings/global
Seed data filesRelocated to SafetyApp.Infrastructure/Seeds/Data/

Frontend

FileChange
system-setting.component.tsNew System Settings page
system-setting-form-regional.component.tsRegional settings form with first day of week
global-setting.service.tsNew service for system-wide settings
global-setting.model.tsAdded firstDayOfWeek property
thai-buddhist-date-adapter.tsReads first day of week from GlobalSettingService
training-session-calendar.component.tsRespects first day of week setting
employer-setting.component.tsRefactored with sticky toolbar, removed GlobalSetting
toast.component.tsChanged position to bottom center
messages.json / messages.en.jsonAdded system settings i18n keys

6. Date Picker Off-by-One Fix

Issue: #228 Thai Name: แก้ไขวันที่ลบหนึ่งเมื่อแก้ไขรอบอบรม

Description: Bug fix for date picker showing one day earlier when editing training sessions. When selecting a date (e.g., Jan 12), the saved value would be one day earlier (Jan 11).

Location: Tools > กำหนดค่า > จัดการการอบรม > รอบอบรม

MoM 2026-01-06, Item 6:

MoM Screenshot 1

MoM Screenshot 2

Root Cause

Using toISOString().split('T')[0] to format dates converts the Date object to UTC string. In positive timezone regions like Asia/Bangkok (+07:00), this causes dates to shift backward by one day.

// ❌ BUG: Converts to UTC, loses a day in +07:00 timezone
private formatDate(date: Date): string {
return date.toISOString().split('T')[0];
}
// User selects: Jan 12, 2026 00:00 local time
// toISOString(): "2026-01-11T17:00:00.000Z" (UTC)
// Result: "2026-01-11" ← WRONG!

Fix Applied

LayerFileChange
Frontendtraining-session-form.component.tsFixed formatDate() to use local date methods
Frontendtraining-session-list-toolbar.component.tsFixed parseDate() and formatDate()
Frontenddialog-generate-sessions.component.tsFixed formatDate()
Frontenddialog-approve-training.component.tsFixed formatDate()
Docsangular.mdAdded "Date String Formatting (Golden Rule)"

Correct Implementation

// ✅ CORRECT: Uses local date components
private formatDate(date: Date | null): string {
if (!date) return '';
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}

What to Test

#Test CaseStatus
1Edit existing training session, change date, verify correct date is saved Pending
2Create new training session via "Generate Sessions", verify dates are correct Pending
3Approve training with expiry date, verify correct date is saved Pending
4Date filter in session list toolbar works correctly Pending

7. Back Button with Unsaved Changes Confirm

Issue: #229 Thai Name: เปลี่ยน "ยกเลิก" เป็น "กลับ" พร้อมยืนยันเมื่อมีการแก้ไข

Description: Change the "ยกเลิก" (Cancel) button to "ย้อนกลับ" (Back) in training settings forms. When there are unsaved changes, show a confirmation dialog before navigating away.

Location: Tools > กำหนดค่า > จัดการการอบรม > แผนการอบรม/รอบอบรม

MoM 2026-01-06, Item 7:

MoM Screenshot

Problem

The "ยกเลิก" (Cancel) button was confusing because:

  1. Users thought it might cancel the training session itself
  2. Changes were discarded silently without confirmation

Fix Applied

LayerFileChange
Frontendtraining-setting.component.tsChanged button text/icon, added formDirty signal, implemented goBack()
Frontendtraining-schedule-form.component.tsAdded formDirty model, markDirty() method on all inputs
Frontendtraining-session-form.component.tsAdded formDirty model, markDirty() method on all inputs
Frontendmessages.jsonAdded common.unsavedChangesWarning
Frontendmessages.en.jsonAdded common.unsavedChangesWarning

What to Test

#Test CaseStatus
1Edit training plan, make changes, click "ย้อนกลับ" → confirmation dialog appears Tested
2Click "ยกเลิก" in dialog → stays on form Tested
3Click "ตกลง" in dialog → goes back to list Tested
4Edit without making changes, click "ย้อนกลับ" → goes back immediately Tested

8. Move Search to Training Sessions

Issue: #230 Thai Name: ย้ายการค้นหาจากแผนการอบรมไปรอบอบรม

Description: Move the search functionality from Training Plan (แผนการอบรม) tab to Training Sessions (รอบอบรม) tab. Training plans are few in number so search is unnecessary there, but searching sessions by schedule name, nickname, or location is useful.

Location: Tools > กำหนดค่า > จัดการการอบรม > รอบอบรม

MoM 2026-01-06, Item 8:

MoM Screenshot

Before/After

LocationBeforeAfter
Training Plan tabHad search barNo search bar
Training Sessions tabNo keyword searchHas search bar with keyword filter

Search Behavior

The keyword search on Training Sessions filters by:

  • Schedule name (English)
  • Schedule nickname (Thai)
  • Session location

What to Test

#Test CaseStatus
1Training Plan tab has no search bar Tested
2Training Sessions tab has search bar Tested
3Search by schedule name returns matching sessions Tested
4Search by nickname returns matching sessions Tested
5Search by location returns matching sessions Tested

Files Modified

LayerFileChange
Frontendtraining-schedule-list-toolbar.component.tsRemoved search bar
Frontendtraining-session-list-toolbar.component.tsAdded search bar and keyword model
Frontendtraining-setting.component.tsUpdated bindings for keyword
Frontendtraining-setting.contract.tsAdded keyword to SearchSessionsRequest
Frontendtraining-approval-dashboard.component.tsAdded keyword to searchSessions call
BackendSearchSessionsEndpoint.csAdded Keyword parameter
BackendITrainingSessionService.csAdded keyword parameter to interface
BackendTrainingSessionService.csImplemented keyword filtering

9. Work Owner Send Actions (Deferred)

Issue: #231 Thai Name: เจ้าของงานส่งไปจัดซื้อและผู้รับเหมาไม่ได้ Status: Deferred

Description: Work owner cannot send projects to purchasing or contractor, blocking workflow testing.

MoM 2026-01-06, Item 9:

MoM Screenshot

Reason for Deferral: This issue is related to the Project Registration Workflow which is a separate feature scope. Will be addressed when implementing/fixing the Project Registration module.

Location: Project Registration > Work Owner Actions


10. Contractor No Projects (Deferred)

Issue: #232 Thai Name: ผู้รับเหมาไม่มีโครงการให้ทดสอบ flow Status: Deferred

Description: Contractor has no projects to test the workflow because work owner cannot send projects (blocked by #231).

MoM 2026-01-06, Item 10:

MoM Screenshot

Reason for Deferral: This issue is related to the Project Registration Workflow which is a separate feature scope. Will be addressed when implementing/fixing the Project Registration module.

Location: Project Registration > Contractor View


11. Hide Disabled JSA Templates

Issue: #233 Thai Name: ซ่อน JSA Template ที่ถูกปิดใช้งานจากหน้าผู้รับเหมา

Description: JSA templates that are disabled by the system admin should not appear in the contractor's JSA Request form. Previously, disabled templates were still visible in the dropdown.

Location: Contractor > JSA Request > Select JSA Template

MoM 2026-01-06, Item 11:

MoM Screenshot 1

MoM Screenshot 2

Root Cause

The GetJsaTemplateByContractor endpoint was not filtering by the IsEnabled flag when returning available JSA templates.

Fix Applied

LayerFileChange
BackendJsaTemplateService.csAdded .Where(t => t.IsEnabled) filter to contractor query

What to Test

#Test CaseStatus
1Disable a JSA template in System Settings Pending
2Login as contractor, create JSA Request Pending
3Verify disabled template is NOT shown in dropdown Pending
4Re-enable template, verify it appears again Pending

12. Hide System JSA Listing Until Imported

Issue: #234 Thai Name: ไม่ต้องแสดง listing ของระบบ จนกว่าจะนำเข้าจากระบบมาเป็นของตนเอง

Description: Hide system JSA templates from the contractor's view until they import them. Also added source tracking to show which templates were imported from the system, duplicate import warning badges, and improved success toast notifications.

Location: Tools > กำหนดค่า > JSA Template (Contractor view)

MoM 2026-01-06, Item 12:

MoM Screenshot

Implemented Features

FeatureDescription
Source TrackingShows "นำเข้าจากระบบ" badge for templates imported from system
Duplicate WarningAmber badge in import dialog for already-imported templates
Green ToastSuccess toast notification uses green color (not black)
Batch ImportImport multiple system templates at once via checkbox selection

Root Cause

The original implementation showed all system templates in the contractor's JSA list, even those they hadn't imported. This made it confusing for contractors to distinguish between their own templates and system templates.

Fix Applied

LayerFileChange
BackendJsaTemplate.csAdded SourceTemplateId field for tracking import source
BackendJsaTemplateService.csSet SourceTemplateId when importing, include SourceTemplate in queries
BackendJsaTemplateDto.csAdded SourceTemplateId and SourceTemplateName fields
BackendJsaTemplateMapper.csMap source template fields
BackendCheckImportedTemplatesEndpoint.csNew endpoint to check which templates are already imported
BackendBatchImportJsaTemplateEndpoint.csNew endpoint for batch import
Frontendjsa-template.model.tsAdded sourceTemplateId, sourceTemplateName fields
Frontendjsa-template-list.component.tsAdded purple "นำเข้าจากระบบ" badge next to template name
Frontenddialog-import-template.component.tsAdded amber badge for already-imported templates
Frontendjsa-template-setting.component.tsChanged to ToastService.success() for green color
DatabaseMigrationAdded source_template_id column with self-reference FK

What to Test

#Test CaseStatus
1Import a system template as contractor Pending
2Verify imported template shows "นำเข้าจากระบบ" badge Pending
3Open import dialog again, verify imported template shows amber badge Pending
4Import same template again (with warning) Pending
5Verify success toast is green color Pending
6Batch import multiple templates via checkbox Pending

13. Contractor Flow Blocked (Deferred)

Issue: #235 Thai Name: ทดสอบ flow ผู้รับเหมาต่อไม่ได้ เพราะไม่มีโครงการ Status: Deferred

Description: Cannot test contractor workflow because no projects are available (consequence of #231 and #232).

MoM 2026-01-06, Item 13:

MoM Screenshot

Reason for Deferral: This issue is related to the Project Registration Workflow which is a separate feature scope. Will be addressed when implementing/fixing the Project Registration module.

Location: Project Registration > Contractor Flow


14. Reports Menu Structure

Issue: #236 Thai Name: เตรียม Menu Reports จะเป็น Task Dashboard Reports

Description: Add Reports menu structure with placeholder page. This prepares the foundation for future dashboard reports (Items 15-16: Daily/Monthly dashboards).

Location: Top navigation bar > รายงาน

MoM 2026-01-06, Item 14:

MoM Screenshot

Implementation

ComponentDescription
NavigationTop-level "รายงาน" button between Dashboard and เครื่องมือ
Route/reports with auth guard
Placeholder"Coming Soon" page with analytics icon
Role AccessAll roles except TenantAdministrator

Files Created

FileDescription
features/reports/reports.routes.tsRoute configuration
features/reports/reports.component.tsPlaceholder component

Files Modified

FileChange
app.routes.tsAdded /reports route
layout-default.component.tsAdded "รายงาน" nav button
messages.jsonAdded 4 Thai i18n keys
messages.en.jsonAdded 4 English i18n keys

What to Test

#Test CaseStatus
1Login as Safety Officer → Verify "รายงาน" button in navbar Pending
2Click "รายงาน" → Navigate to /reports Pending
3Verify "Coming Soon" placeholder displays Pending
4Login as TenantAdmin → "รายงาน" button hidden Pending

15. Dashboard WP Status Chart

Issue: #237 Thai Name: แดชบอร์ดแสดงสถานะใบอนุญาตทำงาน (WP)

Description: Add WP Status Chart to Safety Officer Dashboard with daily/weekly toggle view. Shows work permit status breakdown with proper color interpretation.

Location: Dashboard (Safety Officer role only)

MoM 2026-01-06, Item 15:

MoM Screenshot

Status Colors

StatusThaiColorHex
รออนุมัติAwaiting ApprovalOrange#f59e0b
เปิดOpen/ApprovedBlue#3b82f6
ปิดClosed/CompletedGreen#22c55e

View Modes

ModeChart TypeDescription
วันนี้ (Daily)Donut ChartToday's WP status breakdown
7 วัน (Weekly)Grouped Bar Chart7-day WP status trend

Files Created/Modified

FileChange
dashboard/models/dashboard.models.tsCreated - Data models and color constants
dashboard/ui/wp-status-chart.component.tsCreated - WP Status Chart component
dashboard/ui/safety-officer-dashboard.component.tsModified - Integrated WP Status Chart
locale/messages.jsonModified - Added i18n keys
locale/messages.en.jsonModified - Added English translations

What to Test

#Test CaseStatus
1Login as Safety Officer → Navigate to Dashboard Pending
2Verify WP Status Chart displays with donut chart (daily view) Pending
3Click "7 วัน" toggle → Verify grouped bar chart displays Pending
4Verify colors: Orange (รออนุมัติ), Blue (เปิด), Green (ปิด) Pending
5Verify date range displays correctly in Thai Buddhist calendar Pending

16. Monthly Summary Chart

Issue: #238 Thai Name: แดชบอร์ดสรุปรายเดือน

Description: Add Monthly Summary Chart with stacked bar chart showing daily breakdown of WP count, contractor count, and worker count. Includes month navigation with prev/next arrows and quick-jump dropdown.

Location: Dashboard (Safety Officer role only)

MoM 2026-01-06, Item 16:

MoM Screenshot

Chart Series

SeriesThaiColorHex
WP CountใบอนุญาตทำงานBlue#3b82f6
Contractor Countผู้รับเหมาPurple#8b5cf6
Worker CountคนงานAmber#f59e0b
FeatureDescription
Previous MonthLeft arrow button
Next MonthRight arrow button
Quick JumpDropdown with recent 12 months

Files Created/Modified

FileChange
dashboard/models/dashboard.models.tsModified - Added monthly summary types
dashboard/ui/monthly-summary-chart.component.tsCreated - Monthly Summary Chart component
dashboard/ui/safety-officer-dashboard.component.tsModified - Integrated Monthly Summary Chart
dashboard/dashboard.component.tsModified - Moved board toggle to Safety Board section
locale/messages.jsonModified - Added i18n keys
locale/messages.en.jsonModified - Added English translations

What to Test

#Test CaseStatus
1Login as Safety Officer → Navigate to Dashboard Pending
2Verify Monthly Summary Chart displays stacked bar chart Pending
3Click left arrow → Navigate to previous month Pending
4Click right arrow → Navigate to next month Pending
5Use dropdown → Quick jump to specific month Pending
6Verify Thai Buddhist year display (e.g., มกราคม 2569) Pending
7Verify summary totals below chart Pending

17. Capacity Dropdown

Issue: #239 Thai Name: ให้กำหนดความจุได้ มีค่า default หรือเลือกจากรายการ

Description: Add capacity dropdown with preset options (10, 20, 30, 40, 50 คน) to training session and schedule forms. Also includes "กำหนดเอง" (Custom) option for manual input.

Location: Tools > กำหนดค่า > จัดการการอบรม > แผนการอบรม/รอบอบรม

MoM 2026-01-06, Item 17:

MoM Screenshot

Features

FeatureDescription
Preset OptionsDropdown with 10, 20, 30, 40, 50 คน
Custom Input"กำหนดเอง" option shows manual input field
Default Value30 คน (pre-selected)
Batch SessionsUses schedule capacity when generating sessions

Files Modified

FileChange
training-session-form.component.tsAdded capacity dropdown with custom option
training-schedule-form.component.tsAdded morning/afternoon capacity dropdowns

What to Test

#Test CaseStatus
1Create new training session → default 30 selected Pending
2Select preset value (e.g., 20) → capacity updates Pending
3Select "กำหนดเอง" → custom input appears Pending
4Type custom value → saves correctly Pending
5Edit schedule → morning/afternoon dropdowns work Pending
6Generate sessions → uses schedule capacity values Pending

Internal Improvements

The following items are improvements initiated internally by the development team. They do not have associated MoM items or GitHub issues.

Internal Improvements


18. Training Info for Contractors

Source: Internal Request Thai Name: สร้างหน้าข้อมูลการอบรมสำหรับผู้รับเหมา

Description: Created a dedicated read-only Training Info page for contractors. This separates the contractor's view from the admin Training Settings, providing a cleaner UX with only relevant features (view sessions, filter, export).

Location: Tools > ข้อมูลการอบรม (Contractor only)

Features

FeatureDescription
Sessions ListRead-only table of training sessions
Calendar ViewToggle between list and calendar view
FiltersFilter by date range, status, schedule, keyword
ExportExport to XLSX and PDF
RoleCardRoute
Admin/Safety Officerจัดการการอบรม (Training Settings)/tools/settings/training
Contractorข้อมูลการอบรม (Training Info)/tools/training-info

Files Created

Backend:

FileDescription
Features/TrainingInfo/SearchInfoSessionsEndpoint.csSearch training sessions
Features/TrainingInfo/GetInfoSchedulesEndpoint.csGet schedules for filter dropdown
Features/TrainingInfo/ExportInfoXlsxEndpoint.csExport to XLSX
Features/TrainingInfo/ExportInfoPdfEndpoint.csExport to PDF

Frontend:

FileDescription
training-info/training-info.component.tsMain component
training-info/training-info.service.tsState management
training-info/training-info.contract.tsType definitions
training-info/ui/training-info-toolbar.component.tsFilters and actions
training-info/ui/training-info-list.component.tsSessions table
training-info/ui/training-info-calendar.component.tsCalendar view

Cleanup

Removed all isContractor() logic from Training Settings component, simplifying the codebase.

What to Test

#Test CaseStatus
1Login as Contractor → Go to Tools Pending
2Verify "ข้อมูลการอบรม" card visible, "จัดการการอบรม" hidden Pending
3Click Training Info → Verify sessions list loads Pending
4Test filters (date, status, schedule, keyword) Pending
5Toggle to calendar view Pending
6Export to XLSX and PDF Pending
7Login as Admin → Verify Training Settings works without contractor logic Pending

19. Status Column i18n Fix

Source: Internal Request Thai Name: แก้ไขคอลัมน์สถานะแสดงเป็นภาษาอังกฤษ

Description: Fixed the status column in Training Info list showing English text ("Open", "Full") instead of Thai ("เปิดรับสมัคร", "เต็ม").

Location: Tools > ข้อมูลการอบรม > Sessions List

Root Cause

The component was displaying session.statusName directly from the backend response (English) instead of using the frontend getSessionStatusName() translation function.

Fix Applied

FileChange
training-info-list.component.tsImport getSessionStatusName, add getStatusName() method, use in template

Status Translations

EnglishThai
Openเปิดรับสมัคร
Fullเต็ม
Closedปิดรับสมัคร
Completedเสร็จสิ้น
Cancelledยกเลิก

What to Test

#Test CaseStatus
1View Training Info as Contractor Tested
2Verify status column shows Thai text Tested