@@ -519,6 +519,13 @@ const TechniquesTable = ({
519519 } ) ;
520520 }
521521 }
522+
523+ if ( focusedCell . col + 1 > columnNumber ) {
524+ setFocusedCell ( ( prev ) => {
525+ const newCol = prev ? prev . col - 1 : 0 ;
526+ return { row : prev . row , col : newCol } ;
527+ } ) ;
528+ }
522529 setTableData ( updatedData ) ;
523530 } else {
524531 // operation == add
@@ -535,6 +542,13 @@ const TechniquesTable = ({
535542 } else {
536543 setAddedColumns ( [ ...addedColumns , newColumnIndex ] ) ;
537544 }
545+
546+ if ( focusedCell . col + 1 > columnNumber ) {
547+ setFocusedCell ( ( prev ) => {
548+ const newCol = prev ? prev . col + 1 : 0 ;
549+ return { row : prev . row , col : newCol } ;
550+ } ) ;
551+ }
538552 }
539553 } ) ;
540554
@@ -787,7 +801,14 @@ const TechniquesTable = ({
787801 if ( subCells . length > 0 ) {
788802 subCells [ index ] ?. focus ( ) ; // Focus the first <li> element
789803 // Set the background color of the newly focused subcell
790- subCells [ index ] . style . backgroundColor = FOCUS ;
804+ for ( let i = 0 ; i < subCells . length ; i ++ ) {
805+
806+ if ( i == index ) {
807+ subCells [ i ] . style . backgroundColor = FOCUS ;
808+ } else {
809+ subCells [ i ] . style . backgroundColor = NO_FOCUS ;
810+ }
811+ }
791812 }
792813 }
793814 onValueClick ( line ) ;
@@ -800,7 +821,7 @@ const TechniquesTable = ({
800821 // Reset previously focused subcell's background color (if any)
801822 if ( focusedCell ) {
802823 const previousCell = tableRef . current ?. querySelector (
803- `tr:nth-child(${ focusedCell . row + 1 } ) td:nth-child(${ focusedCell . col + 1 } )` ,
824+ `tbody tr:nth-child(${ focusedCell . row + 1 } ) td:nth-child(${ focusedCell . col } )` ,
804825 ) ;
805826 if ( previousCell ) {
806827 // If the previous cell had subcells, reset their background color
@@ -870,82 +891,202 @@ const TechniquesTable = ({
870891
871892 } , [ riskScoreInfo ] ) ;
872893
894+ function extractText ( node ) {
895+ if ( typeof node === 'string' || typeof node === 'number' ) {
896+ return node ;
897+ }
898+ if ( Array . isArray ( node ) ) {
899+ return node . map ( extractText ) . join ( '' ) ;
900+ }
901+ if ( node ?. props ?. children ) {
902+ return extractText ( node . props . children ) ;
903+ }
904+ return '' ;
905+ }
906+
907+ function extractLiValues ( reactUlElement ) {
908+ const children = reactUlElement ?. props ?. children ;
909+ if ( ! children ) return [ ] ;
910+
911+ const liElements = Array . isArray ( children ) ? children : [ children ] ;
912+
913+ return liElements
914+ . filter ( child => child ?. type === 'li' )
915+ . map ( li => extractText ( li . props . children ) ) ;
916+ }
917+
918+
919+
873920 const renderRows = ( ) => {
874- if ( tableData && tableData . length == 0 ) {
875- setTableData ( JSON . parse ( localStorage . getItem ( 'technique_table' ) ) ) ;
921+ if ( tableData && tableData . length === 0 ) {
922+ const savedData = localStorage . getItem ( 'technique_table' ) ;
923+ if ( savedData ) setTableData ( JSON . parse ( savedData ) ) ;
876924 }
877925
878926 return (
879927 tableData &&
880928 tableData . map ( ( item , rowIndex ) => (
881929 < tr key = { rowIndex } >
882- { Object . keys ( item ) . map ( ( key , colIndex ) => (
883- < td
884- key = { rowIndex + '-' + colIndex }
885- className = { item [ key ] === '' ? 'emptycell' : 'tabledata' }
886- tabIndex = { 0 }
887- style = { {
888- backgroundColor :
889- cellColors [ item [ key ] ] ? cellColors [ item [ key ] ] :
890- focusedCell . row === rowIndex &&
930+ { Object . keys ( item ) . map ( ( key , colIndex ) => {
931+ const cellValue = item [ key ] ;
932+
933+ let isSubcell = false
934+ let sub_techniques = [ ]
935+
936+ if ( cellValue !== null && typeof cellValue === 'object' && ! Array . isArray ( cellValue ) ) { //Sub Techniques
937+ isSubcell = true
938+ sub_techniques = extractLiValues ( cellValue )
939+ }
940+
941+ return (
942+ < td
943+ key = { rowIndex + '-' + colIndex }
944+ className = { cellValue === '' ? 'emptycell' : 'tabledata' }
945+ tabIndex = { 0 }
946+ style = { {
947+ backgroundColor :
948+ cellColors [ cellValue ] ??
949+ ( focusedCell . row === rowIndex &&
891950 focusedCell . col === colIndex &&
892951 focusedLiIndex == null
893952 ? FOCUS
894- : NO_FOCUS ,
895- outline : 'none' ,
896- // color: 'red'
897- // color: (item[key] === selectedTechnique && hideStatus) ? 'grey' : 'white'
898- color : hiddenTechniques ?. includes ( item [ key ] ) ? 'grey' : 'white' ,
899- } }
900- onClick = { ( ) => {
901- if ( item [ key ] !== '' ) {
902- handleCellClick ( rowIndex , colIndex , item , key ) ;
903- }
904- } }
905- >
906-
907- { item [ key ] &&
908- item [ key ] . length > 0 &&
909- editStatus && (
953+ : NO_FOCUS ) ,
954+ outline : 'none' ,
955+ color : hiddenTechniques ?. includes ( cellValue ) ? 'grey' : 'white' ,
956+ } }
957+ onClick = { ( ) => {
958+ if ( cellValue !== '' ) {
959+ handleCellClick ( rowIndex , colIndex , item , key ) ;
960+ }
961+ } }
962+ >
963+ { /* Subcell rendering */ }
964+ { isSubcell ? (
965+ // <ul>
966+ // {sub_tech.map((subItem, subIndex) => (
967+ // <li
968+ // key={subIndex}
969+ // style={{ backgroundColor: cellColors[subItem] }}
970+ // >
971+ // {subItem}
972+ // {editStatus && (
973+ // <div
974+ // className="editicon"
975+ // aria-label="edit"
976+ // onClick={(e) => {
977+ // e.stopPropagation();
978+ // handleEdit(subItem);
979+ // }}
980+ // >
981+ // <RiEdit2Fill className="white-icon" />
982+ // </div>
983+ // )}
984+ // </li>
985+ // ))}
986+ // </ul>
987+ < ul >
988+ { sub_techniques &&
989+ sub_techniques . map ( ( line , index ) => (
990+ < li
991+ style = { { display : 'flex' , justifyContent : 'space-between' , alignItems : 'center' } }
992+ tabIndex = { 0 }
993+ key = { index }
994+ onFocus = { ( ) => {
995+ let row = rowIndex ;
996+ let col = colIndex ;
997+ const currentCell = tableRef . current ?. querySelector (
998+ `tr:nth-child(${ row + 1 } ) td:nth-child(${ col + 2 } )` ,
999+ ) ;
1000+
1001+ if ( ! currentCell ) return ;
1002+
1003+ const subCells = currentCell . querySelectorAll ( 'li' ) ;
1004+ const isSubcell = subCells . length > 0 ;
1005+
1006+ if ( isSubcell ) {
1007+ for ( let i = 0 ; i < subCells . length ; i ++ ) {
1008+ if ( i === index ) {
1009+ subCells [ i ] ?. focus ( ) ;
1010+ subCells [ i ] . style . backgroundColor = FOCUS ;
1011+ } else {
1012+ subCells [ i ] . style . backgroundColor = NO_FOCUS ;
1013+ }
1014+ }
1015+ }
1016+ } }
1017+ onClick = { ( e ) => {
1018+ e . stopPropagation ( ) ; // Prevents the event from bubbling up to the <td>
1019+ // onValueClick(line); // Trigger the onValueClick function
1020+ handleSubCellClick ( rowIndex , colIndex , line , index ) ;
1021+ } }
1022+ >
1023+ { /* {line} */ }
1024+ < span style = { { flex : 1 , textAlign : 'center' } } > { line } </ span >
1025+ { editStatus && (
1026+ < >
1027+ < div
1028+ // className="sub-technique-editicon"
1029+ style = { {
1030+ paddingRight : '10px' ,
1031+ cursor : 'pointer' ,
1032+ backgroundColor : 'rgb(48, 48, 48)' ,
1033+ color : 'white'
1034+ } }
1035+ aria-label = "edit"
1036+ onClick = { ( e ) => {
1037+ e . stopPropagation ( ) ;
1038+ // e.preventDefault();
1039+ handleEdit ( line ) ;
1040+ } }
1041+ >
1042+ < RiEdit2Fill className = "white-icon" />
1043+ </ div >
1044+ </ >
1045+ ) }
1046+
1047+ { /* <RiEdit2Fill/> */ }
1048+ </ li >
1049+ ) ) }
1050+ </ ul >
1051+ ) : (
9101052 < >
911- < div
912- className = "editicon"
913- aria-label = "edit"
914- onClick = { ( e ) => {
915- e . stopPropagation ( ) ;
916- // e.preventDefault();
917- handleEdit ( item [ key ] ) ;
918- } }
919- >
920- < RiEdit2Fill className = "white-icon" />
921- </ div >
1053+ { editStatus && cellValue && (
1054+ < div
1055+ className = "editicon"
1056+ aria-label = "edit"
1057+ onClick = { ( e ) => {
1058+ e . stopPropagation ( ) ;
1059+ handleEdit ( cellValue ) ;
1060+ } }
1061+ >
1062+ < RiEdit2Fill className = "white-icon" />
1063+ </ div >
1064+ ) }
1065+ { cellValue }
9221066 </ >
923- )
924- }
1067+ ) }
9251068
926- { item [ key ] }
927- { item [ key ] &&
928- item [ key ] . length > 0 &&
929- hasSubTechnique ( item [ key ] ) && (
930- < >
1069+ { /* Expand/collapse if sub-technique is present */ }
1070+ { cellValue &&
1071+ hasSubTechnique ( cellValue ) && (
9311072 < div
9321073 className = "sidebar"
9331074 aria-label = "expand collapse"
9341075 onClick = { ( e ) => {
9351076 e . stopPropagation ( ) ;
9361077 manage_columns (
937- item [ key ] . toLowerCase ( ) ,
1078+ typeof cellValue === 'string' ? cellValue . toLowerCase ( ) : '' ,
9381079 rowIndex ,
939- colIndex ,
1080+ colIndex
9401081 ) ;
9411082 } }
9421083 >
9431084 < RiExpandLeftRightFill />
9441085 </ div >
945- </ >
946- ) }
947- </ td >
948- ) ) }
1086+ ) }
1087+ </ td >
1088+ ) ;
1089+ } ) }
9491090 </ tr >
9501091 ) )
9511092 ) ;
@@ -1068,7 +1209,7 @@ const TechniquesTable = ({
10681209 handleCellColoring ( )
10691210 } , [ focusedCell , focusedLiIndex , cellColors ] ) ;
10701211
1071- const handleCellColoring = ( ) => {
1212+ const handleCellColoring = ( ) => {
10721213 if ( tableData && tableData . length > 0 ) {
10731214 const headers = Object . keys ( tableData [ 0 ] ) ;
10741215
0 commit comments