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

fix(haskolagatt): Small fixes in application #16726

Merged
merged 6 commits into from
Nov 6, 2024

Conversation

johannaagma
Copy link
Member

@johannaagma johannaagma commented Nov 5, 2024

What

Program selection step:

  • display alertMessage if programList is empty
  • clear program selection when selecting school
  • save universityName and programName in answers when using preDetermined selection
  • fix default value for modeOfDelivery (not always ON_SITE)
  • make sure modeOfDelivery is not cleared when going back and forth
  • make sure modeOfDelivery is reset when selecting program

Overview step:

  • display attachments
  • display other document
  • format date
  • show country name not code
  • show degree level name not code

Checklist:

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • Formatting passes locally with my changes
  • I have rebased against main before asking for a review

Summary by CodeRabbit

  • New Features

    • Introduced hidden validation for mode of delivery in forms.
    • Added enhanced document review component for better presentation of attachments.
    • Implemented dynamic rendering of educational details based on user input.
    • Added new alert messages for empty program lists to improve user experience.
    • Added utility functions for formatting dates and retrieving country names and degree level labels.
    • Enhanced degree level selection with dynamic options.
  • Bug Fixes

    • Simplified function signatures for better clarity and maintainability.
  • Documentation

    • Updated message definitions to enhance user feedback.
  • Chores

    • Removed deprecated components and optimized imports across various files.

-display alertMessage if programList is empty
-clear program selection when selecting school
-save universityName and programName in answers when using preDetermined selection
-fix default value for modeOfDelivery (not always ON_SITE)
-make sure modeOfDelivery is not cleared when going back and forth
-make sure modeOfDelivery is reset when selecting program
-display attachments
-display other document
-format date
-show country name not code
-show degree level name not code
Copy link
Contributor

coderabbitai bot commented Nov 5, 2024

Walkthrough

The pull request introduces various changes across multiple components within the university application template. Key modifications include the addition of a new validation component, HiddenValidation, and the refactoring of existing components such as DetailsRepeaterItem, ProgramSelection, and OtherDocumentsReview. The changes streamline the handling of educational details, improve conditional rendering, and enhance the overall structure of the forms. Additionally, utility functions for formatting and retrieving labels are added, while some components are removed or replaced to optimize functionality.

Changes

File Change Summary
libs/application/templates/university/src/fields/EducationDetails/DetailsRepeaterItem.tsx Added import for degreeLevelOptions, modified props by removing field and goToScreen, updated Box margin, refactored SelectController to use degreeLevelOptions, wrapped InputController in Box.
libs/application/templates/university/src/fields/HiddenTextInput/index.tsx Removed HiddenTextInput component.
libs/application/templates/university/src/fields/HiddenValidation/index.tsx Added new HiddenValidation component for form validation.
libs/application/templates/university/src/fields/Overview/index.tsx Imported getChosenProgram, modified rendering logic for OtherDocumentsReview based on showOtherDocuments.
libs/application/templates/university/src/fields/ProgramSelection/index.tsx Simplified props, renamed variables for clarity, added state management for program selection, and updated rendering logic.
libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx Updated to use SummaryBlock, made route property mandatory, added extraApplicationFields property.
libs/application/templates/university/src/fields/Review/SchoolCareerReview.tsx Enhanced rendering of educational details with new utility functions for formatting.
libs/application/templates/university/src/fields/Review/index.tsx Added import for OtherDocumentsReview, updated logic for displaying documents.
libs/application/templates/university/src/fields/index.ts Replaced export of HiddenTextInput with HiddenValidation.
libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/Exemption.ts Simplified condition function by removing externalData.
libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/NotFinishedEducation.ts Adjusted import statement and simplified condition function.
libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/ThirdLevelEducation.ts Moved import statement and simplified condition function.
libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/degreeLevelOptions.ts Removed degreeLevelOptions export.
libs/application/templates/university/src/forms/UniversityForm/InformationSection/ModeOfDeliverySubSection.ts Added a hidden validation field.
libs/application/templates/university/src/forms/UniversityForm/InformationSection/ProgramSubSection.ts Added a hidden input field to the form.
libs/application/templates/university/src/forms/UniversityForm/InformationSection/UserInformationSubSection.ts Added doesNotRequireAnswer property to alert message field.
libs/application/templates/university/src/lib/constants.ts Added degreeLevelOptions constant.
libs/application/templates/university/src/lib/dataSchema.ts Exported OtherDocumentsSchema, renamed modeOfDeliverInformationSchema, updated schema references.
libs/application/templates/university/src/lib/messages/information.ts Added new messages for empty program list warnings.
libs/application/templates/university/src/lib/messages/review.ts Modified defaultMessage values for labels.
libs/application/templates/university/src/shared/types.ts Added OtherDocumentsDetailsItem type, modified visibility of ProgramExtraApplicationField.
libs/application/templates/university/src/utils/formatDate.ts Added formatDateStr function.
libs/application/templates/university/src/utils/getCountryName.ts Added getCountryName function.
libs/application/templates/university/src/utils/getDegreeLevelLabel.ts Added getDegreeLevelLabel function.
libs/application/templates/university/src/utils/index.ts Added exports for new utility functions.

Possibly related PRs

Suggested labels

automerge

Suggested reviewers

  • Rikkiabb
  • eirikurn
  • Valur

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.

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.

@johannaagma
Copy link
Member Author

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Nov 5, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

codecov bot commented Nov 5, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 36.54%. Comparing base (8bdbd53) to head (cb334d0).
Report is 5 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #16726      +/-   ##
==========================================
- Coverage   36.54%   36.54%   -0.01%     
==========================================
  Files        6890     6890              
  Lines      143640   143640              
  Branches    40926    41047     +121     
==========================================
- Hits        52488    52487       -1     
- Misses      91152    91153       +1     
Flag Coverage Δ
air-discount-scheme-backend 54.04% <ø> (ø)
air-discount-scheme-web 0.00% <ø> (ø)
api 3.37% <ø> (ø)
api-domains-air-discount-scheme 36.99% <ø> (ø)
api-domains-assets 26.71% <ø> (ø)
api-domains-auth-admin 48.48% <ø> (ø)
api-domains-communications 39.76% <ø> (ø)
api-domains-criminal-record 47.44% <ø> (ø)
api-domains-driving-license 44.46% <ø> (ø)
api-domains-education 31.24% <ø> (ø)
api-domains-health-insurance 34.28% <ø> (ø)
api-domains-mortgage-certificate 34.65% <ø> (ø)
api-domains-payment-schedule 41.22% <ø> (ø)
application-api-files 56.54% <ø> (ø)
application-core 71.87% <ø> (+0.24%) ⬆️
application-system-api 41.11% <ø> (ø)
application-template-api-modules 27.68% <ø> (+<0.01%) ⬆️
application-templates-accident-notification 29.21% <ø> (ø)
application-templates-car-recycling 3.12% <ø> (ø)
application-templates-criminal-record 26.26% <ø> (ø)
application-templates-driving-license 18.40% <ø> (ø)
application-templates-estate 12.18% <ø> (ø)
application-templates-example-payment 25.17% <ø> (ø)
application-templates-financial-aid 15.56% <ø> (ø)
application-templates-general-petition 23.40% <ø> (ø)
application-templates-inheritance-report 6.52% <ø> (ø)
application-templates-marriage-conditions 15.20% <ø> (ø)
application-templates-mortgage-certificate 43.55% <ø> (ø)
application-templates-parental-leave 29.93% <ø> (ø)
application-types 6.60% <ø> (ø)
application-ui-components 1.27% <ø> (ø)
application-ui-shell 20.86% <ø> (ø)
clients-charge-fjs-v2 24.11% <ø> (ø)
clients-driving-license 40.16% <ø> (ø)
clients-driving-license-book 43.41% <ø> (ø)
clients-financial-statements-inao 48.94% <ø> (ø)
clients-license-client 1.83% <ø> (ø)
clients-regulations 42.23% <ø> (ø)
clients-rsk-company-registry 29.76% <ø> (ø)
clients-rsk-personal-tax-return 38.00% <ø> (ø)
clients-smartsolutions 12.77% <ø> (ø)
clients-syslumenn 49.17% <ø> (ø)
cms 0.42% <ø> (ø)
cms-translations 38.89% <ø> (ø)
content-search-toolkit 8.14% <ø> (ø)
contentful-apps 4.69% <ø> (ø)
dokobit-signing 62.50% <ø> (ø)
download-service 44.24% <ø> (ø)
email-service 60.33% <ø> (ø)
feature-flags 90.40% <ø> (ø)
file-storage 52.53% <ø> (ø)
financial-aid-backend 51.25% <ø> (ø)
judicial-system-api 19.57% <ø> (ø)
judicial-system-audit-trail 68.61% <ø> (ø)
judicial-system-backend 55.17% <ø> (ø)
judicial-system-message 66.73% <ø> (ø)
judicial-system-message-handler 47.62% <ø> (ø)
judicial-system-scheduler 70.37% <ø> (ø)
license-api 42.60% <ø> (+0.05%) ⬆️
nest-config 77.81% <ø> (ø)
nest-feature-flags 50.90% <ø> (ø)
nova-sms 61.80% <ø> (ø)
portals-admin-regulations-admin 1.85% <ø> (ø)
portals-core 15.96% <ø> (ø)
services-auth-admin-api 52.47% <ø> (+0.02%) ⬆️
services-auth-delegation-api 58.20% <ø> (ø)
services-auth-ids-api 52.08% <ø> (-0.01%) ⬇️
services-auth-personal-representative 45.61% <ø> (+0.02%) ⬆️
services-auth-personal-representative-public 41.74% <ø> (-0.05%) ⬇️
services-auth-public-api 49.58% <ø> (ø)
services-endorsements-api 53.59% <ø> (ø)
services-sessions 65.38% <ø> (+0.04%) ⬆️
services-university-gateway 48.86% <ø> (-0.44%) ⬇️
services-user-notification 46.84% <ø> (ø)
services-user-profile 61.83% <ø> (+0.07%) ⬆️
web 1.80% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

see 1 file with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 85f8c21...cb334d0. Read the comment docs.

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

🧹 Outside diff range and nitpick comments (25)
libs/application/templates/university/src/utils/getDegreeLevelLabel.ts (1)

3-5: Consider improving type safety and error handling.

The implementation could benefit from the following improvements:

  1. Explicit return type for better type safety
  2. Proper error handling for invalid values
  3. Memoization for better performance when used in React components

Consider applying these changes:

-export const getDegreeLevelLabel = (value: string | undefined) => {
+type DegreeLevel = typeof degreeLevelOptions[number]['value'];
+
+export const getDegreeLevelLabel = (value: string | undefined): string => {
+  // Validate that value is a valid degree level
+  if (value && !degreeLevelOptions.some(option => option.value === value)) {
+    console.warn(`Invalid degree level value: ${value}`);
+  }
   return degreeLevelOptions.find((x) => x.value === value)?.label || ''
 }
+
+// Memoized version for use in React components
+export const useDegreeLabel = (value: string | undefined): string => {
+  return useMemo(() => getDegreeLevelLabel(value), [value]);
+}
libs/application/templates/university/src/utils/formatDate.ts (2)

6-7: Add input validation for date string format.

While the implementation is functional, it would be more robust with proper date string validation.

Consider adding validation:

 export const formatDateStr = (dateStr: string | undefined): string => {
+  if (!dateStr) return '';
+  const date = new Date(dateStr);
+  if (isNaN(date.getTime())) return '';
+  return formatDate(date);
-  dateStr ? formatDate(new Date(dateStr)) : ''
 }

3-4: Consider consistent handling of invalid dates.

The formatDate function checks for the existence of date but not its validity. For consistency with the new formatDateStr function, consider handling Invalid Date cases.

 export const formatDate = (date: Date): string =>
-  date ? format(new Date(date), 'dd.MM.yyyy') : ''
+  date && !isNaN(date.getTime()) ? format(date, 'dd.MM.yyyy') : ''
libs/application/templates/university/src/utils/getCountryName.ts (1)

3-7: Consider adding type safety improvements and documentation.

The function implementation is clean and handles edge cases well. However, there are some improvements that could make it more maintainable and type-safe.

Consider applying these enhancements:

+/** 
+ * Retrieves the localized country name for a given country code
+ * @param code - ISO country code
+ * @returns The country name in Icelandic if available, otherwise in English, or empty string if not found
+ */
-export const getCountryName = (code: string | undefined) => {
+export const getCountryName = (code: string | undefined): string => {
   const countries = getAllCountryCodes()
   const country = countries.find((x) => x.code === code)
   return country?.name_is || country?.name || ''
 }

Additionally, consider these optimizations if this function is called frequently:

  1. Memoize the getAllCountryCodes() result to avoid repeated array creation
  2. Add input validation for invalid country codes if needed
libs/application/templates/university/src/fields/HiddenValidation/index.tsx (4)

1-5: Improve type imports for better tree-shaking

Consider using more specific imports to enable better tree-shaking:

-import { Box } from '@island.is/island-ui/core'
+import Box from '@island.is/island-ui/core/Box'

7-9: Enhance documentation with JSDoc comments

The current comments explain the purpose but could be more structured. Consider adding a proper JSDoc comment block to improve IDE integration and documentation.

-// Special validation to make sure chosenMode is not empty,
-// since we sometimes need to set the value to dummy 'EMPTY_MODE_OF_DELIVERY'
-// when trying to clear the field in the programSelection step
+/**
+ * Special validation component for the mode of delivery field.
+ * Ensures chosenMode is not empty by validating against a dummy value 'EMPTY_MODE_OF_DELIVERY'
+ * which is used when clearing the field in the programSelection step.
+ */

10-13: Add proper TypeScript interface for component props

The component uses FieldBaseProps but should have its own interface extending it for better type safety and documentation.

+interface HiddenValidationProps extends FieldBaseProps {
+  setBeforeSubmitCallback?: (callback: () => Promise<[boolean, string | null]>) => void;
+}

-export const HiddenValidation: FC<FieldBaseProps> = ({
+export const HiddenValidation: FC<HiddenValidationProps> = ({

25-25: Consider adding data-testid for testing purposes

Since this is a hidden component that affects form validation, adding a test ID would make it easier to test:

-  return <Box hidden={true}></Box>
+  return <Box hidden={true} data-testid="hidden-mode-validation"></Box>
libs/application/templates/university/src/lib/constants.ts (1)

41-58: Consider enhancing type safety and immutability.

While the implementation is functional, we could improve type safety and maintainability.

Consider applying these improvements:

+export const enum DegreeLevel {
+  FRAMHALDSSKOLI = 'framhaldsskoli',
+  BACHELORS = 'bachelors',
+  MASTERS = 'masters',
+  DOCTORS = 'doctors',
+}

+export type DegreeLevelOption = {
+  readonly label: string;
+  readonly value: DegreeLevel;
+}

-export const degreeLevelOptions = [
+export const degreeLevelOptions: readonly DegreeLevelOption[] = Object.freeze([
   {
     label: formerEducation.labels.educationDetails.framhaldsskoliSelectionLabel,
-    value: 'framhaldsskoli',
+    value: DegreeLevel.FRAMHALDSSKOLI,
   },
   {
     label: formerEducation.labels.educationDetails.bachelorsSelectionLabel,
-    value: 'bachelors',
+    value: DegreeLevel.BACHELORS,
   },
   {
     label: formerEducation.labels.educationDetails.mastersSelectionLabel,
-    value: 'masters',
+    value: DegreeLevel.MASTERS,
   },
   {
     label: formerEducation.labels.educationDetails.doctorsSelectionLabel,
-    value: 'doctors',
+    value: DegreeLevel.DOCTORS,
   },
-]
+])

These changes provide:

  1. Type safety through the DegreeLevel enum
  2. Runtime immutability with Object.freeze
  3. Better TypeScript type inference and documentation
  4. Consistent usage of the degree level values across the codebase
libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/Exemption.ts (1)

18-21: LGTM! Consider enhancing type safety.

The removal of the unused externalData parameter improves code clarity. The function remains focused and maintains its single responsibility.

Consider adding a return type annotation for better type safety:

-  condition: (answers: FormValue) => {
+  condition: (answers: FormValue): boolean => {
libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/NotFinishedEducation.ts (1)

18-21: Consider adding explicit return type annotation.

While the function works correctly, adding an explicit return type would improve type safety and documentation.

-  condition: (answers: FormValue) => {
+  condition: (answers: FormValue): boolean => {
libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx (2)

28-30: Add type guard for safer type casting.

The type casting could be made safer with a type guard check.

-const answers = application.answers as UniversityApplication
-const otherDocuments =
-  answers.otherDocuments as Array<OtherDocumentsDetailsItem>
+const answers = application.answers as UniversityApplication
+const otherDocuments = answers.otherDocuments 
+  ? (answers.otherDocuments as Array<OtherDocumentsDetailsItem>)
+  : []

32-76: Consider extracting attachment rendering to a separate component.

The nested rendering logic could be simplified by extracting it to a reusable component.

interface AttachmentProps {
  fileName: string;
}

const Attachment: FC<AttachmentProps> = ({ fileName }) => (
  <Box display="flex" alignItems="center" marginBottom="smallGutter">
    <Box marginRight={1} display="flex" alignItems="center">
      <Icon color="blue400" icon="document" size="small" type="outline" />
    </Box>
    <Text>{fileName}</Text>
  </Box>
);

This would improve reusability and make the main component cleaner.

🧰 Tools
🪛 Biome

[error] 48-52: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

libs/application/templates/university/src/fields/Review/index.tsx (1)

36-40: Consider extracting complex conditions into descriptive variables

While the logic is correct, readability could be improved by breaking down the conditions.

Consider this refactoring:

  const chosenProgram = getChosenProgram(application.externalData, answers)
- const showOtherDocuments =
-   !!chosenProgram &&
-   chosenProgram.extraApplicationFields &&
-   chosenProgram.extraApplicationFields.length > 0
+ const hasExtraFields = chosenProgram?.extraApplicationFields?.length > 0
+ const showOtherDocuments = !!chosenProgram && hasExtraFields
libs/application/templates/university/src/forms/UniversityForm/InformationSection/UserInformationSubSection.ts (1)

Line range hint 1-143: Well-structured component following best practices!

The component demonstrates excellent practices:

  • Leverages reusable form building functions from the core library
  • Uses proper TypeScript types for external data
  • Follows a modular structure that enables tree-shaking

Consider extracting the default value transformations into separate utility functions if they are used across different forms, to enhance reusability.

libs/application/templates/university/src/fields/Overview/index.tsx (3)

51-55: Consider adding explicit type annotation for chosenProgram.

While the code is functionally correct, adding an explicit type annotation would improve code maintainability and documentation.

-  const chosenProgram = getChosenProgram(application.externalData, answers)
+  const chosenProgram: UniversityProgram | null = getChosenProgram(application.externalData, answers)

101-110: Add null check for extraApplicationFields access.

While the showOtherDocuments check helps prevent most issues, adding an null check operator when accessing extraApplicationFields would make the code more robust.

-          extraApplicationFields={chosenProgram.extraApplicationFields}
+          extraApplicationFields={chosenProgram?.extraApplicationFields ?? []}

Line range hint 22-27: Enhance TypeScript usage in component props.

While the component uses TypeScript, consider extracting and exporting the specific props interface for better reusability and documentation:

export interface OverviewProps extends FieldBaseProps {
  application: Application;
  field: Field;
  goToScreen: (screen: string) => void;
  refetch: () => void;
}

export const Overview: FC<OverviewProps> = ({
  application,
  field,
  goToScreen,
  refetch,
}) => {
libs/application/templates/university/src/forms/UniversityForm/InformationSection/ModeOfDeliverySubSection.ts (1)

123-127: Consider adding TypeScript improvements and documentation

The hidden validation field is a good addition to handle mode of delivery validation. However, consider these improvements:

  1. Add type safety:
type CustomFieldComponent = 'HiddenValidation' | /* other valid components */;

buildCustomField<CustomFieldComponent>({
  id: `${Routes.MODEOFDELIVERYINFORMATION}.chosenModeHiddenValidation`,
  title: '',
  component: 'HiddenValidation',
})
  1. Add a comment explaining the validation rules and purpose of this hidden field.
libs/application/templates/university/src/lib/messages/information.ts (1)

84-94: Consider extracting warning messages to a separate section.

Since these are warning messages, consider moving them to a dedicated warnings section within programSelection or at the root level. This would improve organization and make it easier to maintain warning messages across different sections.

Example restructuring:

export const information = {
  warnings: defineMessages({
    emptyProgramList: {
      title: {
        id: 'uni.application:information.warnings.emptyProgramList.title',
        defaultMessage: 'Athugið',
        description: 'Warning empty program list title',
      },
      message: {
        id: 'uni.application:information.warnings.emptyProgramList.message',
        defaultMessage:
          'Ekki er hægt að sækja um nám fyrir þennan skóla að svo stöddu',
        description: 'Warning empty program list message',
      },
    },
  }),
  // ... rest of the structure
}
libs/application/templates/university/src/fields/ProgramSelection/index.tsx (3)

Line range hint 22-25: Consider using a more efficient deep copy approach.

The current deep copy implementation using JSON.parse(JSON.stringify()) can be inefficient and may not handle certain JavaScript types correctly (like Date objects or undefined values).

Consider using a more efficient approach:

-const sortedProgramsDeepCopy = JSON.parse(
-  JSON.stringify(programs),
-) as Array<Program>
+const sortedProgramsDeepCopy = programs.map(program => ({...program}))

191-207: Optimize string concatenation logic.

The getProgramNameAndExtra function can be simplified and made more maintainable.

Consider refactoring to:

 const getProgramNameAndExtra = (program: Program) => {
-  const extra =
-    lang === 'is' && program
-      ? program.specializationNameIs
-        ? ` - ${formatMessage(
-            information.labels.programSelection.specializationLabel,
-          )}: ${program.specializationNameIs}`
-        : ''
-      : program && program.specializationNameEn
-      ? ` - ${formatMessage(
-          information.labels.programSelection.specializationLabel,
-        )}: ${program.specializationNameEn}`
-      : ''
+  if (!program) return ''
+  
+  const name = lang === 'is' ? program.nameIs : program.nameEn
+  const specialization = lang === 'is' ? program.specializationNameIs : program.specializationNameEn
+  
+  if (!specialization) return name
+  
+  const label = formatMessage(information.labels.programSelection.specializationLabel)
+  return `${name} - ${label}: ${specialization}`
-  return (
-    program && `${lang === 'is' ? program.nameIs : program.nameEn}${extra}`
-  )
 }
🧰 Tools
🪛 Biome

[error] 199-199: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


243-254: Extract sorting logic for better maintainability.

The sorting logic within the options mapping could be extracted into a separate function for better maintainability and reusability.

Consider extracting the sorting logic:

+const sortPrograms = (programs: Program[], lang: string) => {
+  return programs.sort((x, y) => {
+    const nameX = lang === 'is' ? x.nameIs : x.nameEn
+    const nameY = lang === 'is' ? y.nameIs : y.nameEn
+    return nameX.localeCompare(nameY)
+  })
+}

// In the render:
-options={filteredPrograms
-  .sort((x, y) => {
-    if (lang === 'is' && x.nameIs > y.nameIs) return 1
-    else if (lang === 'en' && x.nameEn > y.nameEn) return 1
-    else return -1
-  })
+options={sortPrograms(filteredPrograms, lang)
libs/application/templates/university/src/fields/Review/SchoolCareerReview.tsx (1)

Line range hint 1-264: Consider breaking down the component for better maintainability

The component is quite large and handles multiple types of education information. Consider breaking it down into smaller, focused components:

  1. ExemptionReview
  2. ThirdLevelEducationReview
  3. NotFinishedEducationReview
  4. FinishedEducationReview

This would improve:

  • Maintainability
  • Reusability across different NextJS applications
  • Testing capabilities
  • Code readability

Would you like me to provide an example implementation of this restructuring?

🧰 Tools
🪛 Biome

[error] 53-57: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

libs/application/templates/university/src/fields/EducationDetails/DetailsRepeaterItem.tsx (1)

Line range hint 1-411: Consider implementing form validation.

While the current changes improve the UI, consider adding form validation for:

  • Date ranges (beginningDate should be before endDate)
  • Required fields when degreeFinished is true
  • File upload size and type restrictions
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2d97d44 and 5295eb4.

📒 Files selected for processing (25)
  • libs/application/templates/university/src/fields/EducationDetails/DetailsRepeaterItem.tsx (4 hunks)
  • libs/application/templates/university/src/fields/HiddenTextInput/index.tsx (0 hunks)
  • libs/application/templates/university/src/fields/HiddenValidation/index.tsx (1 hunks)
  • libs/application/templates/university/src/fields/Overview/index.tsx (3 hunks)
  • libs/application/templates/university/src/fields/ProgramSelection/index.tsx (5 hunks)
  • libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx (1 hunks)
  • libs/application/templates/university/src/fields/Review/SchoolCareerReview.tsx (9 hunks)
  • libs/application/templates/university/src/fields/Review/index.tsx (3 hunks)
  • libs/application/templates/university/src/fields/index.ts (1 hunks)
  • libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/Exemption.ts (1 hunks)
  • libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/NotFinishedEducation.ts (1 hunks)
  • libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/ThirdLevelEducation.ts (1 hunks)
  • libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/degreeLevelOptions.ts (0 hunks)
  • libs/application/templates/university/src/forms/UniversityForm/InformationSection/ModeOfDeliverySubSection.ts (2 hunks)
  • libs/application/templates/university/src/forms/UniversityForm/InformationSection/ProgramSubSection.ts (2 hunks)
  • libs/application/templates/university/src/forms/UniversityForm/InformationSection/UserInformationSubSection.ts (1 hunks)
  • libs/application/templates/university/src/lib/constants.ts (2 hunks)
  • libs/application/templates/university/src/lib/dataSchema.ts (3 hunks)
  • libs/application/templates/university/src/lib/messages/information.ts (1 hunks)
  • libs/application/templates/university/src/lib/messages/review.ts (1 hunks)
  • libs/application/templates/university/src/shared/types.ts (3 hunks)
  • libs/application/templates/university/src/utils/formatDate.ts (1 hunks)
  • libs/application/templates/university/src/utils/getCountryName.ts (1 hunks)
  • libs/application/templates/university/src/utils/getDegreeLevelLabel.ts (1 hunks)
  • libs/application/templates/university/src/utils/index.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • libs/application/templates/university/src/fields/HiddenTextInput/index.tsx
  • libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/degreeLevelOptions.ts
✅ Files skipped from review due to trivial changes (1)
  • libs/application/templates/university/src/fields/index.ts
🧰 Additional context used
📓 Path-based instructions (22)
libs/application/templates/university/src/fields/EducationDetails/DetailsRepeaterItem.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/fields/HiddenValidation/index.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/fields/Overview/index.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/fields/ProgramSelection/index.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/fields/Review/SchoolCareerReview.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/fields/Review/index.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/Exemption.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/NotFinishedEducation.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/ThirdLevelEducation.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/forms/UniversityForm/InformationSection/ModeOfDeliverySubSection.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/forms/UniversityForm/InformationSection/ProgramSubSection.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/forms/UniversityForm/InformationSection/UserInformationSubSection.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/lib/constants.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/lib/dataSchema.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/lib/messages/information.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/lib/messages/review.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/shared/types.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/utils/formatDate.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/utils/getCountryName.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/utils/getDegreeLevelLabel.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/utils/index.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
🪛 Biome
libs/application/templates/university/src/fields/ProgramSelection/index.tsx

[error] 199-199: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx

[error] 48-52: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

libs/application/templates/university/src/fields/Review/SchoolCareerReview.tsx

[error] 53-57: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)


[error] 136-140: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)


[error] 239-243: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🔇 Additional comments (31)
libs/application/templates/university/src/utils/index.ts (2)

3-5: LGTM! Good practices for utility exports.

The new exports follow good practices:

  • Each utility is in its own file, enabling effective tree-shaking
  • Function names are clear and descriptive
  • The barrel file pattern promotes reusability across the application

3-5: Verify type exports from utility modules.

Since this is in the libs directory, ensure that these utility modules export their TypeScript types for consumers.

✅ Verification successful

These utility functions don't require type exports

After reviewing the implementation of these utility functions, I can confirm that they don't need to export any additional types because:

  • getChosenProgram uses types imported from other modules (ExternalData, FormValue, Program)
  • getDegreeLevelLabel and getCountryName are simple string manipulation functions that don't introduce any new types
  • All type information needed by consumers is already available through the function signatures and imported types
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the new utility modules export their types

# Test: Look for type exports in the new utility files
echo "Checking type exports in utility modules..."
for util in "getChosenProgram" "getDegreeLevelLabel" "getCountryName"; do
  echo "Checking $util..."
  rg -t typescript "export.*type|interface|enum" "$(fd -t f "${util}.ts" libs)"
done

Length of output: 1081


Script:

#!/bin/bash
# Let's try a different approach using ast-grep to check for type exports
echo "Checking getChosenProgram.ts..."
ast-grep --pattern 'export type $_' libs/application/templates/university/src/utils/getChosenProgram.ts

echo -e "\nChecking getDegreeLevelLabel.ts..."
ast-grep --pattern 'export type $_' libs/application/templates/university/src/utils/getDegreeLevelLabel.ts

echo -e "\nChecking getCountryName.ts..."
ast-grep --pattern 'export type $_' libs/application/templates/university/src/utils/getCountryName.ts

# Also check for interface exports
echo -e "\nChecking for interfaces..."
for file in getChosenProgram getDegreeLevelLabel getCountryName; do
    echo "In $file.ts:"
    ast-grep --pattern 'export interface $_' "libs/application/templates/university/src/utils/$file.ts"
done

# Let's also look at the actual content of these files
echo -e "\nFile contents:"
for file in getChosenProgram getDegreeLevelLabel getCountryName; do
    echo -e "\n=== Content of $file.ts ==="
    cat "libs/application/templates/university/src/utils/$file.ts"
done

Length of output: 3155

libs/application/templates/university/src/utils/getDegreeLevelLabel.ts (1)

1-1: Verify the imported constant's structure.

Let's ensure the imported degreeLevelOptions has the expected structure for type safety.

✅ Verification successful

The imported constant has the correct structure

The degreeLevelOptions constant is correctly defined as an array of objects, where each object contains the expected label and value properties. The structure is consistent with type safety requirements, containing four education levels: framhaldsskoli, bachelors, masters, and doctors.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the structure of degreeLevelOptions constant
# Expected: Array of objects with 'value' and 'label' properties

# Search for the definition of degreeLevelOptions
ast-grep --pattern 'export const degreeLevelOptions = $_'

Length of output: 1651

libs/application/templates/university/src/utils/getCountryName.ts (1)

1-2: LGTM! Clean import from shared utils.

The import is properly scoped to only what's needed from the shared utilities package.

libs/application/templates/university/src/forms/UniversityForm/InformationSection/ProgramSubSection.ts (2)

6-6: LGTM: Clean import addition

The import follows the established pattern and maintains tree-shakability.


25-28: Verify mode of delivery state persistence

The hidden input implementation looks good and aligns with the requirement to maintain mode of delivery state during navigation. However, we should verify the interaction with program selection.

Let's check for any related state management code:

✅ Verification successful

Mode of delivery state persistence is properly implemented

The implementation correctly handles mode of delivery state persistence through:

  • Automatic state preservation via the hidden input
  • Proper state management in ProgramSelection component that:
    • Preserves the chosen mode when navigating back and forth
    • Sets appropriate mode when a program is selected (default mode if program has single delivery mode, or 'EMPTY_MODE_OF_DELIVERY' otherwise)
  • Valid schema validation through ModeOfDeliverInformationSchema
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Look for mode of delivery state management in related files
# Expected: Find state updates when program is selected

# Search for files handling mode of delivery state
rg -l "chosenMode" --type ts

# Search for program selection state management
rg -B 3 -A 3 "ProgramSelection.*setFieldValue.*chosenMode" --type ts

Length of output: 621


Script:

#!/bin/bash
# Let's check the implementation of ProgramSelection component and mode of delivery state handling

# Check ProgramSelection implementation
ast-grep --pattern 'export const ProgramSelection = $$$'

# Check for any state updates related to chosenMode in these files
rg -B 5 -A 5 "chosenMode" libs/application/templates/university/src/fields/ProgramSelection/index.tsx

# Also check the ModeOfDeliverySubSection implementation
rg -B 5 -A 5 "chosenMode" libs/application/templates/university/src/forms/UniversityForm/InformationSection/ModeOfDeliverySubSection.ts

# Check the data schema to understand the relationship
rg -B 5 -A 5 "chosenMode" libs/application/templates/university/src/lib/dataSchema.ts

Length of output: 3034

libs/application/templates/university/src/lib/constants.ts (1)

2-2: LGTM!

The import statement is clean and the imported messages are properly utilized.

libs/application/templates/university/src/shared/types.ts (2)

6-6: LGTM! Well-structured type addition.

The new OtherDocumentsDetailsItem type follows the established pattern of using zod for type inference, maintaining consistency with other similar types in the file.

Also applies to: 21-21


65-68: LGTM! Good decision to export the type.

Making ProgramExtraApplicationField exportable improves reusability across the application, which aligns with the coding guidelines for library code.

libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/Exemption.ts (1)

Line range hint 1-52: Component structure aligns with library guidelines.

The component demonstrates good practices for library code:

  • Proper use of TypeScript for type safety
  • Reusable structure using core utility functions
  • Modular design with shared constants and messages
  • Tree-shakeable exports
libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/NotFinishedEducation.ts (1)

11-11: LGTM! Import statement is well-organized.

The combined import of related constants follows good practices and enables effective tree-shaking.

libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx (1)

6-17: LGTM! Well-structured type definitions and imports.

The changes improve type safety by making route required and properly typing extraApplicationFields. The component maintains good reusability by using shared types and UI components.

libs/application/templates/university/src/fields/Review/index.tsx (2)

15-16: LGTM: Imports follow best practices

The new imports are properly structured for effective tree-shaking and follow TypeScript conventions.


100-109: Verify type safety for extraApplicationFields prop

While the implementation is correct, ensure that the extraApplicationFields prop type in OtherDocumentsReview matches the type from chosenProgram.extraApplicationFields.

✅ Verification successful

Type safety for extraApplicationFields prop is properly implemented

The type checking is correctly implemented:

  • OtherDocumentsReview component's Props interface explicitly defines extraApplicationFields as Array<ProgramExtraApplicationField>
  • ProgramExtraApplicationField is a well-defined type in the shared types module with proper structure
  • This matches the type expected from chosenProgram.extraApplicationFields as seen in the program model
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for OtherDocumentsReview component definition to verify prop types
ast-grep --pattern 'interface $_ {
  extraApplicationFields: $_;
}'

Length of output: 69


Script:

#!/bin/bash
# Let's try to find the OtherDocumentsReview component definition and its props
ast-grep --pattern 'const OtherDocumentsReview = ({ $$ }: $_) => $_'

# Also search for any type definitions related to OtherDocumentsReview
rg "OtherDocumentsReview.*Props" -A 5

# Let's also check the type of extraApplicationFields in the chosenProgram
rg "chosenProgram.*type" -A 5

Length of output: 750


Script:

#!/bin/bash
# Let's find the Props interface definition in OtherDocumentsReview.tsx
rg "interface Props" -A 10 libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx

# Also check imports to understand the type of extraApplicationFields
rg "^import.*extraApplicationFields" libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx

Length of output: 501


Script:

#!/bin/bash
# Let's find the type definition of ProgramExtraApplicationField
rg "type.*ProgramExtraApplicationField" -A 5

# Also check where this type is imported from in OtherDocumentsReview
rg "^import.*ProgramExtraApplicationField" libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx

# And check the type of chosenProgram.extraApplicationFields
rg "chosenProgram:.*{" -A 10

Length of output: 1898

libs/application/templates/university/src/lib/messages/review.ts (1)

Line range hint 1-116: LGTM for reusability!

The message definitions follow good practices for reusability across NextJS apps:

  • Uses react-intl for internationalization
  • Messages are properly organized by context
  • Each message has a clear description
  • Exports are properly typed via TypeScript
libs/application/templates/university/src/lib/dataSchema.ts (3)

122-124: LGTM! Well-structured schema for document attachments.

The schema follows TypeScript best practices and promotes reusability through proper exportation. The optional attachments array allows flexibility in document handling.


141-141: Schema references updated correctly.

The changes to UniversitySchema properly integrate the new schemas:

  • modeOfDeliveryInformation uses the renamed schema
  • otherDocuments is now an optional array of the new OtherDocumentsSchema

These updates support the PR objectives for handling attachments and mode of delivery.

Also applies to: 151-151


126-134: Verify the impact of the new 'EMPTY_MODE_OF_DELIVERY' enum value.

The addition of 'EMPTY_MODE_OF_DELIVERY' aligns with the PR objective to fix the default value issue. However, we should verify its usage across the codebase.

✅ Verification successful

Let me gather more context about the implementation details of how this enum value is being used.


'EMPTY_MODE_OF_DELIVERY' is safely implemented as a temporary state

The implementation is correct and safe. 'EMPTY_MODE_OF_DELIVERY' is used as a temporary state in two specific scenarios:

  • As a placeholder when clearing the mode of delivery field in program selection
  • When a program has multiple delivery modes, requiring user selection

Key safety measures are in place:

  • HiddenValidation component prevents form submission with 'EMPTY_MODE_OF_DELIVERY'
  • The value is only used internally for UI state management
  • It doesn't affect the backend as validation prevents its propagation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage of EMPTY_MODE_OF_DELIVERY and related validation
# Expected: Find references in components that handle mode of delivery selection

# Search for EMPTY_MODE_OF_DELIVERY usage
echo "Searching for EMPTY_MODE_OF_DELIVERY usage:"
rg "EMPTY_MODE_OF_DELIVERY"

# Search for ModeOfDelivery enum usage
echo -e "\nSearching for ModeOfDelivery enum usage:"
rg "ModeOfDelivery\."

Length of output: 2841


Script:

#!/bin/bash
# Check the implementation details around EMPTY_MODE_OF_DELIVERY usage
echo "Checking HiddenValidation implementation:"
cat libs/application/templates/university/src/fields/HiddenValidation/index.tsx

echo -e "\nChecking ProgramSelection implementation:"
cat libs/application/templates/university/src/fields/ProgramSelection/index.tsx

echo -e "\nChecking ModeOfDelivery enum definition:"
rg -A 5 "enum ModeOfDelivery"

Length of output: 11180

libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/ThirdLevelEducation.ts (2)

13-13: LGTM! Import statement follows best practices.

The combined import of degreeLevelOptions and Routes from constants follows tree-shaking practices and improves code organization.


22-25: LGTM! Function signature simplified while maintaining functionality.

The condition function has been simplified by removing the unused externalData parameter while maintaining its core functionality.

Let's verify that the externalData parameter is not used elsewhere in similar condition functions:

✅ Verification successful

The previous ast-grep pattern might have been too strict. Let's try with ripgrep to find condition functions and their implementations. The pattern looks for "condition:" followed by parameters and arrow function syntax, showing 3 lines of context after each match to understand the implementation.


This will help us verify if other similar condition functions in the same directory use the externalData parameter, which will give us better context about whether removing it was appropriate.


This will help us understand if the file actually needs the externalData parameter by checking its implementation and dependencies.


Removal of unused externalData parameter is correct

Looking at the implementation of ThirdLevelEducation.ts, the condition function only uses the answers parameter to check the education options via getValueViaPath. The externalData parameter was not used in the function's logic at all. The removal maintains clean code principles by eliminating unused parameters while preserving the core functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other condition functions that might still use externalData
ast-grep --pattern 'condition: ($params) => {
  $$$
}'

Length of output: 56


Script:

#!/bin/bash
# Search for condition functions with a more flexible pattern
rg -U "condition:\s*\([^)]*\)\s*=>" -A 3

Length of output: 427038


Script:

#!/bin/bash
# Let's specifically look at the condition functions in the UniversityForm directory to understand the pattern
rg -U "condition:\s*\([^)]*externalData[^)]*\)\s*=>" libs/application/templates/university/src/forms/UniversityForm/

Length of output: 1092


Script:

#!/bin/bash
# Let's look at the specific file and its imports to understand the context better
cat libs/application/templates/university/src/forms/UniversityForm/FormerEducation/EducationDetails/ThirdLevelEducation.ts

Length of output: 4854

libs/application/templates/university/src/forms/UniversityForm/InformationSection/UserInformationSubSection.ts (1)

96-96: LGTM! The alert message field is correctly marked as not requiring an answer.

The addition of doesNotRequireAnswer: true is appropriate for an informational alert that doesn't expect user input.

libs/application/templates/university/src/fields/Overview/index.tsx (1)

19-19: LGTM! Clean import of shared utility.

The import follows TypeScript conventions and promotes code reusability by utilizing a shared utility function.

libs/application/templates/university/src/forms/UniversityForm/InformationSection/ModeOfDeliverySubSection.ts (1)

7-7: LGTM: Import follows best practices

The import is correctly placed and follows good tree-shaking practices by importing only the needed function from the core package.

libs/application/templates/university/src/lib/messages/information.ts (1)

84-94: LGTM! The new messages follow the established patterns.

The new warning messages are well-structured with:

  • Properly namespaced IDs
  • Clear descriptions
  • Consistent formatting with existing messages
libs/application/templates/university/src/fields/ProgramSelection/index.tsx (1)

Line range hint 1-15: LGTM! Well-structured imports following best practices.

The imports are properly organized and follow tree-shaking best practices by importing specific components. TypeScript types are appropriately used for props definition.

libs/application/templates/university/src/fields/Review/SchoolCareerReview.tsx (2)

14-15: LGTM: Clean import structure

The imports are well-organized and follow TypeScript best practices, supporting reusability across different NextJS applications.


83-85: LGTM: Improved data formatting

The use of utility functions for formatting degree levels, country names, and dates improves readability and internationalization support. The implementation is consistent throughout the component.

Also applies to: 103-111, 188-190, 209-218

libs/application/templates/university/src/fields/EducationDetails/DetailsRepeaterItem.tsx (4)

26-26: LGTM! Good practice moving options to constants.

Moving degree level options to a separate constants file improves maintainability and reusability.


124-124: LGTM! Improved spacing consistency.

Increasing marginBottom from 1 to 2 provides better visual separation between repeater items.


182-185: LGTM! Enhanced i18n handling.

The refactored degree level options mapping improves internationalization by:

  • Using the centralized options from constants
  • Properly formatting labels using the i18n system

393-409: LGTM! Better visual hierarchy.

Adding a Box wrapper with marginTop for the moreDetails field:

  • Improves visual spacing consistency
  • Creates better separation from preceding elements

@datadog-island-is
Copy link

datadog-island-is bot commented Nov 5, 2024

Datadog Report

All test runs 0000a92 🔗

4 Total Test Services: 0 Failed, 4 Passed
➡️ Test Sessions change in coverage: 8 no change

Test Services
Service Name Failed Known Flaky New Flaky Passed Skipped Total Time Code Coverage Change Test Service View
api 0 0 0 4 0 2.36s 1 no change Link
application-system-api 0 0 0 120 2 3m 22.45s 1 no change Link
application-template-api-modules 0 0 0 123 0 2m 2.16s 1 no change Link
application-ui-shell 0 0 0 74 0 30.98s 1 no change Link

@johannaagma johannaagma marked this pull request as ready for review November 5, 2024 15:53
@johannaagma johannaagma requested a review from a team as a code owner November 5, 2024 15:53
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: 3

🧹 Outside diff range and nitpick comments (8)
libs/application/templates/university/src/lib/constants.ts (2)

41-41: Consider using TypeScript union type for mode of delivery.

Instead of using a string literal as a sentinel value, consider creating a TypeScript union type for mode of delivery that includes this empty state. This would provide better type safety and autocompletion.

export type ModeOfDelivery = 'ON_SITE' | 'REMOTE' | 'EMPTY_MODE_OF_DELIVERY'
export const EMPTY_MODE_OF_DELIVERY: ModeOfDelivery = 'EMPTY_MODE_OF_DELIVERY'

43-60: Enhance type safety for degree level options.

Good job on centralizing degree level options and using translation messages for labels. To improve type safety and maintainability, consider adding TypeScript types:

export type DegreeLevel = 'framhaldsskoli' | 'bachelors' | 'masters' | 'doctors'

interface DegreeOption {
  label: string
  value: DegreeLevel
}

export const degreeLevelOptions: readonly DegreeOption[] = [
  // ... existing options
] as const

This change would:

  • Prevent typos in degree level values
  • Ensure consistent typing across the application
  • Make the options array immutable
libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx (2)

28-30: Consider using type assertion alternatives.

Instead of using type assertion with as, consider using type guards or runtime validation for better type safety.

-  const answers = application.answers as UniversityApplication
-  const otherDocuments =
-    answers.otherDocuments as Array<OtherDocumentsDetailsItem>
+  const answers = application.answers
+  if (!isUniversityApplication(answers)) {
+    return null
+  }
+  const otherDocuments = answers.otherDocuments
+  if (!Array.isArray(otherDocuments)) {
+    return null
+  }

32-76: Consider enhancing component reusability.

The component could be made more reusable across different NextJS applications by:

  1. Extracting the document display logic into a separate component
  2. Making the formatting and layout more configurable

Would you like me to provide an example of how to extract this into a reusable component?

🧰 Tools
🪛 Biome

[error] 48-52: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

libs/application/templates/university/src/fields/ProgramSelection/index.tsx (3)

40-47: Consider optimizing state initialization.

The state variables could be initialized with values from answers to avoid unnecessary re-renders. Consider combining related states into a single object for better state management.

-  const [selectedUniversity, setSelectedUniversity] = useState<string>()
-  const [selectedProgram, setSelectedProgram] = useState<string>()
-  const [filteredPrograms, setFilteredPrograms] = useState<Array<Program>>([])
+  const [selection, setSelection] = useState({
+    university: universityAnswer || undefined,
+    program: programAnswer || undefined,
+    filteredPrograms: [] as Array<Program>
+  })

191-207: Simplify program name formatting logic.

The string concatenation logic could be simplified using template literals and optional chaining.

-    const extra =
-      lang === 'is' && program
-        ? program.specializationNameIs
-          ? ` - ${formatMessage(
-              information.labels.programSelection.specializationLabel,
-            )}: ${program.specializationNameIs}`
-          : ''
-        : program && program.specializationNameEn
-        ? ` - ${formatMessage(
-            information.labels.programSelection.specializationLabel,
-          )}: ${program.specializationNameEn}`
-        : ''
+    const specializationName = lang === 'is' 
+      ? program?.specializationNameIs 
+      : program?.specializationNameEn
+    const extra = specializationName
+      ? ` - ${formatMessage(
+          information.labels.programSelection.specializationLabel
+        )}: ${specializationName}`
+      : ''
🧰 Tools
🪛 Biome

[error] 199-199: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


243-254: Extract sorting logic to improve readability.

Consider moving the sorting logic to a separate function for better maintainability.

+  const sortPrograms = (programs: Program[]) => 
+    programs.sort((x, y) => {
+      const name1 = lang === 'is' ? x.nameIs : x.nameEn
+      const name2 = lang === 'is' ? y.nameIs : y.nameEn
+      return name1.localeCompare(name2)
+    })

   options={filteredPrograms
-    .sort((x, y) => {
-      if (lang === 'is' && x.nameIs > y.nameIs) return 1
-      else if (lang === 'en' && x.nameEn > y.nameEn) return 1
-      else return -1
-    })
+    .sort(sortPrograms)
libs/application/templates/university/src/fields/Review/SchoolCareerReview.tsx (1)

15-15: Consider exporting formatting utilities at package level

Since this is in the libs directory, consider making the formatting utilities (formatDateStr, getCountryName, getDegreeLevelLabel) available at the package level for reuse across different NextJS applications.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 5295eb4 and 0766c8c.

📒 Files selected for processing (7)
  • libs/application/templates/university/src/fields/HiddenValidation/index.tsx (1 hunks)
  • libs/application/templates/university/src/fields/ProgramSelection/index.tsx (5 hunks)
  • libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx (1 hunks)
  • libs/application/templates/university/src/fields/Review/SchoolCareerReview.tsx (9 hunks)
  • libs/application/templates/university/src/lib/constants.ts (2 hunks)
  • libs/application/templates/university/src/lib/dataSchema.ts (4 hunks)
  • libs/application/templates/university/src/lib/messages/review.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • libs/application/templates/university/src/fields/HiddenValidation/index.tsx
  • libs/application/templates/university/src/lib/dataSchema.ts
  • libs/application/templates/university/src/lib/messages/review.ts
🧰 Additional context used
📓 Path-based instructions (4)
libs/application/templates/university/src/fields/ProgramSelection/index.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/fields/Review/SchoolCareerReview.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
libs/application/templates/university/src/lib/constants.ts (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
🪛 Biome
libs/application/templates/university/src/fields/ProgramSelection/index.tsx

[error] 199-199: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx

[error] 48-52: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

libs/application/templates/university/src/fields/Review/SchoolCareerReview.tsx

[error] 137-141: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)


[error] 240-244: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🔇 Additional comments (6)
libs/application/templates/university/src/fields/Review/OtherDocumentsReview.tsx (1)

6-17: LGTM! Well-structured imports and type definitions.

The changes demonstrate good TypeScript practices with explicit typing and proper interface definitions. The specific imports support effective tree-shaking.

libs/application/templates/university/src/fields/ProgramSelection/index.tsx (3)

3-3: LGTM: Props interface simplified and imports well-organized.

The component follows TypeScript best practices and maintains good tree-shaking capabilities with specific imports. The props interface simplification improves component responsibility.

Also applies to: 5-5, 16-16


54-58: Add cleanup for async operations to prevent memory leaks.

The async operation could lead to race conditions if the component unmounts before the data is fetched.


Line range hint 1-277: Overall implementation looks good with room for optimization.

The component is well-structured, follows TypeScript best practices, and handles edge cases appropriately. The changes improve error handling and user experience. Consider implementing the suggested optimizations for better maintainability.

🧰 Tools
🪛 Biome

[error] 199-199: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

libs/application/templates/university/src/fields/Review/SchoolCareerReview.tsx (2)

14-15: LGTM: Clean import organization

The new imports are well-organized and properly scoped to support the formatting enhancements.


84-86: Verify error handling in formatting utilities

The new formatting utilities improve data presentation, but we should ensure they handle edge cases gracefully:

  • getDegreeLevelLabel for invalid degree levels
  • getCountryName for unknown country codes
  • formatDateStr for invalid date strings

Let's check the implementation of these utilities:

Also applies to: 104-106, 110-112, 116-116, 189-191, 210-210, 215-215, 219-219

✅ Verification successful

Let me check the implementation of degreeLevelOptions and getAllCountryCodes to fully understand the error handling:


Let me check the implementation of countryCodes and formatDate to complete the analysis:


Based on the analysis of the utility functions' implementations, I can now generate the final response:

Edge cases are properly handled in formatting utilities

The formatting utilities have appropriate fallback handling:

  • getDegreeLevelLabel returns empty string for undefined/invalid degree levels
  • getCountryName returns empty string for undefined/invalid country codes
  • formatDateStr returns empty string for undefined/invalid date strings

All utilities use optional chaining and nullish coalescing to handle edge cases gracefully, making them safe to use in the UI.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for error handling in the utility functions
echo "Checking error handling in utility functions..."
rg -A 5 "export.*(?:getDegreeLevelLabel|getCountryName|formatDateStr)"

Length of output: 2176


Script:

#!/bin/bash
# Search for degreeLevelOptions and getAllCountryCodes implementations
echo "Checking degreeLevelOptions implementation..."
rg -A 5 "degreeLevelOptions.*=|const.*degreeLevelOptions"

echo -e "\nChecking getAllCountryCodes implementation..."
rg -A 5 "getAllCountryCodes.*=|const.*getAllCountryCodes"

Length of output: 6239


Script:

#!/bin/bash
# Search for countryCodes and formatDate implementations
echo "Checking countryCodes implementation..."
rg -A 5 "countryCodes.*=|const.*countryCodes"

echo -e "\nChecking formatDate implementation..."
rg -A 5 "formatDate.*=|const.*formatDate"

Length of output: 50499

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 and nitpick comments (2)
libs/application/templates/university/src/fields/ProgramSelection/index.tsx (2)

40-47: Consider memoizing filtered programs for performance.

The filtered programs list could be memoized using useMemo to prevent unnecessary recalculations, especially with large program lists.

-  const [filteredPrograms, setFilteredPrograms] = useState<Array<Program>>([])
+  const filteredPrograms = useMemo(() => 
+    selectedUniversity 
+      ? sortedProgramsDeepCopy.filter(
+          (program) => program.universityId === selectedUniversity
+        )
+      : []
+  , [selectedUniversity, sortedProgramsDeepCopy])

239-278: Enhance accessibility for program selection.

Consider adding ARIA labels and role attributes to improve screen reader support:

   <Box marginTop={2}>
     {!!filteredPrograms.length && (
       <SelectController
         id={`${Routes.PROGRAMINFORMATION}.program`}
+        aria-label={formatMessage(
+          information.labels.programSelection.selectProgramPlaceholder,
+        )}
         label={formatMessage(
           information.labels.programSelection.selectProgramPlaceholder,
         )}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 0766c8c and 0c94974.

📒 Files selected for processing (1)
  • libs/application/templates/university/src/fields/ProgramSelection/index.tsx (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
libs/application/templates/university/src/fields/ProgramSelection/index.tsx (1)

Pattern libs/**/*: "Confirm that the code adheres to the following:

  • Reusability of components and hooks across different NextJS apps.
  • TypeScript usage for defining props and exporting types.
  • Effective tree-shaking and bundling practices."
🪛 Biome
libs/application/templates/university/src/fields/ProgramSelection/index.tsx

[error] 206-206: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (1)
libs/application/templates/university/src/fields/ProgramSelection/index.tsx (1)

3-3: LGTM: Clean imports and props structure.

The changes follow TypeScript best practices and align with the component's focused responsibility.

Also applies to: 5-5, 16-16

@johannaagma johannaagma added the automerge Merge this PR as soon as all checks pass label Nov 6, 2024
@kodiakhq kodiakhq bot merged commit 94a84fb into main Nov 6, 2024
202 checks passed
@kodiakhq kodiakhq bot deleted the fix/haskolagatt-small-fixes-application branch November 6, 2024 13:19
robertaandersen pushed a commit that referenced this pull request Nov 11, 2024
* Fixes in program selection step
-display alertMessage if programList is empty
-clear program selection when selecting school
-save universityName and programName in answers when using preDetermined selection
-fix default value for modeOfDelivery (not always ON_SITE)
-make sure modeOfDelivery is not cleared when going back and forth
-make sure modeOfDelivery is reset when selecting program

* Fixes in overview:
-display attachments
-display other document
-format date
-show country name not code
-show degree level name not code

* Cleanup

* cleanup

* Clear testing site

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
jonnigs pushed a commit that referenced this pull request Nov 12, 2024
* Fixes in program selection step
-display alertMessage if programList is empty
-clear program selection when selecting school
-save universityName and programName in answers when using preDetermined selection
-fix default value for modeOfDelivery (not always ON_SITE)
-make sure modeOfDelivery is not cleared when going back and forth
-make sure modeOfDelivery is reset when selecting program

* Fixes in overview:
-display attachments
-display other document
-format date
-show country name not code
-show degree level name not code

* Cleanup

* cleanup

* Clear testing site

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge Merge this PR as soon as all checks pass
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants