Add support for sorting saved searches & dashboards by favorite status#24809
Add support for sorting saved searches & dashboards by favorite status#24809dennisoelkers merged 7 commits intomasterfrom
Conversation
dennisoelkers
left a comment
There was a problem hiding this comment.
Looks good, just one suggestion for improvement.
| mongodb.mongoConnection() | ||
| .getMongoDatabase() | ||
| .getCollection("favorites") | ||
| .insertOne(new org.bson.Document() | ||
| .append("user_id", searchUser.getUser().getId()) | ||
| .append("items", java.util.List.of( | ||
| "grn::::search:" + view2.id(), | ||
| "grn::::search:" + view4.id() | ||
| ))); |
There was a problem hiding this comment.
We should replace this with using the FavoritesService to make sure we do not introduce potential drift for the underlying storage format.
There was a problem hiding this comment.
Since FavoriteService is protected, I cannot use it in the test. Instead, I use FavoritesForUserDTOto be as close as possible on the used StorageFormat.
There was a problem hiding this comment.
I would suggest you just make the constructor public or add a second, public one that is better suited for testing.
This change enables users to sort their saved searches by whether they are marked as favorites. The sorting works by leveraging the existing MongoDB aggregation pipeline that computes the favorite field at query time via a lookup join with the favorites collection. Changes: - Add FIELD_FAVORITE to ViewDTO.SORT_FIELDS to allow sorting by this field - Enable favorite sorting in SavedSearchesResource by removing sortable(false) - Update OpenAPI schema to include "favorite" in allowable sort values - Add integration test to verify favorite sorting works correctly in both ascending and descending order The implementation maintains the current architecture where favorites are stored in a separate collection, avoiding data duplication. The favorite field is computed dynamically during the query via MongoDB aggregation, then sorting is applied to the computed result. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Update the mock attributes in SavedSearchesModal.test.tsx to include the favorite attribute with sortable: true, reflecting the backend change that now allows sorting by favorite status. This ensures the test data matches the actual API response structure and validates that the favorite column is properly displayed and sortable in the saved searches list. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated searchPaginatedSortedByFavorite test to use FavoritesService.save() instead of directly inserting into the MongoDB favorites collection. This addresses review feedback to prevent potential drift in the storage format. Changes: - Added GRNExtension to provide GRNRegistry for test setup - Created FavoritesService using reflection to access protected constructor - Created proper test user with specific ID using TestUser.builder() - Use favoritesService.save() with FavoritesForUserDTO to create favorites - Create GRNs using grnRegistry.newGRN() for proper GRN format This ensures the test uses the same code path as production for creating favorites, maintaining consistency with the actual storage format. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
7f563f6 to
8c3925d
Compare
Replace reflection-based FavoritesService instantiation with direct
MongoCollection access to avoid forbidden API violation (setAccessible).
The test now uses mongoCollections.collection("favorites", FavoritesForUserDTO.class)
to insert favorites, which ensures proper serialization using the same
FavoritesForUserDTO structure as FavoritesService, preventing storage
format drift without violating forbidden API rules.
Changes:
- Removed reflection imports and reflection-based constructor access
- Use MongoCollection<FavoritesForUserDTO> from mongoCollections
- Create and insert FavoritesForUserDTO directly using insertOne()
- Added comment explaining this uses the same structure as FavoritesService
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR adds the ability to sort saved searches and dashboards by their favorite status, allowing users to quickly view their favorited items first or last based on sort order.
Changes:
- Added "favorite" to the list of sortable fields in the backend API and data model
- Updated frontend test fixtures to include the favorite column as sortable
- Added comprehensive integration tests to verify sorting by favorite status works correctly
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| ViewDTO.java | Added FIELD_FAVORITE to the SORT_FIELDS set to enable sorting by favorite status |
| SavedSearchesResource.java | Removed sortable(false) restriction and added "favorite" to API schema's allowable sort values |
| DashboardsResource.java | Changed sortable(false) to sortable(true) for favorite field and added "favorite" to allowable sort values; also made attributes list final |
| ViewServiceTest.java | Added integration test searchPaginatedSortedByFavorite() validating sort functionality with MongoDB aggregation |
| SavedSearchesModal.test.tsx | Updated test fixture to include favorite as a sortable column |
| issue-21659.toml | Added changelog entry documenting the new feature |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
dennisoelkers
left a comment
There was a problem hiding this comment.
Looks good, works fine!
#24809) * Add support for sorting saved searches by favorite status This change enables users to sort their saved searches by whether they are marked as favorites. The sorting works by leveraging the existing MongoDB aggregation pipeline that computes the favorite field at query time via a lookup join with the favorites collection. Changes: - Add FIELD_FAVORITE to ViewDTO.SORT_FIELDS to allow sorting by this field - Enable favorite sorting in SavedSearchesResource by removing sortable(false) - Update OpenAPI schema to include "favorite" in allowable sort values - Add integration test to verify favorite sorting works correctly in both ascending and descending order The implementation maintains the current architecture where favorites are stored in a separate collection, avoiding data duplication. The favorite field is computed dynamically during the query via MongoDB aggregation, then sorting is applied to the computed result. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Update saved searches test to include sortable favorite attribute Update the mock attributes in SavedSearchesModal.test.tsx to include the favorite attribute with sortable: true, reflecting the backend change that now allows sorting by favorite status. This ensures the test data matches the actual API response structure and validates that the favorite column is properly displayed and sortable in the saved searches list. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Use FavoritesService instead of direct MongoDB insert in test Updated searchPaginatedSortedByFavorite test to use FavoritesService.save() instead of directly inserting into the MongoDB favorites collection. This addresses review feedback to prevent potential drift in the storage format. Changes: - Added GRNExtension to provide GRNRegistry for test setup - Created FavoritesService using reflection to access protected constructor - Created proper test user with specific ID using TestUser.builder() - Use favoritesService.save() with FavoritesForUserDTO to create favorites - Create GRNs using grnRegistry.newGRN() for proper GRN format This ensures the test uses the same code path as production for creating favorites, maintaining consistency with the actual storage format. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Add changelog entry for favorite sorting feature Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Fix forbidden API violation by using MongoCollection directly Replace reflection-based FavoritesService instantiation with direct MongoCollection access to avoid forbidden API violation (setAccessible). The test now uses mongoCollections.collection("favorites", FavoritesForUserDTO.class) to insert favorites, which ensures proper serialization using the same FavoritesForUserDTO structure as FavoritesService, preventing storage format drift without violating forbidden API rules. Changes: - Removed reflection imports and reflection-based constructor access - Use MongoCollection<FavoritesForUserDTO> from mongoCollections - Create and insert FavoritesForUserDTO directly using insertOne() - Added comment explaining this uses the same structure as FavoritesService Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Enabling sort by favorite for dashboards as well. * Updating changelog snippet. --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Dennis Oelkers <dennis@graylog.com>
#24809) * Add support for sorting saved searches by favorite status This change enables users to sort their saved searches by whether they are marked as favorites. The sorting works by leveraging the existing MongoDB aggregation pipeline that computes the favorite field at query time via a lookup join with the favorites collection. Changes: - Add FIELD_FAVORITE to ViewDTO.SORT_FIELDS to allow sorting by this field - Enable favorite sorting in SavedSearchesResource by removing sortable(false) - Update OpenAPI schema to include "favorite" in allowable sort values - Add integration test to verify favorite sorting works correctly in both ascending and descending order The implementation maintains the current architecture where favorites are stored in a separate collection, avoiding data duplication. The favorite field is computed dynamically during the query via MongoDB aggregation, then sorting is applied to the computed result. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Update saved searches test to include sortable favorite attribute Update the mock attributes in SavedSearchesModal.test.tsx to include the favorite attribute with sortable: true, reflecting the backend change that now allows sorting by favorite status. This ensures the test data matches the actual API response structure and validates that the favorite column is properly displayed and sortable in the saved searches list. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Use FavoritesService instead of direct MongoDB insert in test Updated searchPaginatedSortedByFavorite test to use FavoritesService.save() instead of directly inserting into the MongoDB favorites collection. This addresses review feedback to prevent potential drift in the storage format. Changes: - Added GRNExtension to provide GRNRegistry for test setup - Created FavoritesService using reflection to access protected constructor - Created proper test user with specific ID using TestUser.builder() - Use favoritesService.save() with FavoritesForUserDTO to create favorites - Create GRNs using grnRegistry.newGRN() for proper GRN format This ensures the test uses the same code path as production for creating favorites, maintaining consistency with the actual storage format. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Add changelog entry for favorite sorting feature Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Fix forbidden API violation by using MongoCollection directly Replace reflection-based FavoritesService instantiation with direct MongoCollection access to avoid forbidden API violation (setAccessible). The test now uses mongoCollections.collection("favorites", FavoritesForUserDTO.class) to insert favorites, which ensures proper serialization using the same FavoritesForUserDTO structure as FavoritesService, preventing storage format drift without violating forbidden API rules. Changes: - Removed reflection imports and reflection-based constructor access - Use MongoCollection<FavoritesForUserDTO> from mongoCollections - Create and insert FavoritesForUserDTO directly using insertOne() - Added comment explaining this uses the same structure as FavoritesService Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Enabling sort by favorite for dashboards as well. * Updating changelog snippet. --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Dennis Oelkers <dennis@graylog.com>
#24809) * Add support for sorting saved searches by favorite status This change enables users to sort their saved searches by whether they are marked as favorites. The sorting works by leveraging the existing MongoDB aggregation pipeline that computes the favorite field at query time via a lookup join with the favorites collection. Changes: - Add FIELD_FAVORITE to ViewDTO.SORT_FIELDS to allow sorting by this field - Enable favorite sorting in SavedSearchesResource by removing sortable(false) - Update OpenAPI schema to include "favorite" in allowable sort values - Add integration test to verify favorite sorting works correctly in both ascending and descending order The implementation maintains the current architecture where favorites are stored in a separate collection, avoiding data duplication. The favorite field is computed dynamically during the query via MongoDB aggregation, then sorting is applied to the computed result. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Update saved searches test to include sortable favorite attribute Update the mock attributes in SavedSearchesModal.test.tsx to include the favorite attribute with sortable: true, reflecting the backend change that now allows sorting by favorite status. This ensures the test data matches the actual API response structure and validates that the favorite column is properly displayed and sortable in the saved searches list. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Use FavoritesService instead of direct MongoDB insert in test Updated searchPaginatedSortedByFavorite test to use FavoritesService.save() instead of directly inserting into the MongoDB favorites collection. This addresses review feedback to prevent potential drift in the storage format. Changes: - Added GRNExtension to provide GRNRegistry for test setup - Created FavoritesService using reflection to access protected constructor - Created proper test user with specific ID using TestUser.builder() - Use favoritesService.save() with FavoritesForUserDTO to create favorites - Create GRNs using grnRegistry.newGRN() for proper GRN format This ensures the test uses the same code path as production for creating favorites, maintaining consistency with the actual storage format. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Add changelog entry for favorite sorting feature Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Fix forbidden API violation by using MongoCollection directly Replace reflection-based FavoritesService instantiation with direct MongoCollection access to avoid forbidden API violation (setAccessible). The test now uses mongoCollections.collection("favorites", FavoritesForUserDTO.class) to insert favorites, which ensures proper serialization using the same FavoritesForUserDTO structure as FavoritesService, preventing storage format drift without violating forbidden API rules. Changes: - Removed reflection imports and reflection-based constructor access - Use MongoCollection<FavoritesForUserDTO> from mongoCollections - Create and insert FavoritesForUserDTO directly using insertOne() - Added comment explaining this uses the same structure as FavoritesService Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Enabling sort by favorite for dashboards as well. * Updating changelog snippet. --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Dennis Oelkers <dennis@graylog.com>
…rite status (7.0) (#24847) * Add support for sorting saved searches & dashboards by favorite status (#24809) * Add support for sorting saved searches by favorite status This change enables users to sort their saved searches by whether they are marked as favorites. The sorting works by leveraging the existing MongoDB aggregation pipeline that computes the favorite field at query time via a lookup join with the favorites collection. Changes: - Add FIELD_FAVORITE to ViewDTO.SORT_FIELDS to allow sorting by this field - Enable favorite sorting in SavedSearchesResource by removing sortable(false) - Update OpenAPI schema to include "favorite" in allowable sort values - Add integration test to verify favorite sorting works correctly in both ascending and descending order The implementation maintains the current architecture where favorites are stored in a separate collection, avoiding data duplication. The favorite field is computed dynamically during the query via MongoDB aggregation, then sorting is applied to the computed result. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Update saved searches test to include sortable favorite attribute Update the mock attributes in SavedSearchesModal.test.tsx to include the favorite attribute with sortable: true, reflecting the backend change that now allows sorting by favorite status. This ensures the test data matches the actual API response structure and validates that the favorite column is properly displayed and sortable in the saved searches list. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Use FavoritesService instead of direct MongoDB insert in test Updated searchPaginatedSortedByFavorite test to use FavoritesService.save() instead of directly inserting into the MongoDB favorites collection. This addresses review feedback to prevent potential drift in the storage format. Changes: - Added GRNExtension to provide GRNRegistry for test setup - Created FavoritesService using reflection to access protected constructor - Created proper test user with specific ID using TestUser.builder() - Use favoritesService.save() with FavoritesForUserDTO to create favorites - Create GRNs using grnRegistry.newGRN() for proper GRN format This ensures the test uses the same code path as production for creating favorites, maintaining consistency with the actual storage format. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Add changelog entry for favorite sorting feature Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Fix forbidden API violation by using MongoCollection directly Replace reflection-based FavoritesService instantiation with direct MongoCollection access to avoid forbidden API violation (setAccessible). The test now uses mongoCollections.collection("favorites", FavoritesForUserDTO.class) to insert favorites, which ensures proper serialization using the same FavoritesForUserDTO structure as FavoritesService, preventing storage format drift without violating forbidden API rules. Changes: - Removed reflection imports and reflection-based constructor access - Use MongoCollection<FavoritesForUserDTO> from mongoCollections - Create and insert FavoritesForUserDTO directly using insertOne() - Added comment explaining this uses the same structure as FavoritesService Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Enabling sort by favorite for dashboards as well. * Updating changelog snippet. --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Dennis Oelkers <dennis@graylog.com> * Enable sorting in the SavedSearchesResource --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Dennis Oelkers <dennis@graylog.com>
…rite status (7.0) (#24847) * Add support for sorting saved searches & dashboards by favorite status (#24809) * Add support for sorting saved searches by favorite status This change enables users to sort their saved searches by whether they are marked as favorites. The sorting works by leveraging the existing MongoDB aggregation pipeline that computes the favorite field at query time via a lookup join with the favorites collection. Changes: - Add FIELD_FAVORITE to ViewDTO.SORT_FIELDS to allow sorting by this field - Enable favorite sorting in SavedSearchesResource by removing sortable(false) - Update OpenAPI schema to include "favorite" in allowable sort values - Add integration test to verify favorite sorting works correctly in both ascending and descending order The implementation maintains the current architecture where favorites are stored in a separate collection, avoiding data duplication. The favorite field is computed dynamically during the query via MongoDB aggregation, then sorting is applied to the computed result. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Update saved searches test to include sortable favorite attribute Update the mock attributes in SavedSearchesModal.test.tsx to include the favorite attribute with sortable: true, reflecting the backend change that now allows sorting by favorite status. This ensures the test data matches the actual API response structure and validates that the favorite column is properly displayed and sortable in the saved searches list. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Use FavoritesService instead of direct MongoDB insert in test Updated searchPaginatedSortedByFavorite test to use FavoritesService.save() instead of directly inserting into the MongoDB favorites collection. This addresses review feedback to prevent potential drift in the storage format. Changes: - Added GRNExtension to provide GRNRegistry for test setup - Created FavoritesService using reflection to access protected constructor - Created proper test user with specific ID using TestUser.builder() - Use favoritesService.save() with FavoritesForUserDTO to create favorites - Create GRNs using grnRegistry.newGRN() for proper GRN format This ensures the test uses the same code path as production for creating favorites, maintaining consistency with the actual storage format. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Add changelog entry for favorite sorting feature Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Fix forbidden API violation by using MongoCollection directly Replace reflection-based FavoritesService instantiation with direct MongoCollection access to avoid forbidden API violation (setAccessible). The test now uses mongoCollections.collection("favorites", FavoritesForUserDTO.class) to insert favorites, which ensures proper serialization using the same FavoritesForUserDTO structure as FavoritesService, preventing storage format drift without violating forbidden API rules. Changes: - Removed reflection imports and reflection-based constructor access - Use MongoCollection<FavoritesForUserDTO> from mongoCollections - Create and insert FavoritesForUserDTO directly using insertOne() - Added comment explaining this uses the same structure as FavoritesService Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Enabling sort by favorite for dashboards as well. * Updating changelog snippet. --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Dennis Oelkers <dennis@graylog.com> * Enable sorting in the SavedSearchesResource --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Dennis Oelkers <dennis@graylog.com>
…rite status (7.0) (#24847) (#24913) * Add support for sorting saved searches & dashboards by favorite status (#24809) * Add support for sorting saved searches by favorite status This change enables users to sort their saved searches by whether they are marked as favorites. The sorting works by leveraging the existing MongoDB aggregation pipeline that computes the favorite field at query time via a lookup join with the favorites collection. Changes: - Add FIELD_FAVORITE to ViewDTO.SORT_FIELDS to allow sorting by this field - Enable favorite sorting in SavedSearchesResource by removing sortable(false) - Update OpenAPI schema to include "favorite" in allowable sort values - Add integration test to verify favorite sorting works correctly in both ascending and descending order The implementation maintains the current architecture where favorites are stored in a separate collection, avoiding data duplication. The favorite field is computed dynamically during the query via MongoDB aggregation, then sorting is applied to the computed result. * Update saved searches test to include sortable favorite attribute Update the mock attributes in SavedSearchesModal.test.tsx to include the favorite attribute with sortable: true, reflecting the backend change that now allows sorting by favorite status. This ensures the test data matches the actual API response structure and validates that the favorite column is properly displayed and sortable in the saved searches list. * Use FavoritesService instead of direct MongoDB insert in test Updated searchPaginatedSortedByFavorite test to use FavoritesService.save() instead of directly inserting into the MongoDB favorites collection. This addresses review feedback to prevent potential drift in the storage format. Changes: - Added GRNExtension to provide GRNRegistry for test setup - Created FavoritesService using reflection to access protected constructor - Created proper test user with specific ID using TestUser.builder() - Use favoritesService.save() with FavoritesForUserDTO to create favorites - Create GRNs using grnRegistry.newGRN() for proper GRN format This ensures the test uses the same code path as production for creating favorites, maintaining consistency with the actual storage format. * Add changelog entry for favorite sorting feature * Fix forbidden API violation by using MongoCollection directly Replace reflection-based FavoritesService instantiation with direct MongoCollection access to avoid forbidden API violation (setAccessible). The test now uses mongoCollections.collection("favorites", FavoritesForUserDTO.class) to insert favorites, which ensures proper serialization using the same FavoritesForUserDTO structure as FavoritesService, preventing storage format drift without violating forbidden API rules. Changes: - Removed reflection imports and reflection-based constructor access - Use MongoCollection<FavoritesForUserDTO> from mongoCollections - Create and insert FavoritesForUserDTO directly using insertOne() - Added comment explaining this uses the same structure as FavoritesService * Enabling sort by favorite for dashboards as well. * Updating changelog snippet. --------- * Enable sorting in the SavedSearchesResource --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Dennis Oelkers <dennis@graylog.com>
Description
This PR enables users to sort their saved searches & dashboards by whether they are marked as favorites. Users can now click on the "Favorite" column header in the saved searches/dashboards list to toggle between:
The implementation leverages the existing MongoDB aggregation pipeline that computes the favorite field at query time via a lookup join with the favorites collection, avoiding data duplication.
Motivation and Context
Users requested the ability to sort saved searches/dashboards by favorite status to quickly access their most important searches. Previously, the favorite field was displayed in the table but could not be used for sorting, requiring users to manually scan through the list to find their favorite searches.
How Has This Been Tested?
Backend testing:
ViewServiceTest.searchPaginatedSortedByFavorite()Types of changes
Checklist: