Skip to content

Commit 4281b81

Browse files
committed
table cleanup
1 parent 8a181b5 commit 4281b81

1 file changed

Lines changed: 73 additions & 19 deletions

File tree

packages/b2c-cli/src/commands/job/search.ts

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,38 @@ import {
88
} from '@salesforce/b2c-tooling/operations/jobs';
99
import {t} from '../../i18n/index.js';
1010

11+
/**
12+
* Column definition for table output.
13+
*/
14+
interface ColumnDef {
15+
header: string;
16+
get: (e: JobExecution) => string;
17+
}
18+
19+
/**
20+
* Available columns for job execution list output.
21+
*/
22+
const COLUMNS: Record<string, ColumnDef> = {
23+
id: {
24+
header: 'Execution ID',
25+
get: (e) => e.id ?? '-',
26+
},
27+
jobId: {
28+
header: 'Job ID',
29+
get: (e) => e.job_id ?? '-',
30+
},
31+
status: {
32+
header: 'Status',
33+
get: (e) => e.exit_status?.code || e.execution_status || '-',
34+
},
35+
startTime: {
36+
header: 'Start Time',
37+
get: (e) => (e.start_time ? new Date(e.start_time).toISOString().replace('T', ' ').slice(0, 19) : '-'),
38+
},
39+
};
40+
41+
const DEFAULT_COLUMNS = ['id', 'jobId', 'status', 'startTime'];
42+
1143
export default class JobSearch extends InstanceCommand<typeof JobSearch> {
1244
static description = t('commands.job.search.description', 'Search for job executions on a B2C Commerce instance');
1345

@@ -97,33 +129,55 @@ export default class JobSearch extends InstanceCommand<typeof JobSearch> {
97129
return results;
98130
}
99131

132+
/**
133+
* Calculate dynamic column widths based on content.
134+
*/
135+
private calculateColumnWidths(executions: JobExecution[], columnKeys: string[]): Map<string, number> {
136+
const widths = new Map<string, number>();
137+
const padding = 2;
138+
139+
for (const key of columnKeys) {
140+
const col = COLUMNS[key];
141+
let maxWidth = col.header.length;
142+
143+
for (const exec of executions) {
144+
const value = col.get(exec);
145+
maxWidth = Math.max(maxWidth, value.length);
146+
}
147+
148+
widths.set(key, maxWidth + padding);
149+
}
150+
151+
return widths;
152+
}
153+
100154
private printExecutionsTable(executions: JobExecution[]): void {
101-
const ui = cliui({width: process.stdout.columns || 120});
155+
const termWidth = process.stdout.columns || 120;
156+
const ui = cliui({width: termWidth});
157+
const columnKeys = DEFAULT_COLUMNS;
158+
159+
const widths = this.calculateColumnWidths(executions, columnKeys);
102160

103161
// Header
104-
ui.div(
105-
{text: 'Execution ID', width: 38, padding: [0, 1, 0, 0]},
106-
{text: 'Job ID', width: 30, padding: [0, 1, 0, 0]},
107-
{text: 'Status', width: 12, padding: [0, 1, 0, 0]},
108-
{text: 'Start Time', width: 20, padding: [0, 0, 0, 0]},
109-
);
162+
const headerCols = columnKeys.map((key) => ({
163+
text: COLUMNS[key].header,
164+
width: widths.get(key),
165+
padding: [0, 1, 0, 0] as [number, number, number, number],
166+
}));
167+
ui.div(...headerCols);
110168

111169
// Separator
112-
ui.div({text: '─'.repeat(100), padding: [0, 0, 0, 0]});
170+
const totalWidth = [...widths.values()].reduce((sum, w) => sum + w, 0);
171+
ui.div({text: '─'.repeat(Math.min(totalWidth, termWidth)), padding: [0, 0, 0, 0]});
113172

114173
// Rows
115174
for (const exec of executions) {
116-
const status = exec.exit_status?.code || exec.execution_status;
117-
const startTime = exec.start_time
118-
? new Date(exec.start_time).toISOString().replace('T', ' ').slice(0, 19)
119-
: 'N/A';
120-
121-
ui.div(
122-
{text: exec.id ?? '', width: 38, padding: [0, 1, 0, 0]},
123-
{text: exec.job_id ?? '', width: 30, padding: [0, 1, 0, 0]},
124-
{text: status ?? '', width: 12, padding: [0, 1, 0, 0]},
125-
{text: startTime, width: 20, padding: [0, 0, 0, 0]},
126-
);
175+
const rowCols = columnKeys.map((key) => ({
176+
text: COLUMNS[key].get(exec),
177+
width: widths.get(key),
178+
padding: [0, 1, 0, 0] as [number, number, number, number],
179+
}));
180+
ui.div(...rowCols);
127181
}
128182

129183
ux.stdout(ui.toString());

0 commit comments

Comments
 (0)