clean up formatting
This commit is contained in:
parent
b949d4a6c6
commit
66d89adfd0
@ -3,6 +3,7 @@ import { Knex } from 'knex';
|
|||||||
export abstract class BaseRepository<T extends { created_at?: Date; updated_at?: Date }> {
|
export abstract class BaseRepository<T extends { created_at?: Date; updated_at?: Date }> {
|
||||||
protected tableName: string;
|
protected tableName: string;
|
||||||
protected db: Knex;
|
protected db: Knex;
|
||||||
|
protected items: T[] = [];
|
||||||
|
|
||||||
constructor(db: Knex, tableName: string) {
|
constructor(db: Knex, tableName: string) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { PrintHistory, Step } from '@shared/index';
|
import { PrintHistory, Step, Task } from '@shared/index';
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { BaseRepository } from './base-repository';
|
import { BaseRepository } from './base-repository';
|
||||||
|
|
||||||
export class InMemoryRepository<T extends { id: number; created_at?: Date; updated_at?: Date }> extends BaseRepository<T> {
|
export class InMemoryRepository<T extends { id: number; created_at?: Date; updated_at?: Date }> extends BaseRepository<T> {
|
||||||
private items: T[] = [];
|
protected items: T[] = [];
|
||||||
private nextId = 1;
|
private nextId = 1;
|
||||||
|
|
||||||
constructor(db: Knex, tableName: string) {
|
constructor(db: Knex, tableName: string) {
|
||||||
@ -76,4 +76,15 @@ export class InMemoryStepRepository extends InMemoryRepository<Step> {
|
|||||||
last_printed_at: new Date(),
|
last_printed_at: new Date(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findTaskById(stepId: number): Promise<Task | undefined> {
|
||||||
|
const step = this.items.find(s => s.id === stepId);
|
||||||
|
return step ? { id: step.task_id, name: 'Test Task', group_id: 1, print_count: 0, created_at: new Date(), updated_at: new Date() } : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
async findStepNumber(stepId: number): Promise<number> {
|
||||||
|
const step = this.items.find(s => s.id === stepId);
|
||||||
|
if (!step) return 0;
|
||||||
|
return this.items.filter(s => s.task_id === step.task_id).findIndex(s => s.id === stepId) + 1;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { BaseRepository } from './base-repository';
|
import { BaseRepository } from './base-repository';
|
||||||
import { Step } from '@shared/index';
|
import { Step, Task } from '@shared/index';
|
||||||
|
|
||||||
export class StepRepository extends BaseRepository<Step> {
|
export class StepRepository extends BaseRepository<Step> {
|
||||||
constructor(db: Knex) {
|
constructor(db: Knex) {
|
||||||
@ -23,4 +23,35 @@ export class StepRepository extends BaseRepository<Step> {
|
|||||||
last_printed_at: new Date()
|
last_printed_at: new Date()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findTaskById(stepId: number): Promise<Task | undefined> {
|
||||||
|
const step = await this.db('steps')
|
||||||
|
.where({ id: stepId })
|
||||||
|
.first();
|
||||||
|
|
||||||
|
if (!step) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await this.db('tasks')
|
||||||
|
.where({ id: step.task_id })
|
||||||
|
.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
async findStepNumber(stepId: number): Promise<number> {
|
||||||
|
const step = await this.db('steps')
|
||||||
|
.where({ id: stepId })
|
||||||
|
.first();
|
||||||
|
|
||||||
|
if (!step) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const steps = await this.db('steps')
|
||||||
|
.where({ task_id: step.task_id })
|
||||||
|
.orderBy('order', 'asc')
|
||||||
|
.select('id');
|
||||||
|
|
||||||
|
return steps.findIndex(s => s.id === stepId) + 1;
|
||||||
|
}
|
||||||
}
|
}
|
@ -83,9 +83,7 @@ describe('formatUtils', () => {
|
|||||||
expect(section).toEqual([
|
expect(section).toEqual([
|
||||||
'[ ] Header',
|
'[ ] Header',
|
||||||
'='.repeat(40),
|
'='.repeat(40),
|
||||||
'',
|
|
||||||
'Content',
|
'Content',
|
||||||
''
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -94,9 +92,7 @@ describe('formatUtils', () => {
|
|||||||
expect(section).toEqual([
|
expect(section).toEqual([
|
||||||
'[ ] Header',
|
'[ ] Header',
|
||||||
'-'.repeat(40),
|
'-'.repeat(40),
|
||||||
'',
|
|
||||||
'Content',
|
'Content',
|
||||||
''
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -106,8 +102,6 @@ describe('formatUtils', () => {
|
|||||||
'[ ] Header',
|
'[ ] Header',
|
||||||
'='.repeat(40),
|
'='.repeat(40),
|
||||||
'',
|
'',
|
||||||
'',
|
|
||||||
''
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -116,10 +110,35 @@ describe('formatUtils', () => {
|
|||||||
expect(section).toEqual([
|
expect(section).toEqual([
|
||||||
'[ ] ',
|
'[ ] ',
|
||||||
'='.repeat(40),
|
'='.repeat(40),
|
||||||
'',
|
|
||||||
'Content',
|
'Content',
|
||||||
''
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('formatStepHeader', () => {
|
||||||
|
it('should format step header with just step name and number', () => {
|
||||||
|
const header = formatUtils.formatStepHeader('Test Step', 1);
|
||||||
|
expect(header).toBe('Step 1: Test Step');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format step header with step number and task name in single step view', () => {
|
||||||
|
const header = formatUtils.formatStepHeader('Test Step', 1, 'Test Task');
|
||||||
|
expect(header).toBe('Step 1 of Test Task: Test Step');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format step header with step number but no task name in task view', () => {
|
||||||
|
const header = formatUtils.formatStepHeader('Test Step', 1, 'Test Task', true);
|
||||||
|
expect(header).toBe('Step 1: Test Step');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle empty step name', () => {
|
||||||
|
const header = formatUtils.formatStepHeader('', 1);
|
||||||
|
expect(header).toBe('Step 1: ');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle zero step number', () => {
|
||||||
|
const header = formatUtils.formatStepHeader('Test Step', 0);
|
||||||
|
expect(header).toBe('Step 0: Test Step');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
@ -31,6 +31,28 @@ export const formatUtils = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a step header with task context
|
||||||
|
* @param stepName Name of the step
|
||||||
|
* @param stepNumber Step number (1-based)
|
||||||
|
* @param taskName Name of the parent task (only used in single step view)
|
||||||
|
* @param isTaskView Whether this is being used in a task view
|
||||||
|
* @returns Formatted step header
|
||||||
|
*/
|
||||||
|
formatStepHeader(stepName: string, stepNumber: number, taskName?: string, isTaskView: boolean = false): string {
|
||||||
|
const parts = ['Step'];
|
||||||
|
if (stepNumber !== undefined) {
|
||||||
|
parts.push(' ');
|
||||||
|
parts.push(stepNumber.toString());
|
||||||
|
}
|
||||||
|
if (!isTaskView && taskName) {
|
||||||
|
parts.push(` of ${taskName}`);
|
||||||
|
}
|
||||||
|
parts.push(': ');
|
||||||
|
parts.push(stepName);
|
||||||
|
return parts.join('');
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a section with a header and content
|
* Formats a section with a header and content
|
||||||
* @param header Section header
|
* @param header Section header
|
||||||
@ -42,9 +64,7 @@ export const formatUtils = {
|
|||||||
return [
|
return [
|
||||||
this.formatCheckbox(header),
|
this.formatCheckbox(header),
|
||||||
this.createBanner(bannerChar),
|
this.createBanner(bannerChar),
|
||||||
'',
|
|
||||||
content,
|
content,
|
||||||
'',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -72,7 +72,11 @@ export class SerialPrinter implements PrinterInterface {
|
|||||||
// Print steps
|
// Print steps
|
||||||
for (let i = 0; i < taskSteps.length; i++) {
|
for (let i = 0; i < taskSteps.length; i++) {
|
||||||
const step = taskSteps[i];
|
const step = taskSteps[i];
|
||||||
const stepSection = formatUtils.formatSection(`Step ${i + 1}: ${step.name}`, step.instructions, '-');
|
const stepSection = formatUtils.formatSection(
|
||||||
|
formatUtils.formatStepHeader(step.name, i + 1, task.name, true),
|
||||||
|
step.instructions,
|
||||||
|
'-'
|
||||||
|
);
|
||||||
|
|
||||||
await this.printer
|
await this.printer
|
||||||
.size(1, 1) // Normal size for step header
|
.size(1, 1) // Normal size for step header
|
||||||
@ -89,9 +93,7 @@ export class SerialPrinter implements PrinterInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await this.printer
|
await this.printer
|
||||||
.text('')
|
.cut(true, 2)
|
||||||
.text('')
|
|
||||||
.cut()
|
|
||||||
.close();
|
.close();
|
||||||
|
|
||||||
logger.info(`Printed task ${task.id}`);
|
logger.info(`Printed task ${task.id}`);
|
||||||
@ -107,13 +109,20 @@ export class SerialPrinter implements PrinterInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async printStep(step: Step, _db: Knex): Promise<void> {
|
async printStep(step: Step, db: Knex): Promise<void> {
|
||||||
if (!this.printer || !this.device) {
|
if (!this.printer || !this.device) {
|
||||||
throw new Error('Printer not initialized');
|
throw new Error('Printer not initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const stepSection = formatUtils.formatSection(`Step: ${step.name}`, step.instructions);
|
// Get the task name for context
|
||||||
|
const task = await this.stepRepository.findTaskById(step.id);
|
||||||
|
const stepNumber = await this.stepRepository.findStepNumber(step.id);
|
||||||
|
|
||||||
|
const stepSection = formatUtils.formatSection(
|
||||||
|
formatUtils.formatStepHeader(step.name, stepNumber, task?.name),
|
||||||
|
step.instructions
|
||||||
|
);
|
||||||
|
|
||||||
await this.printer
|
await this.printer
|
||||||
.font('a')
|
.font('a')
|
||||||
@ -132,9 +141,7 @@ export class SerialPrinter implements PrinterInterface {
|
|||||||
// Print step ID as barcode
|
// Print step ID as barcode
|
||||||
await this.printer
|
await this.printer
|
||||||
.barcode(step.id.toString(), 'CODE128', { width: 2, height: 50 })
|
.barcode(step.id.toString(), 'CODE128', { width: 2, height: 50 })
|
||||||
.text('')
|
.cut(true, 2)
|
||||||
.text('')
|
|
||||||
.cut()
|
|
||||||
.close();
|
.close();
|
||||||
|
|
||||||
logger.info(`Printed step ${step.id}`);
|
logger.info(`Printed step ${step.id}`);
|
||||||
|
@ -38,7 +38,11 @@ export class TestPrinter implements Printer {
|
|||||||
const content = [
|
const content = [
|
||||||
...formatUtils.formatSection(`Task: ${task.name}`, ''),
|
...formatUtils.formatSection(`Task: ${task.name}`, ''),
|
||||||
...taskSteps.map((step, index) =>
|
...taskSteps.map((step, index) =>
|
||||||
formatUtils.formatSection(`Step ${index + 1}: ${step.name}`, step.instructions, '-')
|
formatUtils.formatSection(
|
||||||
|
formatUtils.formatStepHeader(step.name, index + 1, task.name, true),
|
||||||
|
step.instructions,
|
||||||
|
'-'
|
||||||
|
)
|
||||||
).flat(),
|
).flat(),
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
@ -57,7 +61,14 @@ export class TestPrinter implements Printer {
|
|||||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||||
const filename = path.join(this.outputDir, `step-${step.id}-${timestamp}.txt`);
|
const filename = path.join(this.outputDir, `step-${step.id}-${timestamp}.txt`);
|
||||||
|
|
||||||
const content = formatUtils.formatSection(`Step: ${step.name}`, step.instructions).join('\n');
|
// Get the task name for context
|
||||||
|
const task = await this.stepRepository.findTaskById(step.id);
|
||||||
|
const stepNumber = await this.stepRepository.findStepNumber(step.id);
|
||||||
|
|
||||||
|
const content = formatUtils.formatSection(
|
||||||
|
formatUtils.formatStepHeader(step.name, stepNumber, task?.name),
|
||||||
|
step.instructions
|
||||||
|
).join('\n');
|
||||||
|
|
||||||
await fs.writeFile(filename, content);
|
await fs.writeFile(filename, content);
|
||||||
logger.info(`Printed step ${step.id} to ${filename}`);
|
logger.info(`Printed step ${step.id} to ${filename}`);
|
||||||
|
Loading…
Reference in New Issue
Block a user