Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SRO Add conditional search/filter for relic sets/lightcones #2604

Merged
merged 1 commit into from
Jan 29, 2025
Merged

Conversation

frzyc
Copy link
Owner

@frzyc frzyc commented Jan 22, 2025

Describe your changes

Currently, all the relic sets/lc sheets are displayed in the UI. this is very laggy.

Limit view to to only the ones with conditionals + searched.

only lc with conditionals set are shown.

image

search a relic set, searched set comes first, then the set conditionals

image

Issue or discord link

Testing/validation

Checklist before requesting a review (leave this PR as draft if any part of this list is not done.)

  • I have commented my code in hard-to understand areas.
  • I have made corresponding changes to README or wiki.
  • For front-end changes, I have updated the corresponding English translations.
  • I have run yarn run mini-ci locally to validate format and lint.
  • If I have added a new library or app, I have updated the deployment scripts to ignore changes as needed

Summary by CodeRabbit

Release Notes

  • New Features

    • Added search functionality for Light Cones and Relic Sets
    • Introduced dynamic filtering for Light Cone and Relic Set displays
  • Improvements

    • Enhanced type safety for Light Cone and Relic Set keys
    • Improved user interface with autocomplete search components
    • Updated component rendering to support more interactive experiences
  • Technical Updates

    • Modified export methods for certain components
    • Updated import statements to support new component structures

@frzyc frzyc added the SRO For Star Rail Optimizer label Jan 22, 2025
Copy link
Contributor

coderabbitai bot commented Jan 22, 2025

Walkthrough

This pull request introduces type safety and search functionality for light cones and relic sets. New type guard functions isLightConeKey and isRelicSetKey have been added to enhance key validation. The LightConeSheetsDisplay and RelicSheetsDisplay components have been updated to include dynamic filtering, autocomplete search capabilities, and improved state management. The changes also modify the export style of the LightConeAutocomplete component from a default to a named export.

Changes

File Change Summary
libs/sr/consts/src/lightCone.ts Added isLightConeKey type guard function
libs/sr/consts/src/relic.ts Added isRelicSetKey type guard function
libs/sr/page-team/src/LightConeSheetsDisplay.tsx Refactored component with dynamic filtering, autocomplete, and state management
libs/sr/page-team/src/RelicSheetsDisplay.tsx Updated with dynamic relic set filtering and search functionality
libs/sr/ui/src/LightCone/LightConeAutocomplete.tsx Changed export from default to named export
libs/sr/ui/src/LightCone/LightConeEditor/LightConeEditorCard.tsx Updated import for LightConeAutocomplete

Assessment against linked issues

