11let allModules = [ ] ;
2+ let skippedModules = [ ] ;
23let filteredModuleList = [ ] ;
34const cardTemplate = document . getElementById ( "card-template" ) ;
45const resetButton = document . getElementById ( "reset-button" ) ;
@@ -33,6 +34,23 @@ function toggleMenu () {
3334function createCard ( moduleData ) {
3435 const card = document . importNode ( cardTemplate . content , true ) ;
3536
37+ // Skipped module special handling
38+ if ( moduleData . skipped ) {
39+ card . querySelector ( ".card" ) . classList . add ( "skipped" ) ;
40+ card . querySelector ( ".name" ) . textContent = moduleData . name || "Unknown Module" ;
41+ card . querySelector ( ".name" ) . href = moduleData . url || "#" ;
42+ card . querySelector ( ".description" ) . innerHTML = `<span style='color:red;font-weight:bold'>Error: Module could not be loaded.</span><br>${ moduleData . error || "Unknown Error" } ` ;
43+ // Remove other info sections
44+ card . querySelector ( ".maintainer" ) . textContent = moduleData . maintainer || "?" ;
45+ [ ".stars" , ".tags" , ".img-container" , ".info" , ".outdated-note" ] . forEach ( ( selector ) => {
46+ const element = card . querySelector ( selector ) ;
47+ if ( element ) {
48+ element . remove ( ) ;
49+ }
50+ } ) ;
51+ return card ;
52+ }
53+
3654 /* Set the header data */
3755 card . querySelector ( ".name" ) . href = moduleData . url ;
3856 card . querySelector ( ".name" ) . textContent = moduleData . name ;
@@ -132,7 +150,7 @@ function updateModuleCardContainer () {
132150 let moduleCounter = filteredModuleList . length ;
133151
134152 filteredModuleList . forEach ( ( moduleData ) => {
135- if ( ! moduleData . outdated || showOutdated . checked ) {
153+ if ( ( ! moduleData . outdated || showOutdated . checked ) && ( ! moduleData . skipped || showOutdated . checked ) ) {
136154 try {
137155 const cardNode = createCard ( moduleData ) ;
138156 if ( cardNode ) {
@@ -229,7 +247,8 @@ function displayStatistics (data) {
229247
230248function filterBySearchText ( searchText ) {
231249 const searchLower = searchText . toLowerCase ( ) ;
232- filteredModuleList = allModules . filter ( ( card ) => {
250+ const allModulesList = allModules . concat ( skippedModules ) ;
251+ filteredModuleList = allModulesList . filter ( ( card ) => {
233252 const cardText = card . text
234253 ? card . text . toLowerCase ( )
235254 : "" ;
@@ -295,8 +314,8 @@ function filterByTag (tag) {
295314function addCategoryFilter ( ) {
296315 const categoryFilter = document . getElementById ( "category-filter" ) ;
297316 const categories = [ ...new Set ( allModules . map ( ( module ) => module . category ) ) ] ;
298-
299317 categories . sort ( ) ;
318+ categories . push ( "Problematic Modules" ) ;
300319
301320 categories . forEach ( ( category ) => {
302321 const option = document . createElement ( "option" ) ;
@@ -308,15 +327,15 @@ function addCategoryFilter () {
308327 categoryFilter . addEventListener ( "change" , ( ) => {
309328 const selectedCategory = categoryFilter . value ;
310329 if ( selectedCategory === "all" ) {
311- filteredModuleList = allModules ;
330+ filteredModuleList = allModules . concat ( skippedModules ) ;
331+ } else if ( selectedCategory === "Problematic Modules" ) {
332+ filteredModuleList = skippedModules ;
312333 } else {
313334 filteredModuleList = allModules . filter ( ( module ) => module . category === selectedCategory ) ;
314335 }
315336
316337 searchInput . value = "" ;
317-
318338 removeSelectedMarkingFromTagsAndCards ( ) ;
319-
320339 updateModuleCardContainer ( ) ;
321340 } ) ;
322341}
@@ -338,7 +357,7 @@ moduleCardContainer.addEventListener("click", (event) => {
338357resetButton . addEventListener ( "click" , ( ) => {
339358 resetCategoryFilter ( ) ;
340359 const root = document . querySelector ( ":root" ) ;
341- filteredModuleList = allModules ;
360+ filteredModuleList = allModules . concat ( skippedModules ) ;
342361 searchInput . value = "" ;
343362 showOutdated . checked = true ;
344363 removeSelectedMarkingFromTagsAndCards ( ) ;
@@ -360,7 +379,7 @@ searchInput.addEventListener("input", () => {
360379 if ( searchInput . value ) {
361380 filterBySearchText ( searchInput . value ) ;
362381 } else {
363- filteredModuleList = allModules ;
382+ filteredModuleList = allModules . concat ( skippedModules ) ;
364383 updateModuleCardContainer ( ) ;
365384 }
366385 } , 180 ) ;
@@ -413,15 +432,27 @@ async function initiate () {
413432 const response = await fetch ( modulesFile ) ;
414433 const data = await response . json ( ) ;
415434 allModules = data ;
416- filteredModuleList = data ;
417- sortData ( sortDropdown . value ) ;
418- updateModuleCardContainer ( ) ;
419- displayTagButtonContainer ( ) ;
420- addCategoryFilter ( ) ;
421435 } catch ( error ) {
422- console . error ( "Error fetching data:" , error ) ;
436+ allModules = [ ] ;
437+ console . error ( "Error fetching modules:" , error ) ;
438+ }
439+
440+ // Load skipped modules
441+ try {
442+ const skippedRes = await fetch ( "data/skipped_modules.json" ) ;
443+ const skippedRaw = await skippedRes . json ( ) ;
444+ skippedModules = skippedRaw . map ( ( moduleObj ) => ( { ...moduleObj , skipped : true , defaultSortWeight : 1000 , lastCommit : "" } ) ) ;
445+ } catch {
446+ skippedModules = [ ] ;
423447 }
424448
449+ filteredModuleList = allModules . concat ( skippedModules ) ;
450+ sortData ( sortDropdown . value ) ;
451+ updateModuleCardContainer ( ) ;
452+ displayTagButtonContainer ( ) ;
453+ addCategoryFilter ( ) ;
454+
455+ // Load statistics
425456 const statisticsFile = "data/stats.json" ;
426457 try {
427458 const response = await fetch ( statisticsFile ) ;
0 commit comments