@@ -359,65 +359,13 @@ function selectState(state) { // eslint-disable-line no-unused-vars
359359/**
360360 * Displays fields based on selected category
361361 */
362- function renderSummaryPageFields ( ) {
363- const acceptedFields = [ ] ;
364- const rejectedFields = [ ] ;
365- const missingFields = [ ] ;
366- const emptyFields = [ ] ;
367-
368- const processedFields = new Set ( ) ;
369-
370- if ( state_dict && Object . keys ( state_dict ) . length > 0 ) {
371- const fields = document . querySelectorAll ( '.field' ) ;
372- for ( let field of fields ) {
373- let field_id = field . id . slice ( 6 ) ;
374- const fieldValue = $ ( field ) . find ( '.value' ) . text ( ) . replace ( / \s + / g, ' ' ) . trim ( ) ;
375- const fieldState = getFieldState ( field_id ) ;
376- const fieldCategory = field . getAttribute ( 'data-category' ) ;
377- let fieldName = field_id . replace ( / \. / g, ' ' ) ;
378- const uniqueFieldIdentifier = `${ fieldName } -${ fieldCategory } ` ;
379- if ( isEmptyValue ( fieldValue ) ) {
380- emptyFields . push ( { fieldName, fieldValue, fieldCategory : "emptyFields" } ) ;
381- processedFields . add ( uniqueFieldIdentifier ) ;
382- } else if ( fieldState === 'ok' ) {
383- acceptedFields . push ( { fieldName, fieldValue, fieldCategory } ) ;
384- processedFields . add ( uniqueFieldIdentifier ) ;
385- }
386- else if ( fieldState === 'rejected' ) {
387- rejectedFields . push ( { fieldName, fieldValue, fieldCategory } ) ;
388- processedFields . add ( uniqueFieldIdentifier ) ;
389- }
390- }
391- }
392-
393- for ( const review of current_review . reviews ) {
394- const field_id = `#field_${ review . key } ` . replaceAll ( "." , "\\." ) ;
395- const fieldValue = $ ( field_id ) . find ( '.value' ) . text ( ) . replace ( / \s + / g, ' ' ) . trim ( ) ;
396- const isAccepted = review . fieldReview . some ( ( fieldReview ) => fieldReview . state === 'ok' ) ;
397- const isRejected = review . fieldReview . some ( ( fieldReview ) => fieldReview . state === 'rejected' ) ;
398- const fieldCategory = review . category ;
399- let fieldName = review . key . replace ( / \. / g, ' ' ) ;
400-
401- const uniqueFieldIdentifier = `${ fieldName } -${ fieldCategory } ` ;
402362
403- if ( processedFields . has ( uniqueFieldIdentifier ) ) {
404- continue ; // Skipp fields that have already been processed from state_dict
405- }
406-
407-
408- if ( isEmptyValue ( fieldValue ) ) {
409- emptyFields . push ( { fieldName, fieldValue, fieldCategory : "emptyFields" } ) ;
410- } else if ( isAccepted ) {
411- acceptedFields . push ( { fieldName, fieldValue, fieldCategory } ) ;
412- } else if ( isRejected ) {
413- rejectedFields . push ( { fieldName, fieldValue, fieldCategory } ) ;
414- }
415- }
416-
417- const categories = document . querySelectorAll ( ".tab-pane" ) ;
363+ function renderSummaryPageFields ( ) {
364+ const categoriesMap = { } ;
418365
419- for ( const category of categories ) {
420- const category_name = category . id . slice ( 0 ) ;
366+ function addFieldToCategory ( category , field ) {
367+ if ( ! categoriesMap [ category ] ) categoriesMap [ category ] = [ ] ;
368+ categoriesMap [ category ] . push ( field ) ;
421369
422370 if ( category_name === "summary" ) {
423371 continue ;
@@ -441,73 +389,197 @@ function renderSummaryPageFields() {
441389 }
442390 }
443391
444- const summaryContainer = document . getElementById ( "summary" ) ;
445-
446- function clearSummaryTable ( ) {
447- while ( summaryContainer . firstChild ) {
448- summaryContainer . firstChild . remove ( ) ;
392+ const fields = document . querySelectorAll ( '.field' ) ;
393+ fields . forEach ( field => {
394+ const field_id = field . id . slice ( 6 ) ;
395+ const fieldValue = $ ( field ) . find ( '.value' ) . text ( ) . trim ( ) ;
396+ const fieldState = getFieldState ( field_id ) ;
397+ const fieldCategory = field . getAttribute ( 'data-category' ) ;
398+ let fieldName = field_id . replace ( / \. / g, ' ' ) ;
399+ if ( fieldCategory !== "general" ) {
400+ fieldName = fieldName . split ( ' ' ) . slice ( 1 ) . join ( ' ' ) ;
449401 }
450- }
451402
452- function generateTable ( data ) {
453- let table = document . createElement ( 'table' ) ;
454- table . className = 'table review-summary ';
403+ let fieldStatus = isEmptyValue ( fieldValue ) ? 'Empty' :
404+ fieldState === 'ok' ? 'Accepted' :
405+ fieldState === 'rejected' ? 'Rejected' : 'Missing ';
455406
456- let thead = document . createElement ( 'thead' ) ;
457- let header = document . createElement ( 'tr' ) ;
458- header . innerHTML = '<th scope="col">Status</th><th scope="col">Field Category</th><th scope="col">Field Name</th><th scope="col">Field Value</th>' ;
459- thead . appendChild ( header ) ;
460- table . appendChild ( thead ) ;
461-
462- let tbody = document . createElement ( 'tbody' ) ;
407+ addFieldToCategory ( fieldCategory , { fieldName, fieldValue, fieldStatus } ) ;
408+ } ) ;
463409
464- data . forEach ( ( item ) => {
465- let row = document . createElement ( 'tr' ) ;
410+ const summaryContainer = document . getElementById ( "summary" ) ;
411+ summaryContainer . innerHTML = '' ;
412+
413+ const tabsNav = document . createElement ( 'ul' ) ;
414+ tabsNav . className = 'nav nav-tabs' ;
415+
416+ const tabsContent = document . createElement ( 'div' ) ;
417+ tabsContent . className = 'tab-content' ;
418+
419+ let firstTab = true ;
420+
421+ for ( const category in categoriesMap ) {
422+ const tabId = `tab-${ category } ` ;
423+
424+ const navItem = document . createElement ( 'li' ) ;
425+ navItem . className = 'nav-item' ;
426+ navItem . innerHTML = `<button class="nav-link${ firstTab ? ' active' : '' } " data-bs-toggle="tab" data-bs-target="#${ tabId } ">${ category } </button>` ;
427+ tabsNav . appendChild ( navItem ) ;
428+
429+ const tabPane = document . createElement ( 'div' ) ;
430+ tabPane . className = `tab-pane fade${ firstTab ? ' show active' : '' } ` ;
431+ tabPane . id = tabId ;
432+
433+ const fields = categoriesMap [ category ] ;
434+ const singleFields = [ ] ;
435+ const groupedFields = { } ;
436+
437+ fields . forEach ( field => {
438+ const words = field . fieldName . split ( ' ' ) ;
439+ if ( words . length === 1 ) {
440+ singleFields . push ( field ) ;
441+ } else {
442+ const prefix = words [ 0 ] ;
443+ const rest = words . slice ( 1 ) ;
444+ const indices = rest . filter ( word => ! isNaN ( word ) ) ;
445+ const nameWithoutIndices = rest . filter ( word => isNaN ( word ) ) . join ( ' ' ) ;
446+
447+ if ( ! groupedFields [ prefix ] ) groupedFields [ prefix ] = { indexed : { } , noIndex : [ ] } ;
448+
449+ if ( indices . length > 0 ) {
450+ const indexKey = indices . map ( num => ( parseInt ( num , 10 ) + 1 ) ) . join ( '.' ) ;
451+ if ( ! groupedFields [ prefix ] . indexed [ indexKey ] ) groupedFields [ prefix ] . indexed [ indexKey ] = [ ] ;
452+ groupedFields [ prefix ] . indexed [ indexKey ] . push ( { ...field , fieldName : nameWithoutIndices } ) ;
453+ } else {
454+ groupedFields [ prefix ] . noIndex . push ( { ...field , fieldName : nameWithoutIndices } ) ;
455+ }
466456
467457 let th = document . createElement ( 'th' ) ;
468458 th . scope = "row" ;
469459 th . className = "status" ;
470460 if ( item . fieldStatus === "Pending" ) {
471461 th . className = "status missing" ;
472462 }
473- th . textContent = item . fieldStatus ;
474- row . appendChild ( th ) ;
475-
476- let tdFieldCategory = document . createElement ( 'td' ) ;
477- tdFieldCategory . textContent = item . fieldCategory ;
478- row . appendChild ( tdFieldCategory ) ;
479-
480- let tdFieldId = document . createElement ( 'td' ) ;
481- tdFieldId . textContent = item . fieldName ;
482- row . appendChild ( tdFieldId ) ;
483-
484- let tdFieldValue = document . createElement ( 'td' ) ;
485- tdFieldValue . textContent = item . fieldValue ;
486- row . appendChild ( tdFieldValue ) ;
487-
488- tbody . appendChild ( row ) ;
489463 } ) ;
490464
491- table . appendChild ( tbody ) ;
492-
493- return table ;
494- }
495-
496- function updateSummaryTable ( ) {
497- clearSummaryTable ( ) ;
465+ if ( singleFields . length > 0 ) {
466+ const table = document . createElement ( 'table' ) ;
467+ table . className = 'table review-summary' ;
468+ table . innerHTML = `
469+ <thead><tr><th>Status</th><th>Field Name</th><th>Field Value</th></tr></thead>
470+ <tbody>${ singleFields . map ( f => `
471+ <tr>
472+ <td class="status ${ f . fieldStatus . toLowerCase ( ) } ">${ f . fieldStatus } </td>
473+ <td>${ f . fieldName } </td>
474+ <td>${ f . fieldValue } </td>
475+ </tr>` ) . join ( '' ) }
476+ </tbody>` ;
477+ tabPane . appendChild ( table ) ;
478+ }
498479
499- let allData = [ ] ;
500- allData . push ( ...missingFields . map ( ( item ) => ( { ...item , fieldStatus : 'Pending' } ) ) ) ;
501- allData . push ( ...rejectedFields . map ( ( item ) => ( { ...item , fieldStatus : 'Rejected' } ) ) ) ;
502- allData . push ( ...acceptedFields . map ( ( item ) => ( { ...item , fieldStatus : 'Accepted' } ) ) ) ;
480+ if ( Object . keys ( groupedFields ) . length > 0 ) {
481+ const accordionContainer = document . createElement ( 'div' ) ;
482+ accordionContainer . className = 'accordion' ;
483+ accordionContainer . id = `accordion-${ category } ` ;
484+
485+ let accordionIndex = 0 ;
486+ for ( const prefix in groupedFields ) {
487+ const accordionItem = document . createElement ( 'div' ) ;
488+ accordionItem . className = 'accordion-item' ;
489+ const headingId = `heading-${ category } -${ accordionIndex } ` ;
490+ const collapseId = `collapse-${ category } -${ accordionIndex } ` ;
491+
492+ const { noIndex, indexed } = groupedFields [ prefix ] ;
493+
494+ let innerHTML = '' ;
495+
496+ if ( noIndex . length > 0 ) {
497+ innerHTML += `
498+ <table class="table table-sm table-bordered">
499+ <thead><tr><th>Status</th><th>Field Name</th><th>Field Value</th></tr></thead>
500+ <tbody>${ noIndex . map ( f => `
501+ <tr>
502+ <td class="status ${ f . fieldStatus . toLowerCase ( ) } ">${ f . fieldStatus } </td>
503+ <td>${ f . fieldName } </td>
504+ <td>${ f . fieldValue } </td>
505+ </tr>` ) . join ( '' ) }
506+ </tbody>
507+ </table>` ;
508+ }
503509
504- allData . push ( ...emptyFields . map ( ( item ) => ( { ...item , fieldStatus : 'Empty' } ) ) ) ;
510+ if ( Object . keys ( indexed ) . length > 0 ) {
511+ const subAccordionId = `subAccordion-${ category } -${ accordionIndex } ` ;
512+ innerHTML += `<div class="accordion" id="${ subAccordionId } ">` ;
513+
514+ Object . entries ( indexed ) . forEach ( ( [ idx , idxFields ] , idxAccordionIndex ) => {
515+ const idxHeadingId = `idxHeading-${ category } -${ accordionIndex } -${ idxAccordionIndex } ` ;
516+ const idxCollapseId = `idxCollapse-${ category } -${ accordionIndex } -${ idxAccordionIndex } ` ;
517+
518+ const tabLabel = [ 'source' , 'license' ] . includes ( category ) ? 'fields' : `${ prefix } ${ idx } ` ;
519+
520+ innerHTML += `
521+ <div class="accordion-item">
522+ <h2 class="accordion-header" id="${ idxHeadingId } ">
523+ <button class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#${ idxCollapseId } ">
524+ ${ tabLabel }
525+ </button>
526+ </h2>
527+ <div id="${ idxCollapseId } " class="accordion-collapse collapse" data-bs-parent="#${ subAccordionId } ">
528+ <div class="accordion-body">
529+ <table class="table table-sm table-bordered">
530+ <thead><tr><th>Status</th><th>Field Name</th><th>Field Value</th></tr></thead>
531+ <tbody>${ idxFields . map ( f => `
532+ <tr>
533+ <td class="status ${ f . fieldStatus . toLowerCase ( ) } ">${ f . fieldStatus } </td>
534+ <td>${ f . fieldName } </td>
535+ <td>${ f . fieldValue } </td>
536+ </tr>` ) . join ( '' ) }
537+ </tbody>
538+ </table>
539+ </div>
540+ </div>
541+ </div>` ;
542+ } ) ;
543+
544+ innerHTML += `</div>` ;
545+ }
505546
506- let table = generateTable ( allData ) ;
507- summaryContainer . appendChild ( table ) ;
547+ tabsContent . appendChild ( tabPane ) ;
548+ firstTab = false ;
508549 }
509-
510- updateSummaryTable ( ) ;
550+ const viewsNavItem = document . createElement ( 'li' ) ;
551+ viewsNavItem . className = 'nav-item' ;
552+ viewsNavItem . innerHTML = < button class = "nav-link" data-bs-toggle = "tab" data-bs-target = "#tab-views" > views</ button > ;
553+
554+
555+ tabsNav . appendChild ( viewsNavItem ) ;
556+
557+ const viewsPane = document . createElement ( 'div' ) ;
558+ viewsPane . className = 'tab-pane fade' ;
559+ viewsPane . id = 'tab-views' ;
560+
561+ const allFields = Object . entries ( categoriesMap ) . flatMap ( ( [ category , fields ] ) =>
562+ fields . map ( f => ( { ...f , category} ) )
563+ ) ;
564+
565+ viewsPane . innerHTML =
566+ < table class = "table review-summary" >
567+ < thead >
568+ < tr > < th > Status</ th > < th > Category</ th > < th > Field Name</ th > < th > Field Value</ th > </ tr >
569+ </ thead >
570+ < tbody > ${ allFields . map ( f =>
571+ < tr >
572+ < td class = "status ${f.fieldStatus.toLowerCase()}" > ${ f . fieldStatus } </ td >
573+ < td > ${ f . category } </ td >
574+ < td > ${ f . fieldName } </ td >
575+ < td > ${ f . fieldValue } </ td >
576+ </ tr > ) . join ( '' ) }
577+ </ tbody >
578+ </ table > ;
579+
580+ tabsContent . appendChild ( viewsPane ) ;
581+ summaryContainer . appendChild ( tabsNav ) ;
582+ summaryContainer . appendChild ( tabsContent ) ;
511583 updateTabProgressIndicatorClasses ( ) ;
512584}
513585
0 commit comments