Skip to content

A bunch of different tasks related to the admin page#1557

Open
Michael-Kolpakov wants to merge 5 commits into
release/1.2.3from
feature/issue-2344
Open

A bunch of different tasks related to the admin page#1557
Michael-Kolpakov wants to merge 5 commits into
release/1.2.3from
feature/issue-2344

Conversation

@Michael-Kolpakov

@Michael-Kolpakov Michael-Kolpakov commented Mar 17, 2025

Copy link
Copy Markdown
Contributor

Ticket

❗❗❗ATTENTION: related PR on the backend. Make sure to merge them together.❗❗❗

Code reviewers

Summary of issue

  1. Duplicate requests on the admin page.
  2. Problems with disappearing images in the 'Партнери' section of the admin page.
  3. Problems with tag record not disappearing after deleting it from table.
  4. Pagination disappears after navigating past page 5 in the dictionary

Summary of change

  1. Both the frontend and backend codebases have been updated to eliminate unnecessary duplicate requests from the client to the server.
  2. Now all the necessary fields are pulled from the server and the pictures in the 'Партнери' section no longer disappear.
  3. Now the frontend correctly interacts with the tag storage and they are correctly displayed in the table.
  4. The pagination was redesigned to match the rest of the admin part of the website and there are no more problems interacting with it.

CHECK LIST

  • СI passed
  • Сode coverage >=95%
  • PR is reviewed manually again (to make sure you have 100% ready code)
  • All reviewers agreed to merge the PR
  • I've checked new feature as logged in and logged out user if needed
  • PR meets all conventions

Summary by CodeRabbit

  • New Features

    • Added pagination support with summary data for listings.
    • Enabled automatic UI refresh after submitting updates in admin panels.
  • Refactor

    • Optimized data fetching throughout the application to reduce unnecessary updates and improve responsiveness.
    • Streamlined conditional API calls for enhanced performance in key UI areas.
  • Style

    • Made minor formatting and layout adjustments to improve table readability and modal consistency across the interface.

@Michael-Kolpakov

Copy link
Copy Markdown
Contributor Author

@coderabbitai ignore

@coderabbitai

coderabbitai Bot commented Mar 17, 2025

Copy link
Copy Markdown
Contributor

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Walkthrough

This pull request implements several enhancements across the codebase. API methods for streetcodes and terms now support pagination and return enriched objects. Data fetching in modals and pages has been refactored to use the useQuery hook with a refetch callback, replacing previous useEffect approaches. State stores have been updated to improve data management, including shifting from array-based storage to maps and adding pagination controls. Several modal components now accept an afterSubmit prop to trigger data refreshes, and minor formatting updates have been applied across multiple components.

Changes

Files Change Summary
src/app/api/streetcode/.../streetcodes.api.ts, src/app/api/streetcode/text-content/terms.api.ts Updated API methods to support optional page/pageSize parameters; changed return types to include totalAmount alongside data arrays; removed unused imports.
src/app/common/components/modals/HeaderLogin/...HeaderLoginModal.component.tsx, src/app/layout/footer/Footer.component.tsx Modified active job fetching: added conditional checks and replaced direct API calls with useQuery to manage async state and caching.
src/app/stores/news-store/news-store.ts, src/app/stores/streetcodeshort-store.ts, src/app/stores/tags-store.ts, src/app/stores/term-store.ts Refactored store methods: removed extra API chaining, migrated streetcodes storage from array to Map, introduced pagination properties/methods, and updated deletion targets.
src/features/AdminPage/CategoriesPage/..., src/features/AdminPage/ContextPage/..., src/features/AdminPage/JobsPage/..., src/features/AdminPage/NewsPage/... Streamlined data fetching and control flow: removed useEffect hooks, integrated refetch from useQuery, and added afterSubmit callbacks to modals to trigger fresh data on submissions.
src/features/AdminPage/PartnersPage/..., src/features/AdminPage/TagsPage/..., src/features/AdminPage/TeamPage/..., src/features/AdminPage/TeamPositionsPage/... Updated modal interactions and UI logic: corrected naming conventions, improved streetcode selection, and consistently added afterSubmit props for post-action data refresh.
src/features/AdminPage/NewStreetcode/.../TextEditor.component.tsx, src/features/AdminPage/TermDictionary/TermDictionary.component.tsx, src/features/AdminPage/TermDictionary/TermDictionary.styles.scss Enhanced term management: replaced useEffect-based fetching with useQuery, added pagination to tables, updated term fetching method, and introduced a new CSS class for layout spacing.
src/components/modals/validators/combinedImageValidator.ts Introduced new validator functions for combined image checks and file validation to support updated partner modal logic.

