@@ -28,24 +28,14 @@ export class ScheduleMakerApp {
2828
2929 _init ( ) {
3030 this . notification = new NotificationManager ( ) ; this . helpModal = new HelpModal ( ) ;
31- this . importModal = new ImportModal ( {
32- notification : this . notification ,
33- onTimetableLoaded : s => this . onTimetableLoaded ( s ) ,
34- onCrnsImported : entries => this . onCrnsImported ( entries ) ,
35- onOpenHelp : ( ) => this . helpModal . open ( )
36- } ) ;
31+ this . importModal = new ImportModal ( { notification : this . notification , onTimetableLoaded : s => this . onTimetableLoaded ( s ) , onCrnsImported : entries => this . onCrnsImported ( entries ) , onOpenHelp : ( ) => this . helpModal . open ( ) } ) ;
3732 this . courseSelector = new CourseSelector ( { notification : this . notification , onCoursesChange : g => this . onWantedCoursesChanged ( g ) , onGenerate : ( ) => this . generateSchedules ( ) } ) ;
3833 this . calendarGrid = new CalendarGrid ( 'calendarGridMatrix' , { onCourseClick : s => this . showCourseDetailModal ( s ) } ) ; this . tableView = new TableView ( 'scheduleDetailTbody' ) ;
3934 this . filterBar = new FilterBar ( { onFilterChange : f => this . applyFilters ( f ) } ) ;
4035 this . scheduleController = new ScheduleController ( { state : this . state , getFilterState : ( ) => this . filterBar . getFilterState ( ) } ) ;
4136 this . _initDOMElements ( ) ;
4237 this . scheduleActions = new ScheduleActions ( { state : this . state , storageService, exportService, notification : this . notification , translate : t } ) ;
43- this . resultsView = new ScheduleResultsView ( { state : this . state , calendarGrid : this . calendarGrid , tableView : this . tableView , elements : {
44- resultsToolbar : this . resultsToolbar , resultsPlaceholder : this . resultsPlaceholder , calendarViewContainer : this . calendarViewContainer , tableViewContainer : this . tableViewContainer ,
45- btnViewCalendar : this . btnViewCalendar , btnViewTable : this . btnViewTable , btnPrevSchedule : this . btnPrevSchedule , btnNextSchedule : this . btnNextSchedule ,
46- currScheduleIndex : this . currScheduleIndex , totalSchedulesCount : this . totalSchedulesCount , statScore : this . statScore , valScore : this . valScore ,
47- valDaysOff : this . valDaysOff , valTotalGaps : this . valTotalGaps
48- } } ) ;
38+ this . resultsView = new ScheduleResultsView ( { state : this . state , calendarGrid : this . calendarGrid , tableView : this . tableView , elements : { resultsToolbar : this . resultsToolbar , resultsPlaceholder : this . resultsPlaceholder , calendarViewContainer : this . calendarViewContainer , tableViewContainer : this . tableViewContainer , btnViewCalendar : this . btnViewCalendar , btnViewTable : this . btnViewTable , btnPrevSchedule : this . btnPrevSchedule , btnNextSchedule : this . btnNextSchedule , currScheduleIndex : this . currScheduleIndex , totalSchedulesCount : this . totalSchedulesCount , statScore : this . statScore , valScore : this . valScore , valDaysOff : this . valDaysOff , valTotalGaps : this . valTotalGaps } } ) ;
4939 this . diagnosticsView = new ScheduleDiagnosticsView ( { element : this . conflictDiagnosticBox , translate : t , escapeHtml : s => this . _escapeHtml ( s ) } ) ;
5040 this . courseDetailView = new CourseDetailView ( { modal : this . courseDetailModal , body : this . courseDetailBody , escapeHtml : s => this . _escapeHtml ( s ) } ) ;
5141 this . _bindEvents ( ) ; this . _checkCachedData ( ) ; updateDOMTranslations ( ) ;
@@ -60,12 +50,7 @@ export class ScheduleMakerApp {
6050 let imported = 0 ;
6151 const unmatched = [ ] ;
6252 const duplicate = [ ] ;
63- const normalize = value => String ( value ?? '' )
64- . replace ( / \u00a0 / g, ' ' )
65- . replace ( / \s + / g, '' )
66- . replace ( / ^ ش ع ب ة / i, '' )
67- . replace ( / ^ s e c t i o n | ^ s e c | ^ c r n / i, '' )
68- . toUpperCase ( ) ;
53+ const normalize = value => String ( value ?? '' ) . replace ( / \u00a0 / g, ' ' ) . replace ( / \s + / g, '' ) . replace ( / ^ ش ع ب ة / i, '' ) . replace ( / ^ s e c t i o n | ^ s e c | ^ c r n / i, '' ) . toUpperCase ( ) ;
6954
7055 for ( const entry of entries ) {
7156 const wantedCode = normalize ( entry . courseCode ) ;
@@ -79,44 +64,27 @@ export class ScheduleMakerApp {
7964 return secCode === wantedCode && secNumber === wantedNumber && secSection === wantedSection ;
8065 } ) ;
8166
82- if ( ! matching . length ) {
83- unmatched . push ( entry ) ;
84- continue ;
85- }
67+ if ( ! matching . length ) { unmatched . push ( entry ) ; continue ; }
8668
8769 const key = `${ entry . courseCode . toUpperCase ( ) } -${ entry . courseNumber } ` ;
88- if ( this . courseSelector . wantedCourses [ key ] ) {
89- duplicate . push ( entry ) ;
90- continue ;
91- }
70+ if ( this . courseSelector . wantedCourses [ key ] ) { duplicate . push ( entry ) ; continue ; }
9271
9372 this . courseSelector . inputCode . value = entry . courseCode ;
9473 this . courseSelector . inputNumber . value = entry . courseNumber ;
9574 this . courseSelector . inputSection . value = entry . crn ;
9675 this . courseSelector . addCurrentCourse ( ) ;
97- imported ++ ;
76+ if ( this . courseSelector . wantedCourses [ key ] ) imported ++ ;
77+ else unmatched . push ( entry ) ;
9878 }
9979
10080 if ( imported > 0 ) this . generateSchedules ( ) ;
10181
102- return {
103- extracted : entries . length ,
104- imported,
105- unmatched,
106- duplicate,
107- timetableSections : this . courseSelector . allSections . length
108- } ;
82+ return { extracted : entries . length , imported, unmatched, duplicate, timetableSections : this . courseSelector . allSections . length } ;
10983 }
11084
11185 loadDemoDataset ( ) {
112- this . courseSelector . clearAll ( ) ;
113- this . onTimetableLoaded ( getSampleSections ( ) ) ;
114- setTimeout ( ( ) => {
115- const code = document . getElementById ( 'courseCode' ) , number = document . getElementById ( 'courseNumber' ) ;
116- for ( const [ c , n ] of [ [ 'CS' , '181' ] , [ 'MATH' , '101' ] , [ 'PHYS' , '101' ] , [ 'EXP' , '901' ] , [ 'EXP' , '902' ] , [ 'EXP' , '903' ] ] ) { code . value = c ; number . value = n ; this . courseSelector . addCurrentCourse ( ) ; }
117- this . notification . showSuccess ( getLang ( ) === 'ar' ?'تم تحميل بيانات تجريبية، ويتم الآن إنشاء جدول مناسب.' :'Sample data loaded. Building a schedule now.' ) ;
118- this . generateSchedules ( ) ;
119- } , 150 ) ;
86+ this . courseSelector . clearAll ( ) ; this . onTimetableLoaded ( getSampleSections ( ) ) ;
87+ setTimeout ( ( ) => { const code = document . getElementById ( 'courseCode' ) , number = document . getElementById ( 'courseNumber' ) ; for ( const [ c , n ] of [ [ 'CS' , '181' ] , [ 'MATH' , '101' ] , [ 'PHYS' , '101' ] , [ 'EXP' , '901' ] , [ 'EXP' , '902' ] , [ 'EXP' , '903' ] ] ) { code . value = c ; number . value = n ; this . courseSelector . addCurrentCourse ( ) ; } this . notification . showSuccess ( getLang ( ) === 'ar' ?'تم تحميل بيانات تجريبية، ويتم الآن إنشاء جدول مناسب.' :'Sample data loaded. Building a schedule now.' ) ; this . generateSchedules ( ) ; } , 150 ) ;
12088 }
12189 onWantedCoursesChanged ( groups ) { this . wantedCourseGroups = groups ; if ( ! groups . length ) { this . state . resetResults ( ) ; this . resultsView . updateVisibility ( ) ; } }
12290 async generateSchedules ( ) { if ( ! this . wantedCourseGroups . length ) return ; const result = await this . scheduleController . generate ( this . wantedCourseGroups ) ; if ( ! result . schedules . length ) { this . notification . showError ( t ( 'toast_no_schedules_found' ) ) ; this . diagnosticsView . render ( this . scheduleController . diagnoseConflicts ( this . wantedCourseGroups ) ) ; this . resultsView . updateVisibility ( ) ; return ; } this . diagnosticsView . render ( [ ] ) ; this . notification . playChime ( ) ; this . notification . showSuccess ( t ( 'toast_schedules_found' , { count :result . schedules . length } ) ) ; this . applyFilters ( result . filters ) ; }
0 commit comments