Skip to content

feat: Allow editing saved filters in data browser #2942

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

Merged
merged 23 commits into from
Jul 26, 2025

Conversation

mtrezza
Copy link
Member

@mtrezza mtrezza commented Jul 26, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced filter management: Users can now create, edit, save, copy, and delete named filter views, including support for relative date filters.
    • Improved UI with detailed edit mode, change detection, delete confirmation dialogs, and icon button states.
    • Filter actions are synchronized with the URL for easier sharing and navigation.
    • Added delete filter functionality accessible via toolbar and filter components.
  • Bug Fixes

    • Fixed button focus behavior to prevent sticky focus after mouse interactions.
  • Style

    • Minor formatting improvements to button styles.
    • Added new styles for enabled and disabled icon buttons.
  • Refactor

    • Updated filter matching logic for better accuracy and legacy support.
    • Improved filter management by handling filters via unique IDs and updating preferences accordingly.
  • Chores

    • Reorganized import statements for better code clarity.

Copy link

🚀 Thanks for opening this pull request!

Copy link

coderabbitai bot commented Jul 26, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

"""

Walkthrough

This set of changes introduces comprehensive enhancements to filter management within the data browser UI. The BrowserFilter component now supports editing, saving, deleting, and copying named filters with relative date awareness, including UI state management and synchronization with URL parameters. Supporting components and methods are updated to handle filter IDs, propagate delete actions, improve filter matching logic, and manage filter lifecycle events.

Changes

File(s) Change Summary
src/components/BrowserFilter/BrowserFilter.react.js Major refactor: Adds state and methods for editing, saving, deleting, copying named filters with relative date handling, UI state, and URL sync.
src/dashboard/Data/Browser/Browser.react.js Refactors filter save logic to support filter IDs, adds delete method for filters, updates preferences, preserves filterId in URL, and passes delete handler to children.
src/dashboard/Data/Browser/BrowserToolbar.react.js Adds onDeleteFilter prop and forwards it to BrowserFilter.
src/components/CategoryList/CategoryList.react.js Improves filter matching to prioritize by filter ID, removes close button from filter list.
src/components/Button/Button.react.js Adds onMouseLeave handler to blur button, reorders imports.
src/components/Button/Button.scss Minor formatting fix in CSS selector.
src/components/BrowserFilter/BrowserFilter.scss Adds .iconButton and .iconButtonDisabled CSS classes for icon button styling and disabled states.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant BrowserFilter
    participant Browser
    participant Preferences
    participant URL

    User->>BrowserFilter: Edit or copy filter (name, relative date, etc.)
    BrowserFilter->>Browser: saveFilters(filters, name, relativeDate, [filterId])
    Browser->>Preferences: Update saved filters (add/edit)
    Browser->>BrowserFilter: Return filterId
    BrowserFilter->>URL: Update with filterId (if new/edited)
    User->>BrowserFilter: Delete filter
    BrowserFilter->>Browser: deleteFilter(filterId)
    Browser->>Preferences: Remove filter by filterId
    Browser->>BrowserFilter: Confirm deletion
    BrowserFilter->>URL: Remove filterId
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error code ERR_SSL_WRONG_VERSION_NUMBER
npm error errno ERR_SSL_WRONG_VERSION_NUMBER
npm error request to https://10.0.0.28:4873/npm/-/npm-10.9.3.tgz failed, reason: C03C70DAAD7F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:354:
npm error
npm error A complete log of this run can be found in: /.npm/_logs/2025-07-26T11_33_36_865Z-debug-0.log


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6711f52 and 205781f.

📒 Files selected for processing (3)
  • src/components/BrowserFilter/BrowserFilter.react.js (7 hunks)
  • src/components/BrowserFilter/BrowserFilter.scss (1 hunks)
  • src/dashboard/Data/Browser/Browser.react.js (8 hunks)

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 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.

@parseplatformorg
Copy link
Contributor

parseplatformorg commented Jul 26, 2025

🎉 Snyk checks have passed. No issues have been found so far.

security/snyk check is complete. No issues have been found. (View Details)

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: 6

🧹 Nitpick comments (2)
src/dashboard/Data/Browser/Browser.react.js (1)

29-29: Consider renaming the imported Map to avoid shadowing.

The import of Map from Immutable shadows the global JavaScript Map constructor. Consider using a named import alias to avoid confusion:

-import { List, Map } from 'immutable';
+import { List, Map as ImmutableMap } from 'immutable';

Then update all usages of Map in the file to ImmutableMap.

src/components/BrowserFilter/BrowserFilter.react.js (1)

231-253: Simplify filter comparison using Immutable.js methods

Since you're using Immutable.js, you can simplify the comparison logic by leveraging its built-in equality checking.

Replace the manual property comparison with:

-    // Compare each filter
-    for (let i = 0; i < currentFilters.size; i++) {
-      const currentFilter = currentFilters.get(i);
-      const originalFilter = originalFilters.get(i);
-
-      // Compare each property of the filter
-      const currentClass = currentFilter.get('class');
-      const currentField = currentFilter.get('field');
-      const currentConstraint = currentFilter.get('constraint');
-      const currentCompareTo = currentFilter.get('compareTo');
-
-      const originalClass = originalFilter.get('class');
-      const originalField = originalFilter.get('field');
-      const originalConstraint = originalFilter.get('constraint');
-      const originalCompareTo = originalFilter.get('compareTo');
-
-      // Check all properties for equality
-      if (currentClass !== originalClass ||
-          currentField !== originalField ||
-          currentConstraint !== originalConstraint ||
-          currentCompareTo !== originalCompareTo) {
-        return true;
-      }
-    }
-
-    return false;
+    // Use Immutable.js equality check
+    return !currentFilters.equals(originalFilters);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 3c43959 and b50b761.

📒 Files selected for processing (6)
  • src/components/BrowserFilter/BrowserFilter.react.js (6 hunks)
  • src/components/Button/Button.react.js (2 hunks)
  • src/components/Button/Button.scss (1 hunks)
  • src/components/CategoryList/CategoryList.react.js (3 hunks)
  • src/dashboard/Data/Browser/Browser.react.js (5 hunks)
  • src/dashboard/Data/Browser/BrowserToolbar.react.js (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/dashboard/Data/Browser/Browser.react.js (2)

Learnt from: mtrezza
PR: #2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the confirmExecuteScriptRows method in src/dashboard/Data/Browser/Browser.react.js), individual setState calls to update processedScripts counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.

Learnt from: mtrezza
PR: #2769
File: src/lib/ClassPreferences.js:26-26
Timestamp: 2025-05-02T11:55:52.809Z
Learning: Preference reads and writes in the ClassPreferences.js module are expected to be infrequent operations, so optimizing for performance (like caching) is unnecessary in this context.

🪛 Biome (2.1.2)
src/dashboard/Data/Browser/Browser.react.js

[error] 29-29: Do not shadow the global "Map" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

src/components/BrowserFilter/BrowserFilter.react.js

[error] 19-19: Do not shadow the global "Map" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

⏰ 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: Docker linux/amd64
🔇 Additional comments (5)
src/components/Button/Button.scss (1)

80-80: LGTM!

The formatting fix improves code consistency by adding the missing space before the opening brace.

src/dashboard/Data/Browser/BrowserToolbar.react.js (1)

35-35: LGTM!

The addition of the onDeleteFilter prop properly integrates filter deletion functionality into the toolbar component, enabling it to propagate delete actions from the BrowserFilter component up to the parent.

Also applies to: 405-405

src/components/Button/Button.react.js (1)

10-11: Good UX improvement!

The addition of the onMouseLeave handler effectively prevents sticky focus states on buttons, improving the user experience. The import reordering is also fine.

Also applies to: 56-59

src/components/CategoryList/CategoryList.react.js (1)

9-9: Well-implemented filter ID matching with backward compatibility!

The changes properly prioritize filter matching by ID while maintaining backward compatibility through the legacy fallback. This aligns well with the new filter management system. The removal of the inline close button is appropriate as filter deletion is now handled through dedicated UI flows.

Also applies to: 60-70, 124-131

src/dashboard/Data/Browser/Browser.react.js (1)

1203-1268: Well-structured filter save/update implementation!

The enhanced saveFilters method properly handles both creating new filters with generated UUIDs and updating existing filters by ID. The return value allows callers to track newly created filters, and the fallback logic ensures robustness.

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

♻️ Duplicate comments (1)
src/dashboard/Data/Browser/Browser.react.js (1)

1270-1303: Consider renaming the misleading parameter name.

The deleteFilter method's parameter is named filterIdOrObject but can also accept a filter object as indicated by the fallback logic. This is confusing. Consider renaming it to better reflect its dual purpose:

-deleteFilter(filterIdOrObject) {
+deleteFilter(filterOrId) {

Also update the references within the method accordingly. The implementation logic itself is solid with good backward compatibility support.

🧹 Nitpick comments (1)
src/dashboard/Data/Browser/Browser.react.js (1)

29-29: Address the global Map shadowing issue.

The static analysis tool correctly identifies that importing Map from Immutable.js shadows the global Map constructor. Consider using a more explicit import to avoid confusion:

-import { List, Map } from 'immutable';
+import { List, Map as ImmutableMap } from 'immutable';

Then update the usage throughout the file accordingly. This makes it clear when you're using Immutable's Map versus the native Map constructor.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b50b761 and 5128026.

📒 Files selected for processing (2)
  • src/components/BrowserFilter/BrowserFilter.react.js (7 hunks)
  • src/dashboard/Data/Browser/Browser.react.js (5 hunks)
🧰 Additional context used
🧠 Learnings (2)
src/dashboard/Data/Browser/Browser.react.js (2)

Learnt from: mtrezza
PR: #2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the confirmExecuteScriptRows method in src/dashboard/Data/Browser/Browser.react.js), individual setState calls to update processedScripts counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.

Learnt from: mtrezza
PR: #2769
File: src/lib/ClassPreferences.js:26-26
Timestamp: 2025-05-02T11:55:52.809Z
Learning: Preference reads and writes in the ClassPreferences.js module are expected to be infrequent operations, so optimizing for performance (like caching) is unnecessary in this context.

src/components/BrowserFilter/BrowserFilter.react.js (1)

Learnt from: mtrezza
PR: #2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the confirmExecuteScriptRows method in src/dashboard/Data/Browser/Browser.react.js), individual setState calls to update processedScripts counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.

🪛 Biome (2.1.2)
src/dashboard/Data/Browser/Browser.react.js

[error] 29-29: Do not shadow the global "Map" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

⏰ 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: Docker linux/amd64
🔇 Additional comments (18)
src/dashboard/Data/Browser/Browser.react.js (3)

230-230: LGTM!

Proper method binding in the constructor for the new deleteFilter method.


1203-1268: Excellent enhancement to support filter editing.

The updated saveFilters method effectively handles both creating new filters and updating existing ones. Key improvements:

  • Clean separation between create/update logic based on filterId parameter
  • Proper fallback when existing filter not found by ID
  • Returns the filter ID for caller convenience
  • Uses modern crypto.randomUUID() for ID generation
  • Maintains backward compatibility

The implementation is robust and well-structured.


2298-2298: LGTM!

Proper integration of the onDeleteFilter prop to enable filter deletion functionality in the DataBrowser component.

src/components/BrowserFilter/BrowserFilter.react.js (15)

19-19: LGTM! Map shadowing issue has been resolved.

The import has been properly aliased as ImmutableMap to avoid shadowing the global Map object, addressing the previous review concern.


40-44: Well-structured state additions for enhanced filter management.

The new state variables are appropriately named and initialized to support the editing, deletion, and change tracking functionality.


55-98: Robust filter detection with appropriate fallback logic.

The method correctly prioritizes URL-based filter identification and includes a sensible fallback for legacy compatibility. The error handling prevents crashes from malformed saved filters.


119-123: Error handling has been improved.

The catch block now properly logs parsing errors for debugging while gracefully handling the failure case, addressing the previous review concern about silent error handling.


143-176: Well-structured toggle logic for edit mode transitions.

The method properly manages state transitions, stores original values for comparison, and handles filter conversion appropriately for the enhanced editing functionality.


178-190: Proper duplicate name detection with edit-mode awareness.

The method correctly excludes the current filter ID when checking for duplicates, preventing false positives during filter editing.


192-214: Comprehensive date format normalization for reliable comparisons.

The method properly handles all three date formats (JavaScript Date, Parse Date, RelativeDate) and converts them to a consistent ISO string format for accurate filter comparison.


216-257: Thorough change detection with comprehensive filter comparison.

The method provides detailed comparison logic that properly normalizes filters and checks all relevant properties to accurately detect content changes.


259-281: Proper date format conversion for UI display.

The method correctly converts various date formats to JavaScript Date objects while preserving existing Date objects, ensuring consistent UI behavior.


283-283: Method naming has been improved for clarity.

The method name has been updated from the previously misleading convertRelativeDatesForDisplay to convertRelativeDatesToParseFormat, which accurately reflects its purpose of converting for saving rather than display.


299-336: Delete logic has been properly extracted into a dedicated method.

The delete functionality has been moved from the inline onClick handler to this dedicated method, improving testability and maintainability as suggested in the previous review.


349-354: Proper date conversion and state management in toggle method.

The addition of date conversion for display and showMore state reset appropriately supports the enhanced filter editing functionality.


405-475: Comprehensive save method enhancement for editing capabilities.

The method now properly handles both new filter creation and editing existing filters, with appropriate URL management, date conversion, and UI state preservation.


544-569: Well-structured UI additions for enhanced filter editing.

The conditional rendering provides appropriate input fields for filter name and relative dates checkbox, with proper field structure and labeling.


624-645: Duplicate rendering logic has been eliminated.

The conditional rendering has been simplified to remove the duplicate code that was rendering identical UI elements in different branches, improving maintainability as suggested in the previous review.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jul 26, 2025
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: 0

🧹 Nitpick comments (1)
src/dashboard/Data/Browser/Browser.react.js (1)

29-29: Address the global property shadowing warning.

The import of Map from Immutable shadows the global Map property, which can cause confusion about variable origins.

Consider using a named import to avoid shadowing:

-import { List, Map } from 'immutable';
+import { List, Map as ImmutableMap } from 'immutable';

Then update all usages of Map to ImmutableMap throughout the file.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5128026 and 96aa9f1.

📒 Files selected for processing (1)
  • src/dashboard/Data/Browser/Browser.react.js (6 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/dashboard/Data/Browser/Browser.react.js (2)

Learnt from: mtrezza
PR: #2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the confirmExecuteScriptRows method in src/dashboard/Data/Browser/Browser.react.js), individual setState calls to update processedScripts counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.

Learnt from: mtrezza
PR: #2769
File: src/lib/ClassPreferences.js:26-26
Timestamp: 2025-05-02T11:55:52.809Z
Learning: Preference reads and writes in the ClassPreferences.js module are expected to be infrequent operations, so optimizing for performance (like caching) is unnecessary in this context.

🪛 Biome (2.1.2)
src/dashboard/Data/Browser/Browser.react.js

[error] 29-29: Do not shadow the global "Map" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

⏰ 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: Docker linux/amd64
🔇 Additional comments (5)
src/dashboard/Data/Browser/Browser.react.js (5)

230-230: LGTM: Proper method binding.

The binding for the deleteFilter method is correctly added to ensure proper this context.


527-544: Excellent enhancement for date filter handling.

The conversion of date strings to Parse Date objects is well-implemented and essential for proper Parse query functionality. The logic correctly:

  1. Validates date strings using Date.parse()
  2. Converts to Parse Date format with __type: 'Date' and ISO string
  3. Preserves all other filter properties

This ensures that date filters work correctly with Parse's query system.


1216-1281: Excellent enhancement supporting filter creation and updates.

The enhanced saveFilters method is well-implemented with several improvements:

  1. Dual functionality: Supports both creating new filters and updating existing ones via optional filterId parameter
  2. Relative date handling: Properly converts date filters to relative date format when needed
  3. Modern ID generation: Uses crypto.randomUUID() for unique filter identifiers
  4. Robust fallback: Creates new filter if existing one isn't found during update
  5. Return value: Returns filter ID for caller integration

The relative date conversion logic correctly transforms Parse Date objects to RelativeDate format with proper time calculations.


1283-1316: Solid implementation with good backward compatibility.

The deleteFilter method provides robust filter deletion with excellent fallback logic:

  1. Primary approach: Deletes by filter ID (modern, efficient)
  2. Fallback approach: Falls back to object comparison for backward compatibility
  3. Proper cleanup: Updates preferences and forces component update

The dual approach ensures compatibility with both new ID-based filters and legacy filter objects. Good to see the previous feedback about parameter naming was already addressed in commit 5128026.


2311-2311: LGTM: Proper prop connection for filter deletion.

The onDeleteFilter prop correctly connects the deleteFilter method to the DataBrowser component, enabling the filter deletion functionality in the UI.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jul 26, 2025
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

🔭 Outside diff range comments (1)
src/dashboard/Data/Browser/Browser.react.js (1)

1371-1392: Fix trailing spaces while maintaining good filterId preservation logic.

The filterId preservation in relation URLs follows the same pattern as updateFilters and works correctly. However, static analysis detected trailing spaces that should be removed.

Apply this diff to remove trailing spaces:

-        // Preserve filterId from current URL if it exists
+// Preserve filterId from current URL if it exists
-        const currentUrlParams = new URLSearchParams(window.location.search);
+const currentUrlParams = new URLSearchParams(window.location.search);
-        const currentFilterId = currentUrlParams.get('filterId');
+const currentFilterId = currentUrlParams.get('filterId');
-        
+
-          // Preserve filterId if it exists in current URL
+// Preserve filterId if it exists in current URL
-          
+
-        
+
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 96aa9f1 and 6711f52.

📒 Files selected for processing (1)
  • src/dashboard/Data/Browser/Browser.react.js (8 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/dashboard/Data/Browser/Browser.react.js (2)

Learnt from: mtrezza
PR: #2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the confirmExecuteScriptRows method in src/dashboard/Data/Browser/Browser.react.js), individual setState calls to update processedScripts counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.

Learnt from: mtrezza
PR: #2769
File: src/lib/ClassPreferences.js:26-26
Timestamp: 2025-05-02T11:55:52.809Z
Learning: Preference reads and writes in the ClassPreferences.js module are expected to be infrequent operations, so optimizing for performance (like caching) is unnecessary in this context.

🪛 Biome (2.1.2)
src/dashboard/Data/Browser/Browser.react.js

[error] 29-29: Do not shadow the global "Map" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🪛 GitHub Check: Lint
src/dashboard/Data/Browser/Browser.react.js

[failure] 1225-1225:
Trailing spaces not allowed


[failure] 1222-1222:
Trailing spaces not allowed


[failure] 1217-1217:
Trailing spaces not allowed


[failure] 1208-1208:
Trailing spaces not allowed


[failure] 1204-1204:
Trailing spaces not allowed


[failure] 1387-1387:
Trailing spaces not allowed


[failure] 1384-1384:
Trailing spaces not allowed


[failure] 1379-1379:
Trailing spaces not allowed


[failure] 1374-1374:
Trailing spaces not allowed

⏰ 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: Docker linux/amd64
🔇 Additional comments (6)
src/dashboard/Data/Browser/Browser.react.js (6)

8-44: Import reorganization looks good.

The new imports support the enhanced filter management functionality. The static analysis warning about shadowing the global "Map" property is a false positive - this is the standard way to import Immutable's Map, which is a different entity from the global Map constructor.


230-230: LGTM!

Standard method binding pattern for the new deleteFilter functionality.


527-547: Excellent enhancement for date handling in filters.

The date string conversion logic properly handles the serialization/deserialization of date filters in URL parameters. Converting string dates back to Parse Date objects ensures queries work correctly when filters are loaded from URLs.


1235-1300: Well-designed dual-purpose method for filter management.

The enhanced saveFilters method elegantly handles both creating new filters and updating existing ones. The relative date conversion logic is particularly valuable for maintaining time-based filters that should be dynamic. The use of crypto.randomUUID() and returning the filter ID enables proper integration with the UI.


1302-1335: Robust filter deletion with good backward compatibility.

The deleteFilter method implements a solid dual-approach strategy - primary deletion by ID with fallback to object comparison for backward compatibility. The implementation properly updates preferences and refreshes the component. I note that the parameter naming concern from previous reviews has been addressed.


2340-2340: LGTM!

Clean prop addition that enables filter deletion functionality in the DataBrowser component.

@mtrezza mtrezza merged commit daaccaa into parse-community:alpha Jul 26, 2025
10 of 11 checks passed
@mtrezza mtrezza deleted the feat/edit-saved-filter2 branch July 26, 2025 11:33
parseplatformorg pushed a commit that referenced this pull request Jul 26, 2025
# [7.3.0-alpha.31](7.3.0-alpha.30...7.3.0-alpha.31) (2025-07-26)

### Features

* Allow editing saved filters in data browser ([#2942](#2942)) ([daaccaa](daaccaa))
@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 7.3.0-alpha.31

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state:released-alpha Released as alpha version
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants