|
1 | 1 | import { CSS_CLASSES } from "../../utils/constants/css_constants"; |
2 | 2 | import { attachTooltip } from "../renderables/tooltip_manager"; |
| 3 | +import { Table } from "./table"; |
| 4 | +import { Flags, TCP_FLAGS_KEY } from "../../packets/tcp"; |
3 | 5 |
|
4 | 6 | export interface InfoField { |
5 | 7 | key: string; |
@@ -58,7 +60,10 @@ export class TextInfo { |
58 | 60 | private createListItem(field: InfoField): HTMLLIElement { |
59 | 61 | const { key, value, tooltip } = field; |
60 | 62 |
|
61 | | - if (typeof value === "object" && value !== null) { |
| 63 | + if (key === TCP_FLAGS_KEY) { |
| 64 | + const flags = value as Flags; |
| 65 | + return this.createFlagsElement(flags, tooltip); |
| 66 | + } else if (typeof value === "object" && value !== null) { |
62 | 67 | return this.createPayloadElement(key, value, tooltip); |
63 | 68 | } else { |
64 | 69 | return this.createDetailElement(key, value as string, tooltip); |
@@ -133,4 +138,77 @@ export class TextInfo { |
133 | 138 |
|
134 | 139 | return listItem; |
135 | 140 | } |
| 141 | + |
| 142 | + /** |
| 143 | + * Creates a TCP flags display element with ticks and crosses using the Table class |
| 144 | + * @param flags An object containing the TCP flag values |
| 145 | + * @param tooltip Optional tooltip for the flags element |
| 146 | + * @returns HTMLLIElement containing the flags table |
| 147 | + */ |
| 148 | + createFlagsElement(flags: Flags, tooltip?: string): HTMLLIElement { |
| 149 | + // Create list item container |
| 150 | + const listItem = document.createElement("li"); |
| 151 | + listItem.classList.add(CSS_CLASSES.DETAIL_ITEM); |
| 152 | + |
| 153 | + // Create key element |
| 154 | + const keyElement = document.createElement("span"); |
| 155 | + keyElement.textContent = "TCP Flags"; |
| 156 | + keyElement.classList.add( |
| 157 | + CSS_CLASSES.DETAIL_KEY, |
| 158 | + CSS_CLASSES.TCP_FLAG_HEADER, |
| 159 | + ); |
| 160 | + keyElement.style.display = CSS_CLASSES.BLOCK; |
| 161 | + |
| 162 | + if (tooltip) { |
| 163 | + attachTooltip(keyElement, tooltip); |
| 164 | + } |
| 165 | + |
| 166 | + // Create rows for the table |
| 167 | + const statusRow: string[] = []; |
| 168 | + const valueRow: string[] = []; |
| 169 | + |
| 170 | + Object.entries(flags).forEach(([, value]) => { |
| 171 | + statusRow.push(value ? "✓" : "✗"); |
| 172 | + valueRow.push(value ? "1" : "0"); |
| 173 | + }); |
| 174 | + |
| 175 | + // Create headers for the table |
| 176 | + const headers = Object.keys(flags); |
| 177 | + |
| 178 | + // Create the table using the Table class |
| 179 | + const flagsTable = new Table({ |
| 180 | + headers: headers.reduce( |
| 181 | + (acc, header) => { |
| 182 | + acc[header] = header; |
| 183 | + return acc; |
| 184 | + }, |
| 185 | + {} as Record<string, string>, |
| 186 | + ), |
| 187 | + fieldsPerRow: Object.keys(flags).length, |
| 188 | + rows: [statusRow, valueRow], |
| 189 | + tableClasses: [CSS_CLASSES.TABLE, CSS_CLASSES.RIGHT_BAR_TABLE], |
| 190 | + }); |
| 191 | + |
| 192 | + // Get the table element |
| 193 | + const tableElement = flagsTable.toHTML(); |
| 194 | + |
| 195 | + // Apply custom styling to the status row cells (ticks and crosses) |
| 196 | + const tbody = tableElement.querySelector("tbody"); |
| 197 | + if (tbody && tbody.rows.length > 0) { |
| 198 | + const statusCells = tbody.rows[0].cells; |
| 199 | + for (const cell of statusCells) { |
| 200 | + if (cell.textContent === "✓") { |
| 201 | + cell.classList.add(CSS_CLASSES.TCP_FLAG_ACTIVE); |
| 202 | + } else { |
| 203 | + cell.classList.add(CSS_CLASSES.TCP_FLAG_INACTIVE); |
| 204 | + } |
| 205 | + } |
| 206 | + } |
| 207 | + |
| 208 | + // Append elements to list item |
| 209 | + listItem.appendChild(keyElement); |
| 210 | + listItem.appendChild(tableElement); |
| 211 | + |
| 212 | + return listItem; |
| 213 | + } |
136 | 214 | } |
0 commit comments