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

feat(web): Organization page with "standalone" theme - Level 1 sitemap #17068

Merged

Conversation

RunarVestmann
Copy link
Member

@RunarVestmann RunarVestmann commented Nov 28, 2024

Organization page with "standalone" theme - Level 1 sitemap

What

  • If an organization page has it's theme set to "standalone" we've got another form of navigation there.
  • Level 1 is essentially one level below the top level navigation (see image below)

Screenshots / Gifs

Screenshot 2024-11-28 at 12 19 58

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

Release Notes

  • New Features

    • Introduced a new page type, STANDALONE_LEVEL1_SITEMAP, enhancing sitemap rendering capabilities.
    • Added a StandaloneLevel1Sitemap component for displaying organization-level sitemaps.
    • Enhanced SEO for StandaloneParentSubpage with dynamic title generation.
    • New GraphQL query for fetching organization page standalone sitemap level 1 data.
    • Updated LanguageToggler component to provide clearer messaging regarding translation availability.
  • Bug Fixes

    • Improved error handling for data retrieval in organization-related queries.

These updates enhance navigation, improve SEO, and expand the application's functionality related to organization pages.

@RunarVestmann RunarVestmann added the automerge Merge this PR as soon as all checks pass label Nov 28, 2024
@RunarVestmann RunarVestmann requested review from a team as code owners November 28, 2024 12:21
Copy link
Contributor

coderabbitai bot commented Nov 28, 2024

Walkthrough

The pull request introduces several enhancements to the handling of organization pages within the application. A new page type, STANDALONE_LEVEL1_SITEMAP, is added to the PageType enum, enabling the rendering of a new component, StandaloneLevel1Sitemap. This component is designed to display a level 1 sitemap for organizations and incorporates new GraphQL queries and input types to facilitate data retrieval. Additionally, the StandaloneParentSubpage component receives an SEO enhancement through dynamic title setting, while various service and resolver updates improve data handling for organization-related queries.

Changes

File Path Change Summary
apps/web/pages/s/[...slugs]/index.tsx Added STANDALONE_LEVEL1_SITEMAP to PageType enum; updated Props interface; modified rendering logic for new page type.
apps/web/screens/Organization/Standalone/Level1Sitemap.tsx Introduced StandaloneLevel1Sitemap component with props interface; added getProps method for data fetching.
apps/web/screens/Organization/Standalone/ParentSubpage.tsx Updated StandaloneParentSubpage to include a seo prop for dynamic title setting; retained existing error handling.
apps/web/screens/queries/Organization.tsx Added new GraphQL query GET_ORGANIZATION_PAGE_STANDALONE_SITEMAP_LEVEL1_QUERY for fetching sitemap data.
libs/cms/src/lib/cms.contentful.service.ts Added method getOrganizationPageStandaloneSitemapLevel1 to retrieve structured sitemap data; included necessary imports.
libs/cms/src/lib/cms.resolver.ts Introduced query method getOrganizationPageStandaloneSitemapLevel1 in CmsResolver; added relevant imports.
libs/cms/src/lib/dto/getOrganizationPageStandaloneSitemap.input.ts Created new input type GetOrganizationPageStandaloneSitemapLevel1Input for GraphQL operations.
libs/cms/src/lib/models/organizationPageStandaloneSitemap.model.ts Added two new GraphQL object types: OrganizationPageStandaloneSitemapLink and OrganizationPageStandaloneSitemap.
apps/web/components/LanguageToggler/LanguageToggler.tsx Updated DialogPrompt properties for clearer messaging regarding translation availability.

Possibly related PRs

Suggested labels

automerge

Suggested reviewers

  • mannipje: Suggested as a reviewer for the changes made in this pull request.

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (6)
libs/cms/src/lib/dto/getOrganizationPageStandaloneSitemap.input.ts (2)

6-18: Add JSDoc documentation and consider using a union type for lang.

While the implementation is functional, adding documentation would improve maintainability. Also, the lang field could benefit from a more specific type.

Consider adding documentation and improving type safety:

+/**
+ * Input type for fetching organization page standalone sitemap data
+ */
 @InputType()
 export class GetOrganizationPageStandaloneSitemapLevel1Input {
+  /** The slug of the organization page */
   @Field()
   @IsString()
   organizationPageSlug!: string
 
+  /** The slug of the category */
   @Field()
   @IsString()
   categorySlug!: string
 
+  /** The locale for content, defaults to Icelandic */
   @Field(() => String)
   @IsString()
-  lang: ElasticsearchIndexLocale = 'is'
+  lang: Extract<ElasticsearchIndexLocale, 'is' | 'en'> = 'is'
 }

6-18: Consider using constructor initialization instead of non-null assertions.

The non-null assertion operator (!) can be replaced with constructor-based initialization for better type safety.

Consider this alternative implementation:

 @InputType()
 export class GetOrganizationPageStandaloneSitemapLevel1Input {
   @Field()
   @IsString()
-  organizationPageSlug!: string
+  organizationPageSlug: string
 
   @Field()
   @IsString()
-  categorySlug!: string
+  categorySlug: string
 
   @Field(() => String)
   @IsString()
   lang: ElasticsearchIndexLocale = 'is'
+
+  constructor(organizationPageSlug: string, categorySlug: string) {
+    this.organizationPageSlug = organizationPageSlug;
+    this.categorySlug = categorySlug;
+  }
 }
libs/cms/src/lib/models/organizationPageStandaloneSitemap.model.ts (2)

4-14: Consider using constructor initialization instead of non-null assertions

While the TypeScript implementation is good, we can make it more robust by initializing required fields through a constructor instead of using non-null assertions (!).

Here's a suggested improvement:

 @ObjectType()
 export class OrganizationPageStandaloneSitemapLink {
   @Field()
-  label!: string
+  label: string

   @Field()
-  href!: string
+  href: string

   @Field(() => String, { nullable: true })
   description?: string | null
+
+  constructor(label: string, href: string, description?: string | null) {
+    this.label = label;
+    this.href = href;
+    this.description = description;
+  }
 }

16-20: Consider using constructor initialization for consistency

Similar to the previous class, we can improve type safety by using constructor initialization.

Here's a suggested improvement:

 @ObjectType()
 export class OrganizationPageStandaloneSitemap {
   @CacheField(() => [OrganizationPageStandaloneSitemapLink])
-  childLinks!: OrganizationPageStandaloneSitemapLink[]
+  childLinks: OrganizationPageStandaloneSitemapLink[]
+
+  constructor(childLinks: OrganizationPageStandaloneSitemapLink[]) {
+    this.childLinks = childLinks;
+  }
 }
apps/web/screens/Organization/Standalone/ParentSubpage.tsx (1)

71-76: Good SEO implementation, consider adding meta description.

The title implementation follows SEO best practices by providing context and hierarchy. However, we could enhance SEO further.

Consider adding a meta description to improve search engine snippets:

 <StandaloneLayout
   organizationPage={organizationPage}
   seo={{
     title: `${subpage.title} | ${organizationPage.title}`,
+    description: subpage.description || organizationPage.description,
   }}
 >
apps/web/pages/s/[...slugs]/index.tsx (1)

178-178: Consider extracting theme check to a utility function

While the boolean variable improves readability, consider extracting this check into a reusable utility function for consistency across the codebase.

+ const isStandaloneTheme = (page: typeof organizationPage): boolean => 
+   page.theme === 'standalone'

- const isStandaloneTheme = organizationPage.theme === 'standalone'
+ const hasStandaloneTheme = isStandaloneTheme(organizationPage)
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6a313ad and 7cdefe0.

📒 Files selected for processing (8)
  • apps/web/pages/s/[...slugs]/index.tsx (8 hunks)
  • apps/web/screens/Organization/Standalone/Level1Sitemap.tsx (1 hunks)
  • apps/web/screens/Organization/Standalone/ParentSubpage.tsx (1 hunks)
  • apps/web/screens/queries/Organization.tsx (1 hunks)
  • libs/cms/src/lib/cms.contentful.service.ts (2 hunks)
  • libs/cms/src/lib/cms.resolver.ts (2 hunks)
  • libs/cms/src/lib/dto/getOrganizationPageStandaloneSitemap.input.ts (1 hunks)
  • libs/cms/src/lib/models/organizationPageStandaloneSitemap.model.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
apps/web/pages/s/[...slugs]/index.tsx (1)

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

  • NextJS best practices, including file structure, API routes, and static generation methods.
  • Efficient state management and server-side rendering techniques.
  • Optimal use of TypeScript for component and utility type safety."
apps/web/screens/Organization/Standalone/Level1Sitemap.tsx (1)

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

  • NextJS best practices, including file structure, API routes, and static generation methods.
  • Efficient state management and server-side rendering techniques.
  • Optimal use of TypeScript for component and utility type safety."
apps/web/screens/Organization/Standalone/ParentSubpage.tsx (1)

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

  • NextJS best practices, including file structure, API routes, and static generation methods.
  • Efficient state management and server-side rendering techniques.
  • Optimal use of TypeScript for component and utility type safety."
apps/web/screens/queries/Organization.tsx (1)

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

  • NextJS best practices, including file structure, API routes, and static generation methods.
  • Efficient state management and server-side rendering techniques.
  • Optimal use of TypeScript for component and utility type safety."
libs/cms/src/lib/cms.contentful.service.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/cms/src/lib/cms.resolver.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/cms/src/lib/dto/getOrganizationPageStandaloneSitemap.input.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/cms/src/lib/models/organizationPageStandaloneSitemap.model.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."
🔇 Additional comments (14)
libs/cms/src/lib/dto/getOrganizationPageStandaloneSitemap.input.ts (1)

1-5: LGTM! Clean imports and proper decorator usage.

The imports are specific and well-organized, following tree-shaking best practices. The @InputType() decorator correctly identifies this as a GraphQL input type.

libs/cms/src/lib/models/organizationPageStandaloneSitemap.model.ts (2)

1-2: LGTM! Well-structured imports

The imports are minimal and specific, which is good for tree-shaking optimization.


16-19: Good use of caching for the array field

The @CacheField decorator is appropriately used for the childLinks array, which can help optimize performance when fetching sitemap data.

apps/web/screens/queries/Organization.tsx (1)

434-446: LGTM! The query follows GraphQL and TypeScript best practices.

The new query is well-structured, follows naming conventions, and aligns with the PR objectives for implementing a Level 1 sitemap.

Let's verify the input type exists and matches the query structure:

✅ Verification successful

Input type exists and is properly integrated across the codebase

The input type GetOrganizationPageStandaloneSitemapLevel1Input is well-defined in libs/cms/src/lib/dto/getOrganizationPageStandaloneSitemap.input.ts with:

  • Required fields: organizationPageSlug, categorySlug
  • Optional field: lang (defaults to 'is')

The type is properly imported and used in:

  • GraphQL resolver (cms.resolver.ts)
  • Contentful service (cms.contentful.service.ts)
  • Web queries (Organization.tsx)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the input type exists and its structure matches the query
# Expected: Find the input type definition with matching fields

# Search for the input type definition
ast-grep --pattern 'class GetOrganizationPageStandaloneSitemapLevel1Input {
  $$$
}'

# Search for any references to ensure it's properly imported
rg "GetOrganizationPageStandaloneSitemapLevel1Input"

Length of output: 2045

apps/web/pages/s/[...slugs]/index.tsx (5)

34-36: LGTM: Clean import declaration

The import follows TypeScript best practices by explicitly importing types and maintaining consistent import structure.


52-52: LGTM: Consistent enum value addition

The new enum value follows the established naming convention and pattern.


69-71: LGTM: Consistent pageMap implementation

The new page type mapping follows the established pattern of the pageMap object.


100-103: LGTM: Well-typed Props interface extension

The Props interface extension maintains type safety and follows the established pattern.


251-256: 🛠️ Refactor suggestion

Verify link matching logic robustness

The current link matching logic using split('/').pop() might be fragile if:

  1. The href format changes
  2. The href contains trailing slashes
  3. The href is empty

Consider using a more robust URL parsing approach.

- slugs[1] === link.href.split('/').pop()
+ const linkPath = new URL(link.href, 'http://dummy.com').pathname
+ slugs[1] === linkPath.split('/').filter(Boolean).pop()
libs/cms/src/lib/cms.resolver.ts (2)

131-132: LGTM!

The imports follow the established naming conventions and are properly organized with related imports.


723-731: Verify error handling in the service layer.

The resolver implementation follows the established patterns and is properly typed. However, ensure that the service method getOrganizationPageStandaloneSitemapLevel1 implements proper error handling for cases such as:

  • Non-existent organization pages
  • Invalid input parameters
  • Content fetching failures
✅ Verification successful

Let me gather more information about the error handling patterns in the service.


Let me check for the error handler utility since we saw a reference to errorHandler in the code.


Error handling is properly implemented in the service layer

The service method getOrganizationPageStandaloneSitemapLevel1 implements comprehensive error handling through:

  • A global error handler that logs errors and throws ApolloError
  • Proper null checks for non-existent data (if (!tree) return null)
  • Contentful repository calls wrapped with .catch(errorHandler('getOrganizationPageStandaloneSitemapLevel1'))
  • Consistent error handling pattern across organization-related methods
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check error handling implementation in the service layer

# Search for the service method implementation and its error handling
ast-grep --pattern 'getOrganizationPageStandaloneSitemapLevel1($$$) {
  $$$
  try {
    $$$
  } catch {
    $$$
  }
  $$$
}'

# Search for similar methods to verify consistent error handling patterns
rg -A 5 "getOrganizationPage.*\{" libs/cms/src/lib/cms.contentful.service.ts

Length of output: 571


Script:

#!/bin/bash
# Search for the complete implementation of getOrganizationPageStandaloneSitemapLevel1
rg -B 5 -A 20 "getOrganizationPageStandaloneSitemapLevel1" libs/cms/src/lib/cms.contentful.service.ts

# Look for error handling patterns in similar methods within the service
rg -A 10 "async get.*Organization.*\{" libs/cms/src/lib/cms.contentful.service.ts

# Check if there's a common error handling utility or wrapper
rg -l "try.*catch" libs/cms/src/lib/cms.contentful.service.ts

Length of output: 2937


Script:

#!/bin/bash
# Search for the errorHandler implementation
rg -B 5 -A 10 "errorHandler.*=.*" libs/cms/src/lib

# Check for any custom error types or interfaces
rg -l "interface.*Error|type.*Error|class.*Error" libs/cms/src/lib

# Look for error-related imports
rg "import.*Error" libs/cms/src/lib/cms.contentful.service.ts

Length of output: 1941

apps/web/screens/Organization/Standalone/Level1Sitemap.tsx (1)

1-154: Overall code implementation looks good

The StandaloneLevel1Sitemap component and its getProps method are well-structured and adhere to Next.js and TypeScript best practices. The code is clean, readable, and makes optimal use of TypeScript for type safety. Server-side data fetching is efficiently handled, and error cases are thoughtfully managed.

libs/cms/src/lib/cms.contentful.service.ts (2)

91-94: Imports added appropriately

The necessary imports for the new functionality have been correctly added.


1183-1270: Method implementation follows TypeScript best practices

The getOrganizationPageStandaloneSitemapLevel1 method is correctly implemented with appropriate TypeScript types and aligns with the coding guidelines regarding reusability and type definitions.

libs/cms/src/lib/cms.contentful.service.ts Outdated Show resolved Hide resolved
libs/cms/src/lib/cms.contentful.service.ts Outdated Show resolved Hide resolved
Copy link

codecov bot commented Nov 28, 2024

Codecov Report

Attention: Patch coverage is 22.00000% with 78 lines in your changes missing coverage. Please review.

Project coverage is 35.68%. Comparing base (a40be29) to head (6a544ed).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
libs/cms/src/lib/cms.contentful.service.ts 4.87% 39 Missing ⚠️
.../screens/Organization/Standalone/Level1Sitemap.tsx 0.00% 23 Missing ⚠️
apps/web/pages/s/[...slugs]/index.tsx 0.00% 10 Missing ⚠️
libs/cms/src/lib/cms.resolver.ts 71.42% 2 Missing ⚠️
.../models/organizationPageStandaloneSitemap.model.ts 80.00% 2 Missing ⚠️
apps/web/screens/queries/Organization.tsx 0.00% 1 Missing ⚠️
.../dto/getOrganizationPageStandaloneSitemap.input.ts 87.50% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #17068      +/-   ##
==========================================
- Coverage   35.69%   35.68%   -0.01%     
==========================================
  Files        6938     6941       +3     
  Lines      147122   147218      +96     
  Branches    41824    41849      +25     
==========================================
+ Hits        52516    52538      +22     
- Misses      94606    94680      +74     
Flag Coverage Δ
api 3.34% <ø> (ø)
api-domains-auth-admin 48.49% <ø> (ø)
api-domains-communications 39.53% <29.68%> (-0.07%) ⬇️
application-system-api 38.73% <33.33%> (-0.01%) ⬇️
application-template-api-modules 27.79% <29.68%> (+0.01%) ⬆️
cms 0.40% <0.00%> (-0.01%) ⬇️
cms-translations 38.86% <29.68%> (-0.07%) ⬇️
judicial-system-api 20.36% <ø> (ø)
judicial-system-backend 55.65% <33.33%> (-0.08%) ⬇️
services-user-notification 46.69% <33.33%> (-0.08%) ⬇️
web 2.44% <0.00%> (-0.01%) ⬇️

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

Files with missing lines Coverage Δ
...web/components/LanguageToggler/LanguageToggler.tsx 0.00% <ø> (ø)
.../screens/Organization/Standalone/ParentSubpage.tsx 0.00% <ø> (ø)
apps/web/screens/queries/Organization.tsx 0.00% <0.00%> (ø)
.../dto/getOrganizationPageStandaloneSitemap.input.ts 87.50% <87.50%> (ø)
libs/cms/src/lib/cms.resolver.ts 66.91% <71.42%> (+0.05%) ⬆️
.../models/organizationPageStandaloneSitemap.model.ts 80.00% <80.00%> (ø)
apps/web/pages/s/[...slugs]/index.tsx 0.00% <0.00%> (ø)
.../screens/Organization/Standalone/Level1Sitemap.tsx 0.00% <0.00%> (ø)
libs/cms/src/lib/cms.contentful.service.ts 11.13% <4.87%> (-0.68%) ⬇️

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 a40be29...6a544ed. Read the comment docs.

@datadog-island-is
Copy link

datadog-island-is bot commented Nov 28, 2024

Datadog Report

All test runs fb2bdf8 🔗

11 Total Test Services: 0 Failed, 10 Passed
🔻 Test Sessions change in coverage: 5 decreased, 1 increased (+0.01%), 23 no change

Test Services
This report shows up to 10 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.39s 1 no change Link
api-domains-auth-admin 0 0 0 18 0 10.05s 1 no change Link
api-domains-communications 0 0 0 5 0 29.41s 1 decreased (-0.11%) Link
api-domains-license-service 0 0 0 0 0 477.47ms 1 no change Link
application-system-api 0 0 0 40 0 2m 15.89s 1 no change Link
application-template-api-modules 0 0 0 118 0 2m 26.18s 1 increased (+0.01%) Link
cms-translations 0 0 0 3 0 26.15s 1 decreased (-0.12%) Link
judicial-system-api 0 0 0 61 0 6.48s 1 no change Link
judicial-system-backend 0 0 0 21007 0 21m 43.05s 1 decreased (-0.09%) Link
services-user-notification 0 0 0 51 0 1m 24.33s 1 decreased (-0.1%) Link

🔻 Code Coverage Decreases vs Default Branch (5)

  • cms-translations - jest 48.37% (-0.12%) - Details
  • api-domains-communications - jest 48.72% (-0.11%) - Details
  • services-user-notification - jest 69.17% (-0.1%) - Details
  • judicial-system-backend - jest 59.33% (-0.09%) - Details
  • cms - jest 0.48% (-0.01%) - Details

@kodiakhq kodiakhq bot removed the automerge Merge this PR as soon as all checks pass label Nov 28, 2024
Copy link
Contributor

kodiakhq bot commented Nov 28, 2024

This PR currently has a merge conflict. Please resolve this and then re-add the automerge label.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (4)
libs/cms/src/lib/cms.contentful.service.ts (4)

1183-1191: Add input validation

Consider validating the input parameters before constructing the query to ensure robustness.

  async getOrganizationPageStandaloneSitemapLevel1(
    input: GetOrganizationPageStandaloneSitemapLevel1Input,
  ): Promise<OrganizationPageStandaloneSitemap | null> {
+   if (!input?.organizationPageSlug || !input?.categorySlug || !input?.lang) {
+     return null
+   }
    const params = {
      content_type: 'organizationPage',
      'fields.slug': input.organizationPageSlug,
      select: 'fields.sitemap',
      limit: 1,
    }

1203-1211: Optimize category finding with early returns

Consider restructuring the code to avoid unnecessary processing when no category is found.

+   if (!tree.childNodes?.length) {
+     return null
+   }

    const category = tree.childNodes.find(
      (node) =>
        node.type === SitemapTreeNodeType.CATEGORY &&
        node.slug === input.categorySlug,
    )

    if (!category) {
      return null
    }

1213-1275: Improve type safety in node mapping

Consider using type guards or discriminated unions for better type safety in the node mapping logic.

+   type NodeWithEntry = {
+     label: string
+     href: string
+     entryId: string
+   }

+   type NodeResult = 
+     | { label: string; href: string; description?: string }
+     | NodeWithEntry

    const entryNodes = new Map<string, NodeWithEntry[]>()

    const result = {
-     childLinks: category.childNodes.map((node) => {
+     childLinks: category.childNodes.map((node): NodeResult => {

1277-1282: Enhance type narrowing in filter predicate

Consider using a type predicate to improve type safety in the filter operation.

+   const isResolvedLink = (
+     link: typeof result.childLinks[number]
+   ): link is { label: string; href: string } => {
+     return !('entryId' in link) || !entryIdsToRemove.includes(link.entryId)
+   }

    result.childLinks = result.childLinks.filter(
-     (link) => !('entryId' in link && entryIdsToRemove.includes(link.entryId)),
+     isResolvedLink
    )
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7cdefe0 and e2d531c.

📒 Files selected for processing (3)
  • apps/web/screens/Organization/Standalone/ParentSubpage.tsx (1 hunks)
  • apps/web/screens/queries/Organization.tsx (1 hunks)
  • libs/cms/src/lib/cms.contentful.service.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web/screens/Organization/Standalone/ParentSubpage.tsx
  • apps/web/screens/queries/Organization.tsx
🧰 Additional context used
📓 Path-based instructions (1)
libs/cms/src/lib/cms.contentful.service.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."
🔇 Additional comments (2)
libs/cms/src/lib/cms.contentful.service.ts (2)

91-94: LGTM: Imports are well-organized

The new imports follow TypeScript best practices and maintain consistency with the existing codebase.


1193-1201: 🛠️ Refactor suggestion

Strengthen null checks for response handling

Add more defensive checks when accessing nested fields.

    const response = await this.contentfulRepository
      .getLocalizedEntries<types.IOrganizationPageFields>(input.lang, params)
      .catch(errorHandler('getOrganizationPageStandaloneSitemapLevel1'))

-   const tree = response.items?.[0]?.fields.sitemap?.fields.tree as SitemapTree
+   const tree = response.items?.[0]?.fields?.sitemap?.fields?.tree as SitemapTree | undefined

    if (!tree) {
      return null
    }

Likely invalid or redundant comment.

@RunarVestmann RunarVestmann added the automerge Merge this PR as soon as all checks pass label Nov 28, 2024
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 (3)
apps/web/screens/Organization/Standalone/Level1Sitemap.tsx (2)

1-9: Consolidate island-ui/core imports

The imports from '@island.is/island-ui/core' are split into two separate statements. Consider consolidating them for better maintainability.

 import {
   CategoryCard,
   GridColumn,
   GridContainer,
   GridRow,
   Stack,
+  Text,
 } from '@island.is/island-ui/core'
-import { Text } from '@island.is/island-ui/core'

143-152: Consider using Array.prototype.find with optional chaining

The current implementation could be simplified using optional chaining to make it more concise and readable.

-  const categoryTitle = organizationPage?.topLevelNavigation?.links.find(
-    (link) => categorySlug === link.href.split('/').pop(),
-  )?.label
+  const categoryTitle = organizationPage?.topLevelNavigation?.links?.find(
+    (link) => link.href?.split('/')?.pop() === categorySlug
+  )?.label
apps/web/components/LanguageToggler/LanguageToggler.tsx (1)

Line range hint 1-240: Consider splitting the component for better maintainability.

To improve the component's architecture and maintainability, consider:

  1. Extracting the GraphQL query logic into a custom hook (e.g., useContentSlug)
  2. Moving the ButtonElement component to a separate file
  3. Splitting the language toggle and content fetching responsibilities

This would make the code more modular and easier to test.

Example structure:

// hooks/useContentSlug.ts
export const useContentSlug = () => {
  const client = useApolloClient()
  
  const getContentSlug = async (contentfulId: string) => {
    return client.query<GetContentSlugQuery, GetContentSlugQueryVariables>({
      query: GET_CONTENT_SLUG,
      variables: { input: { id: contentfulId } },
    })
  }
  
  return { getContentSlug }
}

// components/LanguageToggler/ButtonElement.tsx
export const ButtonElement: FC<ButtonElementProps> = ({ ... })

// components/LanguageToggler/LanguageToggler.tsx
// Main component with reduced complexity
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e2d531c and fc46488.

📒 Files selected for processing (2)
  • apps/web/components/LanguageToggler/LanguageToggler.tsx (1 hunks)
  • apps/web/screens/Organization/Standalone/Level1Sitemap.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
apps/web/components/LanguageToggler/LanguageToggler.tsx (1)

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

  • NextJS best practices, including file structure, API routes, and static generation methods.
  • Efficient state management and server-side rendering techniques.
  • Optimal use of TypeScript for component and utility type safety."
apps/web/screens/Organization/Standalone/Level1Sitemap.tsx (1)

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

  • NextJS best practices, including file structure, API routes, and static generation methods.
  • Efficient state management and server-side rendering techniques.
  • Optimal use of TypeScript for component and utility type safety."
🔇 Additional comments (5)
apps/web/screens/Organization/Standalone/Level1Sitemap.tsx (5)

34-46: LGTM! Well-structured type definitions

The types and interfaces are well-defined with proper TypeScript types and nullability handling.


55-57: LGTM! Good SEO implementation

The SEO title is properly constructed by combining the category title and organization page title.


68-78: Use unique keys instead of indices in list rendering

Using array indices as React keys can lead to issues with component reconciliation.

-                  <GridColumn span={GRID_COLUMN_SPAN} key={index}>
+                  <GridColumn span={GRID_COLUMN_SPAN} key={href}>

94-95: Validate presence of required slugs before proceeding

The destructuring of slugs lacks validation, which could lead to runtime errors.

 const [organizationPageSlug, categorySlug] = (query.slugs ?? []) as string[]
+if (!organizationPageSlug || !categorySlug) {
+  throw new CustomNextError(400, 'Missing required slug parameters')
+}

103-130: LGTM! Efficient parallel data fetching

The use of Promise.all for parallel data fetching is a good practice for optimizing performance. The implementation also includes proper error handling and type safety.

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