Sequence Diagram(s)

sequenceDiagram
  participant U as User
  participant M as Modal Component
  participant API as API Service
  participant P as Parent Component

  U->>M: Submit form data
  M->>API: Call create/update endpoint
  API-->>M: Return success response
  M->>M: Invoke afterSubmit callback (if provided)
  M->>P: Trigger refetch of data
  P-->>U: Render updated UI
Loading

Suggested reviewers

  • vlad-zhadan
  • YuliiaAndreieva
  • ilko-dev
  • YaroslavRosnovskyi

Poem

In lines of code our changes gleam,
With modals refined and data supreme,
API calls now smartly delay,
And stores manage state in a brand new way.
Cheers to clean code and progress on stream!


🪧 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.
  • @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.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (2)
src/app/stores/tags-store.ts (1)

131-138: ⚠️ Potential issue

Fixed tag deletion by targeting the correct map.

This change corrects which map we're deleting tags from - now removing from AllTagsMap instead of TagMap. This directly addresses the issue mentioned in the PR objectives where "tag records not disappearing after deletion" by ensuring tags are properly removed from the data structure that drives the UI.

Let's verify this change fixes the issue by checking where AllTagsMap is used for rendering:

#!/bin/bash
# Check where AllTagsMap values are used in components
rg "AllTagsMap|getAllTagsArray" -A 3 -B 3 --type=tsx
src/features/AdminPage/TermDictionary/TermDictionary.component.tsx (1)

31-43: 🛠️ Refactor suggestion

Use consistent async/await
Here, termsStore.createTerm(newTerm) is called in a .then() chain, then you await refetch(). Consider a fully async/await style for improved readability and error handling.

- termsStore.createTerm(newTerm).then((response) => {
-   setData([...data || [], response ?? newTerm]);
-   setTerm({ title: '', description: '' });
- });
- await refetch();
+ try {
+   const response = await termsStore.createTerm(newTerm);
+   setData([...data || [], response ?? newTerm]);
+   setTerm({ title: '', description: '' });
+   await refetch();
+ } catch (error) {
+   // handle or log error
+ }
🧹 Nitpick comments (12)
src/app/layout/footer/Footer.component.tsx (1)

32-36: Improved dependency handling in useEffect

The useEffect now correctly depends on the data variable and handles the possibility of undefined data. This is more robust than the previous implementation.

However, consider adding error handling to address potential API failures:

-const { data } = useQuery({
+const { data, isError, error } = useQuery({
     queryKey: ['jobsActive'],
     queryFn: () => JobApi.getActive(),
 });

 useEffect(() => {
+    if (isError) {
+        console.error('Failed to fetch job data:', error);
+    }
     if (data) {
         setHasVacancies(data.length > 0);
     }
-}, [data]);
+}, [data, isError, error]);
src/app/common/components/modals/HeaderLogin/HeaderLoginModal.component.tsx (1)

29-37: Improved optimization with conditional API call

Great improvement! Conditionally fetching data only when the modal is open reduces unnecessary network requests and improves application performance.

For consistency with the Footer component, consider refactoring this to use React Query:

+import { useQuery } from '@tanstack/react-query';

// In the component:
+const { data } = useQuery({
+    queryKey: ['jobsActive'],
+    queryFn: () => JobApi.getActive(),
+    enabled: login.isOpen, // Only fetch when modal is open
+});
+
+useEffect(() => {
+    if (data) {
+        setHasVacancies(data.length > 0);
+    }
+}, [data]);

-useEffect(() => {
-    if (login.isOpen) {
-        JobApi.getActive()
-            .then((result) => {
-                setHasVacancies(result.length > 0);
-            })
-            .catch((error) => {
-                console.error(error);
-            });
-    }
-}, [login.isOpen]);

This would bring several benefits:

  • Consistent data fetching pattern across components
  • Automatic caching and request deduplication
  • Better error and loading state management
src/features/AdminPage/TermDictionary/TermDictionary.component.tsx (2)

26-29: Consider handling Query errors
You may want to handle potential query errors using onError or an error boundary. This would improve resilience if the fetch fails.


46-57: Harmonize edit logic with add
Likewise, unify your async/await usage in handleEdit for better consistency and clear error-handling paths.

src/features/AdminPage/NewsPage/News.component.tsx (2)

33-33: Pagination dependency
The query key includes newsStore.CurrentPage. If page sizes can vary, consider adding it to the key as well. Otherwise, all good.


40-46: Chained news & image deletion
Cascading deletion helps maintain data consistency. Be sure to handle partial failures—e.g., if deleting the image fails, you might want to revert the news deletion or alert the user.

src/features/AdminPage/PartnersPage/Partners.component.tsx (3)

37-40: Consider adding error handling in your query.
While refetch is used to manually refresh data, errors might occur during fetching. You could add an onError callback in useQuery or catch errors to display them in the UI or log them more visibly.

-const { isLoading: isLoadingPartners, refetch: refetchPartners } = useQuery({
-    queryKey: ['partners', partnersStore.PaginationInfo.CurrentPage],
-    queryFn: () => partnersStore.getAll(),
-});
+const { isLoading: isLoadingPartners, refetch: refetchPartners, error } = useQuery({
+    queryKey: ['partners', partnersStore.PaginationInfo.CurrentPage],
+    queryFn: () => partnersStore.getAll(),
+    onError: (err) => {
+        console.error('Error fetching partners:', err);
+    },
+});

42-45: Likewise, handle possible errors in streetcode data retrieval.
Providing an onError callback or similar mechanism helps prevent silent failures and improves user experience.

-const { isLoading: isLoadingStreetcodesShort, refetch: refetchStreetcodesShort } = useQuery({
-    queryKey: ['streetcodesShort', streetcodeShortStore.PaginationInfo.CurrentPage],
-    queryFn: () => streetcodeShortStore.fetchStreetcodesAll(),
-});
+const { isLoading: isLoadingStreetcodesShort, refetch: refetchStreetcodesShort, error } = useQuery({
+    queryKey: ['streetcodesShort', streetcodeShortStore.PaginationInfo.CurrentPage],
+    queryFn: () => streetcodeShortStore.fetchStreetcodesAll(),
+    onError: (err) => {
+        console.error('Error fetching streetcodes:', err);
+    },
+});

83-90: Open external links cautiously.
Consider adding target="_blank" and rel="noopener noreferrer" when linking to external URLs to enhance security and prevent potential issues with external scripts.

<a
    className="site-link"
-   key={`${targetUrl.href}`}
-   href={targetUrl.href}
+   key={targetUrl.href}
+   href={targetUrl.href}
+   target="_blank"
+   rel="noopener noreferrer"
>
    {targetUrl.title ?? targetUrl.href}
</a>
src/features/AdminPage/TeamPage/TeamPage.component.tsx (2)

31-34: Use of refetch is appropriate.
You can consider adding onError to handle potential fetch failures, ensuring robust error feedback.


40-46: Enhance error handling.
Currently, errors are only logged to console.error. Consider showing a user-friendly notification or message if deletion fails, to improve clarity.

src/app/stores/streetcodeshort-store.ts (1)

45-51: Consider adding await or returning a promise.
fetchStreetcodesAll is declared async, but relies on .then(). Either remove async or use await for clarity. Also, you might expose any errors to the UI rather than just logging them.

-public fetchStreetcodesAll = async (pageSize?: number) => {
-    StreetcodesApi.getAllShort(…)
-        .then((response) => {
-
-        })
-        .catch((error) => console.error(error));
-};
+public fetchStreetcodesAll = async (pageSize?: number): Promise<void> => {
+    try {
+        const response = await StreetcodesApi.getAllShort(
+            this.PaginationInfo.CurrentPage,
+            pageSize ?? this.paginationInfo.PageSize,
+        );
+        this.paginationInfo.TotalItems = response.totalAmount;
+        this.setInternalMap(response.streetcodesShort);
+    } catch (error) {
+        console.error(error);
+    }
+};
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8dea32a and 4ac1794.

📒 Files selected for processing (28)
  • src/app/api/streetcode/streetcodes.api.ts (2 hunks)
  • src/app/api/streetcode/text-content/terms.api.ts (1 hunks)
  • src/app/common/components/modals/HeaderLogin/HeaderLoginModal.component.tsx (1 hunks)
  • src/app/layout/footer/Footer.component.tsx (2 hunks)
  • src/app/stores/news-store/news-store.ts (1 hunks)
  • src/app/stores/streetcodeshort-store.ts (1 hunks)
  • src/app/stores/tags-store.ts (1 hunks)
  • src/app/stores/term-store.ts (2 hunks)
  • src/features/AdminPage/CategoriesPage/CategoriesPage.component.tsx (4 hunks)
  • src/features/AdminPage/CategoriesPage/CategoriesPage/CategoryAdminModal.component.tsx (2 hunks)
  • src/features/AdminPage/ContextPage/ContextMainPage.component.tsx (3 hunks)
  • src/features/AdminPage/ContextPage/ContextModal/ContextAdminModal.component.tsx (8 hunks)
  • src/features/AdminPage/JobsPage/JobsModal/JobsModal.component.tsx (4 hunks)
  • src/features/AdminPage/JobsPage/JobsTable/JobsTable.component.tsx (4 hunks)
  • src/features/AdminPage/NewStreetcode/TextBlock/TextForm/Editors/TextEditor.component.tsx (2 hunks)
  • src/features/AdminPage/NewsPage/News.component.tsx (6 hunks)
  • src/features/AdminPage/NewsPage/NewsModal/NewsModal.component.tsx (6 hunks)
  • src/features/AdminPage/PartnersPage/PartnerModal/PartnerModal.component.tsx (7 hunks)
  • src/features/AdminPage/PartnersPage/Partners.component.tsx (5 hunks)
  • src/features/AdminPage/StreetcodesTable/StreetcodesTable.component.tsx (1 hunks)
  • src/features/AdminPage/TagsPage/TagsMainPage.component.tsx (5 hunks)
  • src/features/AdminPage/TagsPage/TagsPage/TagAdminModal.tsx (3 hunks)
  • src/features/AdminPage/TeamPage/TeamModal/TeamModal.component.tsx (2 hunks)
  • src/features/AdminPage/TeamPage/TeamPage.component.tsx (4 hunks)
  • src/features/AdminPage/TeamPositionsPage/TeamPositionsMainPage.component.tsx (3 hunks)
  • src/features/AdminPage/TeamPositionsPage/TeamPositionsModal/TeamPositionsAdminModal.component.tsx (5 hunks)
  • src/features/AdminPage/TermDictionary/TermDictionary.component.tsx (5 hunks)
  • src/features/AdminPage/TermDictionary/TermDictionary.styles.scss (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Jenkins
🔇 Additional comments (102)
src/app/layout/footer/Footer.component.tsx (2)

14-14: Well-chosen library for data fetching

Adding React Query is a great enhancement for managing API requests. This library provides caching, automatic retries, and better state management.


27-30: Great implementation of useQuery

The implementation with a descriptive query key and reuse of the existing API method is clean and follows best practices. This will help with automatic caching and request deduplication.

src/features/AdminPage/TermDictionary/TermDictionary.styles.scss (1)

86-88: Consistent spacing added for underTable elements.

The new .underTableElement class with padding-bottom: 10px provides consistent spacing for elements beneath tables, improving the interface's visual consistency. This likely addresses pagination styling in the dictionary section.

src/features/AdminPage/StreetcodesTable/StreetcodesTable.component.tsx (1)

298-311: Improved switch statement formatting for better readability.

The reformatted switch-case statement follows a more consistent coding style with proper indentation and line breaks. This enhances code readability without changing functionality, making future maintenance easier.

src/features/AdminPage/NewStreetcode/TextBlock/TextForm/Editors/TextEditor.component.tsx (2)

34-34: Updated method reference to use the new pagination-aware API.

Changed destructured method from likely fetchTerms to getAll, aligning with the updated TermsStore API that now supports pagination.


94-94: Updated terms fetch method in useAsync hook.

The useAsync hook now calls getAll instead of the previous fetchTerms method, completing the refactoring to use the updated pagination-aware API. This change helps reduce duplicate requests as mentioned in the PR objectives.

src/features/AdminPage/NewsPage/NewsModal/NewsModal.component.tsx (3)

237-240: Great improvement: Added braces to if block assignment

Adding curly braces around the assignment in the if statement improves code readability and reduces potential bugs if more statements are added in the future.


254-258: Good implementation of the afterSubmit pattern

Using the afterSubmit callback to trigger data refreshes is a great pattern. This ensures parent components can refresh their data after successful form submissions.


424-429: Nice code formatting improvement

The DatePicker component properties are now properly formatted with one property per line, which enhances readability and follows consistent coding patterns.

src/features/AdminPage/CategoriesPage/CategoriesPage/CategoryAdminModal.component.tsx (2)

36-37: Great addition: afterSubmit callback property

Adding the afterSubmit callback to the interface allows parent components to execute code after successful form submission, following React best practices for component communication.


127-130: Well-implemented callback execution

The implementation correctly checks if the afterSubmit callback exists before calling it, preventing potential null reference errors. This pattern matches similar implementations throughout the codebase.

src/app/api/streetcode/text-content/terms.api.ts (1)

10-20: Excellent pagination implementation

The updated getAll method now properly supports pagination with optional page and pageSize parameters. The implementation correctly:

  1. Handles optional parameters
  2. Builds query parameters efficiently
  3. Returns a structured response with totalAmount and the terms array

This change aligns with the PR objective to fix pagination issues in the dictionary.

src/features/AdminPage/ContextPage/ContextModal/ContextAdminModal.component.tsx (4)

24-25: Good addition: afterSubmit callback property

Adding the afterSubmit callback to the interface maintains consistency with other modal components and enables proper data refreshing after form submission.


66-69: Performance optimization: Skip redundant updates

Adding an early return when the context title hasn't changed prevents unnecessary API calls, improving application performance. This is a good optimization.


80-83: Well-implemented callback execution

The implementation correctly checks if the afterSubmit callback exists before calling it, maintaining consistent patterns across modal components.


111-152: Improved button state management

The save button is now properly disabled based on form state changes through the handleInputChange function and state updates. This improves user experience by preventing invalid form submissions.

src/app/stores/news-store/news-store.ts (2)

104-108: Refactored store method to delegate refresh responsibility

The removal of automatic data refresh after creation is a good refactoring decision. This change aligns with the new pattern of using the afterSubmit prop and refetch callback in modal components, creating a more consistent approach to data refreshing across the application.


110-114: Refactored update method following the same pattern

Similarly to the create method, removing the automatic refresh here is appropriate. This change moves the responsibility for refreshing data to the component that initiated the update, which is a cleaner separation of concerns.

src/features/AdminPage/CategoriesPage/CategoriesPage.component.tsx (4)

4-4: Simplified imports by removing unused useEffect

Removing the unused useEffect import helps keep the code clean and focused. This is a good practice.


27-30: Enhanced useQuery implementation to expose refetch capability

Excellent improvement to destructure the refetch function from useQuery. This allows for manual data refreshing after operations, which is exactly what's needed for the new pattern being implemented.


151-155: Added afterSubmit prop to refresh data after modal submission

Good implementation of the afterSubmit pattern for the add modal. This ensures that newly added categories are immediately reflected in the UI without requiring a page refresh.


156-161: Applied the same afterSubmit pattern to the edit modal

Consistent implementation of the afterSubmit pattern for the edit modal. This maintains a uniform approach to data refreshing across different operations.

src/features/AdminPage/TeamPage/TeamModal/TeamModal.component.tsx (2)

37-47: Improved code formatting for better readability

The reformatting of props declaration and destructuring enhances readability and maintainability. Each prop is now on its own line, making it easier to track changes in version control and understand the component's interface.


242-246: Added proper handling of afterSubmit callback

Good implementation of the afterSubmit pattern with appropriate null/undefined check. The added blank line also improves code readability by visually separating the callback from the success state update.

src/features/AdminPage/JobsPage/JobsModal/JobsModal.component.tsx (5)

7-7: Repositioned import for better organization

Moving the BUTTON_LABELS import is a minor but good change for maintainability, as it keeps related imports grouped together.


26-27: Added afterSubmit prop to support the new data refresh pattern

Good addition of the optional afterSubmit callback to the Props interface. This maintains consistency with the pattern being implemented across the application.


29-34: Improved code formatting for better readability

The reformatting of the function parameter destructuring enhances readability by placing each prop on its own line, consistent with the changes in other components.


119-122: Implemented afterSubmit callback for data refreshing

Excellent implementation of the afterSubmit pattern. The null check ensures the function is only called when provided, and the blank lines improve readability by visually separating this logic.


231-231: Updated to use constant for button label

Good practice to use the constant from BUTTON_LABELS for the save button text. This promotes consistency across the application and supports easier localization if needed.

src/features/AdminPage/TagsPage/TagsPage/TagAdminModal.tsx (3)

24-24: Good enhancement with the afterSubmit callback

Adding this optional callback property provides a clean way to trigger actions after successful form submission, improving component reusability.


76-78: Improved code formatting with curly braces

The refactoring of this conditional check with proper curly braces enhances code readability and consistency, making the early return more explicit.


90-92: Well-implemented callback execution

Good implementation of the afterSubmit callback. This pattern allows parent components to refresh their data after a successful operation without tightly coupling the components.

src/features/AdminPage/TeamPositionsPage/TeamPositionsMainPage.component.tsx (3)

4-4: Clean import statement

Removing the unused useEffect import helps keep the codebase clean and focused.


25-25: Good use of destructured refetch function

Destructuring the refetch function from useQuery is an excellent approach for on-demand data refreshing, reducing unnecessary re-renders and API calls.


131-132: Effective use of the afterSubmit prop

Using the refetch function as an afterSubmit callback creates a clear data flow that ensures the table data is refreshed after modal operations, eliminating the need for useEffect-based solutions.

Also applies to: 137-138

src/features/AdminPage/TagsPage/TagsMainPage.component.tsx (4)

4-4: Clean import statement

Removing the unused useEffect import streamlines dependencies.


25-25: Efficient query management with refetch

Adding the refetch function from useQuery provides a controlled way to refresh data exactly when needed, addressing the "duplicate requests" issue mentioned in the PR objectives.


51-51: Simplified render function

Removing the unused record parameter from the render function improves code cleanliness.


132-133: Consistent pattern with afterSubmit

The implementation of the afterSubmit prop with refetch ensures that tag data is refreshed after modal operations, addressing the issue where "tag records were not disappearing after deletion" as mentioned in the PR objectives.

Also applies to: 138-139

src/app/api/streetcode/streetcodes.api.ts (2)

5-7: Clean import optimization

Removing unused imports for EventStreetcode and PersonStreetcode keeps the codebase clean and may slightly improve bundle size.


61-74: Enhanced API method with pagination support

The refactored getAllShort method now properly supports pagination, which is crucial for performance when dealing with large datasets. The implementation:

  1. Correctly handles optional parameters
  2. Filters out undefined parameters
  3. Returns total count along with results for proper pagination UI

This change directly addresses the "pagination issues when navigating past page 5" mentioned in the PR objectives.

src/features/AdminPage/ContextPage/ContextMainPage.component.tsx (3)

4-4: Import refactoring for cleaner dependencies

The import statement has been updated to remove useEffect, which is no longer needed since the component now uses React Query for data fetching. This keeps imports lean and clear.


24-27: Improved data fetching with React Query

The useQuery hook has been updated to destructure the refetch function, which allows for explicit data refreshing when needed. This is a more maintainable approach than using useEffect for data fetching.


130-130: Enhanced modal integration with data refreshing

Adding the afterSubmit prop to both modal instances provides a clean way to trigger data refreshing after form submission. This pattern eliminates redundant fetch calls and ensures data consistency.

Also applies to: 136-136

src/app/stores/term-store.ts (5)

3-3: Added pagination model import

The import for PaginationInfo supports the implementation of pagination functionality for terms, aligning with the PR objective to fix pagination issues.


9-16: Added pagination configuration

The addition of defaultPageSize and paginationInfo properties properly configures the store for paginated data fetching. The default values are sensible and consistent with other stores in the application.


23-23: Improved data management with Map clearing

The update to setInternalMap now clears the TermMap before adding new items, which prevents stale data from persisting when fetching a new page.


35-45: Added pagination state management methods

The implementation of setCurrentPage and accessor methods for PaginationInfo follows the established pattern in other stores, maintaining consistency throughout the application.


47-54: Implemented paginated data fetching

The getAll method properly handles pagination parameters and updates the pagination metadata with the total count from the API response. This enables the UI to correctly display pagination controls.

src/features/AdminPage/JobsPage/JobsTable/JobsTable.component.tsx (4)

5-5: Simplified import dependencies

The import statement has been updated to remove useEffect, as the component now uses React Query for data fetching, keeping the imports focused on what's actually used.


28-31: Enhanced data fetching with React Query

The useQuery hook now provides refetch capability, enabling explicit data refreshing when needed instead of relying on side effects. The query key includes the current page, ensuring proper cache invalidation when the page changes.


38-43: Cleaner promise handling in DeleteJob function

The promise chain has been simplified with a more concise format, improving readability while maintaining the same functionality.


183-188: Enhanced modal with data refresh capability

Adding the afterSubmit prop to the JobsModalComponent ensures that data is refreshed after form submission, eliminating the need for extra effect hooks to trigger refetching.

src/features/AdminPage/PartnersPage/PartnerModal/PartnerModal.component.tsx (6)

10-10: Added comprehensive image validation

The import of combinedImageValidator and checkFile provides robust image validation functions that help prevent invalid image uploads, enhancing the user experience.


142-146: Improved streetcode selection logic

The onStreetcodeSelect function has been updated to use the StreetcodesShortMap for finding and adding streetcodes to the selection. This approach is more reliable than the previous array-based lookup.


270-272: Fixed partner identification logic

The condition for identifying existing partners now correctly checks both the title and logoId, addressing potential issues with partner data synchronization.


286-291: Added callback support for data refresh

The implementation now properly calls the afterSubmit callback with the updated partner data, ensuring that the parent component can refresh its data after changes. This addresses the issue with disappearing partner data mentioned in the PR objectives.


339-339: Minor text adjustment

Small text change for better readability or language consistency.


445-450: Enhanced data source for streetcode options

The rendering of streetcode options now uses Array.from(streetcodeShortStore.StreetcodesShortMap.values()) instead of directly mapping over the array. This ensures consistent data source usage and aligns with the store's data structure changes.

src/features/AdminPage/TermDictionary/TermDictionary.component.tsx (10)

4-4: Importing useState
No concerns here. This is a standard React usage.


7-7: Adopting useQuery
Integrating React Query is a good step for consistent data fetching and automatic cache updates.


9-11: Refined imports from antd
Centralizing UI components from antd is a neat approach for clarity and consistency.


118-118: Minor line adjustment
No functional difference here. This looks fine.


121-121: Usage of <PageBar />
Using the shared PageBar component is consistent with the rest of the admin UI.


136-138: Disabling default Table pagination
By disabling built-in pagination, you rely on custom pagination below. Confirm that large datasets don’t cause performance issues with a single render.


140-148: Localized loading and empty states
This is a neat usage of locale in the Table to display custom placeholders for loading or empty data states.


150-165: External pagination
The external Pagination component is properly connected to your store. Looks good for controlling pages from the outside.


168-180: Modal callbacks
Passing handleAdd, handleEdit, and handleDelete to individual modals is a clean approach, ensuring cohesive data flow. Great job.


60-63:

Details

❓ Verification inconclusive

Confirm data consistency on delete
Currently this removes items locally without calling refetch(). Ensure the data remains up-to-date if external changes or concurrency issues occur.


🏁 Script executed:

#!/bin/bash
# Checking if the state remains synced after deletion
# 1) Create a new term
# 2) Delete the term
# 3) Verify store or subsequent queries reflect the deletion
echo "Please confirm that 'termsStore.getAll()' excludes deleted terms if 'refetch' is omitted."

Length of output: 200


Verify Data Consistency After Deletion

The deletion handler currently filters the local state without triggering a refetch, so please confirm that the underlying store remains consistent—specifically, ensure that calling termsStore.getAll() will not return a term that was just deleted. If there’s a risk of stale data (for example, when external updates or concurrent changes occur), consider either adding a refetch or implementing a mechanism that automatically keeps the state in sync.

  • File: src/features/AdminPage/TermDictionary/TermDictionary.component.tsx (lines 60-63)
  • Action: Confirm that the deletion not only updates the local state but also that termsStore.getAll() properly excludes the deleted term in all scenarios.
src/features/AdminPage/NewsPage/News.component.tsx (5)

8-9: Reintroducing label and confirmation constants
Good to see these constants in use again for standardizing messaging and button labels.


31-31: Adding refetch from useQuery
Fetching is now easily refreshed after mutations. This improves the reliability of your UI data.


95-100: Popover for scheduled news
Nice user experience improvement. Visually clarifying planned publications can reduce confusion.


173-177: Refetch after adding news
Triggering refresh post-submission is a solid approach to maintain up-to-date listings without manual reload.


182-182: Refetch after editing news
Ensures local state and server data remain in sync. Nicely done.

src/features/AdminPage/TeamPositionsPage/TeamPositionsModal/TeamPositionsAdminModal.component.tsx (11)

3-3: New SVG Import
Importing a custom cancel button is fine. Looks consistent with your existing approach to images.


5-6: Refined imports
The addition of React and rearranging constants fosters clarity and eliminates any unused references.


10-12: Consolidated Ant Design imports
Collecting these UI components in one block simplifies tracking usage.


22-22: afterSubmit callback
Adding an optional callback for post-submission tasks is a flexible design, allowing parent components to trigger data refetch.


29-31: New props destructuring
The inclusion of isNewPosition and afterSubmit helps differentiate new from existing positions and triggers a refresh if needed.


32-32: Store usage
teamPositionsStore is accessed cleanly here, maintaining the MobX pattern.


48-50: Uniqueness validator
Great to see a custom validator preventing duplicates. Confirm messages are localized if needed.


62-63: Early return on unchanged data
Smart check to avoid unnecessary updates when the position name is unmodified. This helps with performance.


75-77: Unified post-submission flow
Invoking afterSubmit is a good pattern to let external components handle state refresh.


133-135: Validation rules
These rules ensure data quality. The new multiline format is more readable.


139-139: showCount on Input
Showing the character count can enhance user awareness of length constraints.

src/features/AdminPage/PartnersPage/Partners.component.tsx (6)

4-4: No immediate concerns.
Importing useState here appears consistent with the updated state usage for partner editing.


31-31: Great addition of streetcodeShortStore.
Including streetcodeShortStore in the component ensures seamless integration of street code data alongside partner data.


35-35: Improved naming convention.
Renaming partnerToedit to partnerToEdit enhances readability and follows a consistent naming pattern.


47-47: Efficient single loading flag.
Combining both loading states into a single flag isLoading is a neat simplification for the UI.


206-214: Good practice to refetch data after adding a partner.
Using afterSubmit={() => { refetchPartners(); refetchStreetcodesShort(); }} ensures up-to-date partner and streetcode data upon modal closure.


220-223: Consistent refetch logic for the edit flow.
Refetching data in the edit modal ensures an updated partner list and aligns well with the add-partner approach.

src/features/AdminPage/TeamPage/TeamPage.component.tsx (5)

5-5: State usage is straightforward.
Replacing other hooks with plain useState looks intentional and aligned with the simplified logic.


29-29: Consistent naming.
Renaming teamToedit to teamToEdit promotes clear readability.


153-153: Smooth editing experience.
Storing the clicked team member in teamToEdit has no apparent issues.


207-211: Refreshing data after adding a team member.
Refetching ensures newly added team members appear promptly. Good practice for data consistency.


216-216: Same approach for editing.
Refetching keeps the team list in sync post-edit. This pattern aligns with other modals in the app.

src/app/stores/streetcodeshort-store.ts (6)

2-4: Imports look good.
makeAutoObservable from Mobx combined with PaginationInfo and StreetcodeShort sets a clear foundation for store management.


9-18: Good shift to a Map-based structure.
Using a Map for StreetcodesShortMap enables faster lookups and cohesive store organization. The default pagination initialization also seems prudent.


24-27: Efficient bulk insertion.
setInternalMap clears old data and populates the map in one go, promoting consistency in your store.


29-30: Flexible insertion logic.
setItem() helps modularize how items are inserted, making the store more maintainable.


33-35: Easy pagination control.
setCurrentPage directly updates paginationInfo, allowing smoother UI integration for page changes.


37-43: Pagination get/set works consistently.
Exposing PaginationInfo as a getter and setter offers a clear interface for reading and updating pagination.

@coderabbitai

coderabbitai Bot commented Mar 17, 2025

Copy link
Copy Markdown
Contributor
✅ Actions performed

Reviews paused.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
28.3% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants