Skip to content

Commit 01df12f

Browse files
Fixed the Focus cell on click scenarios
1 parent f5f4923 commit 01df12f

File tree

2 files changed

+198
-54
lines changed

2 files changed

+198
-54
lines changed

src/components/TableContent/TechniquesTable.jsx

Lines changed: 195 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/utils/dataMap.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,11 @@ export const filterDataMap = (selectedIcon, filterType) => {
108108

109109
export const fetchTechnique = (technique) => {
110110
if (!technique) return undefined;
111+
112+
if(!(technique !== null && typeof technique === 'object' && !Array.isArray(technique))){
111113
const key = technique?.toLowerCase().replace(/\s+/g, '_');
112114
return dataMap[key];
115+
}
113116
};
114117

115118
export const hasSubTechnique = (technique) => {

0 commit comments

Comments
 (0)