diff --git a/src/query/output.ts b/src/query/output.ts index e923b5e..7dbf6ea 100644 --- a/src/query/output.ts +++ b/src/query/output.ts @@ -1,4 +1,5 @@ import type { SearchIssueResponse, SearchRepoResponse } from "src/github/response"; +import { getProp, titleCase } from "src/util"; import type { TableParams } from "./params"; @@ -10,15 +11,19 @@ export function renderTable( const table = el.createEl("table", { cls: "github-link-query-table" }); const thead = table.createEl("thead"); for (const col of params.columns) { - thead.createEl("th", { text: col }); + thead.createEl("th", { text: titleCase(col) }); } const tbody = table.createEl("tbody"); for (const row of result.items) { const tr = tbody.createEl("tr"); for (const col of params.columns) { const cell = tr.createEl("td"); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - cell.setText((row as any)[col] ?? ""); + const cellVal = getProp(row, col); + if (cellVal !== null) { + cell.setText(typeof cellVal === "string" ? cellVal : JSON.stringify(cellVal)); + } else { + cell.setText(""); + } } } } diff --git a/src/util.ts b/src/util.ts index 712fa38..4369325 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,7 +1,33 @@ +export function titleCase(value: string): string { + const words = value.split(/[-_]/); + return words.map((w) => w.charAt(0)?.toUpperCase() + w.slice(1)).join(" "); +} + export function valueWithin(value: number, min: number, max: number) { return value >= min && value <= max; } +/** + * Attempts to handle getting a nested property using a string of js object notation + */ +export function getProp(value: T, prop: string): unknown | null { + if (!prop.includes(".")) { + return value[prop] ?? null; + } + + const parts = prop.split("."); + let val: T = value; + for (const part of parts) { + try { + val = val[part] as T; + } catch (err) { + return null; + } + } + + return val ?? null; +} + export function safeJSONParse(value: string, props: Record): T | null { // Handle parsing with try / catch let parsed: T;