Skip to content

Morpheme analysis UI: suggestions for #104#111

Merged
alex-rawlings-yyc merged 4 commits into
token-analysisfrom
token-analysis-review-fixes
Jun 17, 2026
Merged

Morpheme analysis UI: suggestions for #104#111
alex-rawlings-yyc merged 4 commits into
token-analysisfrom
token-analysis-review-fixes

Conversation

@imnasnainaec

@imnasnainaec imnasnainaec commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Suggested modifications on #104

Devin: https://app.devin.ai/review/sillsdev/interlinearizer-extension/pull/111

Summary of changes

  • Don't save meaningless morpheme breakdowns. A breakdown that is empty or just the whole word as a single morpheme carries no real segmentation, so the Done button is disabled for it and the Enter / outside-click commit paths dismiss without writing.
  • Localization. Morpheme-editor strings and the morpheme-gloss + token morpheme-trigger aria-labels now go through useLocalizedStrings (with {form} / {token} interpolation); new keys added to localizedStrings.json.
  • Validate morpheme shape at the persistence boundary. isTextAnalysis now rejects malformed morphemes via new isTokenAnalysisRecord / isMorphemeAnalysis guards.
  • Focus restore. Closing the morpheme popover returns focus to the first morpheme gloss.
  • Disabled morpheme trigger no longer shows a pointer/hover affordance.
  • De-duplicate the five identical boolean project-setting validators into one shared isBoolean.
  • Docs. Document the deliberate provenance-field exclusion in isEmptyTokenAnalysis; de-stale the viewOptions memo comment.
  • Tests updated accordingly.

Devin: https://app.devin.ai/review/sillsdev/interlinearizer-extension/pull/111

🤖 Generated with Claude Code


This change is Reviewable

Summary by CodeRabbit

  • New Features

    • Added localized string labels for morpheme editing UI controls.
  • Improvements

    • Enhanced focus management when closing the morpheme editor popup.
    • Validation now prevents saving empty or meaningless morpheme breakdowns; the Done button is disabled for such drafts.
    • Strengthened morpheme analysis validation for data integrity.

- Don't save empty or whole-word morpheme breakdowns: disable the Done
  button and guard the Enter / outside-click commit paths
- Localize morpheme editor strings and morpheme/trigger aria-labels
- Validate morpheme element shape in isTextAnalysis at the persistence
  boundary (isTokenAnalysisRecord / isMorphemeAnalysis)
- Restore focus to the token gloss input when the morpheme popover closes
- Gate the disabled morpheme trigger's hover/cursor affordance
- De-duplicate the boolean project-setting validators into one isBoolean
- Document the deliberate provenance exclusion in isEmptyTokenAnalysis and
  de-stale the viewOptions memo comment

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@imnasnainaec imnasnainaec added the 🟪Idea Idea-priority PR: can be closed... label Jun 17, 2026
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d9d2b7a1-dcda-48e8-b86b-838d22578241

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

MorphemeBreakdownPopover gains two new props (surfaceText, glossInputId) to block saving of "meaningless" drafts (empty or whole-word-as-single-morpheme) and to restore focus on close. All morpheme editor and token chip UI labels are moved to localized strings. Morpheme type guards are strengthened with a new isMorphemeAnalysis predicate, the PopoverContent test mock gains an onCloseAutoFocus sentinel, and tests are refactored to match.

Changes

Morpheme editor improvements, localization, and type guard strengthening

Layer / File(s) Summary
Localization strings and morpheme type guards
contributions/localizedStrings.json, src/store/analysisSlice.ts, src/types/type-guards.ts
Adds 7 localized string keys for morpheme UI. Adds isMorphemeAnalysis guard and strengthens isTokenAnalysisRecord to validate each morpheme's id, form, and writingSystem. Switches isTextAnalysis to use the stricter guard. JSDoc on isEmptyTokenAnalysis clarifies provenance-field exclusion.
MorphemeBreakdownPopover: new props, save logic, focus restoration, localization
src/components/MorphemeEditor.tsx
Adds surfaceText and glossInputId props. Replaces trimmed-non-empty save gate with isMeaningless derived state. Adds onCloseAutoFocus to focus the first morpheme gloss input (or fall back to the token gloss input). Disables Done for meaningless drafts. Replaces all hardcoded English labels with localized strings including MorphemeGlossInput aria-label.
TokenChip localization wiring
src/components/TokenChip.tsx
Imports useLocalizedStrings, defines STRING_KEYS, and replaces hardcoded aria-label templates for the morpheme trigger button with localized strings using {token} placeholder substitution.
PopoverContent mock and test coverage
__mocks__/platform-bible-react.tsx, src/__tests__/components/MorphemeEditor.test.tsx, src/__tests__/components/TokenChip.test.tsx
Extends PopoverContent stub with onCloseAutoFocus prop and a close sentinel button. Refactors MorphemeEditor tests around a renderPopover helper with mocked localization. Adds assertions for meaningless-draft disabled state, popover panel rendering, and focus restoration. Adds useLocalizedStrings mocking to TokenChip tests.
Minor supporting cleanup
src/main.ts, src/components/InterlinearizerLoader.tsx
Extracts a shared isBoolean validator in activate() to replace five repeated inline boolean checks. Rewords a memoization comment in InterlinearizerLoader.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant TokenChip
  participant MorphemeBreakdownPopover
  participant PopoverContent
  participant DOM as Token label DOM

  User->>TokenChip: clicks morpheme trigger button
  TokenChip->>MorphemeBreakdownPopover: open with surfaceText and glossInputId
  User->>MorphemeBreakdownPopover: edits breakdown
  MorphemeBreakdownPopover->>MorphemeBreakdownPopover: derive isMeaningless(draft, surfaceText)
  alt draft is meaningful
    User->>MorphemeBreakdownPopover: clicks Done or Enter
    MorphemeBreakdownPopover->>TokenChip: onSave(draft)
  else draft is meaningless
    MorphemeBreakdownPopover->>MorphemeBreakdownPopover: Done disabled, close without saving
  end
  PopoverContent->>MorphemeBreakdownPopover: onCloseAutoFocus(event)
  alt morpheme gloss field exists in token label
    MorphemeBreakdownPopover->>DOM: focus first input[data-morpheme-gloss]
  else no morpheme gloss field
    MorphemeBreakdownPopover->>DOM: focus token gloss input via glossInputId
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • sillsdev/interlinearizer-extension#109: Modifies the same MorphemeBreakdownPopover popover commit/cancel logic, specifically the unedited/draft equality check that governs whether outside interactions trigger a save.

Suggested labels

🟨Medium

🐇 A popover that once spoke in English alone,
Now speaks every tongue in a localized tone.
Empty morphemes? Dismissed with a hop!
Focus restored — to the right gloss on top.
The guards are now stronger, the drafts properly screened,
The rabbit says: meaningful breakdowns convened! 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title directly references issue #104 and accurately describes the changes as morpheme analysis UI improvements, which aligns with the main objectives of preventing incomplete breakdowns, enhancing localization, and improving focus management.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch token-analysis-review-fixes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@imnasnainaec imnasnainaec marked this pull request as ready for review June 17, 2026 19:54
@imnasnainaec imnasnainaec changed the title Morpheme analysis UI: review suggestions for #104 Morpheme analysis UI: suggestions for #104 Jun 17, 2026
coderabbitai[bot]

This comment was marked as resolved.

@alex-rawlings-yyc alex-rawlings-yyc left a comment

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.

Left a nit, but otherwise looks great

@alex-rawlings-yyc reviewed 10 files and all commit messages, and made 2 comments.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on imnasnainaec).


src/components/MorphemeEditor.tsx line 168 at r1 (raw file):

      onInteractOutside={handleInteractOutside}
      onOpenAutoFocus={(e) => e.preventDefault()}
      onCloseAutoFocus={(e) => {

Given its large body size, this could become a handler to keep the component code clean. That's my preference, but it's certainly not a rule

@imnasnainaec imnasnainaec force-pushed the token-analysis-review-fixes branch from da0d7b7 to 1685766 Compare June 17, 2026 20:10

@alex-rawlings-yyc alex-rawlings-yyc left a comment

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.

@alex-rawlings-yyc reviewed 1 file and all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on imnasnainaec).

@alex-rawlings-yyc alex-rawlings-yyc left a comment

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.

@alex-rawlings-yyc reviewed 1 file and all commit messages, and resolved 1 discussion.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on imnasnainaec).

@imnasnainaec

Copy link
Copy Markdown
Contributor Author

src/components/MorphemeEditor.tsx line 168 at r1 (raw file):

      onInteractOutside={handleInteractOutside}
      onOpenAutoFocus={(e) => e.preventDefault()}
      onCloseAutoFocus={(e) => {

Given its large body size, this could become a handler to keep the component code clean. That's my preference, but it's certainly not a rule

Done.

@alex-rawlings-yyc alex-rawlings-yyc merged commit 53bfe54 into token-analysis Jun 17, 2026
2 checks passed
@alex-rawlings-yyc alex-rawlings-yyc deleted the token-analysis-review-fixes branch June 17, 2026 20:14
alex-rawlings-yyc added a commit that referenced this pull request Jun 17, 2026
* Add UI for morphosyntactic analysis of tokens

* Improve editor, allow deletion of MSA

* Minor adjustments

* Add writing system to morpheme pipeline, fix input focus issue, prevent morpheme ID regeneration on unedited done/enter

* Minor adjustments

* Migrate MorphemeEditor to Platform.Bible popover, clean up analysisSlice, other minor improvements

* Recenter on showMorphology toggle

* Minor adjustments

* Cleanup

* Minor adjustments

* Memoize viewOptions, clear blank morpheme gloss

* Tiny tweaks (#109)

* Address token-analysis review comments

- MorphemeEditor: normalize internal whitespace in isUnedited to avoid
  no-op saves on spacing-only changes
- TokenChip: document the deliberate onOpenChange omission on the
  controlled Popover

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add JSDoc to normalize helper in MorphemeEditor

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add validator for show morphology setting

* Close morphology popover when token chip disabled,

* Morpheme analysis UI: suggestions for #104 (#111)

* Address review feedback on morpheme analysis UI

- Don't save empty or whole-word morpheme breakdowns: disable the Done
  button and guard the Enter / outside-click commit paths
- Localize morpheme editor strings and morpheme/trigger aria-labels
- Validate morpheme element shape in isTextAnalysis at the persistence
  boundary (isTokenAnalysisRecord / isMorphemeAnalysis)
- Restore focus to the token gloss input when the morpheme popover closes
- Gate the disabled morpheme trigger's hover/cursor affordance
- De-duplicate the boolean project-setting validators into one isBoolean
- Document the deliberate provenance exclusion in isEmptyTokenAnalysis and
  de-stale the viewOptions memo comment

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Focus on 1st morph gloss

* Tweak

* Extract handle

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fix formatting issue

---------

Co-authored-by: D. Ror. <imnasnainaec@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🟪Idea Idea-priority PR: can be closed...

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants