Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

515 helper link functionality #530

Merged
merged 19 commits into from
Feb 11, 2025
Merged

515 helper link functionality #530

merged 19 commits into from
Feb 11, 2025

Conversation

DeboraSerra
Copy link
Contributor

Describe your changes

Add new fields to helper link to activate/deactivate it and to choose to display in specific urls.

image

Issue number

#515

Please ensure all items are checked off before requesting a review:

  • I deployed the code locally.
  • I have performed a self-review of my code.
  • I have included the issue # in the PR.
  • I have labelled the PR correctly.
  • The issue I am working on is assigned to me.
  • I didn't use any hardcoded values (otherwise it will not scale, and will make it difficult to maintain consistency across the application).
  • I made sure font sizes, color choices etc are all referenced from the theme.
  • My PR is granular and targeted to one specific feature.
  • I took a screenshot or a video and attached to this PR if there is a UI change.

@DeboraSerra DeboraSerra requested a review from erenfn January 30, 2025 18:32
Copy link
Contributor

coderabbitai bot commented Jan 30, 2025

Walkthrough

This pull request introduces comprehensive changes to the helper link functionality across the backend and frontend. The modifications include adding new columns to the database migration, updating the HelperLink model, enhancing validation logic, and modifying various components to support new fields like url, active, and absolutePath. The changes ensure that the application can handle a more complex schema for helper links, improving overall data management.

Changes

File Change Summary
backend/migrations/0001-1.0-helperlink.js Added new columns: title, headerBackgroundColor, linkFontColor, iconColor, createdBy
backend/migrations/0011-1.1-helperlink.js Added new columns: url, active, absolutePath with specific data types and constraints
backend/src/models/HelperLink.js Introduced new properties: url, active, absolutePath with validations
backend/src/utils/helperLink.helper.js Added validation rules for url, active, and absolutePath
frontend/src/scenes/links/* Updated components to handle new link properties, modified state management
frontend/src/services/* Updated services to include new link properties in API calls
frontend/src/utils/linkHelper.js Added new validation schemas for link-related fields
frontend/src/tests/scenes/links/NewLinksPopup.test.jsx Updated tests to reflect new input fields in the appearance form

Possibly related PRs

  • Added helper_link and link seeder. #496: The changes in the main PR, which involve adding new columns to the helper_link table, are directly related to the retrieved PR that introduces a bulk insert for the helper_link table, including fields like title, url, and others, indicating a connection at the code level.
  • 390 refactoring validations in link and helper link routes with express validator #448: The changes in the main PR, which involve adding new columns to the helper_link table, are related to the modifications in the retrieved PR that refactors validations for the url, active, and absolutePath fields, as both PRs deal with the same data model and its validation logic.
  • 410 dialog reset #429: The changes in the main PR, which involve adding new columns to the helper_link table and modifying the HelperLink model, are related to the retrieved PR as both involve updates to the helper_link structure, specifically the addition of the url, active, and absolutePath properties.

Suggested Reviewers

  • swoopertr

Tip

🌐 Web search-backed reviews and chat
  • We have enabled web search-based reviews and chat for all users. This feature allows CodeRabbit to access the latest documentation and information on the web.
  • You can disable this feature by setting web_search: false in the knowledge_base settings.
  • Please share any feedback in the Discord discussion.
✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

Documentation and Community

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

Copy link
Contributor

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

🧹 Nitpick comments (5)
backend/migrations/0001-1.0-helperlink.js (3)

9-47: Check your references, or you might lose yourself

His palms are sweaty, knees weak, arms are heavy, but your table definitions look stable. Be sure your 'users' table reference matches the actual table name if your database is case-sensitive. Also, indexing 'createdBy' can help performance when querying large datasets.


49-58: Be mindful of your 255-character limit

Even if mom’s spaghetti is on the menu, sometimes URLs are longer than expected. Consider whether 255 characters is enough or if your use case might require a bigger limit to prevent future migrations.


71-80: Clarify 'absolutePath' usage

Arms are heavy, but remember that an absolute path column can be confusing without a clear definition of how it's used. A quick doc comment or additional migration note outlining valid path types can prevent confusion down the road.

backend/src/models/HelperLink.js (1)

29-29: These hardcoded colors are making my knees weak! Let's make them reusable!

The default hex colors are duplicated across the codebase. Consider extracting them to a constants file.

Create a new file constants/colors.js:

export const COLORS = {
  DEFAULT_BACKGROUND: '#F8F9F8',
  DEFAULT_FONT: '#344054',
  DEFAULT_ICON: '#7F56D9',
};

Then update the model:

-        defaultValue: '#F8F9F8',
+        defaultValue: COLORS.DEFAULT_BACKGROUND,

Also applies to: 39-39, 49-49

frontend/src/services/linksProvider.jsx (1)

37-37: Arms are heavy! Let's validate these defaults on initialization!

The default values are used directly without validation.

Add validation on initialization:

-  const [helper, setHelper] = useState(DEFAULT_VALUES);
+  const [helper, setHelper] = useState(() => {
+    try {
+      // Validate default values
+      Object.entries(DEFAULT_VALUES).forEach(([key, value]) => {
+        if (key.includes('Color') && !value.match(/^#[0-9A-F]{6}$/i)) {
+          throw new Error(`Invalid color format for ${key}`);
+        }
+        if (key === 'url' && !value.match(/^(\/|https?:\/\/).+/)) {
+          throw new Error('Invalid URL format');
+        }
+      });
+      return DEFAULT_VALUES;
+    } catch (error) {
+      console.error('Default values validation failed:', error);
+      return {};
+    }
+  });
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e3cf460 and 519dd75.

📒 Files selected for processing (12)
  • backend/migrations/0001-1.0-helperlink.js (2 hunks)
  • backend/src/models/HelperLink.js (3 hunks)
  • backend/src/utils/helperLink.helper.js (1 hunks)
  • frontend/src/scenes/hints/CreateHintPage.jsx (0 hunks)
  • frontend/src/scenes/links/LinkPage.module.scss (2 hunks)
  • frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (4 hunks)
  • frontend/src/scenes/links/LinksDefaultPage.jsx (1 hunks)
  • frontend/src/scenes/links/NewLinksPopup.jsx (2 hunks)
  • frontend/src/services/helperLinkService.js (5 hunks)
  • frontend/src/services/linksProvider.jsx (2 hunks)
  • frontend/src/utils/guideHelper.js (1 hunks)
  • frontend/src/utils/linkHelper.js (2 hunks)
💤 Files with no reviewable changes (1)
  • frontend/src/scenes/hints/CreateHintPage.jsx
🔇 Additional comments (13)
backend/migrations/0001-1.0-helperlink.js (1)

60-69: Confirmed 'active' default is set

Knees might be weak, but this boolean column is sturdy. Using allowNull: false and defaulting to true is clear. Double-check if there's any scenario where you need a three-state logic before finalizing.

frontend/src/utils/guideHelper.js (1)

6-6: Handle unexpected error structures gracefully

Mom’s spaghetti might be on the line, so ensure error.response.data.errors[i].msg is always defined. Consider a fallback if msg is missing or has an unexpected format.

frontend/src/utils/linkHelper.js (2)

34-37: Validate large and varied URLs

Knees weak, but this is good progress. The validateUrl function allows absolute or relative paths, though keep in mind your user might paste an extremely long domain. The max length of 2000 is helpful—just confirm your environment can handle that.


47-48: Confirm expected boolean usage

Arms are heavy, but toggling active and absolutePath is straightforward. Ensure your forms and API calls never pass these as strings or other types.

frontend/src/services/helperLinkService.js (3)

25-37: Validation looking fresh, fam! 🔥

The validation messages are clear, descriptive, and cover all required fields.


76-78: Consistency is key, and this is looking 💯!

The new fields are consistently implemented in both createHelper and updateHelper functions.


51-53: Hold up! We're missing some validation checks!

The new fields url, active, and absolutePath are added to the payload but aren't validated in the validateHelper function. Consider adding validation for these fields to maintain data integrity.

frontend/src/scenes/links/NewLinksPopup.jsx (2)

12-12: Straight fire! 🔥 Moving those default values to a central location!

Good practice moving the default values to a centralized provider. This improves maintainability and consistency.


44-44: Clean initialization with DEFAULT_VALUES! 👊

Using DEFAULT_VALUES instead of empty objects ensures all fields are properly initialized with consistent default values.

Also applies to: 74-74

frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (2)

25-29: Switch handling looking clean! ✨

Good implementation of the switch value handling for active and absolutePath fields.


67-90: URL input implementation is on point! 🎯

The URL input field follows the same pattern as other fields with proper validation and error handling.

frontend/src/scenes/links/LinkPage.module.scss (2)

72-75: Flexbox game strong! 💪

Clean implementation of the row layout using flexbox for the switch components.


94-96: Error styling looking fresh! 🎨

Good use of CSS variables for error styling, maintaining consistency with the design system.

backend/migrations/0001-1.0-helperlink.js Outdated Show resolved Hide resolved
backend/src/utils/helperLink.helper.js Show resolved Hide resolved
backend/src/models/HelperLink.js Show resolved Hide resolved
frontend/src/services/linksProvider.jsx Show resolved Hide resolved
frontend/src/services/helperLinkService.js Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (1)
frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (1)

Line range hint 176-178: Yo! PropTypes are out of sync with the component signature! 🍝

The PropTypes still require handleSaveHelper but it's been removed from the component parameters. This mismatch could confuse other developers.

Remove the PropTypes validation since the prop is no longer used:

-LinkAppearance.propTypes = {
-  handleSaveHelper: PropTypes.func.isRequired,
-};
🧹 Nitpick comments (4)
frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (3)

23-27: Let's make this spaghetti code more robust! 🍝

The value destructuring could be safer. Consider using default values to prevent potential undefined errors.

Here's a safer implementation:

-    const { name, checked } = e.target;
-    let { value } = e.target;
+    const { name = '', checked = false, value: targetValue = '' } = e.target;
+    let value = targetValue;
     if (name === 'active' || name === 'absolutePath') {
       value = checked;
     }

Line range hint 32-37: Validation looking heavy like mom's spaghetti! 🍝

The form has both validateOnBlur={true} and manual validateField calls in onBlur handlers. This creates redundant validation calls.

Since validateOnBlur is already true, you can remove the manual validateField calls from the onBlur handlers to optimize performance.


89-103: These switch components are looking like copy-pasta! 🍝

The Switch component implementations for absolutePath and active are very similar. Consider extracting this pattern into a reusable component.

Create a new component like SwitchField that encapsulates this pattern:

const SwitchField = ({ id, name, label, value, onChange }) => (
  <label htmlFor={id} className={`${styles.appearance__label} ${styles.row}`}>
    <span>{label}</span>
    <Switch
      id={id}
      name={name}
      onChange={onChange}
      value={value}
    />
  </label>
);

// Usage:
<SwitchField
  id="absolutePath"
  name="absolutePath"
  label="Display only in absolute path?"
  value={values.absolutePath}
  onChange={(e) => {
    handleChange(e);
    handleHelperChange(e);
  }}
/>

Also applies to: 152-166

backend/src/test/e2e/helperLink.test.mjs (1)

370-377: Mom's spaghetti suggestion: Consider consolidating URL validations.

Having two identical URL validation messages might confuse users. Consider consolidating them into a single message or making them more specific if they validate different URL fields.

         errors: [
           'ID must be an integer',
           'Header is required',
-          'Invalid value for url',
-          'Invalid value for url',
+          'Invalid value for helper URL',
+          'Invalid value for link URL',
           'Invalid value for absolutePath',
           'links must be an array',
         ],
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 519dd75 and 95d5c0e.

📒 Files selected for processing (4)
  • backend/src/test/e2e/helperLink.test.mjs (3 hunks)
  • backend/src/test/mocks/helperLink.mock.js (6 hunks)
  • frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (5 hunks)
  • frontend/src/tests/scenes/links/NewLinksPopup.test.jsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • backend/src/test/mocks/helperLink.mock.js
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build (22.x)
🔇 Additional comments (5)
frontend/src/tests/scenes/links/NewLinksPopup.test.jsx (1)

188-188: Straight fire change on that title input selection! 🔥

Switching to getByLabelText is a solid improvement - it's more resilient and follows testing best practices by testing the way users interact with the form.

frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (1)

Line range hint 11-21: Clean context implementation! 👊

Good job implementing proper context validation and error handling. The focus management with useEffect is also a nice touch for accessibility.

backend/src/test/e2e/helperLink.test.mjs (3)

217-217: Yo, this destructuring looks clean!

The simplified destructuring makes the code more readable and maintainable.


271-271: Same clean destructuring here!

Consistent with the earlier change, keeping the codebase style uniform.


370-377: Hold up! We need to verify these validation messages.

The new validation errors for url and absolutePath fields look good, but there's something sus about having two identical URL validation messages.

Let's check the validation logic in the helper file:

✅ Verification successful

The duplicate URL validation messages are actually correct! 🍝

The validation chain for the URL field has two separate checks that use the same error message:

  • String type validation
  • Custom URL format validation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find and display the validation logic for helper links
ast-grep --pattern 'function validate$_($$$) {
  $$$
}'

Length of output: 57


Script:

#!/bin/bash
# Find validation-related files
fd validation

# Search for URL validation patterns
rg -i "url.*validation" -A 5 -B 5

# Look for helper link related files
fd helper

Length of output: 5834


Script:

#!/bin/bash
# Check helper link validation logic
cat backend/src/utils/helperLink.helper.js

# Check helper link model for schema validation
cat backend/src/models/HelperLink.js

# Also check the test file itself for context
cat backend/src/test/e2e/helperLink.test.mjs

Length of output: 25939

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 95d5c0e and e344274.

📒 Files selected for processing (1)
  • backend/src/test/e2e/link.test.mjs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build (22.x)

backend/src/test/e2e/link.test.mjs Show resolved Hide resolved
@gorkem-bwl
Copy link
Contributor

Looks good!

@DeboraSerra DeboraSerra linked an issue Jan 30, 2025 that may be closed by this pull request
3 tasks
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (1)

179-181: Yo! PropTypes are out of sync with the component signature! 🍝

The component no longer accepts handleSaveHelper prop, but PropTypes still requires it. This mismatch could cause confusion and runtime warnings.

Apply this diff to fix the PropTypes:

-LinkAppearance.propTypes = {
-  handleSaveHelper: PropTypes.func.isRequired,
-};
+LinkAppearance.propTypes = {};
🧹 Nitpick comments (2)
frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (2)

94-106: Mom's spaghetti alert! Let's clean up this Switch logic! 🍝

The absolutePath switch uses inverted logic with double negation, making it harder to understand. We can simplify this by removing the value inversion.

Apply this diff to simplify the logic:

 <Switch
   id="absolutePath"
   name="absolutePath"
   onChange={(e) => {
-    handleChange({
-      target: { ...e.target, value: !e.target.value },
-    });
-    handleHelperChange({
-      target: { ...e.target, value: !e.target.value },
-    });
+    handleChange(e);
+    handleHelperChange(e);
   }}
-  value={!values.absolutePath}
+  value={values.absolutePath}
 />

65-88: Let's make that URL validation message more helpful! 🍝

The URL field's error message could be more descriptive to help users understand what constitutes a valid URL.

Add a helper text below the input field:

 <label htmlFor="url" className={styles.appearance__label}>
   URL (can be relative){' '}
   <input
     type="text"
     id="url"
     className={`${styles.appearance__input} ${
       errors.url && styles.error
     }`}
     name="url"
     value={values.url || ''}
     onChange={(e) => {
       handleChange(e);
       handleHelperChange(e);
     }}
     onBlur={(e) => {
       handleBlur(e);
       handleHelperChange(e);
       validateField('url');
     }}
   />
+  <small className={styles.appearance__helper}>
+    Enter a valid URL (e.g., /help or https://example.com)
+  </small>
   {errors.url && (
     <span className={styles.appearance__error}>{errors.url}</span>
   )}
 </label>
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5042492 and f22f898.

📒 Files selected for processing (1)
  • frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build (22.x)
🔇 Additional comments (1)
frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (1)

32-38: Formik configuration is on point! 👌

The Formik configuration with enableReinitialize, validateOnMount, and validateOnBlur is well thought out and follows best practices.

Copy link
Collaborator

@erenfn erenfn left a comment

Choose a reason for hiding this comment

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

  • Show on dependent pages switch doesn't work

backend/migrations/0001-1.0-helperlink.js Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🔭 Outside diff range comments (4)
frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (1)

178-180: Yo! PropTypes are out of sync with the component signature! 🍝

The component no longer accepts handleSaveHelper prop, but PropTypes still declares it as required. This mismatch could cause confusion and runtime warnings.

Remove the PropTypes declaration since the prop is no longer used:

-LinkAppearance.propTypes = {
-  handleSaveHelper: PropTypes.func.isRequired,
-};
frontend/src/components/Links/Settings/Settings.jsx (2)

54-89: Lose yourself in the error handling, the moment you own it!

The handleClose function needs better error handling and async/await usage:

  1. URL validation throws but doesn't handle the error gracefully
  2. State updates after validation could be more robust
 const handleClose = async (e, info) => {
   e?.preventDefault();
+  try {
     if (!info) {
       info = Array.from(settingsRef.current.querySelectorAll('input')).reduce(
         (acc, it) => ({
           ...acc,
           [it.name]: it.name === 'target' ? it.value === 'true' : it.value,
         }),
         {}
       );
     }

     if (!e) {
       e = { target: settingsRef.current };
     }
     if (!info.title.trim() && !info.url.trim()) {
       toggleSettings(e);
       setLinkToEdit(null);
       return;
     }
     if (!validateUrl(info.url)) {
-      throw new Error('Invalid URL format');
+      return;
     }
     if (linkToEdit) {
       setLinks((prev) =>
         prev.map((it) =>
           it.id === oldLink.id ? { ...info, id: oldLink.id } : it
         )
       );
       setLinkToEdit(null);
       toggleSettings(e);
     } else {
       setLinks((prev) => [...prev, { ...info, id: info.id }]);
       toggleSettings(e);
     }
+  } catch (error) {
+    console.error('Error in handleClose:', error);
+  }
 };
🧰 Tools
🪛 Biome (1.9.4)

[error] 59-59: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)


97-105: There's vomit on his sweater already - fix this error handling!

The form submission needs better error handling and user feedback:

 onSubmit={async (values, { setSubmitting }) => {
   try {
     await handleClose(null, state);
   } catch (error) {
-    return;
+    // Show error to user
+    console.error('Form submission failed:', error);
+    // Add toast or error message component here
   } finally {
     setSubmitting(false);
   }
 }}
backend/src/service/helperLink.service.js (1)

57-61: Console.log? More like console.nope! 🍝

Error logging needs to be more robust for production environment.

-      console.log(e);
+      const errorMessage = `Failed to create helper: ${e.message}`;
+      console.error(errorMessage, { error: e, data, links });
       await t.rollback();
-      throw new Error("Error creating helper");
+      throw new Error(errorMessage);
🧹 Nitpick comments (6)
frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (4)

22-32: Mom's spaghetti alert! Let's clean up this event handler! 🍝

The logic for handling different input types could be more straightforward. The negation of checked for absolutePath is particularly confusing.

Consider this cleaner implementation:

 const handleHelperChange = (e) => {
-  const { name, checked } = e.target;
-  let { value } = e.target;
-  if (name === 'active') {
-    value = checked;
-  }
-  if (name === 'absolutePath') {
-    value = !checked;
-  }
+  const { name, checked, value: inputValue } = e.target;
+  const value = name === 'active' ? checked 
+              : name === 'absolutePath' ? !checked 
+              : inputValue;
   setHelper((prev) => ({ ...prev, [name]: value }));
 };

68-91: URL validation could use some real-time love! 🍝

The URL field only validates on blur. For better UX, consider adding real-time validation feedback.

Add validation on change:

 onChange={(e) => {
   handleChange(e);
   handleHelperChange(e);
+  validateField('url');
 }}

96-96: These Switch labels could use more sauce! 🍝

The labels "Show on dependent pages?" and "Helper link is active?" could be more descriptive to better explain their purpose.

Consider more descriptive labels:

  • "Display helper on all child pages?"
  • "Enable this helper link?"

Also applies to: 159-159


107-154: Spaghetti alert! DRY up those color inputs! 🍝

There's significant duplication in the ColorInput components' event handling logic.

Consider creating a wrapper component:

const ColorInputWithHelper = ({ name, value, title, className, errors }) => (
  <ColorInput
    id={`${name}-id`}
    name={name}
    value={value}
    onChange={(e) => {
      handleChange(e);
      handleHelperChange(e);
    }}
    onBlur={(e) => {
      handleBlur(e);
      handleHelperChange(e);
    }}
    error={errors[name]}
    title={title}
    className={className}
  />
);

Then use it like:

<ColorInputWithHelper
  name="headerBackgroundColor"
  value={values.headerBackgroundColor}
  title="Header background color"
  className="header"
  errors={errors}
/>
frontend/src/components/Links/Settings/Settings.jsx (1)

21-22: Yo dawg, we need to talk about this state management!

Managing state in both local useState and Formik could lead to synchronization headaches. Consider letting Formik handle all form state to keep it clean like mom's spaghetti.

-  const [state, setState] = useState(linkToEdit ?? defaultState);
+  // Let Formik handle all form state
backend/src/service/helperLink.service.js (1)

84-92: There's vomit on his sweater already - this Promise.all needs validation!

Add validation to ensure linksToUpdate contains valid data before processing.

+      if (linksToUpdate.some(item => !item.id)) {
+        throw new Error('Invalid link data: missing id in update operation');
+      }
       await Promise.all(
         linksToUpdate.map(async (item) => {
           const { id: linkId, ...link } = item;
           return await Link.update(
             { ...link, helperId: id },
             { transaction: t, where: { id: linkId } }
           );
         })
       );
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f22f898 and 9530317.

📒 Files selected for processing (5)
  • backend/migrations/0001-1.0-helperlink.js (1 hunks)
  • backend/migrations/0011-1.1-helperlink.js (1 hunks)
  • backend/src/service/helperLink.service.js (2 hunks)
  • frontend/src/components/Links/Settings/Settings.jsx (6 hunks)
  • frontend/src/scenes/links/LinkPageComponents/LinkAppearance.jsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/migrations/0001-1.0-helperlink.js
🧰 Additional context used
🪛 Biome (1.9.4)
backend/migrations/0011-1.1-helperlink.js

[error] 1-1: Redundant use strict directive.

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.

(lint/suspicious/noRedundantUseStrict)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build (22.x)
🔇 Additional comments (2)
backend/migrations/0011-1.1-helperlink.js (1)

19-21: URL length limit might be too restrictive!

Consider increasing the VARCHAR length for URLs or using TEXT type to handle longer URLs.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Check if there are any existing URLs in the codebase longer than 255 chars
rg -l 'https?://[^\s]{255,}' 

Length of output: 30


I'm going to run an enhanced verification script that walks through the repository with Python and reports any URLs that are at least 255 characters long so that we can be totally sure if there's any occurrence that might require a longer column definition. This additional script will help us gather the necessary details for proper manual verification.

Once this script is run, please check the output manually to confirm whether any URLs exceeding 255 characters are being stored in the codebase. If none are found, the current limit may be acceptable in practice; however, it's wise to remain cautious if future data might exceed this threshold.

His palms are sweaty, knees weak, arms are heavy – let's make sure our URL strategy is strong and ready!


🏁 Script executed:

#!/bin/bash
python - <<'EOF'
import os
import re

url_pattern = re.compile(r'https?://\S+')
found = False

# Walk through all files in the repository.
for root, dirs, files in os.walk("."):
    # Skip directories that are not relevant.
    if "node_modules" in dirs:
        dirs.remove("node_modules")
    if "dist" in dirs:
        dirs.remove("dist")
    if "build" in dirs:
        dirs.remove("build")
    for file in files:
        file_path = os.path.join(root, file)
        try:
            with open(file_path, "r", encoding="utf-8") as f:
                for line in f:
                    for url in url_pattern.findall(line):
                        if len(url) >= 255:
                            print(f"{file_path}: {url}")
                            found = True
        except Exception:
            continue

if not found:
    print("No URLs of length >=255 found.")
EOF

Length of output: 41


URL Length Limit Verification

Based on the additional checks, no URLs with a length of 255 characters or greater were found anywhere in the repository. It appears that, at least for now, the use of Sequelize.STRING(255) is sufficient. His palms are sweaty, knees weak, arms are heavy – no oversized URLs were detected in our scan!

backend/src/service/helperLink.service.js (1)

44-62: This function's got the right spaghetti code - it's working well!

The createHelper implementation with bulk create is clean and efficient. Good job on using transactions and proper error handling structure.

backend/migrations/0011-1.1-helperlink.js Outdated Show resolved Hide resolved
backend/migrations/0011-1.1-helperlink.js Show resolved Hide resolved
backend/src/service/helperLink.service.js Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
backend/migrations/0011-1.1-helperlink.js (2)

1-1: Yo dawg, let's drop that 'use strict' like it's hot!

The 'use strict' directive is redundant in ES modules as they're automatically in strict mode.

-'use strict';
🧰 Tools
🪛 Biome (1.9.4)

[error] 1-1: Redundant use strict directive.

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.

(lint/suspicious/noRedundantUseStrict)


15-24: URL column looking fresh and clean!

The URL column definition with a default value of '/' and non-null constraint is well thought out. However, consider adding a URL validation pattern to ensure only valid URLs are stored.

       {
         type: Sequelize.STRING(255),
         allowNull: false,
         defaultValue: '/',
+        validate: {
+          isUrl: true,
+        },
       },
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9530317 and fa3ad58.

📒 Files selected for processing (2)
  • backend/migrations/0011-1.1-helperlink.js (1 hunks)
  • backend/src/service/helperLink.service.js (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/src/service/helperLink.service.js
🧰 Additional context used
🪛 Biome (1.9.4)
backend/migrations/0011-1.1-helperlink.js

[error] 1-1: Redundant use strict directive.

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.

(lint/suspicious/noRedundantUseStrict)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build (22.x)
🔇 Additional comments (3)
backend/migrations/0011-1.1-helperlink.js (3)

12-52: Mom's spaghetti alert: Error handling needs some sauce!

The catch block is swallowing errors without logging or propagating them. This could make debugging migration failures harder than finding the last M&M in the bowl.

-    } catch {
+    } catch (error) {
+      console.error('Failed to execute helper link migration:', error);
       await transaction.rollback();
+      throw error;
     }

Also, props on using transactions to keep the database changes atomic! 🍝


54-64: Same spaghetti, different plate - Fix error handling in down migration!

The down migration has the same error handling issue as the up migration.

-    } catch {
+    } catch (error) {
+      console.error('Failed to rollback helper link migration:', error);
       await transaction.rollback();
+      throw error;
     }

57-61: The rollback sequence is on point!

The down migration correctly removes all columns in a transaction. Nice work keeping it clean and organized!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
backend/src/test/unit/services/helperLink.test.js (1)

139-139: Add parameter validation for bulk creation.

While the test covers the call expectations, it would be more robust to validate the parameters passed to bulkCreate.

Add parameter validation like this:

 expect(LinkMock.bulkCreate.called).to.be.true;
+const bulkCreateParams = LinkMock.bulkCreate.getCall(0).args;
+expect(bulkCreateParams[0]).to.deep.equal(
+  mocks.LinksList.map(({ id, ...link }) => link)
+);
+expect(bulkCreateParams[1]).to.deep.equal({
+  transaction: { commit, rollback }
+});

Also applies to: 170-170, 178-178, 187-187, 198-198

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fa3ad58 and bc88144.

📒 Files selected for processing (2)
  • backend/src/service/helperLink.service.js (6 hunks)
  • backend/src/test/unit/services/helperLink.test.js (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/src/service/helperLink.service.js
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build (22.x)
🔇 Additional comments (2)
backend/src/test/unit/services/helperLink.test.js (2)

76-78: LGTM! Proper transition to bulk creation.

The test correctly validates the new bulk creation approach, including proper parameter validation and transaction handling.

Also applies to: 89-90


96-96: LGTM! Proper error handling setup.

The error test correctly sets up the bulk creation stub and verifies transaction rollback.

@erenfn erenfn requested a review from swoopertr February 5, 2025 21:45
@erenfn erenfn merged commit 46ece4a into develop Feb 11, 2025
2 checks passed
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.

Helper link functionality
4 participants