✨ feat(editor): add compress/expand toggle for ph tags#4584
Conversation
- add sequential 1-based numbering to all ph tags in both open (Draft.js) and closed (HTML-rendered) segments - add TagsCompressButton in per-segment SegmentTargetToolbar to toggle compressed view globally - compressed state shows only index number, hides tag content - persist preference in localStorage keyed to config.userMail - toggle body.ph-tags-compressed CSS class for zero-rerender closed segment switching - add tooltip on compressed tags showing full equiv-text - implement ph tag matching by decodedText with splice consumption in checkForMissingTag - add sourceTagMap cross-referencing for target tag indexing in createNewEntitiesFromMap - add unit tests for TagsCompressButton, TagEntityLite, CatToolStore, tagUtils phIndex, createNewEntitiesFromMap, and checkForMissingTag
🧪 Test-Guard ReportCoverage Analysis: ❌ FAILNo changed source files found in coverage report (threshold: 80%) 📋 10 files: 10 ❌ fail
Test File Matching: ❌ FAILFile matching: 6 pass, 1 warning, 3 fail 📋 10 files: 3 ❌ fail, 1
|
| File | Verdict | Reason |
|---|---|---|
public/js/actions/CatToolActions.js |
Test file exists (public/js/actions/CatToolActions.test.js) but was not modified in this PR | |
public/js/components/segments/SegmentTargetToolbar.js |
❌ fail | No matching test file found |
public/js/components/segments/TagEntity/TagEntity.component.js |
❌ fail | No matching test file found |
public/js/components/segments/TagEntity/TagEntityLite.js |
✅ pass | Test file modified in PR: public/js/components/segments/TagEntity/TagEntityLite.test.js |
public/js/components/segments/TagsCompressButton.js |
✅ pass | Test file modified in PR: public/js/components/segments/TagsCompressButton.test.js |
public/js/components/segments/utils/DraftMatecatUtils/TagMenu/checkForMissingTag.js |
✅ pass | Test file modified in PR: public/js/components/segments/utils/DraftMatecatUtils/TagMenu/checkForMissingTag.test.js |
public/js/components/segments/utils/DraftMatecatUtils/createNewEntitiesFromMap.js |
✅ pass | Test file modified in PR: public/js/components/segments/utils/DraftMatecatUtils/createNewEntitiesFromMap.test.js |
public/js/components/segments/utils/DraftMatecatUtils/tagUtils.js |
✅ pass | Test file modified in PR: public/js/components/segments/utils/DraftMatecatUtils/tagUtils.test.js |
public/js/constants/CatToolConstants.js |
❌ fail | No matching test file found |
public/js/stores/CatToolStore.js |
✅ pass | Test file modified in PR: public/js/stores/CatToolStore.test.js |
Per-File Evaluation: ⚠️ WARNING
Evaluated 10 files: 10 via AI (4 batches), 0 via shortcuts.
📋 10 files: 3 ⚠️ warning, 7 ✅ pass
| File | Verdict | Reason |
|---|---|---|
public/js/actions/CatToolActions.js |
New togglePhTagsCompressed action is dispatched but no direct tests shown. | |
public/js/components/segments/SegmentTargetToolbar.js |
TagsCompressButton component added to toolbar but no direct tests shown. | |
public/js/components/segments/TagEntity/TagEntity.component.js |
State and listener added for phTagsCompressed with conditional rendering; no direct tests but related TagEntityLite tests exist. | |
public/js/components/segments/TagEntity/TagEntityLite.js |
✅ pass | Tests cover compressed and uncompressed ph tag rendering and index display. |
public/js/components/segments/TagsCompressButton.js |
✅ pass | Tests cover button rendering, toggling, store updates, and cleanup. |
public/js/components/segments/utils/DraftMatecatUtils/TagMenu/checkForMissingTag.js |
✅ pass | Tests cover ph tag matching by decodedText and non-ph by id and name, including duplicates. |
public/js/components/segments/utils/DraftMatecatUtils/createNewEntitiesFromMap.js |
✅ pass | Tests verify index assignment logic with and without sourceTagMap, including edge cases. |
public/js/components/segments/utils/DraftMatecatUtils/tagUtils.js |
✅ pass | Tests verify ph tag index counter rendering and correct HTML structure. |
public/js/constants/CatToolConstants.js |
✅ pass | Constant addition tested indirectly via store and UI tests. |
public/js/stores/CatToolStore.js |
✅ pass | Store toggle behavior and localStorage integration fully tested with UI class changes. |
Result:
Why this WARNING?
- Coverage Analysis: None of the changed source files are present in the coverage report, indicating a coverage configuration issue (likely source filters exclude these files) → update coverage configuration to include these changed files.
- Test File Matching: SegmentTargetToolbar.js, TagEntity.component.js, and CatToolConstants.js have no matching test files → add or link appropriate test files for these source files.
- Per-File Evaluation: CatToolActions.js and SegmentTargetToolbar.js have new UI or action logic without direct tests shown → add direct tests covering the new togglePhTagsCompressed action and TagsCompressButton usage in the toolbar.
- Per-File Evaluation: TagEntity.component.js has new state and conditional rendering related to phTagsCompressed but no direct tests; related TagEntityLite tests exist → consider adding direct tests for TagEntity.component.js or confirm coverage via TagEntityLite tests.
To resolve: Add missing test files and direct tests for SegmentTargetToolbar.js, TagEntity.component.js, and CatToolActions.js, and fix coverage configuration to include all changed source files.
There was a problem hiding this comment.
Pull request overview
Adds a global UI toggle in the translation editor to compress/expand XLIFF <ph> placeholders, showing either just a sequential index (compressed) or full equiv-text (expanded), persisting the preference per user via localStorage.
Changes:
- Introduces
phTagsCompressedstate inCatToolStorewith a dispatcher action/constant andlocalStoragepersistence plus abodyclass toggle. - Adds a
TagsCompressButtonto the segment target toolbar and updates tag rendering components/utilities to display a sequential<ph>index. - Updates styling and adds/updates Jest tests to cover indexing, rendering, and store persistence behavior.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| public/js/stores/CatToolStore.js | Adds phTagsCompressed state, persistence, and body class toggle + store event. |
| public/js/stores/CatToolStore.test.js | Tests initialization, toggling, persistence keying by userMail, and body class behavior. |
| public/js/constants/CatToolConstants.js | Adds TOGGLE_PH_TAGS_COMPRESSED constant. |
| public/js/actions/CatToolActions.js | Adds togglePhTagsCompressed action dispatch. |
| public/js/components/segments/TagsCompressButton.js | New toolbar toggle button component wired to store/action. |
| public/js/components/segments/TagsCompressButton.test.js | Unit tests for toggle button behavior and store subscription. |
| public/js/components/segments/SegmentTargetToolbar.js | Adds TagsCompressButton as an always-visible toolbar item. |
| public/js/components/segments/TagEntity/TagEntity.component.js | Adds compressed rendering logic and tooltip behavior for <ph> entities. |
| public/js/components/segments/TagEntity/TagEntityLite.js | Adds compressed rendering logic for the lightweight tag decorator. |
| public/js/components/segments/TagEntity/TagEntityLite.test.js | Unit tests for compressed/expanded rendering and index counter display. |
| public/js/components/segments/utils/DraftMatecatUtils/tagUtils.js | Adds <ph> index spans and wraps tag text in span[data-text="true"] for CSS toggling. |
| public/js/components/segments/utils/DraftMatecatUtils/tagUtils.test.js | Updates expected HTML output for new <ph> index markup. |
| public/js/components/segments/utils/DraftMatecatUtils/tagUtils.phIndex.test.js | New tests for <ph> indexing behavior in transformTagsToHtml. |
| public/js/components/segments/utils/DraftMatecatUtils/createNewEntitiesFromMap.js | Adds incremental indexing for <ph> entities and optional source map cross-referencing. |
| public/js/components/segments/utils/DraftMatecatUtils/createNewEntitiesFromMap.test.js | New tests for incremental indexing and source tag map behavior. |
| public/js/components/segments/utils/DraftMatecatUtils/TagMenu/checkForMissingTag.js | Adjusts missing-tag matching so <ph> matches by decodedText with one-by-one consumption. |
| public/js/components/segments/utils/DraftMatecatUtils/TagMenu/checkForMissingTag.test.js | New tests for <ph> decodedText matching and duplicate consumption behavior. |
| public/js/components/segments/SimpleEditor.test.js | Updates expected rendered text output due to inserted <ph> indices. |
| public/css/sass/components/segment/Tag.scss | Adds .index-counter styles and compressed display rules (including body.ph-tags-compressed). |
🧪 Test-Guard ReportCoverage Analysis: ❌ FAILNo changed source files found in coverage report (threshold: 80%) 📋 10 files: 10 ❌ fail
Test File Matching: ❌ FAILFile matching: 6 pass, 1 warning, 3 fail 📋 10 files: 3 ❌ fail, 1
|
| File | Verdict | Reason |
|---|---|---|
public/js/actions/CatToolActions.js |
Test file exists (public/js/actions/CatToolActions.test.js) but was not modified in this PR | |
public/js/components/segments/SegmentTargetToolbar.js |
❌ fail | No matching test file found |
public/js/components/segments/TagEntity/TagEntity.component.js |
❌ fail | No matching test file found |
public/js/components/segments/TagEntity/TagEntityLite.js |
✅ pass | Test file modified in PR: public/js/components/segments/TagEntity/TagEntityLite.test.js |
public/js/components/segments/TagsCompressButton.js |
✅ pass | Test file modified in PR: public/js/components/segments/TagsCompressButton.test.js |
public/js/components/segments/utils/DraftMatecatUtils/TagMenu/checkForMissingTag.js |
✅ pass | Test file modified in PR: public/js/components/segments/utils/DraftMatecatUtils/TagMenu/checkForMissingTag.test.js |
public/js/components/segments/utils/DraftMatecatUtils/createNewEntitiesFromMap.js |
✅ pass | Test file modified in PR: public/js/components/segments/utils/DraftMatecatUtils/createNewEntitiesFromMap.test.js |
public/js/components/segments/utils/DraftMatecatUtils/tagUtils.js |
✅ pass | Test file modified in PR: public/js/components/segments/utils/DraftMatecatUtils/tagUtils.test.js |
public/js/constants/CatToolConstants.js |
❌ fail | No matching test file found |
public/js/stores/CatToolStore.js |
✅ pass | Test file modified in PR: public/js/stores/CatToolStore.test.js |
Per-File Evaluation: ⚠️ WARNING
Evaluated 10 files: 10 via AI (4 batches), 0 via shortcuts.
📋 10 files: 1 ⚠️ warning, 9 ✅ pass
| File | Verdict | Reason |
|---|---|---|
public/js/actions/CatToolActions.js |
New togglePhTagsCompressed action is dispatched but no direct tests shown. | |
public/js/components/segments/SegmentTargetToolbar.js |
✅ pass | TagsCompressButton component added; tested indirectly via TagsCompressButton tests. |
public/js/components/segments/TagEntity/TagEntity.component.js |
✅ pass | State and event listener added for phTagsCompressed; behavior tested in TagEntityLite tests. |
public/js/components/segments/TagEntity/TagEntityLite.js |
✅ pass | Tests cover compressed state, index display, and conditional children rendering. |
public/js/components/segments/TagsCompressButton.js |
✅ pass | Tests cover toggle behavior, UI state, and event listener lifecycle. |
public/js/components/segments/utils/DraftMatecatUtils/TagMenu/checkForMissingTag.js |
✅ pass | Tests cover ph tag matching by decodedText and non-ph by id, including duplicates. |
public/js/components/segments/utils/DraftMatecatUtils/createNewEntitiesFromMap.js |
✅ pass | Tests verify index assignment with and without sourceTagMap, including edge cases. |
public/js/components/segments/utils/DraftMatecatUtils/tagUtils.js |
✅ pass | Tests verify ph tag index counter rendering and HTML structure. |
public/js/constants/CatToolConstants.js |
✅ pass | Constants addition tested indirectly via store and UI tests. |
public/js/stores/CatToolStore.js |
✅ pass | Store toggle behavior and localStorage integration fully tested. |
Result:
Why this WARNING?
- Coverage Analysis: None of the changed source files are included in the coverage report, indicating a coverage configuration issue (likely source filters exclude these files) → update coverage config to include these changed files.
- Test File Matching: No test files found for SegmentTargetToolbar.js, TagEntity.component.js, and CatToolConstants.js → add or link appropriate test files for these source files.
- Per-File Evaluation: The new togglePhTagsCompressed action in CatToolActions.js is dispatched but lacks direct tests → add direct tests for this new action to ensure coverage.
- Per-File Evaluation: SegmentTargetToolbar.js and TagEntity.component.js changes are tested only indirectly via other components → no action needed if indirect test coverage is sufficient.
To resolve: fix coverage configuration to include all changed source files and add missing direct tests for CatToolActions.js togglePhTagsCompressed action and missing test files for SegmentTargetToolbar.js, TagEntity.component.js, and CatToolConstants.js.
Summary
Add a global compress/expand toggle for ph tags in the translation editor. When compressed, ph tags show only their sequential index number; when expanded, they show the full equiv-text content. User preference is persisted per-user via localStorage.
Type
feat— new user-facing featurefix— bug fixrefactor— restructure without behavior changechore— build, deps, config, docsperf— performance improvementtest— test coverageChanges
public/js/components/segments/TagsCompressButton.jspublic/js/components/segments/SegmentTargetToolbar.jspublic/js/components/segments/TagEntity/TagEntity.component.jspublic/js/components/segments/TagEntity/TagEntityLite.jspublic/js/components/segments/utils/DraftMatecatUtils/tagUtils.jstransformTagsToHtmlfor closed segmentspublic/js/components/segments/utils/DraftMatecatUtils/createNewEntitiesFromMap.jsaddIncrementalIndex+ sourceTagMap cross-referencing for target ph indexingpublic/js/components/segments/utils/DraftMatecatUtils/TagMenu/checkForMissingTag.jspublic/js/stores/CatToolStore.jsphTagsCompressedstate, localStorage persistence, body class togglepublic/js/actions/CatToolActions.jstogglePhTagsCompressedactionpublic/js/constants/CatToolConstants.jsTOGGLE_PH_TAGS_COMPRESSEDconstantpublic/css/sass/components/segment/Tag.scss.index-counterstyles,body.ph-tags-compressedrule, inline display fixpublic/js/components/segments/TagsCompressButton.test.jspublic/js/components/segments/TagEntity/TagEntityLite.test.jspublic/js/stores/CatToolStore.test.jspublic/js/components/segments/utils/DraftMatecatUtils/tagUtils.phIndex.test.jspublic/js/components/segments/utils/DraftMatecatUtils/createNewEntitiesFromMap.test.jspublic/js/components/segments/utils/DraftMatecatUtils/TagMenu/checkForMissingTag.test.jspublic/js/components/segments/SimpleEditor.test.jspublic/js/components/segments/utils/DraftMatecatUtils/tagUtils.test.jsTesting
vendor/bin/phpunit --exclude-group=ExternalServices --no-coveragepasses./vendor/bin/phpstanpasses (0 errors, with baseline)Jest test suite: 45/45 suites pass, 260/260 tests pass (2 suites skipped — pre-existing socket tests).
AI Disclosure
Sisyphus (claude-opus-4.6) via OpenCode
Notes
body.ph-tags-compressedclass) — no re-render neededconfig.userMailfor multi-user browser isolation