Skip to content

Conversation

rmunn
Copy link
Contributor

@rmunn rmunn commented Jul 24, 2025

Fixes #1843.

@rmunn rmunn self-assigned this Jul 24, 2025
Copy link

coderabbitai bot commented Jul 24, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

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.

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

📝 Walkthrough

Walkthrough

This change enforces Svelte ESLint rules by removing temporary disables for specific linting rules and systematically adds keyed each-blocks to Svelte templates throughout the frontend and viewer codebases. Minor updates to configuration files and a few string literal replacements are also included, with no changes to public APIs.

Changes

Cohort / File(s) Change Summary
ESLint Configuration Cleanup
frontend/eslint.config.js, frontend/viewer/eslint.config.js
Removes temporary disables for Svelte-specific ESLint rules, re-enabling enforcement for rules such as require-each-key, no-useless-mustaches, and others.
Keyed Each Blocks in Svelte Templates
frontend/src/lib/components/*, frontend/src/lib/forms/*, frontend/src/lib/layout/Breadcrumbs/Breadcrumbs.svelte, frontend/src/routes/(authenticated)/**/*, frontend/src/routes/+error.svelte, frontend/src/routes/email/tester/[email protected], frontend/viewer/src/home/Server.svelte, frontend/viewer/src/home/ServersList.svelte, frontend/viewer/src/lib/DictionaryEntry.svelte, frontend/viewer/src/lib/activity/ActivityView.svelte, frontend/viewer/src/lib/components/reorderer/reorderer-item-list.svelte, frontend/viewer/src/lib/entry-editor/EntryOrSensePicker.svelte, frontend/viewer/src/lib/entry-editor/ItemList.svelte, frontend/viewer/src/lib/entry-editor/NewEntryDialog.svelte, frontend/viewer/src/lib/i18n/LocalizationPicker.svelte, frontend/viewer/src/lib/sandbox/Sandbox.svelte, frontend/viewer/src/project/ProjectDropdown.svelte, frontend/viewer/src/project/browse/SortMenu.svelte, frontend/viewer/src/project/browse/ViewPicker.svelte, frontend/viewer/src/stories/editor/misc/entry-picker.stories.svelte, frontend/viewer/src/stories/editor/misc/reorderer.stories.svelte, frontend/viewer/src/stories/primitives/button.stories.svelte
Adds explicit keys to Svelte {#each} blocks for improved DOM diffing and to comply with linting rules.
Suppressing/Documenting Useless Mustaches
frontend/viewer/src/lib/DictionaryEntry.svelte, frontend/viewer/src/lib/sandbox/EditorSandbox.svelte
Adds ESLint disable comments for intentional use of "useless mustaches" in Svelte templates.
Minor String and Prop Adjustments
frontend/src/routes/(unauthenticated)/register/+page.svelte, frontend/viewer/src/home/HomeView.svelte, frontend/src/routes/(authenticated)/project/[project_code]/AddPurpose.svelte, frontend/viewer/src/project/browse/EntryView.svelte, frontend/viewer/src/project/browse/SortMenu.svelte, frontend/viewer/src/lib/entry-editor/ItemListItem.svelte
Replaces template literals with plain strings, localizes button labels, adds/destructures unused props, and adds TODOs or comments for future cleanup.
Svelte Config and Utility Update
frontend/svelte.config.js, frontend/viewer/src/lib/utils/url.svelte.ts
Comments out unnecessary sourcemap config (now default in Svelte 5) and switches from native URL to SvelteURL in a utility.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15–25 minutes

Assessment against linked issues

Objective Addressed Explanation
Fix new eslint warnings by enforcing Svelte lint rules and removing disables (#1843)
Remove temporary ignores for require-each-key and no-useless-mustaches (#1843)
Add keys to all relevant Svelte {#each} blocks to comply with linting (#1843)

Possibly related PRs

Poem

In fields of code where Svelte does play,
Each block now keyed, no warnings stay.
ESLint’s frown has turned to cheer,
As rabbits hop from there to here.
With lists well-tracked and keys in tow,
The frontend garden’s set to grow!
🐇✨

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/fix-new-eslint-warnings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included labels Jul 24, 2025
Copy link

github-actions bot commented Jul 24, 2025

UI unit Tests

  1 files  ±0   40 suites  ±0   22s ⏱️ +2s
 81 tests ±0   81 ✅ +1  0 💤 ±0  0 ❌  - 1 
114 runs  ±0  114 ✅ +1  0 💤 ±0  0 ❌  - 1 

Results for commit e653f8b. ± Comparison against base commit 5327856.

♻️ This comment has been updated with latest results.

@rmunn rmunn changed the base branch from develop to chore/bump-svelte-andor-eslint-pkgs July 24, 2025 10:59
Copy link

argos-ci bot commented Jul 24, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Jul 31, 2025, 6:59 AM

Copy link

github-actions bot commented Jul 24, 2025

C# Unit Tests

126 tests  ±0   126 ✅ ±0   12s ⏱️ ±0s
 20 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit e653f8b. ± Comparison against base commit 5327856.

♻️ This comment has been updated with latest results.

@rmunn rmunn marked this pull request as ready for review July 25, 2025 01:33
@rmunn rmunn changed the title Chore/fix new eslint warnings Fix new eslint warnings Jul 25, 2025
@rmunn rmunn changed the title Fix new eslint warnings Fix new eslint errors Jul 25, 2025
@rmunn rmunn requested a review from hahn-kev July 25, 2025 01:59
Base automatically changed from chore/bump-svelte-andor-eslint-pkgs to develop July 29, 2025 08:32
@rmunn
Copy link
Contributor Author

rmunn commented Jul 29, 2025

GitHub's auto-rebase is basing off the wrong commit due to when I opened this PR vs. when the "bump NPM versions" PR was merged. Will rebase manually (and correctly).

rmunn added 6 commits July 29, 2025 15:34
Sourcemaps are always on in Svelte 5, no need to enable them explicitly.

We'll leave the line in the config file, commented out, in case anyone
wonders about it.
This was caught by the svelte/no-useless-mustaches rule
The two remaining svelte/no-useless-mustaches errors were auto-fixed by
the eslint rule.
FW Lite UI (frontend/viewer) will be next
@rmunn rmunn force-pushed the chore/fix-new-eslint-warnings branch from 8b0ac1f to eebaaac Compare July 29, 2025 08:35
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (10)
frontend/svelte.config.js (1)

6-9: Drop the stale commented-out option

Leaving legacy config lines around clutters the file. Since Svelte 5 always emits sourcemaps, you can remove the line entirely rather than commenting it out.

-    // enableSourcemap: true // Sourcemaps are always on in Svelte 5, no need to enable them explicitly
frontend/viewer/src/lib/sandbox/EditorSandbox.svelte (1)

79-80: Scope the ESLint disable to a single line

A file-wide eslint-disable can mask future genuine issues. Prefer the next-line variant so only the immediately-following markup is exempt.

-<!-- eslint-disable svelte/no-useless-mustaches - This is a sandbox, we don't need translations -->
+<!-- eslint-disable-next-line svelte/no-useless-mustaches -- sandbox needs static mustaches -->
frontend/src/routes/+error.svelte (1)

12-14: Consider using index-based key for better uniqueness.

While using path as the key works for most cases, URL segments can potentially be duplicated (e.g., /admin/users/admin would have "admin" twice), which could cause rendering issues.

Consider using the index for a more reliable key:

-  {#each page.url.pathname.split('/').slice(1) as path (path)}
+  {#each page.url.pathname.split('/').slice(1) as path, index (index)}
    <PageBreadcrumb>{path}</PageBreadcrumb>
  {/each}
frontend/viewer/src/lib/activity/ActivityView.svelte (1)

112-112: Consider using a more stable key than the object reference.

Using the entire change object as a key relies on object identity, which may not be stable across re-renders. If the change objects get recreated, Svelte will unnecessarily recreate DOM elements.

If the change objects have a unique identifier property, use that instead:

-{#each visibleItems as change (change)}
+{#each visibleItems as change (change.id)}

If no unique property exists and the array order is stable, consider using the index:

-{#each visibleItems as change (change)}
+{#each visibleItems as change, i (i)}
frontend/src/lib/components/TrainTracks.svelte (2)

116-116: Consider using a more stable key for the curves iteration.

Using the curve object itself as a key won't provide optimization benefits since new curve objects are created on each render. Consider using a stable identifier based on the path indices.

-      {#each curves as curve (curve)}
+      {#each curves as curve, i (i)}

Or even better, use the path data that generates the curve:

-      {#each curves as curve (curve)}
+      {#each paths as path, i (path)}
+        <path fill="none" stroke={curves[i].color} stroke-width="1.5" d={curves[i].d} />

119-119: Consider using a more stable key for the svgDots iteration.

Using the dot object itself as a key won't provide optimization benefits since new dot objects are created on each render. Consider using the circle index or a combination of row/col.

-      {#each svgDots as c (c)}
+      {#each svgDots as c, i (i)}

Or use the underlying circle data:

-      {#each svgDots as c (c)}
+      {#each circles as circle, i (circle)}
+        <circle cx={svgDots[i].x} cy={svgDots[i].y} r={circleSize} fill={svgDots[i].color} stroke="none" style="" />
frontend/src/lib/layout/Breadcrumbs/Breadcrumbs.svelte (1)

12-12: Verify that breadcrumb objects provide stable keys.

Using the crumb object itself as a key is appropriate only if the breadcrumb objects maintain stable identities across renders. If new objects are created frequently, consider using a more stable identifier.

If breadcrumbs have stable IDs or paths, use those instead:

-    {#each $crumbs as crumb (crumb)}
+    {#each $crumbs as crumb (crumb.id || crumb.path)}

Otherwise, the current approach is acceptable if the Element objects are stable references.

frontend/viewer/src/lib/DictionaryEntry.svelte (1)

133-133: Consider key stability for sentence iteration.

Using the sentence object as a key may not provide optimization benefits if sentence objects are recreated on each render. If sentences have stable identifiers or the array order is stable, consider using the index or a stable property.

-      {#each example.sentences as sentence, j (sentence)}
+      {#each example.sentences as sentence, j (j)}

However, if sentence objects maintain stable references, the current approach is acceptable.

frontend/viewer/src/project/browse/SortMenu.svelte (1)

45-47: Address the TODO comment for unused prop.

The autoDirection prop is currently unused and marked with a TODO comment. Consider either implementing its usage or removing it to reduce technical debt.

Would you like me to help determine how autoDirection should be used based on the component's functionality, or should this prop be removed?

frontend/viewer/src/lib/sandbox/Sandbox.svelte (1)

325-337: Consider collapsing the four nearly-identical loops to reduce duplication

The two variant loops and the two size loops differ only in whether they render an icon and could be merged to cut repetition and keep the markup in one place. This keeps maintenance light when button props change.

-{#each variants as variant (variant)}
-  <Button loading={buttonsLoading} {variant}>{variant} button</Button>
-{/each}
-{#each variants as variant (variant)}
-  <Button loading={buttonsLoading} {variant} icon="i-mdi-auto-fix"></Button>
-{/each}
+{#each variants as variant (variant)}
+  <Button loading={buttonsLoading} {variant}>{variant} button</Button>
+  <Button loading={buttonsLoading} {variant} icon="i-mdi-auto-fix"/>
+{/each}
-
-{#each sizes as size (size)}
-  <Button loading={buttonsLoading} {size}>Size: {size}</Button>
-{/each}
-{#each sizes as size (size)}
-  <Button loading={buttonsLoading} {size} icon="i-mdi-auto-fix"/>
-{/each}
+{#each sizes as size (size)}
+  <Button loading={buttonsLoading} {size}>Size: {size}</Button>
+  <Button loading={buttonsLoading} {size} icon="i-mdi-auto-fix"/>
+{/each}

Functionality stays the same, ESLint remains satisfied, and the markup is ~40 % shorter.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7aeedf4 and eebaaac.

📒 Files selected for processing (54)
  • frontend/eslint.config.js (0 hunks)
  • frontend/src/lib/components/HgLogView.svelte (1 hunks)
  • frontend/src/lib/components/ProjectList.svelte (1 hunks)
  • frontend/src/lib/components/Projects/ProjectConfidentialityFilterSelect.svelte (1 hunks)
  • frontend/src/lib/components/Projects/ProjectFilter.svelte (1 hunks)
  • frontend/src/lib/components/Projects/ProjectTable.svelte (1 hunks)
  • frontend/src/lib/components/Projects/WritingSystemList.svelte (1 hunks)
  • frontend/src/lib/components/TrainTracks.svelte (1 hunks)
  • frontend/src/lib/components/Users/UserFilter.svelte (3 hunks)
  • frontend/src/lib/components/Users/UserProjects.svelte (1 hunks)
  • frontend/src/lib/components/Users/UserTable.svelte (1 hunks)
  • frontend/src/lib/forms/DisplayLanguageSelect.svelte (1 hunks)
  • frontend/src/lib/forms/ProjectTypeSelect.svelte (1 hunks)
  • frontend/src/lib/forms/RadioButtonGroup.svelte (1 hunks)
  • frontend/src/lib/forms/UserTypeSelect.svelte (1 hunks)
  • frontend/src/lib/forms/UserTypeahead.svelte (1 hunks)
  • frontend/src/lib/layout/Breadcrumbs/Breadcrumbs.svelte (1 hunks)
  • frontend/src/routes/(authenticated)/admin/AdminTabs.svelte (1 hunks)
  • frontend/src/routes/(authenticated)/admin/EditUserAccount.svelte (1 hunks)
  • frontend/src/routes/(authenticated)/authorize/+page.svelte (2 hunks)
  • frontend/src/routes/(authenticated)/org/[org_id]/BulkAddOrgMembers.svelte (3 hunks)
  • frontend/src/routes/(authenticated)/org/[org_id]/OrgMemberTable.svelte (1 hunks)
  • frontend/src/routes/(authenticated)/org/[org_id]/OrgTabs.svelte (1 hunks)
  • frontend/src/routes/(authenticated)/org/list/+page.svelte (1 hunks)
  • frontend/src/routes/(authenticated)/project/[project_code]/AddOrganization.svelte (1 hunks)
  • frontend/src/routes/(authenticated)/project/[project_code]/AddPurpose.svelte (1 hunks)
  • frontend/src/routes/(authenticated)/project/[project_code]/BulkAddProjectMembers.svelte (3 hunks)
  • frontend/src/routes/(authenticated)/project/create/+page.svelte (2 hunks)
  • frontend/src/routes/(unauthenticated)/register/+page.svelte (1 hunks)
  • frontend/src/routes/+error.svelte (1 hunks)
  • frontend/src/routes/email/tester/[email protected] (1 hunks)
  • frontend/svelte.config.js (1 hunks)
  • frontend/viewer/eslint.config.js (0 hunks)
  • frontend/viewer/src/home/HomeView.svelte (1 hunks)
  • frontend/viewer/src/home/Server.svelte (1 hunks)
  • frontend/viewer/src/home/ServersList.svelte (1 hunks)
  • frontend/viewer/src/lib/DictionaryEntry.svelte (3 hunks)
  • frontend/viewer/src/lib/activity/ActivityView.svelte (1 hunks)
  • frontend/viewer/src/lib/components/reorderer/reorderer-item-list.svelte (1 hunks)
  • frontend/viewer/src/lib/entry-editor/EntryOrSensePicker.svelte (1 hunks)
  • frontend/viewer/src/lib/entry-editor/ItemList.svelte (1 hunks)
  • frontend/viewer/src/lib/entry-editor/ItemListItem.svelte (1 hunks)
  • frontend/viewer/src/lib/entry-editor/NewEntryDialog.svelte (1 hunks)
  • frontend/viewer/src/lib/i18n/LocalizationPicker.svelte (1 hunks)
  • frontend/viewer/src/lib/sandbox/EditorSandbox.svelte (1 hunks)
  • frontend/viewer/src/lib/sandbox/Sandbox.svelte (2 hunks)
  • frontend/viewer/src/lib/utils/url.svelte.ts (3 hunks)
  • frontend/viewer/src/project/ProjectDropdown.svelte (1 hunks)
  • frontend/viewer/src/project/browse/EntryView.svelte (1 hunks)
  • frontend/viewer/src/project/browse/SortMenu.svelte (2 hunks)
  • frontend/viewer/src/project/browse/ViewPicker.svelte (1 hunks)
  • frontend/viewer/src/stories/editor/misc/entry-picker.stories.svelte (1 hunks)
  • frontend/viewer/src/stories/editor/misc/reorderer.stories.svelte (1 hunks)
  • frontend/viewer/src/stories/primitives/button.stories.svelte (1 hunks)
💤 Files with no reviewable changes (2)
  • frontend/eslint.config.js
  • frontend/viewer/eslint.config.js
🧰 Additional context used
🧠 Learnings (40)
📓 Common learnings
Learnt from: hahn-kev
PR: sillsdev/languageforge-lexbox#1537
File: frontend/viewer/src/SvelteUxProjectView.svelte:151-153
Timestamp: 2025-03-12T06:32:08.277Z
Learning: When reviewing PRs where files have been moved or code has been relocated from one file to another, focus the review on actual modifications to the code rather than raising issues about pre-existing code patterns that were simply relocated.
Learnt from: rmunn
PR: sillsdev/languageforge-lexbox#1836
File: frontend/viewer/src/lib/components/audio/AudioDialog.svelte:25-25
Timestamp: 2025-07-22T09:19:37.386Z
Learning: In the sillsdev/languageforge-lexbox project, when file size limits or other constants need to be shared between C# backend and TypeScript frontend code, prefer exposing them through Reinforced.Typings type generation rather than hardcoding the values separately. This ensures consistency and prevents discrepancies when values change.
Learnt from: hahn-kev
PR: sillsdev/languageforge-lexbox#1612
File: frontend/viewer/src/lib/entry-editor/DeleteDialog.svelte:39-52
Timestamp: 2025-04-18T10:33:51.961Z
Learning: Svelte 5 uses standard HTML attribute syntax for event handlers (e.g., `onclick={handler}`) instead of the Svelte-specific directive syntax (e.g., `on:click={handler}`) used in previous versions.
Learnt from: hahn-kev
PR: sillsdev/languageforge-lexbox#1612
File: frontend/viewer/src/lib/entry-editor/DeleteDialog.svelte:39-52
Timestamp: 2025-04-18T10:33:51.961Z
Learning: Svelte 5 uses standard HTML attribute syntax for event handlers (e.g., `onclick={handler}`) instead of the Svelte-specific directive syntax (e.g., `on:click={handler}`) used in previous versions.
frontend/svelte.config.js (3)

Learnt from: hahn-kev
PR: #1612
File: frontend/viewer/src/lib/entry-editor/DeleteDialog.svelte:39-52
Timestamp: 2025-04-18T10:33:51.961Z
Learning: Svelte 5 uses standard HTML attribute syntax for event handlers (e.g., onclick={handler}) instead of the Svelte-specific directive syntax (e.g., on:click={handler}) used in previous versions.

Learnt from: hahn-kev
PR: #1612
File: frontend/viewer/src/lib/entry-editor/DeleteDialog.svelte:39-52
Timestamp: 2025-04-18T10:33:51.961Z
Learning: Svelte 5 uses standard HTML attribute syntax for event handlers (e.g., onclick={handler}) instead of the Svelte-specific directive syntax (e.g., on:click={handler}) used in previous versions.

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

frontend/src/lib/forms/RadioButtonGroup.svelte (3)

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/src/lib/components/Projects/ProjectTable.svelte (2)

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

frontend/viewer/src/project/browse/ViewPicker.svelte (2)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

frontend/viewer/src/project/browse/EntryView.svelte (2)

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/viewer/src/lib/sandbox/EditorSandbox.svelte (2)

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/viewer/src/lib/entry-editor/ItemList.svelte (2)

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/viewer/src/project/ProjectDropdown.svelte (1)

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

frontend/src/routes/email/tester/[email protected] (1)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/viewer/src/lib/i18n/LocalizationPicker.svelte (4)

Learnt from: hahn-kev
PR: #1827
File: frontend/viewer/src/lib/i18n/LocalizationPicker.svelte:12-15
Timestamp: 2025-07-17T05:09:27.809Z
Learning: In Svelte 5, the bind:value syntax supports patterns like bind:value={() => $locale, l => setLanguage(l)} where the comma operator is used to specify both the getter and setter functions. This is valid syntax in Svelte 5 and does not cause compilation errors, contrary to what traditional JavaScript comma operator behavior might suggest.

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

Learnt from: hahn-kev
PR: #1827
File: frontend/viewer/src/lib/i18n/LocalizationPicker.svelte:12-15
Timestamp: 2025-07-17T05:09:27.809Z
Learning: In Svelte 5, the bind:value directive supports function binding syntax where you can pass two functions separated by a comma: bind:value={getter, setter}. For example, bind:value={() => $locale, l => setLanguage(l)} is valid syntax where the first function is the getter and the second is the setter. This is not a JavaScript comma operator issue - it's a specific Svelte 5 compiler feature for two-way binding.

frontend/viewer/src/lib/components/reorderer/reorderer-item-list.svelte (3)

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/src/routes/(authenticated)/admin/EditUserAccount.svelte (1)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/viewer/src/lib/entry-editor/EntryOrSensePicker.svelte (1)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/src/routes/(authenticated)/project/[project_code]/AddPurpose.svelte (1)

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

frontend/viewer/src/home/HomeView.svelte (1)

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

frontend/src/lib/components/Users/UserProjects.svelte (2)

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

frontend/viewer/src/stories/editor/misc/entry-picker.stories.svelte (2)

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/viewer/src/lib/DictionaryEntry.svelte (2)

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/src/lib/forms/DisplayLanguageSelect.svelte (3)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

Learnt from: hahn-kev
PR: #1827
File: frontend/viewer/src/lib/i18n/LocalizationPicker.svelte:12-15
Timestamp: 2025-07-17T05:09:27.809Z
Learning: In Svelte 5, the bind:value syntax supports patterns like bind:value={() => $locale, l => setLanguage(l)} where the comma operator is used to specify both the getter and setter functions. This is valid syntax in Svelte 5 and does not cause compilation errors, contrary to what traditional JavaScript comma operator behavior might suggest.

frontend/src/lib/components/Projects/ProjectConfidentialityFilterSelect.svelte (1)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/viewer/src/lib/entry-editor/ItemListItem.svelte (1)

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

frontend/src/lib/forms/UserTypeSelect.svelte (1)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/src/routes/(authenticated)/admin/AdminTabs.svelte (2)

Learnt from: myieye
PR: #1758
File: frontend/viewer/src/project/browse/BrowseView.svelte:78-85
Timestamp: 2025-06-18T09:23:29.799Z
Learning: In Svelte Tabs components, using on:change event handler would cause popups to close when users navigate with arrow keys, which creates poor UX. The user myieye prefers the current activation mode over activationMode="manual" and considers arrow key popup closing to be "too eager" behavior.

Learnt from: myieye
PR: #1758
File: frontend/viewer/src/project/browse/BrowseView.svelte:78-85
Timestamp: 2025-06-18T09:23:29.799Z
Learning: For keyboard accessibility in TabsList components, myieye implements Enter key handlers on the TabsList rather than relying on change events that would interfere with arrow key navigation.

frontend/viewer/src/project/browse/SortMenu.svelte (5)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

Learnt from: hahn-kev
PR: #1827
File: frontend/viewer/src/lib/i18n/LocalizationPicker.svelte:12-15
Timestamp: 2025-07-17T05:09:27.809Z
Learning: In Svelte 5, the bind:value directive supports function binding syntax where you can pass two functions separated by a comma: bind:value={getter, setter}. For example, bind:value={() => $locale, l => setLanguage(l)} is valid syntax where the first function is the getter and the second is the setter. This is not a JavaScript comma operator issue - it's a specific Svelte 5 compiler feature for two-way binding.

Learnt from: hahn-kev
PR: #1827
File: frontend/viewer/src/lib/i18n/LocalizationPicker.svelte:12-15
Timestamp: 2025-07-17T05:09:27.809Z
Learning: In Svelte 5, the bind:value syntax supports patterns like bind:value={() => $locale, l => setLanguage(l)} where the comma operator is used to specify both the getter and setter functions. This is valid syntax in Svelte 5 and does not cause compilation errors, contrary to what traditional JavaScript comma operator behavior might suggest.

frontend/viewer/src/lib/activity/ActivityView.svelte (1)

Learnt from: myieye
PR: #1758
File: frontend/viewer/src/project/browse/BrowseView.svelte:78-85
Timestamp: 2025-06-18T09:23:29.799Z
Learning: In Svelte Tabs components, using on:change event handler would cause popups to close when users navigate with arrow keys, which creates poor UX. The user myieye prefers the current activation mode over activationMode="manual" and considers arrow key popup closing to be "too eager" behavior.

frontend/src/lib/forms/UserTypeahead.svelte (3)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

Learnt from: myieye
PR: #1758
File: frontend/viewer/src/project/browse/BrowseView.svelte:78-85
Timestamp: 2025-06-18T09:23:29.799Z
Learning: In Svelte Tabs components, using on:change event handler would cause popups to close when users navigate with arrow keys, which creates poor UX. The user myieye prefers the current activation mode over activationMode="manual" and considers arrow key popup closing to be "too eager" behavior.

frontend/src/routes/(authenticated)/org/[org_id]/OrgTabs.svelte (2)

Learnt from: myieye
PR: #1758
File: frontend/viewer/src/project/browse/BrowseView.svelte:78-85
Timestamp: 2025-06-18T09:23:29.799Z
Learning: In Svelte Tabs components, using on:change event handler would cause popups to close when users navigate with arrow keys, which creates poor UX. The user myieye prefers the current activation mode over activationMode="manual" and considers arrow key popup closing to be "too eager" behavior.

Learnt from: myieye
PR: #1758
File: frontend/viewer/src/project/browse/BrowseView.svelte:78-85
Timestamp: 2025-06-18T09:23:29.799Z
Learning: For keyboard accessibility in TabsList components, myieye implements Enter key handlers on the TabsList rather than relying on change events that would interfere with arrow key navigation.

frontend/viewer/src/lib/utils/url.svelte.ts (1)

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

frontend/viewer/src/stories/primitives/button.stories.svelte (1)

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

frontend/viewer/src/home/Server.svelte (1)

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

frontend/src/lib/components/ProjectList.svelte (2)

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

frontend/src/lib/components/Projects/ProjectFilter.svelte (2)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

frontend/viewer/src/stories/editor/misc/reorderer.stories.svelte (2)

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

frontend/src/lib/components/HgLogView.svelte (2)

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

frontend/src/lib/forms/ProjectTypeSelect.svelte (2)

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

frontend/src/lib/components/TrainTracks.svelte (1)

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

frontend/src/lib/components/Projects/WritingSystemList.svelte (1)

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

frontend/src/lib/components/Users/UserFilter.svelte (2)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

Learnt from: myieye
PR: #1758
File: frontend/viewer/src/project/browse/BrowseView.svelte:78-85
Timestamp: 2025-06-18T09:23:29.799Z
Learning: In Svelte Tabs components, using on:change event handler would cause popups to close when users navigate with arrow keys, which creates poor UX. The user myieye prefers the current activation mode over activationMode="manual" and considers arrow key popup closing to be "too eager" behavior.

frontend/viewer/src/lib/sandbox/Sandbox.svelte (4)

Learnt from: hahn-kev
PR: #1757
File: frontend/viewer/src/lib/components/field-editors/multi-select.svelte:130-136
Timestamp: 2025-06-18T05:13:00.591Z
Learning: In frontend/viewer/src/lib/components/field-editors/multi-select.svelte, the computeCommandScore function from 'bits-ui' handles empty filter strings appropriately and does not hide all options when the filter is empty, contrary to initial analysis assumptions.

Learnt from: hahn-kev
PR: #1841
File: frontend/viewer/src/project/browse/filter/OpFilter.svelte:10-17
Timestamp: 2025-07-24T03:26:59.388Z
Learning: In Svelte 5, reactive statements use $derived() instead of the Svelte 4 $: syntax. For example, to make an array reactive to translation changes, use const ops = $derived([...]) instead of $: ops = [...].

Learnt from: hahn-kev
PR: #1710
File: frontend/viewer/src/project/browse/BrowseView.svelte:17-19
Timestamp: 2025-05-27T06:18:33.852Z
Learning: The NewEntryButton component in frontend/viewer/src/project/NewEntryButton.svelte already internally checks features.write permission and conditionally renders based on write access, so external disabled props are not needed.

Learnt from: myieye
PR: #1802
File: frontend/viewer/src/project/NewEntryButton.svelte:36-36
Timestamp: 2025-07-04T17:00:57.368Z
Learning: In this codebase, $props.id() (Svelte rune) automatically returns a unique identifier per component instance, so components using it do not require an explicit id prop from parents.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build FW Lite and run tests
🔇 Additional comments (52)
frontend/src/routes/(unauthenticated)/register/+page.svelte (1)

16-17: URL literal looks good

Switching from a template literal to a normal string is fine and avoids unnecessary back-ticks.

frontend/src/routes/(authenticated)/project/[project_code]/AddOrganization.svelte (1)

56-58: Correct use of keyed each block

Adding (org.id) provides a stable key and eliminates the ESLint warning—nice catch.

frontend/viewer/src/home/HomeView.svelte (1)

191-192: Literal string for href is fine

Consistent with other updates; no concerns.

frontend/viewer/src/project/browse/EntryView.svelte (1)

71-71: LGTM! Proper localization of accessibility label.

The change correctly replaces the hardcoded "Toggle pinned" string with a localized version using the $t template literal, improving accessibility for non-English users.

frontend/src/routes/(authenticated)/project/[project_code]/AddPurpose.svelte (1)

71-71: LGTM! Consistent localization of submit button text.

The change correctly replaces the hardcoded "Add Purpose" string with a localized version, maintaining consistency with other internationalized strings in the component.

frontend/src/lib/forms/ProjectTypeSelect.svelte (1)

28-28: LGTM! Proper key addition for each block.

The change correctly adds (type) as the key for the each block iteration. Since the types array contains unique ProjectType enum values, using type as the key is appropriate and will help Svelte efficiently track DOM updates.

frontend/viewer/src/lib/i18n/LocalizationPicker.svelte (1)

31-31: LGTM! Proper key addition for language iteration.

The change correctly adds (lang) as the key for the each block iterating over language entries. Using the language code as the key is appropriate since it's unique and will help Svelte efficiently track the dropdown menu items.

frontend/src/routes/(authenticated)/admin/AdminTabs.svelte (1)

27-27: LGTM! Proper key addition for admin tabs iteration.

The change correctly adds (tab) as the key for the each block iterating over adminTabs. Since the array contains unique string values ('projects', 'users'), using tab as the key is appropriate and will help Svelte efficiently track the tab elements.

frontend/src/lib/forms/RadioButtonGroup.svelte (1)

42-42: LGTM! Appropriate key choice for radio button iteration.

Using button.value as the key is perfect since radio button values should be unique within a group, providing stable DOM tracking for Svelte.

frontend/viewer/src/lib/entry-editor/ItemList.svelte (1)

23-23: LGTM! Reasonable key choice for generic item list.

Using the entire item object as the key is appropriate for this generic component, as it relies on object identity for DOM tracking when specific unique properties aren't known.

frontend/src/lib/forms/UserTypeSelect.svelte (1)

25-25: LGTM! Excellent key choice for user type options.

Using the value (UserType) as the key is perfect since these are unique identifiers (admin, nonAdmin, guest) that provide stable DOM tracking for the select options.

frontend/src/lib/components/HgLogView.svelte (1)

139-139: LGTM! Perfect key choice for version control log entries.

Using log.node as the key is ideal since it represents a unique changeset identifier in the version control system, providing stable DOM tracking for the log table rows.

frontend/src/routes/email/tester/[email protected] (1)

135-135: LGTM! Appropriate key choice for email template dropdown.

Using the entire email object as the key works well here since these are statically defined template configurations that maintain object identity, providing stable DOM tracking for the select options.

frontend/viewer/src/lib/entry-editor/NewEntryDialog.svelte (1)

104-106: LGTM!

Using the error message as the key is appropriate since error messages are typically unique, and duplicate messages would represent the same validation issue anyway.

frontend/viewer/src/lib/utils/url.svelte.ts (3)

1-1: LGTM!

Proper import of SvelteURL from svelte/reactivity to comply with ESLint rules.


42-42: LGTM!

Correctly replaced native URL constructor with SvelteURL for reactive URL handling in the QueryParamState class.


98-98: LGTM!

Proper use of SvelteURL instead of native URL constructor for reactive URL parsing.

frontend/viewer/src/home/ServersList.svelte (1)

58-67: LGTM!

Using status.server.id as the key is ideal since server IDs are unique and stable, allowing Svelte to efficiently track and update Server components during re-renders.

frontend/viewer/src/lib/entry-editor/EntryOrSensePicker.svelte (1)

218-233: LGTM!

Using sense.id as the key is perfect since sense IDs are unique database identifiers that remain stable across re-renders, enabling efficient DOM updates when the senses list changes.

frontend/src/routes/(authenticated)/authorize/+page.svelte (2)

33-33: LGTM! Appropriate key selection for OAuth scopes.

Using the scope string itself as the key is correct since OAuth scopes are unique identifiers.


56-56: LGTM! Correct key usage for object entries.

Using the key from Object.entries() as the each-block key is appropriate since object keys are inherently unique.

frontend/src/routes/(authenticated)/org/[org_id]/OrgTabs.svelte (1)

37-37: LGTM! Tab values make excellent keys.

Using the tab string value as the key is perfect since the tab identifiers ('projects', 'members', etc.) are unique and stable.

frontend/src/lib/forms/DisplayLanguageSelect.svelte (1)

28-28: LGTM! Locale codes are ideal keys.

Using the locale string (e.g., 'en', 'es', 'fr') as the key is correct since locale codes are unique identifiers.

frontend/viewer/src/project/browse/ViewPicker.svelte (1)

33-33: LGTM! Using view.id as key is correct.

Using view.id provides stable unique keys for the view objects, which is the standard pattern for objects with id properties.

frontend/src/routes/(authenticated)/project/create/+page.svelte (2)

242-242: Excellent use of stable keys.

Using org.id as the key is the correct approach for keyed each-blocks, providing stable unique identifiers for efficient DOM updates.


303-303: Excellent use of stable keys.

Using proj.id as the key is the correct approach for keyed each-blocks, providing stable unique identifiers for efficient DOM updates.

frontend/viewer/src/lib/DictionaryEntry.svelte (3)

96-97: Well-documented ESLint disable.

The ESLint disable comment clearly explains the intentional use of mustaches for whitespace preservation, which is a legitimate use case.


106-107: Well-documented ESLint disable.

The ESLint disable comment clearly explains the intentional use of mustaches for whitespace preservation, which is a legitimate use case.


128-129: Well-documented ESLint disable.

The ESLint disable comment clearly explains the intentional use of mustaches for inserting an empty string, which is a legitimate use case for precise whitespace control.

frontend/src/routes/(authenticated)/org/list/+page.svelte (1)

152-152: LGTM! Proper keyed each block implementation.

The addition of (org.id) as the key for the each block is correct and follows Svelte best practices. Using the unique organization ID enables efficient DOM updates when the list changes.

frontend/viewer/src/project/browse/SortMenu.svelte (1)

81-81: LGTM! Keyed each block implementation is correct.

Using the entire option object as the key works correctly for Svelte's keying system. Since sortOptions contains distinct objects with different field and dir combinations, this provides stable keys for efficient DOM updates.

frontend/src/lib/components/Users/UserProjects.svelte (1)

76-76: LGTM! Proper keyed each block implementation.

The addition of (proj.id) as the key is correct and follows Svelte best practices. Using the unique project ID enables efficient DOM updates when the projects list changes.

frontend/src/lib/components/Projects/ProjectTable.svelte (1)

58-58: LGTM! Proper keyed each block implementation.

The addition of (project.id) as the key is correct and follows Svelte best practices. Using the unique project ID enables efficient DOM updates when the projects list changes.

frontend/viewer/src/stories/editor/misc/entry-picker.stories.svelte (1)

46-46: LGTM! Proper keyed each block implementation.

The addition of (selected.entry.id) as the key is correct and follows Svelte best practices. Using the unique entry ID enables efficient DOM updates when the selected entry history changes.

frontend/src/routes/(authenticated)/org/[org_id]/OrgMemberTable.svelte (1)

61-61: LGTM! Proper keyed each block implementation.

The addition of (member.id) as the key correctly fixes the ESLint warning and improves DOM update efficiency by providing Svelte with a unique identifier for each organization member.

frontend/viewer/src/stories/editor/misc/reorderer.stories.svelte (1)

39-39: LGTM! Appropriate key for primitive values.

Using (item) as the key is correct here since the items appear to be unique string values. This is particularly important for a reorderer story where proper DOM tracking is essential for testing reordering functionality.

frontend/src/lib/components/Projects/ProjectFilter.svelte (1)

101-101: LGTM! Correct key selection for filter objects.

Using (filter.key) as the key is appropriate since it provides a unique identifier for each filter type, ensuring proper DOM updates when active filters change.

frontend/src/routes/(authenticated)/admin/EditUserAccount.svelte (1)

148-148: LGTM! Appropriate key for feature flags.

Using (flag) as the key is correct for the feature flags iteration since flags are unique string identifiers. This ensures proper checkbox state management when the feature flags list changes.

frontend/viewer/src/project/ProjectDropdown.svelte (1)

110-110: LGTM! Proper key for project objects.

Using (project.id) as the key is correct since it provides a unique identifier for each project in the dropdown, ensuring proper DOM updates and selection state management.

frontend/viewer/src/lib/components/reorderer/reorderer-item-list.svelte (1)

44-44: LGTM! Appropriate key choice for reorderer component.

Using item as the key is correct for a reorderer component since it provides stable identity for list items regardless of their position changes, which is essential for proper DOM updates during reordering operations.

frontend/src/lib/components/Projects/WritingSystemList.svelte (1)

16-16: LGTM! Correct key choice for writing systems.

Using ws.tag as the key is appropriate since writing system tags are unique, stable identifiers that won't change when other properties are updated.

frontend/src/lib/components/Users/UserTable.svelte (1)

33-33: LGTM! Optimal key choice for user entities.

Using user.id as the key is ideal since user IDs are unique, stable database identifiers that provide optimal DOM diffing performance.

frontend/src/routes/(authenticated)/org/[org_id]/BulkAddOrgMembers.svelte (1)

113-113: LGTM! Appropriate key choice for bulk operation results.

Using user.username as the key is suitable for these bulk operation result lists since usernames are unique identifiers and the primary field being used in the bulk add context.

Also applies to: 128-128, 142-142

frontend/src/lib/components/Projects/ProjectConfidentialityFilterSelect.svelte (1)

24-24: LGTM! Appropriate key choice for option entries.

Using value as the key is correct since the confidentiality values (true, false, unset) are unique, stable identifiers for the options.

frontend/viewer/src/home/Server.svelte (1)

103-103: LGTM! Appropriate key choice for project iteration.

Using project.id as the key is correct since it provides a unique identifier for each project in the list, improving Svelte's rendering efficiency during updates.

frontend/src/routes/(authenticated)/project/[project_code]/BulkAddProjectMembers.svelte (1)

147-147: LGTM! Consistent and appropriate key choice for user iterations.

Using user.username as the key across all three user list iterations (addedMembers, createdMembers, existingMembers) is correct since usernames are unique identifiers and the primary data being displayed.

Also applies to: 162-162, 176-176

frontend/viewer/src/stories/primitives/button.stories.svelte (1)

33-33: LGTM! Appropriate keys for button variants and sizes.

Using the variant and size strings as keys is correct since these are unique values from the button configuration. This properly satisfies the eslint requirement for keyed each blocks in the Storybook stories.

Also applies to: 41-41, 49-49, 57-57

frontend/src/lib/components/ProjectList.svelte (1)

17-17: LGTM! Consistent project key usage.

Using project.id as the key is appropriate and consistent with other project list components in the codebase. This provides stable, unique identification for efficient DOM updates.

frontend/src/lib/components/Users/UserFilter.svelte (2)

58-58: LGTM! Appropriate key choice for filter iteration.

Using filter.key as the key is correct since it uniquely identifies each filter type and is already being used in the conditional logic within the loop.


57-57: Minor formatting improvements.

The whitespace adjustments around the snippet blocks improve code readability without affecting functionality.

Also applies to: 79-79, 82-82, 100-100

frontend/viewer/src/lib/sandbox/Sandbox.svelte (1)

194-201: selectedEntryHistory loop correctly keyed

Using selected.entry.id as the key satisfies the svelte/require-each-key rule and guarantees a stable identity for each rendered row. No further action needed.

frontend/src/lib/forms/UserTypeahead.svelte (1)

136-140: Key addition looks good

Switching to {#each filteredResults as user, idx (user.id)} provides a stable key without affecting the idx variable used for highlighting. Good fix for the ESLint rule.

In a few places, like when iterating over strings from a URL path, we
can't 100% guarantee that they will be unique, so it's better to use the
index as the key. This can result in unnecessary re-renderings, but this
is better than the result that would happen if a Svelte #each block
ended up with the same key pointing at multiple items in the #each. And
there won't be many re-renderings in most of these cases, as they are
not things that change frequently (if at all) in the UI.
@coderabbitai coderabbitai bot mentioned this pull request Jul 31, 2025
Copy link
Collaborator

@hahn-kev hahn-kev left a comment

Choose a reason for hiding this comment

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

looks good to me

Copy link
Collaborator

@hahn-kev hahn-kev left a comment

Choose a reason for hiding this comment

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

the lint report says theres 2 each blocks that were missed

@rmunn
Copy link
Contributor Author

rmunn commented Jul 31, 2025

the lint report says theres 2 each blocks that were missed

It's not reporting that when I run it in my branch. Must be something that just got merged into develop, and CI is running checks on the results of the merge rather than on the branch head. I'll rebase onto current develop (which I would have to do anyway to fix the merge conflicts) and then fix the two new lint errors. (I bet the two missed ones are in the two conflicted files, HomeView.svelte and ActivityView.svelte).

@rmunn
Copy link
Contributor Author

rmunn commented Jul 31, 2025

Yes, the two new lint errors were from a branch that got merged into develop after my PR branched off, which is why I missed them. Now fixed in commit e653f8b.

@rmunn rmunn requested a review from hahn-kev July 31, 2025 07:01
@rmunn rmunn enabled auto-merge (squash) July 31, 2025 07:06
@rmunn rmunn merged commit 52c7b22 into develop Jul 31, 2025
27 checks passed
@rmunn rmunn deleted the chore/fix-new-eslint-warnings branch July 31, 2025 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix new eslint warnings

2 participants