Objective Addressed Explanation
Display only conditionals with set or equipped characters [#2602]
Add autocomplete for new conditionals [#2602]

Possibly related PRs

Suggested reviewers

  • nguyentvan7

Poem

🐰 Hop, hop, through the code we go,
Keys validated, search bars aglow,
Light cones and relics dance with glee,
Type safety springs, now we are free!
A rabbit's code review delight! 🌟

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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. (Beta)
  • @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.

Copy link
Contributor

github-actions bot commented Jan 22, 2025

[sr-frontend] [Wed Jan 22 06:43:02 UTC 2025] - Deployed 07732b8 to https://genshin-optimizer-prs.github.io/pr/2604/sr-frontend (Takes 3-5 minutes after this completes to be available)

[Wed Jan 29 19:26:23 UTC 2025] - Deleted deployment

Copy link
Contributor

@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: 0

🧹 Nitpick comments (6)
libs/sr/ui/src/LightCone/LightConeAutocomplete.tsx (1)

Line range hint 9-14: Consider enhancing type safety and error handling.

While the current implementation is solid, consider these improvements:

  1. Add runtime validation for the empty string case
  2. Add explicit error handling for failed image loads

Here's a suggested implementation:

 type LightConeAutocompleteProps = {
   lcKey: LightConeKey | ''
   setLCKey: (key: LightConeKey | '') => void
   label?: string
+  onError?: (error: Error) => void
 }

And for the image component:

         <ImgIcon
           size={2}
           sx={{ width: 'auto' }}
           src={lightConeAsset(key, 'cover')}
+          onError={(e) => {
+            console.error(`Failed to load light cone image for ${key}`);
+            onError?.(new Error(`Failed to load light cone image for ${key}`));
+          }}
         />
libs/sr/page-team/src/LightConeSheetsDisplay.tsx (2)

21-25: Add translation for the search label.

The TODO comment indicates missing translation for "Search Light Cone".

Would you like me to help set up the translation key in the localization system?


27-32: Consider adding loading states and empty states.

The grid implementation could benefit from handling edge cases:

  • Loading state while fetching data
  • Empty state when no light cones match the filter
 <Grid container columns={3} spacing={1}>
+  {lcList.length === 0 ? (
+    <Grid item xs={3}>
+      <Box sx={{ textAlign: 'center', py: 2 }}>
+        No light cones found
+      </Box>
+    </Grid>
+  ) : (
   {lcList.map((setKey) => (
     <Grid item xs={1} key={setKey}>
       <LightConeSheetDisplay lcKey={setKey} />
     </Grid>
   ))}
+  )}
 </Grid>
libs/sr/page-team/src/RelicSheetsDisplay.tsx (2)

9-11: Consider memoizing team context value.

While the context usage is correct, consider memoizing the destructured value to prevent unnecessary re-renders if the team context changes frequently.

-  const { team } = useTeamContext()
-  const conditionals = team.conditionals
+  const { conditionals } = useMemo(() => {
+    const { team } = useTeamContext()
+    return { conditionals: team.conditionals }
+  }, [])

12-19: Optimize list computation and consider edge cases.

The list computation logic is sound, but there are a few potential improvements:

  1. The sort callback could be simplified
  2. Consider handling empty conditionals array
   const relicList = useMemo(() => {
     const sets = conditionals
       .map((c) => c.sheet)
       .filter(isRelicSetKey) as RelicSetKey[]
     if (relicSetKey) sets.push(relicSetKey)
-    // Make sure the currently selected set is at the front
-    return [...new Set(sets)].sort((set) => (set === relicSetKey ? -1 : 1))
+    const uniqueSets = [...new Set(sets)]
+    return uniqueSets.length > 0 
+      ? uniqueSets.sort((a, b) => Number(b === relicSetKey) - Number(a === relicSetKey))
+      : uniqueSets
   }, [conditionals, relicSetKey])
libs/sr/consts/src/relic.ts (1)

174-180: Consider optimizing type validation and adding tests.

The implementation is correct but could be more efficient and safer:

  1. Consider caching the result for frequently used keys
  2. Add unit tests to verify edge cases
+const relicSetKeyCache = new Set<string>()
+
 export function isRelicSetKey(key: unknown): key is RelicSetKey {
+  if (typeof key !== 'string') return false
+  if (relicSetKeyCache.has(key)) return true
+
+  const isValid = isCavernRelicSetKey(key as RelicSetKey) ||
+    isPlanarRelicSetKey(key as RelicSetKey)
+
+  if (isValid) relicSetKeyCache.add(key)
+  return isValid
-  return (
-    typeof key === 'string' &&
-    (isCavernRelicSetKey(key as RelicSetKey) ||
-      isPlanarRelicSetKey(key as RelicSetKey))
-  )
 }

Would you like me to generate unit tests for this function to ensure proper validation of edge cases?

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4d74491 and 6eace02.

📒 Files selected for processing (6)
  • libs/sr/consts/src/lightCone.ts (1 hunks)
  • libs/sr/consts/src/relic.ts (1 hunks)
  • libs/sr/page-team/src/LightConeSheetsDisplay.tsx (1 hunks)
  • libs/sr/page-team/src/RelicSheetsDisplay.tsx (1 hunks)
  • libs/sr/ui/src/LightCone/LightConeAutocomplete.tsx (1 hunks)
  • libs/sr/ui/src/LightCone/LightConeEditor/LightConeEditorCard.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • libs/sr/ui/src/LightCone/LightConeEditor/LightConeEditorCard.tsx
🔇 Additional comments (7)
libs/sr/ui/src/LightCone/LightConeAutocomplete.tsx (2)

Line range hint 16-52: Implementation follows React best practices!

The component demonstrates excellent use of:

  • Proper memoization with useMemo and useCallback
  • Clear TypeScript typing
  • Internationalization support
  • Loading state handling with Suspense

15-15: Verify all imports are updated after changing to named export.

The switch from default export to named export is a good practice for better tree-shaking and explicit imports. However, this is a breaking change.

Let's verify that all imports are updated correctly:

✅ Verification successful

All imports are already using named import syntax

The change to named export is consistent with the existing codebase, as all imports are already using the correct named import syntax. No updates needed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining default imports of LightConeAutocomplete
rg "import\s+LightConeAutocomplete\s+from" -g '*.{ts,tsx}'

# Search for the new named imports to ensure they exist
rg "import\s+{\s*LightConeAutocomplete\s*}" -g '*.{ts,tsx}'

Length of output: 253


Script:

#!/bin/bash
# Search for any imports of LightConeAutocomplete
rg "import.*LightConeAutocomplete.*from.*['\"]" -g '*.{ts,tsx}'

# Also check the actual file to see its location and original export
rg "export.*LightConeAutocomplete" -g '*.{ts,tsx}'

Length of output: 530

libs/sr/consts/src/lightCone.ts (1)

115-119: Well-implemented type guard function!

The implementation follows TypeScript best practices for runtime type validation. The type guard pattern is correctly used to ensure type safety at runtime.

Consider adding unit tests to verify the behavior with:

  • Valid light cone keys
  • Invalid strings
  • Non-string inputs
libs/sr/page-team/src/LightConeSheetsDisplay.tsx (2)

13-18: Efficient implementation of filtered list computation!

The useMemo hook is appropriately used to optimize performance by preventing unnecessary recomputations. The implementation correctly:

  • Filters valid light cone keys
  • Handles duplicates using Set
  • Ensures selected item appears first

1-7: Verify the impact of removing allLightConeKeys import.

The changes remove the direct usage of allLightConeKeys. Ensure this doesn't affect any functionality that might need the complete list of light cones.

✅ Verification successful

Removal of allLightConeKeys import is safe

The complete list of light cones is still available through the LightConeAutocomplete component, which internally uses allLightConeKeys. The type safety is maintained via LightConeKey type and isLightConeKey function.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other usages of allLightConeKeys in the codebase
rg "allLightConeKeys" --type ts

Length of output: 3880

libs/sr/page-team/src/RelicSheetsDisplay.tsx (2)

1-5: LGTM! Import changes align with new functionality.

The imports are appropriate for the new filtering functionality, bringing in necessary type validation and UI components.


21-36: Address TODO comment and consider responsive design.

The UI structure looks good, but there are two points to address:

  1. There's a TODO comment for translation
  2. The grid columns might need adjustment for different screen sizes
       <RelicSetAutocomplete
         relicSetKey={relicSetKey}
         setRelicSetKey={setRelicSetKey}
-        label="Search Relic Set" // TODO: translation
+        label={t('relicSet.search')} // Add translation key
       />
       <Box>
-        <Grid container columns={3} spacing={1}>
+        <Grid container columns={{ xs: 1, sm: 2, md: 3 }} spacing={1}>

Let me verify if the translation system is set up:

@frzyc frzyc requested a review from nguyentvan7 January 22, 2025 06:56
Copy link
Contributor

@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 (6)
libs/sr/ui/src/LightCone/LightConeAutocomplete.tsx (1)

Line range hint 36-51: Consider adding error handling for image loading.

While the implementation is solid, consider adding error handling for the image loading to improve user experience when assets fail to load.

Here's a suggested improvement:

 const toImg = useCallback(
   (key: LightConeKey | '') =>
     !key ? undefined : (
       <ImgIcon
         size={2}
         sx={{ width: 'auto' }}
         src={lightConeAsset(key, 'cover')}
+        onError={(e) => {
+          e.currentTarget.src = 'fallback-image-path';
+          console.warn(`Failed to load image for light cone: ${key}`);
+        }}
       />
     ),
   []
 )
libs/sr/page-team/src/RelicSheetsDisplay.tsx (1)

12-19: Consider optimizing the set deduplication logic.

While the current implementation works, the deduplication and sorting could be more efficient.

Consider this optimization:

-    if (relicSetKey) sets.push(relicSetKey)
-    // Make sure the currently selected set is at the front
-    return [...new Set(sets)].sort((set) => (set === relicSetKey ? -1 : 1))
+    const uniqueSets = new Set(sets)
+    if (relicSetKey) uniqueSets.add(relicSetKey)
+    return relicSetKey 
+      ? [relicSetKey, ...Array.from(uniqueSets).filter(set => set !== relicSetKey)]
+      : Array.from(uniqueSets)

This approach:

  • Avoids unnecessary array operations
  • Eliminates the need for sorting
  • More clearly expresses the intent
libs/sr/consts/src/relic.ts (1)

174-180: Consider adding descriptive error logging for invalid keys.

The type guard implementation is correct, but debugging invalid keys could be improved.

Consider adding debug logging:

 export function isRelicSetKey(key: unknown): key is RelicSetKey {
+  if (typeof key !== 'string') {
+    console.debug(`Invalid RelicSetKey: expected string, got ${typeof key}`);
+    return false;
+  }
+  const isValid = isCavernRelicSetKey(key as RelicSetKey) ||
+    isPlanarRelicSetKey(key as RelicSetKey);
+  if (!isValid) {
+    console.debug(`Invalid RelicSetKey: "${key}" is neither a cavern nor planar set key`);
+  }
+  return isValid;
-  return (
-    typeof key === 'string' &&
-    (isCavernRelicSetKey(key as RelicSetKey) ||
-      isPlanarRelicSetKey(key as RelicSetKey))
-  )
 }
libs/sr/page-team/src/LightConeSheetsDisplay.tsx (2)

12-18: Consider optimizing the filtering logic.

The current implementation rebuilds the set on every render where either conditionals or lcKey changes. Consider these improvements:

  1. Move the selected key check before creating the Set to avoid unnecessary Set operations
  2. Use a more explicit variable name than sets since it's an array
  const lcList = useMemo(() => {
-   const sets = conditionals.map((c) => c.sheet).filter(isLightConeKey)
-   if (lcKey) sets.push(lcKey)
-   // Make sure the currently selected lc is at the front
-   return [...new Set(sets)].sort((set) => (set === lcKey ? -1 : 1))
+   const lightConeKeys = conditionals.map((c) => c.sheet).filter(isLightConeKey)
+   if (lcKey && !lightConeKeys.includes(lcKey)) {
+     lightConeKeys.unshift(lcKey)
+   }
+   return Array.from(new Set(lightConeKeys))
  }, [conditionals, lcKey])

27-32: Consider adding loading states and error boundaries.

The grid layout looks good, but there's no handling for loading states or errors when displaying light cones.

Consider wrapping the LightConeSheetDisplay with error boundaries and adding loading states for better user experience.

libs/sr/consts/src/lightCone.ts (1)

115-119: Consider caching the light cone keys set for better performance.

The current implementation performs an array inclusion check on every call. For better performance, consider using a Set for O(1) lookups.

+ const lightConeKeysSet = new Set(allLightConeKeys)
  export function isLightConeKey(key: unknown): key is LightConeKey {
    return (
-     typeof key === 'string' && allLightConeKeys.includes(key as LightConeKey)
+     typeof key === 'string' && lightConeKeysSet.has(key as LightConeKey)
    )
  }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4d74491 and 6eace02.

📒 Files selected for processing (6)
  • libs/sr/consts/src/lightCone.ts (1 hunks)
  • libs/sr/consts/src/relic.ts (1 hunks)
  • libs/sr/page-team/src/LightConeSheetsDisplay.tsx (1 hunks)
  • libs/sr/page-team/src/RelicSheetsDisplay.tsx (1 hunks)
  • libs/sr/ui/src/LightCone/LightConeAutocomplete.tsx (1 hunks)
  • libs/sr/ui/src/LightCone/LightConeEditor/LightConeEditorCard.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • libs/sr/ui/src/LightCone/LightConeEditor/LightConeEditorCard.tsx
🔇 Additional comments (7)
libs/sr/ui/src/LightCone/LightConeAutocomplete.tsx (3)

Line range hint 9-14: LGTM! Well-structured type definitions.

The props interface is well-defined with proper TypeScript types, making the component type-safe and maintainable.


Line range hint 18-35: LGTM! Excellent use of React hooks and memoization.

The implementation follows React best practices with proper use of:

  • Memoized options array to prevent unnecessary recalculations
  • Memoized callbacks to maintain referential equality
  • Internationalization with proper translation keys

15-17: Verify the impact of changing to named export.

The component has been changed from default export to named export. This change requires updates to all import statements in other files.

Let's verify all imports are updated correctly:

✅ Verification successful

All imports are correctly using named export syntax

All files importing LightConeAutocomplete are already using the correct named import syntax:

  • libs/sr/ui/src/LightCone/LightConeEditor/LightConeEditorCard.tsx
  • libs/sr/page-team/src/LightConeSheetsDisplay.tsx
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining default imports of LightConeAutocomplete
rg "import LightConeAutocomplete from.*LightConeAutocomplete" -l

# Search for new named imports to ensure they're correct
rg "import \{.*LightConeAutocomplete.*\} from.*LightConeAutocomplete" -l

Length of output: 206


Script:

#!/bin/bash
# Show the actual import line
rg "import.*LightConeAutocomplete.*from" libs/sr/ui/src/LightCone/LightConeEditor/LightConeEditorCard.tsx

# Search for any other import patterns containing LightConeAutocomplete
rg "import.*LightConeAutocomplete" -g '!LightConeAutocomplete.tsx'

Length of output: 485

libs/sr/page-team/src/RelicSheetsDisplay.tsx (3)

1-5: LGTM! Improved type safety and UI component organization.

The imports are well-organized and appropriately chosen for implementing the search functionality and type safety.


9-11: LGTM! Clean state management setup.

Good use of context for team data and local state for search functionality.


21-36: Address the translation TODO comment.

The UI structure looks good, but there's a pending translation task.

Would you like me to help implement the translation for "Search Relic Set" label? I can:

  1. Check if similar translations exist in the codebase
  2. Generate the necessary translation key and entry
libs/sr/page-team/src/LightConeSheetsDisplay.tsx (1)

1-7: LGTM! Clean import structure with proper type safety.

The imports are well-organized, bringing in necessary types and components while maintaining type safety through the isLightConeKey type guard.

@frzyc frzyc changed the title Add conditional search/filter for relic sets/lightcones SRO Add conditional search/filter for relic sets/lightcones Jan 25, 2025
@frzyc frzyc merged commit d91a9a9 into master Jan 29, 2025
10 checks passed
@frzyc frzyc deleted the 2602 branch January 29, 2025 19:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SRO For Star Rail Optimizer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SRO conditional search bar/filter
2 participants