feat: Add validation viewing functionality and UI updates

- Implemented a new function to mark validations as viewed by the user, updating the validation state accordingly.
- Added a new API endpoint for marking validations as viewed, integrated with the existing GitHub routes.
- Enhanced the sidebar to display the count of unviewed validations, providing real-time updates.
- Updated the GitHub issues view to mark validations as viewed when issues are accessed, improving user interaction.
- Introduced a visual indicator for unviewed validations in the issue list, enhancing user awareness of pending validations.
This commit is contained in:
Kacper
2025-12-23 22:11:26 +01:00
parent 6acb751eb3
commit 0c9f05ee38
13 changed files with 300 additions and 12 deletions

View File

@@ -145,3 +145,35 @@ export async function getValidationWithFreshness(
isStale: isValidationStale(validation),
};
}
/**
* Mark a validation as viewed by the user
*
* @param projectPath - Absolute path to project directory
* @param issueNumber - GitHub issue number
* @returns true if validation was marked as viewed, false if not found
*/
export async function markValidationViewed(
projectPath: string,
issueNumber: number
): Promise<boolean> {
const validation = await readValidation(projectPath, issueNumber);
if (!validation) {
return false;
}
validation.viewedAt = new Date().toISOString();
await writeValidation(projectPath, issueNumber, validation);
return true;
}
/**
* Get count of unviewed, non-stale validations for a project
*
* @param projectPath - Absolute path to project directory
* @returns Number of unviewed validations
*/
export async function getUnviewedValidationsCount(projectPath: string): Promise<number> {
const validations = await getAllValidations(projectPath);
return validations.filter((v) => !v.viewedAt && !isValidationStale(v)).length;
}

View File

@@ -14,6 +14,7 @@ import {
createValidationStopHandler,
createGetValidationsHandler,
createDeleteValidationHandler,
createMarkViewedHandler,
} from './routes/validation-endpoints.js';
export function createGitHubRoutes(events: EventEmitter): Router {
@@ -41,6 +42,11 @@ export function createGitHubRoutes(events: EventEmitter): Router {
validatePathParams('projectPath'),
createDeleteValidationHandler()
);
router.post(
'/validation-mark-viewed',
validatePathParams('projectPath'),
createMarkViewedHandler()
);
return router;
}

View File

@@ -17,6 +17,7 @@ import {
getAllValidations,
getValidationWithFreshness,
deleteValidation,
markValidationViewed,
} from '../../../lib/validation-storage.js';
/**
@@ -188,3 +189,36 @@ export function createDeleteValidationHandler() {
}
};
}
/**
* POST /validation-mark-viewed - Mark a validation as viewed by the user
*/
export function createMarkViewedHandler() {
return async (req: Request, res: Response): Promise<void> => {
try {
const { projectPath, issueNumber } = req.body as {
projectPath: string;
issueNumber: number;
};
if (!projectPath) {
res.status(400).json({ success: false, error: 'projectPath is required' });
return;
}
if (!issueNumber || typeof issueNumber !== 'number') {
res
.status(400)
.json({ success: false, error: 'issueNumber is required and must be a number' });
return;
}
const success = await markValidationViewed(projectPath, issueNumber);
res.json({ success });
} catch (error) {
logError(error, 'Mark validation viewed failed');
res.status(500).json({ success: false, error: getErrorMessage(error) });
}
};
}