I want to show in the frontend the Mitre matrix in a table, but the backend response contains more data, like how many tickets have been classified in each tactic. So I want to fill the table vertically column by column instead of row by row. The backend response:
"tableData": [
{
"technique": "Reconnaissance",
"tactics": [
{
"tactic": "Active Scanning",
"id": "T1595",
"total_tickets": 14
},
{
"tactic": "Gather Victim Host Information",
"id": "T1592",
"total_tickets": 0
},
{
"tactic": "Gather Victim Identity Information",
"id": "T1589",
"total_tickets": 0
},
{
"tactic": "Gather Victim Network Information",
"id": "T1590",
"total_tickets": 0
},
{
"tactic": "Gather Victim Org Information",
"id": "T1591",
"total_tickets": 2
},
{
"tactic": "Phishing for Information",
"id": "T1598",
"total_tickets": 1
},
{
"tactic": "Search Closed Sources",
"id": "T1597",
"total_tickets": 0
},
{
"tactic": "Search Open Technical Databases",
"id": "T1596",
"total_tickets": 0
},
{
"tactic": "Search Open Websites/Domains",
"id": "T1593",
"total_tickets": 0
},
{
"tactic": "Search Victim-Owned Websites",
"id": "T1594",
"total_tickets": 1
}
]
},
{
"technique": "Resource Development",
"tactics": [
{
"tactic": "Acquire Infrastructure",
"id": "T1583",
"total_tickets": 1
},
{
"tactic": "Compromise Accounts",
"id": "T1586",
"total_tickets": 1
},
{
"tactic": "Compromise Infrastructure",
"id": "T1584",
"total_tickets": 5
},
{
"tactic": "Develop Capabilities",
"id": "T1587",
"total_tickets": 4
},
{
"tactic": "Establish Accounts",
"id": "T1585",
"total_tickets": 0
},
{
"tactic": "Obtain Capabilities",
"id": "T1588",
"total_tickets": 2
},
{
"tactic": "Stage Capabilities",
"id": "T1608",
"total_tickets": 0
}
]
},
{
"technique": "Initial Access",
"tactics": [
{
"tactic": "Drive-by Compromise",
"id": "T1189",
"total_tickets": 1
},
{
"tactic": "Exploit Public-Facing Application",
"id": "T1190",
"total_tickets": 2
},
{
"tactic": "External Remote Services",
"id": "T1133",
"total_tickets": 0
},
{
"tactic": "Hardware Additions",
"id": "T1200",
"total_tickets": 0
},
{
"tactic": "Phishing",
"id": "T1566",
"total_tickets": 2
},
{
"tactic": "Replication Through Removable Media",
"id": "T1091",
"total_tickets": 1
},
{
"tactic": "Supply Chain Compromise",
"id": "T1195",
"total_tickets": 0
},
{
"tactic": "Trusted Relationship",
"id": "T1199",
"total_tickets": 0
},
{
"tactic": "Valid Accounts",
"id": "T1078",
"total_tickets": 8
}
]
}
]
The HTML of the table, but the following code just filled a single column, but I want that after filled the first column with the firts technique the remaining data will be in the others columns (btw I'm using the NG Zorro library).
<div >
<div >
<div >
<span *ngIf="isLoading">Cargando...</span>
<span *ngIf="!isLoading">{{totalData || 0}} {{title || ''}}</span>
</div>
</div>
<div >
<nz-table #basicTable
[nzShowPagination]="false"
[nzTotal]="totalData"
[nzLoading]="isLoading"
[nzBordered]="true"
[nzData]="data">
<thead>
<tr>
<th *ngFor="let technique of basicTable.data">{{technique.technique}}</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let techniqueObject of basicTable.data">
<tr *ngFor="let tacticObject of techniqueObject.tactics">
<td>{{tacticObject.tactic}}: {{tacticObject.total_tickets}}</td>
</tr>
</ng-container>
</tbody>
</nz-table>
</div>
</div>
CodePudding user response:
Here's a quick StackBlitz example I did to try to achieve what I think you wanted to achieve.
Basically, the strategy is as follows:
// ngOnInit:
// determine how many tactics have each technique:
const tacticsCountPerTechnique = this.data.map(
(technique) => technique.tactics.length
);
// determine what's the max count of tactics in order to know how many rows to display:
const maxTacticsCount = Math.max.apply(null, tacticsCountPerTechnique);
// define a rowIndices array to conviniently render rows and tactics:
this.rowIndices = new Array(maxTacticsCount).fill(null).map((_, i) => i);
Following this approach your HTML would look like this:
<tbody>
<!-- display rows based on max number of tactics -->
<tr *ngFor="let index of rowIndices">
<!-- display columns based on techniques to match headers -->
<td *ngFor="let technique of basicTable.data">
<!-- display tactic info using row index as reference -->
<!-- some techniques may have more tactics than others so we display info only when there's a tactic for that index with ngIf -->
<ng-container *ngIf="technique.tactics[index] as tactic">
{{ tactic.tactic }}:
{{ tactic.total_tickets }}
</ng-container>
</td>
</tr>
</tbody>
There might be a better approach but I hope you get the idea.