Skip to content

chore: Jules batch-2 — 10 perf + a11y improvements with regression tests#457

Merged
aafre merged 11 commits into
stgfrom
jules-batch-2
Apr 11, 2026
Merged

chore: Jules batch-2 — 10 perf + a11y improvements with regression tests#457
aafre merged 11 commits into
stgfrom
jules-batch-2

Conversation

@aafre
Copy link
Copy Markdown
Owner

@aafre aafre commented Apr 11, 2026

Summary

Triaged all 55 open Jules PRs. Picked the single best PR from each duplicate group (most had 4-8 duplicates), cherry-picked 10 into this branch, and added 135 regression tests. The remaining 45 PRs are closed as duplicates/superseded/already-merged.

Performance (4 PRs)

Accessibility (6 PRs)

Regression Tests (135 new tests)

  • keywordMatcher.test.ts — 5 tests for subsumption logic with Map optimization
  • StorageLimitModal.test.tsx — 6 tests for dialog semantics + focus rings
  • IconManager.test.tsx — 4 tests for sr-only input + clear button a11y
  • SectionEditor.test.tsx — 9 tests for button aria-labels + focus rings
  • UploadResumeModal.test.tsx — 7 tests for dialog semantics + keyboard a11y
  • ResumeCard.test.tsx — 3 tests for action button focus rings
  • ResponsiveConfirmDialog.test.tsx — 2 tests for focus states

Closed PRs (45)

Already merged via #381 (13): #382, #384, #390, #395, #393, #396, #385, #387, #392, #394, #397, #383, #400

Superseded by better version (27): #410, #413, #415, #435, #437, #444, #445 (→#421), #403, #416, #432, #453 (→#404), #433, #448, #450, #454 (→#440), #417, #422, #436, #438, #443, #451, #455 (→#442), #423 (→#414), #446 (→#420), #452 (→#399), #402 (→#442+#434)

Generic-titled duplicates (5): #386, #419, #424, #439, #441

Already merged (1): #389 (DeleteResumeModal → ResponsiveConfirmDialog, merged in #381)

Test plan

  • Full vitest suite: 1473 tests pass, 0 failures
  • Manual: Tab through editor — verify focus rings on SectionEditor buttons
  • Manual: Tab through My Resumes — verify focus rings on Edit/Download buttons
  • Manual: Open StorageLimitModal, UploadResumeModal — verify dialog semantics
  • Manual: Upload icon in editor — verify keyboard focus on IconManager
  • Manual: Generate a PDF — verify LaTeX escaping still works correctly
  • Manual: Use keyword matcher — verify results unchanged

aafre added 11 commits April 11, 2026 10:40
Move LATEX_SPECIAL_CHARS dict and LATEX_ESCAPE_PATTERN regex from inside
_escape_latex() to module-level constants in both app.py and
resume_generator_latex.py. Avoids re-compiling the regex and
re-allocating the dict on every function call.

Cherry-picked from Jules PR #440.
Pre-compute a Map of standalone word counts before the subsumption
loop, replacing the nested candidates.find() with O(1) Map.get().

Cherry-picked from Jules PR #456.
Convert sequential for-await loop in exportIconsForYAML to
Promise.all for concurrent FileReader conversions. Error handling
preserved per-icon with console.warn.

Cherry-picked from Jules PR #421.
Wrap the inline resumeData object in useMemo to prevent referential
inequality from triggering expensive JSON.stringify deep-comparison
in useCloudSave on every render.

Cherry-picked from Jules PR #404.
Add role="dialog", aria-modal, aria-labelledby to modal container.
Add focus-visible ring styles to Manage Resumes and Cancel buttons.

Cherry-picked from Jules PR #449.
Convert hidden file input to sr-only peer pattern so it remains in
the keyboard tab order. Add peer-focus-visible ring on the dropzone.
Add aria-label and focus-visible ring on the clear button.

Cherry-picked from Jules PR #434.
Add aria-label and focus-visible ring styles to Save, Cancel, Edit,
Remove, and Add Item buttons in SectionEditor.

Cherry-picked from Jules PR #414.
Add focus-visible ring styles to Close, Cancel, and Confirm buttons
with design-system-aware colors (accent for standard, red for
destructive). Includes regression test.

Cherry-picked from Jules PR #399.
Add role="dialog", aria-modal, aria-labelledby to modal container.
Add aria-label and focus-visible ring to close button.
Convert hidden file input to sr-only peer with peer-focus-visible.
Add focus-visible rings to Cancel and Continue buttons.

Cherry-picked from Jules PR #442.
Add focus-visible ring styles to Edit Resume and Download PDF buttons.
Only a11y changes applied — skipped unrelated quote normalization
from the original PR.

Cherry-picked from Jules PR #420 (a11y changes only).
Add tests for all 10 cherry-picked Jules PRs:
- keywordMatcher: subsumption logic with Map optimization (#456)
- StorageLimitModal: dialog semantics + focus rings (#449)
- IconManager: sr-only file input + clear button a11y (#434)
- SectionEditor: button aria-labels + focus rings (#414)
- UploadResumeModal: dialog semantics + keyboard a11y (#442)
- ResumeCard: action button focus rings (#420)
- ResponsiveConfirmDialog: focus states (#399, test from PR)

135 tests total, all passing.
This was referenced Apr 11, 2026
This was referenced Apr 11, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces accessibility (A11y) enhancements across multiple UI components, including IconManager, ResponsiveConfirmDialog, and several modals, by implementing ARIA roles, descriptive labels, and focus-visible indicators. Performance optimizations were also applied, such as memoizing resume data in useSaveIntegration, parallelizing icon processing in useIconRegistry, and optimizing keyword matching with O(1) lookups. Refactoring of LaTeX escaping logic was performed for better efficiency. Feedback was provided regarding the fallback state for memoized data and the accuracy of dependency tracking for array-based state.

Comment on lines +73 to +81
const resumeDataForCloudSave = useMemo(() => {
return contactInfo && templateId
? {
contact_info: contactInfo,
sections: sections,
template_id: templateId,
}
: { contact_info: { name: '', location: '', email: '', phone: '' }, sections: [], template_id: '' };
}, [contactInfo, sections, templateId]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The memoization of resumeDataForCloudSave is a good performance optimization. However, when contactInfo or templateId is missing, consider using a dedicated 'unknown' or invalid state (like null) instead of defaulting to a valid object literal. This makes the missing data explicit and prevents silent failures downstream. Additionally, ensure that if sections is an array, you use sections.join(',') in the dependency array to correctly detect content changes rather than just the array reference.

References
  1. When parsing structured data, use a dedicated 'unknown' or invalid state for fallbacks instead of defaulting to a valid state to make parsing errors explicit and prevent silent failures.
  2. The dependency array of useMemo should include the values that the memoized calculation depends on. For arrays, use array.join(',') to detect changes in the array's content.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gemini-code-assist Thanks for the review. Both points are safe to dismiss here:

1. Fallback object → null: This fallback already existed in the original inline code before this PR — we're only wrapping it in useMemo, not changing the logic. Switching to null would break useCloudSave, which expects a non-null resumeData object. No change needed.

2. sections.join(',') in deps: sections is an array of Section objects (not strings), so .join(',') would produce [object Object],[object Object] — useless for change detection. The current approach correctly relies on React's standard immutable state updates producing new array references. Additionally, useCloudSave already does its own JSON.stringify deep comparison internally, so referential equality at this level is sufficient.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the clarification, aafre. Your points regarding the existing fallback logic and the nature of the sections array are well-taken and make sense in this context. I appreciate the additional detail on how useCloudSave handles deep comparison, which confirms that the current approach is robust.

@aafre aafre changed the base branch from main to stg April 11, 2026 10:39
@aafre aafre merged commit 6e65601 into stg Apr 11, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant