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

019 nov 10 input value validation for the project #234

Conversation

popovaevgeniya
Copy link
Contributor

@popovaevgeniya popovaevgeniya commented Nov 12, 2024

Implemented validation for Create new project and Add a new risk popups

image
image
image

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced structured validation for selection fields and strings, enhancing user feedback.
    • Added new interfaces for better type safety in form components.
    • Implemented a popup rendering mechanism for creating new projects and managing risks.
  • Bug Fixes

    • Improved error handling and display in input fields and select components.
  • Style

    • Updated error border colors and button styling in the theme for better visual feedback.
  • Documentation

    • Enhanced documentation for new interfaces and validation functions.

@popovaevgeniya popovaevgeniya added the frontend Frontend related tasks/issues label Nov 12, 2024
@popovaevgeniya popovaevgeniya self-assigned this Nov 12, 2024
Copy link

coderabbitai bot commented Nov 12, 2024

Walkthrough

This pull request introduces several enhancements across multiple components in the application. Key changes include the addition of validation functions for form inputs, the refactoring of components to improve type safety and error handling, and the introduction of new interfaces for structured prop management. Components such as MitigationSection, RisksSection, and AddNewRiskForm have been updated to utilize these validations, while styling adjustments have been made to improve user feedback for error states. Additionally, a new PopupRender component has been created to manage popup state within the Home and RisksView pages.

Changes

File Change Summary
Clients/src/application/validations/selectValidation.ts Added feedback and selectValidation functions for structured feedback and validation logic.
Clients/src/application/validations/stringValidation.ts Modified checkStringValidation to change empty string validation logic based on minLength.
Clients/src/presentation/components/AddNewRiskForm/MitigationSection/index.tsx Introduced interfaces for props and form values, refactored event handling and validation logic.
Clients/src/presentation/components/AddNewRiskForm/RisksSection/index.tsx Similar updates as MitigationSection, with structured props and validation handling.
Clients/src/presentation/components/AddNewRiskForm/index.tsx Updated to accept closePopup prop and pass it to child components.
Clients/src/presentation/components/CreateProjectForm/index.tsx Added interfaces for form values and errors, refined state management and validation logic.
Clients/src/presentation/components/Inputs/Datepicker/index.tsx Added error prop to handle error messages and adjusted styling accordingly.
Clients/src/presentation/components/Inputs/Field/index.css Modified styles for input fields, including min-width and standardized border-radius.
Clients/src/presentation/components/Inputs/Field/index.tsx Enhanced error handling and visual feedback for input fields.
Clients/src/presentation/components/Inputs/Select/index.tsx Added isRequired and error props to manage validation states in the select component.
Clients/src/presentation/components/Popup/index.tsx Updated props for Popup, simplifying state management and removing unnecessary properties.
Clients/src/presentation/components/RiskLevel/index.tsx Introduced RiskLevelFormValues interface and updated event handling for selection changes.
Clients/src/presentation/pages/Home/index.tsx Added PopupRender component to manage popup state and removed direct navigation logic.
Clients/src/presentation/pages/ProjectView/RisksView/index.tsx Introduced PopupRender for encapsulating popup logic and updated props handling.
Clients/src/presentation/themes/light.ts Modified error border color and added new variant for MuiButton.

Possibly related PRs

  • 002 sep 20 vendor view design #20: The selectValidation function is utilized in the MitigationSection and RisksSection components for form validation, which is directly related to the new selectValidation function introduced in the main PR.

Suggested labels

Frontend Devs

Suggested reviewers

  • MatthewSharpOTU
  • melpsh

🐰 In the garden where bunnies play,
New validations hop in today!
With forms so neat and errors clear,
We dance with joy, let's give a cheer!
For every field, a guiding light,
Making our app a pure delight! 🌼


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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

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

Copy link

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

🧹 Outside diff range and nitpick comments (26)
Clients/src/application/validations/selectValidation.ts (2)

1-13: Consider enhancing type safety and encapsulation.

While the function is well-documented, we can improve it further:

+interface ValidationFeedback {
+  accepted: boolean;
+  message: string;
+}

-function feedback(accepted: boolean, message: string) {
+function feedback(accepted: boolean, message: string): ValidationFeedback {
     return {
       accepted,
       message,
     };
 }

Also, consider marking this as an internal helper by prefixing with an underscore since it's only used within this module.


15-21: Complete the JSDoc documentation.

The JSDoc is missing the @param title parameter description.

 /**
  * Select field validation
  *
+ * @param title - The display name of the field being validated.
  * @param value - The value to be validated.
  * @returns An object with `accepted` set to `true` if the value passes all validations,
  *          otherwise an object with `accepted` set to `false` and a `message` indicating the reason.
  */
Clients/src/presentation/components/AddNewRiskForm/index.tsx (1)

10-12: Consider adding JSDoc documentation for the interface.

The interface is well-defined but could benefit from documentation explaining its purpose and the closePopup function's expected behavior.

+/**
+ * Props for the AddNewRiskForm component
+ * @property closePopup - Function to close the form popup
+ */
interface AddNewRiskFormProps {
    closePopup: () => void
}
Clients/src/application/validations/stringValidation.ts (2)

Line range hint 1-108: Enhance user-facing error messages for better UX.

Since this validation is used in user-facing forms ("Create new project" and "Add a new risk" popups), consider making the error messages more user-friendly:

  1. For required fields:
-    return feedbackToString(false, `${title} is required.`);
+    return feedbackToString(false, `Please enter ${title.toLowerCase()}.`);
  1. For length constraints:
-      `${title} can't be shorter than ${minLength} characters.`
+      `${title} must be at least ${minLength} characters long.`
  1. For special characters, list the allowed characters:
-      `${title} must contain at least one special character.`
+      `${title} must contain at least one special character (!@#$%^&*()_+-=[]{};:'"\\|,.<>/?).`
  1. For email validation:
-      return feedbackToString(false, `Invalid ${title}.`);
+      return feedbackToString(false, `Please enter a valid email address.`);

Line range hint 1-108: Consider a more flexible validation architecture.

The current implementation could be enhanced for better maintainability and reusability:

  1. Extract validation rules into separate functions:
type ValidationRule = (value: string) => { valid: boolean; message: string };

const createLengthRule = (min: number, max: number): ValidationRule => 
  (value) => ({
    valid: value.length >= min && value.length <= max,
    message: `Must be between ${min} and ${max} characters`
  });

const createPatternRule = (pattern: RegExp, message: string): ValidationRule =>
  (value) => ({
    valid: pattern.test(value),
    message
  });
  1. Make validation configurable:
interface ValidationConfig {
  rules: ValidationRule[];
  stopOnFirst?: boolean;
}

function validate(value: string, config: ValidationConfig) {
  const errors = config.rules
    .map(rule => rule(value))
    .filter(result => !result.valid);
  
  return {
    valid: errors.length === 0,
    errors: errors.map(e => e.message)
  };
}

This approach would:

  • Make it easier to add/remove validation rules
  • Allow for custom validation rules
  • Support collecting multiple validation errors
  • Make testing individual rules easier
Clients/src/presentation/pages/ProjectView/RisksView/index.tsx (1)

78-78: Enhance accessibility for the popup trigger.

The popup trigger button should have proper ARIA labels and role attributes for better accessibility.

Pass accessibility props to the Popup component:

-<PopupRender />
+<PopupRender 
+  aria-label="Add new risk button"
+  role="button"
+/>
Clients/src/presentation/components/Popup/index.tsx (3)

Line range hint 72-77: Enhance accessibility implementation

While basic aria-describedby is implemented, the popup needs additional accessibility features:

  • Keyboard navigation (Escape key to close)
  • Focus trap within the popup when open
  • Additional ARIA attributes for the popup dialog

Consider these improvements:

 <BasePopup id={id} open={open} anchor={anchor}
+           role="dialog"
+           aria-modal="true"
+           aria-labelledby={`${id}-title`}
+           onKeyDown={(e) => e.key === 'Escape' && handleOpenOrClose?.(e as any)}
            style={{...}}>
   <Stack sx={styles.popupContent}>
-    <Typography variant="h1" component="div" sx={{...}}>
+    <Typography id={`${id}-title`} variant="h1" component="div" sx={{...}}>
       {popupTitle}
     </Typography>

Consider using a focus management library like focus-trap-react to handle focus properly.

Also applies to: 96-98


Line range hint 31-67: Improve styling maintainability and consistency

The current styling implementation has several areas for improvement:

  • Hardcoded color values bypass the theme system
  • Mixed usage of pixel values and theme spacing
  • Inline styles make it harder to maintain consistency

Consider these improvements:

 const styles = {
     openPopupButton: {
-        width: 120, height: 34,
+        width: theme.spacing(15),
+        height: theme.spacing(4.25),
         fontSize: 13,
         textTransform: "inherit",
-        backgroundColor: "#4C7DE7",
+        backgroundColor: theme.palette.primary.main,
         boxShadow: "none",
         borderRadius: 2,
-        border: "1px solid #175CD3",
+        border: `1px solid ${theme.palette.primary.dark}`,
         "&:hover": { boxShadow: "none" }
     },
     // Similar changes for other style objects...
 }

Consider moving these styles to a separate styled-components or emotion implementation for better maintainability.


Consider using stable MUI components instead of experimental API

The codebase is using MUI v6 (as seen from dependencies), but relies on an experimental Unstable_Popup component from @mui/base. Since MUI v6 provides stable alternatives:

  • Consider using stable components like Modal, Popper, or Popover from @mui/material based on your use case
  • These components are production-ready and less likely to introduce breaking changes in future updates
🔗 Analysis chain

Line range hint 5-5: Consider implications of using experimental MUI API

The component uses Unstable_Popup from MUI Base, which is an experimental API as indicated by the Unstable_ prefix. This could lead to breaking changes in future MUI updates.


Let me gather more information about the MUI Base package version and available Popup components.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if there's a stable alternative in the codebase
rg -l "import.*@mui/(base|material)/.*Popup" 

# Check package.json for MUI version to verify if stable version is available
fd -t f "package.json" --exec cat {} | jq '.dependencies["@mui/base"]'

Length of output: 181


Script:

#!/bin/bash
# Check all package.json files for MUI dependencies and their versions
fd -t f "package.json" --exec cat {} | jq '.dependencies | select(. != null) | with_entries(select(.key | startswith("@mui")))'

# Search for other Popup-related imports to understand usage patterns
rg -g '*.{ts,tsx,js,jsx}' -A 2 "import.*@mui.*Popup"

Length of output: 611

Clients/src/presentation/components/RiskLevel/index.tsx (1)

Line range hint 22-33: Consider enhancing risk calculation logic

The risk calculation logic could benefit from the following improvements:

  1. Extract threshold values as named constants
  2. Memoize the calculation to prevent unnecessary recalculations
  3. Add documentation explaining the risk calculation formula

Here's a suggested implementation:

+ const RISK_THRESHOLDS = {
+   LOW: 3,
+   MEDIUM: 6,
+   HIGH: 9
+ } as const;

+ /**
+  * Calculates risk level based on likelihood and severity scores
+  * Formula: Risk Score = Likelihood × Severity
+  * @param score - The calculated risk score
+  * @returns Object containing risk level text and associated color
+  */
- const getRiskLevel = (score: number): {text: string, color: string} => {
+ const getRiskLevel = useMemo(() => (score: number): {text: string, color: string} => {
-     if (score <= 3) {
+     if (score <= RISK_THRESHOLDS.LOW) {
          return RISK_LABELS.low;
-     } else if (score <= 6) {
+     } else if (score <= RISK_THRESHOLDS.MEDIUM) {
          return RISK_LABELS.medium;
-     } else if (score <= 9) {
+     } else if (score <= RISK_THRESHOLDS.HIGH) {
          return RISK_LABELS.high;
      } else {
          return RISK_LABELS.critical;
      }
- }
+ }, []);
Clients/src/presentation/components/Inputs/Datepicker/index.tsx (2)

43-45: Consider improving styling readability and specificity

While the logic is correct, the styling could be improved:

  1. The multi-line ternary operator could be simplified
  2. The use of !important suggests potential specificity issues that should be addressed through proper CSS cascade

Consider refactoring to:

-          border: error 
-            ? `1px solid ${theme.palette.status.error.border}!important` 
-            : `1px solid ${theme.palette.border.dark}!important`
+          border: `1px solid ${error ? theme.palette.status.error.border : theme.palette.border.dark}`

Also, consider reviewing the CSS specificity to eliminate the need for !important.


119-132: Enhance error message accessibility

While the error message implementation is solid, it could benefit from improved accessibility for screen readers.

Consider adding ARIA attributes:

       {error && (
         <Typography
           component="span"
           className="input-error"
+          role="alert"
+          aria-live="polite"
           color={theme.palette.status.error.text}
           mt={theme.spacing(2)}
           sx={{
             opacity: 0.8,
             fontSize: 11
           }}
         >
           {error}
         </Typography>
       )}

This ensures screen readers announce error messages when they appear.

Clients/src/presentation/pages/Home/index.tsx (2)

91-99: Enhance accessibility for popup trigger

The popup trigger button should have proper ARIA attributes for better accessibility.

 <Popup
   popupId="create-project-popup"
   popupContent={<CreateProjectForm />}
   openPopupButtonName="New project"
+  aria-haspopup="dialog"
+  aria-expanded={Boolean(anchor)}
   popupTitle="Create new project"
   popupSubtitle="Create a new project from scratch by filling in the following."
   handleOpenOrClose={handleOpenOrClose}
   anchor={anchor}
 />

109-109: Add error boundary and loading states

The popup integration should handle potential errors and loading states for better user experience.

-<PopupRender />
+<ErrorBoundary fallback={<ErrorMessage />}>
+  <Suspense fallback={<LoadingSpinner />}>
+    <PopupRender />
+  </Suspense>
+</ErrorBoundary>
Clients/src/presentation/components/Inputs/Select/index.tsx (2)

35-36: Update JSDoc documentation to include new props

The component's JSDoc comments should be updated to include the new isRequired and error props for better documentation coverage.

Add these to the existing JSDoc:

 * @param {object} [props.sx] - Additional styles to apply to the select component.
+* @param {boolean} [props.isRequired] - Flag to indicate if the field is required.
+* @param {string} [props.error] - Error message to display below the select input.
 */

67-71: Refactor duplicate error styling logic

The error styling logic is duplicated between normal and focused states. Consider extracting the common styling into a variable or using a more concise approach.

 sx={{
   ".MuiOutlinedInput-notchedOutline": {
-    border: error 
-      ? `1px solid ${theme.palette.status.error.border}!important` 
-      : `1px solid ${theme.palette.border.dark}!important`
+    border: `1px solid ${error ? theme.palette.status.error.border : theme.palette.border.dark}!important`
   },
   ".Mui-focused .MuiOutlinedInput-notchedOutline": {
-    border: error 
-      ? `1px solid ${theme.palette.status.error.border}!important` 
-      : `1px solid ${theme.palette.border.dark}!important`
+    border: `1px solid ${error ? theme.palette.status.error.border : theme.palette.border.dark}!important`
   }
 }}

Also, consider investigating why !important flags are necessary, as they might indicate potential style specificity issues.

Also applies to: 73-75

Clients/src/presentation/themes/light.ts (2)

60-60: Consider using semantic color tokens for error states

The error border color has been updated to a lighter shade (#FDA29B). While this change improves visibility, consider defining semantic color tokens for error states to maintain consistency across the application.

- border: "#FDA29B",
+ // Define in a separate color tokens file
+ border: tokens.error.border.light,

Group variant styling needs validation state handling

The group variant styling implementation is incomplete as it doesn't handle form validation states (error, warning, success). While both light and dark themes define these states in their palettes, the Button component's group variant doesn't utilize them. Consider adding validation state styles to maintain consistency with the design system.

  • Clients/src/presentation/themes/light.ts: Add validation state styles to the group variant implementation
  • Clients/src/presentation/themes/dark.ts: Ensure the same validation state handling is mirrored here
🔗 Analysis chain

Line range hint 91-108: Verify the group variant styling implementation

The styling for the new group variant looks good, with proper handling of both default and filled states. However, ensure that this styling is consistent with the design system and works well with the form validation states introduced in this PR.


Let me gather more information to verify the group variant styling implementation.


Let me gather one final piece of information to verify the form validation states.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent usage of the new group variant across components

# Look for components using the group variant
rg -l "variant=\"group\"" --type ts --type tsx

# Check for any custom button styling that might conflict
ast-grep --pattern 'styled(Button)' 

Length of output: 226


Script:

#!/bin/bash
# Search for Button component usage and styling
rg -l "variant.*group" --type ts
rg "Button.*variant" -A 3 --type ts

# Check theme configurations for button styling
fd "theme|style" -e ts -x cat {}

Length of output: 9561


Script:

#!/bin/bash
# Check for form validation states in themes and button components
rg "error|success|warning" -A 3 Clients/src/presentation/themes/light.ts
rg "error|success|warning" -A 3 Clients/src/presentation/themes/dark.ts

# Look for form validation related code
ast-grep --pattern 'props.error'
ast-grep --pattern 'props.variant === "group" && props.error'

Length of output: 811

Clients/src/presentation/components/Inputs/Field/index.tsx (2)

101-104: Simplify error border styling and fix formatting.

The error border styling can be improved for clarity and efficiency:

  1. Remove unnecessary whitespace after 'error'
  2. Consolidate redundant border definitions

Apply this diff to improve the code:

-          border: error 
-            ? `1px solid ${theme.palette.status.error.border}` 
-            : `1px solid ${theme.palette.border.dark}`,
-            borderColor: theme.palette.status.error.border,
+          border: `1px solid ${error ? theme.palette.status.error.border : theme.palette.border.dark}`,

219-219: Consider using theme-based font sizing.

Instead of using a hard-coded font size value, consider using the theme's typography system for better maintainability and consistency across the application.

Apply this diff to improve the code:

-              fontSize: 11
+              fontSize: theme.typography.caption.fontSize
Clients/src/presentation/components/CreateProjectForm/index.tsx (3)

118-118: Remove unnecessary console.log(values) statement.

The console.log(values) statement appears to be for debugging purposes and should be removed to prevent cluttering the console in production.

Apply this diff to remove the statement:

- console.log(values)

149-152: Fetch options for Select components dynamically.

The options for the Select components are currently hardcoded with placeholder values:

  • "Some value 1"
  • "Some value 2"
  • "Some value 3"

Consider fetching these options from an API or a data source to make the form dynamic and reflect actual data.

Also applies to: 164-167, 191-194, 206-209


68-103: Refactor validateForm function to reduce repetition.

The validateForm function contains repetitive code for validating each form field individually. This can make the code harder to maintain, especially as the form grows. Consider refactoring the validation logic to be more concise and scalable.

Here's an example of how you might refactor the function:

const validateForm = (): boolean => {
  const newErrors: FormErrors = {};

  const validations: { [key in keyof FormValues]: () => { accepted: boolean; message: string } } = {
    projectTitle: () => checkStringValidation("Project title", values.projectTitle, 1, 64),
    goal: () => checkStringValidation("Goal", values.goal, 1, 256),
    startDate: () => checkStringValidation("Start date", values.startDate, 1),
    users: () => selectValidation("Users", values.users),
    owner: () => selectValidation("Owner", values.owner),
    riskClassification: () => selectValidation("AI risk classification", values.riskClassification),
    typeOfHighRiskRole: () => selectValidation("Type of high risk role", values.typeOfHighRiskRole),
  };

  for (const field in validations) {
    const validation = validations[field as keyof FormValues]();
    if (!validation.accepted) {
      newErrors[field as keyof FormErrors] = validation.message;
    }
  }

  setErrors(newErrors);
  return Object.keys(newErrors).length === 0;
};
Clients/src/presentation/components/AddNewRiskForm/RisksSection/index.tsx (3)

122-128: Remove unnecessary async keyword in handleSubmit

The handleSubmit function is declared as async but does not contain any asynchronous operations. Unless you plan to add asynchronous code, the async keyword can be removed.

Apply this diff to remove the unnecessary async keyword:

-const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
+const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {

61-65: alert state is defined but never updated

The alert state is initialized and the Alert component is conditionally rendered, but alert is never updated in the code. As a result, the Alert component will not display any messages.

Consider setting the alert state where appropriate or remove it if it's not needed.

Also applies to: 132-140


277-277: Use isRequired prop for consistency

In previous Field components, the isRequired prop is used to indicate mandatory fields. Here, you're using isOptional. For consistency and to avoid confusion, consider using isRequired={false} for optional fields.

Apply this diff to use isRequired prop:

-    isOptional
+    isRequired={false}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between be85b86 and 36084c5.

📒 Files selected for processing (15)
  • Clients/src/application/validations/selectValidation.ts (1 hunks)
  • Clients/src/application/validations/stringValidation.ts (1 hunks)
  • Clients/src/presentation/components/AddNewRiskForm/MitigationSection/index.tsx (1 hunks)
  • Clients/src/presentation/components/AddNewRiskForm/RisksSection/index.tsx (1 hunks)
  • Clients/src/presentation/components/AddNewRiskForm/index.tsx (3 hunks)
  • Clients/src/presentation/components/CreateProjectForm/index.tsx (1 hunks)
  • Clients/src/presentation/components/Inputs/Datepicker/index.tsx (4 hunks)
  • Clients/src/presentation/components/Inputs/Field/index.css (1 hunks)
  • Clients/src/presentation/components/Inputs/Field/index.tsx (2 hunks)
  • Clients/src/presentation/components/Inputs/Select/index.tsx (5 hunks)
  • Clients/src/presentation/components/Popup/index.tsx (3 hunks)
  • Clients/src/presentation/components/RiskLevel/index.tsx (3 hunks)
  • Clients/src/presentation/pages/Home/index.tsx (2 hunks)
  • Clients/src/presentation/pages/ProjectView/RisksView/index.tsx (2 hunks)
  • Clients/src/presentation/themes/light.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • Clients/src/presentation/components/Inputs/Field/index.css
🔇 Additional comments (12)
Clients/src/application/validations/selectValidation.ts (1)

29-29: Verify the integration with form components.

The function is used in MitigationSection and RisksSection components. Let's verify the integration to ensure consistent usage.

✅ Verification successful

Integration with form components is properly implemented

The verification shows that selectValidation is correctly imported and consistently used across both components:

  • In RisksSection:
    • Validates action owner, AI lifecycle phase, risk category, assessment mapping, and controls mapping
  • In MitigationSection:
    • Validates mitigation status, current risk level, approver, and approval status

All validations follow the same pattern of checking the selection and setting appropriate error messages.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for imports and usage of selectValidation in the components
echo "Checking imports and usage in components..."
rg -A 3 "selectValidation" "Clients/src/presentation/components/AddNewRiskForm/"

Length of output: 5643

Clients/src/presentation/components/AddNewRiskForm/index.tsx (2)

14-14: LGTM! Clean component signature update.

The component signature is properly typed with FC and uses correct prop destructuring.


46-47: Verify closePopup implementation in child components.

The closePopup prop is correctly passed to both RiskSection and MitigationSection components. However, we should verify their implementations.

✅ Verification successful

Let me try a different approach to verify the implementation of closePopup in these components.


closePopup is properly implemented in both components

Both RiskSection and MitigationSection components:

  • Correctly define closePopup in their props interface as () => void
  • Properly receive the prop in their component definitions
  • Actually use the closePopup function in their implementations

The implementation is consistent and correct in both components.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that RiskSection and MitigationSection components properly implement the closePopup prop

# Check RiskSection implementation
echo "Checking RiskSection implementation..."
ast-grep --pattern 'interface $interface {
  $$$
  closePopup: () => void
  $$$
}' Clients/src/presentation/components/AddNewRiskForm/RisksSection/index.tsx

# Check MitigationSection implementation
echo "Checking MitigationSection implementation..."
ast-grep --pattern 'interface $interface {
  $$$
  closePopup: () => void
  $$$
}' Clients/src/presentation/components/AddNewRiskForm/MitigationSection/index.tsx

Length of output: 508


Script:

#!/bin/bash
# Search for RiskSection and MitigationSection component definitions and their usage of closePopup
echo "Checking RiskSection implementation..."
rg -A 10 "RiskSection.*=.*{" Clients/src/presentation/components/AddNewRiskForm/RisksSection/index.tsx

echo -e "\nChecking MitigationSection implementation..."
rg -A 10 "MitigationSection.*=.*{" Clients/src/presentation/components/AddNewRiskForm/MitigationSection/index.tsx

# Also check for any closePopup usage in these files
echo -e "\nChecking closePopup usage in RiskSection..."
rg "closePopup" Clients/src/presentation/components/AddNewRiskForm/RisksSection/index.tsx

echo -e "\nChecking closePopup usage in MitigationSection..."
rg "closePopup" Clients/src/presentation/components/AddNewRiskForm/MitigationSection/index.tsx

Length of output: 1269

Clients/src/presentation/components/RiskLevel/index.tsx (2)

7-16: Well-structured type definitions!

The new RiskLevelFormValues interface and updated RiskLevelProps with strongly-typed event handlers improve type safety and maintainability. The use of keyof ensures type-safe property access.


18-18: Implementation aligns well with type changes

The component correctly implements the new typed event handlers while maintaining existing functionality.

Also applies to: 43-43, 58-58

Clients/src/presentation/components/Inputs/Datepicker/index.tsx (2)

15-15: LGTM: Error prop type is well-defined

The error prop is correctly typed as an optional string, following TypeScript best practices.


26-26: LGTM: Props destructuring is consistent

The error prop is correctly destructured and maintains the component's existing pattern.

Clients/src/presentation/pages/Home/index.tsx (1)

93-93: Verify validation implementation in CreateProjectForm

The validation logic might be implemented in the CreateProjectForm component. Let's verify this.

✅ Verification successful

Validation is properly implemented in CreateProjectForm

The CreateProjectForm component has comprehensive validation implemented:

  • Form-level validation through validateForm() function
  • Field-level validations using:
    • checkStringValidation for text fields (project title, goal)
    • selectValidation for select fields (users, owner, risk classification, etc.)
    • Date validation for start date
  • Error states and messages for all form fields
  • Form submission is blocked until all validations pass
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for validation logic in CreateProjectForm
ast-grep --pattern 'function CreateProjectForm() {
  $$$
  validate$_($$$) {
    $$$
  }
  $$$
}'

# Search for any validation-related imports or functions
rg -l "validate|validation" --type typescript

Length of output: 182


Script:

#!/bin/bash
# Search for CreateProjectForm component implementation
ast-grep --pattern 'const CreateProjectForm = $_'

# Search for validation related code with ripgrep
rg "validate|validation" -A 5 -B 5

# Find the actual file containing CreateProjectForm
fd "CreateProjectForm"

Length of output: 49298


Script:

#!/bin/bash
# Search for CreateProjectForm implementation
cat Clients/src/presentation/components/CreateProjectForm/index.tsx

Length of output: 8362

Clients/src/presentation/components/Inputs/Select/index.tsx (1)

Line range hint 1-189: Overall implementation looks good!

The Select component is well-implemented with proper:

  • TypeScript typing
  • Theme integration
  • Error handling
  • Required field indication
  • Material-UI integration

The suggested accessibility improvements will make it more inclusive, but the core functionality is solid.

Clients/src/presentation/themes/light.ts (1)

Line range hint 3-7: LGTM: Type declaration for the new button variant

The type declaration for the group variant is correctly implemented using module augmentation for Material-UI's Button component.

Clients/src/presentation/components/Inputs/Field/index.tsx (1)

Line range hint 1-230: Verify integration with form validation.

The styling changes enhance error state visibility, which aligns with the PR's validation objectives. However, let's verify the integration with the validation logic in the "Create new project" and "Add a new risk" popups.

✅ Verification successful

Based on the search results, I can now generate a final response. The results show that:

  1. The Field component is used across multiple forms with proper validation integration
  2. Each form using the Field component has proper validation logic using checkStringValidation and selectValidation
  3. The error states are properly handled and displayed through the Field component's error prop

The Field component's error state styling changes are well integrated with form validation.

  • The component is used in authentication forms (Login, Register, SetNewPassword) with password validation
  • It's integrated in CreateProjectForm with project title validation
  • Used in AddNewRiskForm with risk name and mitigation plan validation
  • Profile settings use it for name and email validation

All these forms properly pass error states to the Field component, which then uses the new styling to display validation errors consistently.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check how the Field component is used with validation in the relevant popup components

# Search for Field component usage in popup components
echo "Searching for Field usage in popup components..."
rg -A 10 "import.*Field.*from.*components/Inputs/Field" --type typescript

# Search for validation logic connected to Field
echo "Searching for validation logic..."
rg "error.*Field" --type typescript

Length of output: 367


Script:

#!/bin/bash
# Let's try searching without file type restrictions since typescript extension isn't recognized

# Search for Field component usage in popup components
echo "Searching for Field usage in popup components..."
rg -A 10 "import.*Field.*from.*['\"].*Field['\"]"

# Search for validation logic connected to Field component
echo "Searching for validation-related props in Field usage..."
rg "Field.*error=[\"{]" -A 3

# Search for form validation logic
echo "Searching for form validation patterns..."
rg "const.*validate|handleValidation|validation" -A 5

Length of output: 38569

Clients/src/presentation/components/AddNewRiskForm/MitigationSection/index.tsx (1)

261-268: 🛠️ Refactor suggestion

Update the DatePicker label to 'Date of Assessment'.

The DatePicker component is labeled "Start date" but is associated with the dateOfAssessment field. The label should match the field for clarity.

Change the label as follows:

- label="Start date"
+ label="Date of Assessment"

Likely invalid or redundant comment.

Comment on lines +22 to +27
function selectValidation(title: string, value: number): {accepted: boolean; message: string} {
if (value === 0) {
return feedback(false, `${title} is required.`);
}
return feedback(true, "Success");
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Strengthen input validation.

The current validation has several potential issues:

  1. It assumes 0 is always invalid, which might not be true for all select fields.
  2. It doesn't validate for negative values.
  3. No type validation to ensure the value is actually a number.
-function selectValidation(title: string, value: number): {accepted: boolean; message: string} {
+function selectValidation(title: string, value: number): ValidationFeedback {
+    if (typeof value !== 'number') {
+        return feedback(false, `${title} must be a number.`);
+    }
+
+    if (value < 0) {
+        return feedback(false, `${title} cannot be negative.`);
+    }
+
     if (value === 0) {
         return feedback(false, `${title} is required.`);
     }
     return feedback(true, "Success");
 }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +44 to +49
(value.length === 0 ||
value === undefined ||
value === null ||
value === "" ||
value === " "
value === " ") &&
minLength > 0
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Optimize the empty string validation logic.

The current empty string validation can be improved in several ways:

  1. The checks for undefined and null are redundant as they would cause runtime errors before reaching this condition (TypeScript enforces string type).
  2. The empty string check value === "" is redundant as value.length === 0 covers this case.
  3. The single space check value === " " is too specific and doesn't handle multiple spaces.

Consider this improved implementation:

-    (value.length === 0  ||
-    value === undefined ||
-    value === null ||
-    value === "" ||
-    value === " ") && 
-    minLength > 0
+    minLength > 0 && value.trim().length === 0

This change:

  • Uses trim() to handle any amount of whitespace
  • Simplifies the empty check to a single condition
  • Evaluates minLength first for better short-circuiting
  • Maintains the same validation behavior while being more robust
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
(value.length === 0 ||
value === undefined ||
value === null ||
value === "" ||
value === " "
value === " ") &&
minLength > 0
minLength > 0 && value.trim().length === 0

Comment on lines +54 to +71
const PopupRender = () => {
const [anchor, setAnchor] = useState<null | HTMLElement>(null);
const handleOpenOrClose = (event: React.MouseEvent<HTMLElement>) => {
setAnchor(anchor ? null : event.currentTarget);
};

return (
<Popup
popupId="add-new-risk-popup"
popupContent={<AddNewRiskForm closePopup={() => setAnchor(null)} />}
openPopupButtonName="Add new risk"
popupTitle="Add a new risk"
popupSubtitle="Create a detailed breakdown of risks and their mitigation strategies to assist in documenting your risk management activities effectively."
handleOpenOrClose={handleOpenOrClose}
anchor={anchor}
/>
)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Move PopupRender outside RisksView to prevent recreation.

The PopupRender component is defined inside RisksView, causing it to be recreated on every render. This can impact performance and break component state.

Move and refactor the component like this:

-const PopupRender = () => {
+interface PopupRenderProps {
+  // Add any props if needed
+}
+
+const PopupRender: React.FC<PopupRenderProps> = React.memo(() => {
   const [anchor, setAnchor] = useState<null | HTMLElement>(null);
-  const handleOpenOrClose = (event: React.MouseEvent<HTMLElement>) => {
+  const handleOpenOrClose = (event: React.MouseEvent<HTMLButtonElement>) => {
     setAnchor(anchor ? null : event.currentTarget);
   };
   
   return (
     <Popup
       popupId="add-new-risk-popup" 
       popupContent={<AddNewRiskForm closePopup={() => setAnchor(null)} />} 
       openPopupButtonName="Add new risk"
       popupTitle="Add a new risk"
       popupSubtitle="Create a detailed breakdown of risks and their mitigation strategies to assist in documenting your risk management activities effectively."
       handleOpenOrClose={handleOpenOrClose}
       anchor={anchor}
     />
   )
-}
+});
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const PopupRender = () => {
const [anchor, setAnchor] = useState<null | HTMLElement>(null);
const handleOpenOrClose = (event: React.MouseEvent<HTMLElement>) => {
setAnchor(anchor ? null : event.currentTarget);
};
return (
<Popup
popupId="add-new-risk-popup"
popupContent={<AddNewRiskForm closePopup={() => setAnchor(null)} />}
openPopupButtonName="Add new risk"
popupTitle="Add a new risk"
popupSubtitle="Create a detailed breakdown of risks and their mitigation strategies to assist in documenting your risk management activities effectively."
handleOpenOrClose={handleOpenOrClose}
anchor={anchor}
/>
)
}
interface PopupRenderProps {
// Add any props if needed
}
const PopupRender: React.FC<PopupRenderProps> = React.memo(() => {
const [anchor, setAnchor] = useState<null | HTMLElement>(null);
const handleOpenOrClose = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchor(anchor ? null : event.currentTarget);
};
return (
<Popup
popupId="add-new-risk-popup"
popupContent={<AddNewRiskForm closePopup={() => setAnchor(null)} />}
openPopupButtonName="Add new risk"
popupTitle="Add a new risk"
popupSubtitle="Create a detailed breakdown of risks and their mitigation strategies to assist in documenting your risk management activities effectively."
handleOpenOrClose={handleOpenOrClose}
anchor={anchor}
/>
)
});

return (
<Popup
popupId="add-new-risk-popup"
popupContent={<AddNewRiskForm closePopup={() => setAnchor(null)} />}
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

🛠️ Refactor suggestion

Add error handling for form submission failures

The form submission in RisksSection lacks proper error handling. The current implementation:

  • Only validates the form input
  • Makes a backend request without try-catch
  • Closes the popup without waiting for the request result
  • Doesn't handle or display backend errors to the user
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    if (validateForm()) {
-       //request to the backend
-       closePopup();
+       try {
+           await submitRiskToBackend(values);
+           closePopup();
+       } catch (error) {
+           setAlert({
+               variant: "error",
+               title: "Error",
+               body: "Failed to add risk. Please try again.",
+               isToast: true
+           });
+       }
    }
}
🔗 Analysis chain

Add error handling for form submission.

The AddNewRiskForm is rendered without any error handling for form submission failures.

Let's verify the error handling in AddNewRiskForm:

Consider adding error handling:

-popupContent={<AddNewRiskForm closePopup={() => setAnchor(null)} />}
+popupContent={
+  <AddNewRiskForm 
+    closePopup={() => setAnchor(null)}
+    onError={(error) => {
+      console.error('Failed to add risk:', error);
+      // Add error notification here
+    }}
+  />
+}
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if AddNewRiskForm has error handling
ast-grep --pattern 'const AddNewRiskForm = ({ closePopup }) => {
  $$$
  catch($_) {
    $$$
  }
  $$$
}'

Length of output: 107


Script:

#!/bin/bash
# Let's first find the AddNewRiskForm component file
fd "AddNewRiskForm" --type f

# Then let's examine its content for error handling patterns
rg -A 10 "AddNewRiskForm" --type tsx

# Also check for try-catch or error handling patterns in mutation/submission logic
rg "try.*catch|handleSubmit|onSubmit|mutation" --type tsx -A 10 "AddNewRiskForm"

Length of output: 202


Script:

#!/bin/bash
# Let's try without file type restriction since tsx isn't recognized
rg -A 10 "AddNewRiskForm"

# Also search for form submission and error handling patterns in the same files
rg "try.*catch|handleSubmit|onSubmit|mutation" $(fd "AddNewRiskForm" --type f)

Length of output: 10469


Script:

#!/bin/bash
# Let's examine the handleSubmit implementation in RisksSection
rg -B 5 -A 15 "const handleSubmit = async \(event: React\.FormEvent<HTMLFormElement>\)" Clients/src/presentation/components/AddNewRiskForm/RisksSection/index.tsx

Length of output: 740

Comment on lines +13 to +14
handleOpenOrClose?: (event: React.MouseEvent<HTMLElement>) => void,
anchor: null | HTMLElement
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Make handleOpenOrClose required to ensure proper popup control

The handleOpenOrClose prop is marked as optional while anchor is required. Since the popup's visibility depends on anchor, the handler should be required to ensure the popup can always be controlled.

Apply this change to the interface:

-    handleOpenOrClose?: (event: React.MouseEvent<HTMLElement>) => void,
+    handleOpenOrClose: (event: React.MouseEvent<HTMLElement>) => void,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
handleOpenOrClose?: (event: React.MouseEvent<HTMLElement>) => void,
anchor: null | HTMLElement
handleOpenOrClose: (event: React.MouseEvent<HTMLElement>) => void,
anchor: null | HTMLElement

Comment on lines +209 to +218
label="Start date"
date={values.deadline ? dayjs(values.deadline) : null}
handleDateChange={(e) => handleDateChange("deadline", e)}
sx={{
width: 130,
"& input": { width: 85 }
}}
isRequired
error={errors.deadline}
/>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update the DatePicker label to 'Deadline'.

The DatePicker component is labeled "Start date" but is bound to the deadline field. To avoid confusion, the label should accurately reflect the field's purpose.

Change the label as follows:

- label="Start date"
+ label="Deadline"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
label="Start date"
date={values.deadline ? dayjs(values.deadline) : null}
handleDateChange={(e) => handleDateChange("deadline", e)}
sx={{
width: 130,
"& input": { width: 85 }
}}
isRequired
error={errors.deadline}
/>
label="Deadline"
date={values.deadline ? dayjs(values.deadline) : null}
handleDateChange={(e) => handleDateChange("deadline", e)}
sx={{
width: 130,
"& input": { width: 85 }
}}
isRequired
error={errors.deadline}
/>

Comment on lines +103 to +110
const deadline = checkStringValidation("Recommendations", values.deadline, 1);
if (!deadline.accepted) {
newErrors.deadline = deadline.message;
}
const dateOfAssessment = checkStringValidation("Recommendations", values.dateOfAssessment, 1);
if (!dateOfAssessment.accepted) {
newErrors.dateOfAssessment = dateOfAssessment.message;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct the validation labels for 'deadline' and 'dateOfAssessment'.

The validateForm function uses the label "Recommendations" when validating the 'deadline' and 'dateOfAssessment' fields, which is incorrect and may cause misleading error messages.

Update the validation labels:

- const deadline = checkStringValidation("Recommendations", values.deadline, 1);
+ const deadline = checkStringValidation("Deadline", values.deadline, 1);

- const dateOfAssessment = checkStringValidation("Recommendations", values.dateOfAssessment, 1);
+ const dateOfAssessment = checkStringValidation("Date of Assessment", values.dateOfAssessment, 1);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const deadline = checkStringValidation("Recommendations", values.deadline, 1);
if (!deadline.accepted) {
newErrors.deadline = deadline.message;
}
const dateOfAssessment = checkStringValidation("Recommendations", values.dateOfAssessment, 1);
if (!dateOfAssessment.accepted) {
newErrors.dateOfAssessment = dateOfAssessment.message;
}
const deadline = checkStringValidation("Deadline", values.deadline, 1);
if (!deadline.accepted) {
newErrors.deadline = deadline.message;
}
const dateOfAssessment = checkStringValidation("Date of Assessment", values.dateOfAssessment, 1);
if (!dateOfAssessment.accepted) {
newErrors.dateOfAssessment = dateOfAssessment.message;
}

Comment on lines +71 to +73
const handleOnSelectChange = (prop: keyof MitigationFormValues) => (event: SelectChangeEvent<string | number>) => {
setValues({ ...values, [prop]: event.target.value });
setErrors({ ...errors, [prop]: "" });
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure numeric values are correctly handled in handleOnSelectChange.

The handleOnSelectChange function may assign string values to numeric fields in values, since event.target.value is a string. This can lead to type issues and unexpected behavior.

Modify the function to parse numeric values when updating numeric fields:

const handleOnSelectChange = (prop: keyof MitigationFormValues) => (event: SelectChangeEvent<string | number>) => {
-    setValues({ ...values, [prop]: event.target.value });
+    const value = typeof values[prop] === 'number' ? Number(event.target.value) : event.target.value;
+    setValues({ ...values, [prop]: value });
     setErrors({ ...errors, [prop]: "" });
};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleOnSelectChange = (prop: keyof MitigationFormValues) => (event: SelectChangeEvent<string | number>) => {
setValues({ ...values, [prop]: event.target.value });
setErrors({ ...errors, [prop]: "" });
const handleOnSelectChange = (prop: keyof MitigationFormValues) => (event: SelectChangeEvent<string | number>) => {
const value = typeof values[prop] === 'number' ? Number(event.target.value) : event.target.value;
setValues({ ...values, [prop]: value });
setErrors({ ...errors, [prop]: "" });

Comment on lines +67 to 70
const handleOnSelectChange = (prop: keyof RiskFormValues) => (event: SelectChangeEvent<string | number>) => {
setValues({ ...values, [prop]: event.target.value });
setErrors({ ...errors, [prop]: "" });
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Type conversion needed for select inputs

In handleOnSelectChange, the event.target.value returns a string, but you are assigning it to properties in values that expect a number. This can lead to type inconsistencies and runtime errors.

Apply this diff to ensure proper type conversion:

const handleOnSelectChange = (prop: keyof RiskFormValues) => (event: SelectChangeEvent<string | number>) => {
-    setValues({ ...values, [prop]: event.target.value });
+    setValues({ ...values, [prop]: Number(event.target.value) });
    setErrors({ ...errors, [prop]: "" });
};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleOnSelectChange = (prop: keyof RiskFormValues) => (event: SelectChangeEvent<string | number>) => {
setValues({ ...values, [prop]: event.target.value });
setErrors({ ...errors, [prop]: "" });
};
const handleOnSelectChange = (prop: keyof RiskFormValues) => (event: SelectChangeEvent<string | number>) => {
setValues({ ...values, [prop]: Number(event.target.value) });
setErrors({ ...errors, [prop]: "" });
};

<Divider />
<Typography sx={{ fontSize: 16, fontWeight: 600, mt: 6.5 }}>Calculate risk level</Typography>
<Typography sx={{ fontSize: theme.typography.fontSize, mb: 8 }}>The Risk Level is calculated by multiplying the Likelihood and Severity scores. By assigning these scores, the risk level will be determined based on your inputs.</Typography>
<RiskLevel likelihood={values.likelihood} riskSeverity={values.riskSeverity} handleOnSelectChange={handleOnSelectChange} />
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure riskLevel is calculated and updated

The riskLevel in values is not being updated based on likelihood and riskSeverity, which is necessary for accurate risk assessment.

Consider updating riskLevel whenever likelihood or riskSeverity changes:

// Inside handleOnSelectChange
const handleOnSelectChange = (prop: keyof RiskFormValues) => (event: SelectChangeEvent<string | number>) => {
    const newValue = Number(event.target.value);
    const newValues = { ...values, [prop]: newValue };
+   if (prop === 'likelihood' || prop === 'riskSeverity') {
+       newValues.riskLevel = newValues.likelihood * newValues.riskSeverity;
+   }
    setValues(newValues);
    setErrors({ ...errors, [prop]: "" });
};

Committable suggestion skipped: line range outside the PR's diff.

@MuhammadKhalilzadeh MuhammadKhalilzadeh merged commit f2769a0 into bluewave-labs:master Nov 12, 2024
1 check passed
This was referenced Nov 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
frontend Frontend related tasks/issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants