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

✨ Add-project-detail-page #855

Merged
merged 9 commits into from
Mar 12, 2025
Merged

✨ Add-project-detail-page #855

merged 9 commits into from
Mar 12, 2025

Conversation

NoritakaIkeda
Copy link
Member

@NoritakaIkeda NoritakaIkeda commented Mar 11, 2025

Issue

  • resolve:

Why is this change needed?

  • Create Project Detail Page
  • Redirect to the detail page after project creation
2025-03-11.18.41.01.mov
2025-03-11.18.48.00.mov

What would you like reviewers to focus on?

Testing Verification

What was done

🤖 Generated by PR Agent at 904d2c2

  • Add a new ProjectDetailPage component for project details.
  • Implement auto-redirect to project detail after project creation.
  • Fix PageProps type definition and project ID handling.
  • Introduce styles for the ProjectDetailPage component.

Detailed Changes

Relevant files
Enhancement
page.tsx
Add project detail page with migration check                         

frontend/apps/app/app/(app)/app/projects/[id]/page.tsx

  • Add a new page for project details.
  • Handle migration flag and project ID.
  • Redirect to notFound if migration is disabled.
  • +21/-0   
    addProject.ts
    Add auto-redirect to project detail after creation             

    frontend/apps/app/features/projects/actions/addProject.ts

  • Add redirect to project detail page after creation.
  • Retrieve and use project ID for redirection.
  • +5/-1     
    Form.tsx
    Update form component for client-side usage                           

    frontend/apps/app/features/projects/pages/NewProjectPage/Form.tsx

  • Mark the form as client-side.
  • Adjust import order for addProject.
  • +4/-1     
    ProjectDetailPage.tsx
    Create ProjectDetailPage component for project details     

    frontend/apps/app/features/projects/pages/ProjectDetailPage/ProjectDetailPage.tsx

  • Create ProjectDetailPage component to display project details.
  • Fetch project data and handle notFound for invalid IDs.
  • Add navigation links and project metadata display.
  • +61/-0   
    index.ts
    Export ProjectDetailPage component                                             

    frontend/apps/app/features/projects/pages/ProjectDetailPage/index.ts

    • Export ProjectDetailPage component for external use.
    +1/-0     
    index.ts
    Include ProjectDetailPage in exports                                         

    frontend/apps/app/features/projects/pages/index.ts

    • Add ProjectDetailPage to the exports.
    +1/-0     
    ProjectDetailPage.module.css
    Add styles for ProjectDetailPage component                             

    frontend/apps/app/features/projects/pages/ProjectDetailPage/ProjectDetailPage.module.css

  • Add styles for ProjectDetailPage component.
  • Define layout, buttons, and typography styles.
  • +57/-0   

    Additional Notes


    Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • Copy link

    changeset-bot bot commented Mar 11, 2025

    ⚠️ No Changeset found

    Latest commit: da5a88c

    Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

    This PR includes no changesets

    When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

    Click here to learn what changesets are, and how to add one.

    Click here if you're a maintainer who wants to add a changeset to this PR

    Copy link

    vercel bot commented Mar 11, 2025

    The latest updates on your projects. Learn more about Vercel for Git ↗︎

    Name Status Preview Comments Updated (UTC)
    liam-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 7:25am
    liam-erd-sample ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 12, 2025 7:25am
    3 Skipped Deployments
    Name Status Preview Comments Updated (UTC)
    test-liam-docs ⬜️ Ignored (Inspect) Mar 12, 2025 7:25am
    test-liam-erd-sample ⬜️ Ignored (Inspect) Mar 12, 2025 7:25am
    test-liam-erd-web ⬜️ Ignored (Inspect) Mar 12, 2025 7:25am

    Copy link
    Contributor

    qodo-merge-pro-for-open-source bot commented Mar 11, 2025

    CI Feedback 🧐

    (Feedback updated until commit a65454b)

    A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

    Action: Deploy (app, VERCEL_PROJECT_ID_ERD_WEB)

    Failed stage: Run prepare command [❌]

    Failure summary:

    The build process failed due to a type error in the Next.js application. Specifically:

    1. In the file app/(app)/app/projects/[id]/page.tsx, there's a type mismatch where the params
    property of PageProps is incorrectly typed as { id: string; } when it should be a Promise.

    2. Additionally, there's an Edge Runtime compatibility issue where a Node.js module (async_hooks) is
    being loaded, which is not supported in the Edge Runtime environment.

    3. The build command for the @liam-hq/app package failed with exit code 1, causing the entire
    workflow to fail.

    Relevant error logs:
    1:  ##[group]Operating System
    2:  Ubuntu
    ...
    
    181:  Scope: all 12 workspace projects
    182:  Lockfile is up to date, resolution step is skipped
    183:  Progress: resolved 1, reused 0, downloaded 0, added 0
    184:  Packages: +1587
    185:  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    186:  Progress: resolved 1587, reused 1258, downloaded 0, added 0
    187:  Progress: resolved 1587, reused 1570, downloaded 0, added 600
    188:  Progress: resolved 1587, reused 1570, downloaded 0, added 1587, done
    189:  WARN  Failed to create bin at /home/runner/work/liam/liam/frontend/apps/erd-sample/node_modules/.bin/liam. ENOENT: no such file or directory, open '/home/runner/work/liam/liam/frontend/packages/cli/dist-cli/bin/cli.js'
    ...
    
    194:  + @turbo/gen 2.1.2
    195:  + syncpack 13.0.0
    196:  + turbo 2.1.2
    197:  frontend/apps/docs postinstall$ fumadocs-mdx
    198:  frontend/apps/docs postinstall: [MDX] types generated
    199:  frontend/apps/docs postinstall: Done
    200:  frontend/apps/app postinstall$ cp ../../packages/db-structure/node_modules/@ruby/prism/src/prism.wasm prism.wasm
    201:  frontend/apps/app postinstall: Done
    202:  WARN  Failed to create bin at /home/runner/work/liam/liam/frontend/apps/erd-sample/node_modules/.bin/liam. ENOENT: no such file or directory, open '/home/runner/work/liam/liam/frontend/apps/erd-sample/node_modules/@liam-hq/cli/dist-cli/bin/cli.js'
    ...
    
    309:  Wrote /home/runner/work/liam/liam/frontend/packages/erd-core/src/styles/variables.css.d.ts
    310:  Wrote /home/runner/work/liam/liam/frontend/packages/erd-core/src/styles/globals.css.d.ts
    311:  Wrote /home/runner/work/liam/liam/frontend/packages/erd-core/src/features/erd/components/ERDRenderer/ERDRenderer.module.css.d.ts
    312:  Wrote /home/runner/work/liam/liam/frontend/packages/erd-core/src/features/erd/components/ERDContent/ERDContent.module.css.d.ts
    313:  Wrote /home/runner/work/liam/liam/frontend/packages/erd-core/src/features/erd/components/ERDRenderer/Toolbar/DesktopToolbar.module.css.d.ts
    314:  Wrote /home/runner/work/liam/liam/frontend/packages/erd-core/src/features/erd/components/ERDRenderer/TableDetailDrawer/TableDetailDrawer.module.css.d.ts
    315:  Wrote /home/runner/work/liam/liam/frontend/packages/erd-core/src/features/erd/components/ERDRenderer/RelationshipEdgeParticleMarker/RelationshipEdgeParticleMarker.module.css.d.ts
    316:  Wrote /home/runner/work/liam/liam/frontend/packages/erd-core/src/features/erd/components/ERDRenderer/LeftPane/LeftPane.module.css.d.ts
    317:  Wrote /home/runner/work/liam/liam/frontend/packages/erd-core/src/features/erd/components/ERDRenderer/ErrorDisplay/ParseErrorDisplay.module.css.d.ts
    318:  Wrote /home/runner/work/liam/liam/frontend/packages/erd-core/src/features/erd/components/ERDRenderer/ErrorDisplay/NetworkErrorDisplay.module.css.d.ts
    319:  Wrote /home/runner/work/liam/liam/frontend/packages/erd-core/src/features/erd/components/ERDRenderer/ErrorDisplay/ErrorDisplay.module.css.d.ts
    ...
    
    400:  . build:vite:  * [new branch]        avoid-semicolon-logic-2  -> origin/avoid-semicolon-logic-2
    401:  . build:vite:  * [new branch]        avoid-semicolon-logic-test -> origin/avoid-semicolon-logic-test
    402:  . build:vite:  * [new branch]        before-promptfoo-experiment -> origin/before-promptfoo-experiment
    403:  . build:vite:  * [new branch]        changeset-invest1        -> origin/changeset-invest1
    404:  . build:vite:  * [new branch]        changeset-invest3        -> origin/changeset-invest3
    405:  . build:vite:  * [new branch]        changeset-release/changeset-invest1 -> origin/changeset-release/changeset-invest1
    406:  . build:vite:  * [new branch]        check-github-action      -> origin/check-github-action
    407:  . build:vite:  * [new branch]        cli-schema-json-for-local -> origin/cli-schema-json-for-local
    408:  . build:vite:  * [new branch]        console-error-1-draft    -> origin/console-error-1-draft
    ...
    
    413:  . build:vite:  * [new branch]        devin/1738828298-add-multiline-comment-support -> origin/devin/1738828298-add-multiline-comment-support
    414:  . build:vite:  * [new branch]        devin/1739501885-improve-navigation-test-waits -> origin/devin/1739501885-improve-navigation-test-waits
    415:  . build:vite:  * [new branch]        devin/1740113652-update-changeset-docs -> origin/devin/1740113652-update-changeset-docs
    416:  . build:vite:  * [new branch]        devin/1741661851-optimize-github-config-validation -> origin/devin/1741661851-optimize-github-config-validation
    417:  . build:vite:  * [new branch]        devin/1741663537-github-env-validation-at-boot -> origin/devin/1741663537-github-env-validation-at-boot
    418:  . build:vite:  * [new branch]        devin/1741748071-issue-860 -> origin/devin/1741748071-issue-860
    419:  . build:vite:  * [new branch]        docs/ai-coding-rules     -> origin/docs/ai-coding-rules
    420:  . build:vite:  * [new branch]        enhance-the-highlighting-of-related-table-nodes-when-hovering-usememo-1 -> origin/enhance-the-highlighting-of-related-table-nodes-when-hovering-usememo-1
    421:  . build:vite:  * [new branch]        error-message-erd-network-error -> origin/error-message-erd-network-error
    ...
    
    457:  . build:vite:  * [new branch]        primary-key-icon-2       -> origin/primary-key-icon-2
    458:  . build:vite:  * [new branch]        promptfoo-go-1           -> origin/promptfoo-go-1
    459:  . build:vite:  * [new branch]        reduce-set-node-calling-chance-3 -> origin/reduce-set-node-calling-chance-3
    460:  . build:vite:  * [new branch]        refactor-active-highlight -> origin/refactor-active-highlight
    461:  . build:vite:  * [new branch]        refactor-to-testcases    -> origin/refactor-to-testcases
    462:  . build:vite:  * [new branch]        refactor_edge_cardinality_by_using_custom_mark -> origin/refactor_edge_cardinality_by_using_custom_mark
    463:  . build:vite:  * [new branch]        refactor_hidden_node_handle -> origin/refactor_hidden_node_handle
    464:  . build:vite:  * [new branch]        release-debug-branch     -> origin/release-debug-branch
    465:  . build:vite:  * [new branch]        revert-435-error-message-erd -> origin/revert-435-error-message-erd
    ...
    
    608:  A Node.js module is loaded ('async_hooks' at line 6) which is not supported in the Edge Runtime.
    609:  Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime
    610:  Import trace for requested module:
    611:  ../../../node_modules/.pnpm/[email protected]_@[email protected][email protected]_@[email protected]_@playwright+test@1._t3zvkidfsz7urkvhcheci25fnu/node_modules/flags/dist/chunk-OQHOV3IB.js
    612:  ../../../node_modules/.pnpm/[email protected]_@[email protected][email protected]_@[email protected]_@playwright+test@1._t3zvkidfsz7urkvhcheci25fnu/node_modules/flags/dist/next.js
    613:  ./libs/flags/index.ts
    614:  ./libs/index.ts
    615:  Linting and checking validity of types ...
    616:  Failed to compile.
    617:  app/(app)/app/projects/[id]/page.tsx
    618:  Type error: Type 'PageProps' does not satisfy the constraint 'import("/home/runner/work/liam/liam/frontend/apps/app/.next/types/app/(app)/app/projects/[id]/page").PageProps'.
    619:  Types of property 'params' are incompatible.
    620:  Type '{ id: string; }' is missing the following properties from type 'Promise<any>': then, catch, finally, [Symbol.toStringTag]
    621:  ELIFECYCLE  Command failed with exit code 1.
    622:  [ERROR] command finished with error: command (/home/runner/work/liam/liam/frontend/apps/app) /home/runner/setup-pnpm/node_modules/.bin/pnpm run build exited (1)
    ...
    
    654:  Generating static pages (0/31) ...
    655:  Generating static pages (7/31) 
    656:  Generating static pages (15/31) 
    657:  Generating static pages (23/31) 
    658:  ✓ Generating static pages (31/31)
    659:  Finalizing page optimization ...
    660:  Collecting build traces ...
    661:  ##[endgroup]
    662:  ##[error]@liam-hq/app#build: command (/home/runner/work/liam/liam/frontend/apps/app) /home/runner/setup-pnpm/node_modules/.bin/pnpm run build exited (1)
    663:  Tasks:    10 successful, 12 total
    664:  Cached:    0 cached, 12 total
    665:  Time:    2m0.678s 
    666:  Failed:    @liam-hq/app#build
    667:  ERROR  run failed: command  exited (1)
    668:  ELIFECYCLE  Command failed with exit code 1.
    669:  ##[error]Process completed with exit code 1.
    

    Comment on lines 15 to 21
    <form
    action={async (formData) => {
    const project = await addProject(formData)
    router.push(`/app/projects/${project.id}`)
    }}
    className={styles.form}
    >
    Copy link
    Member Author

    Choose a reason for hiding this comment

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

    In this implementation, I'm using an inline async function as the action handler for the form. However, since addProject is a Server Action, is this approach correct, or should I separate the Server Action into a dedicated function and pass it to action instead? Would love to hear your thoughts on best practices for using Server Actions in this case.

    Copy link
    Member

    Choose a reason for hiding this comment

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

    How about performing a page transition within a Server Action?

    export const addProject = async (formData: FormData) => {
      const projectName = formData.get('projectName') as string
      const project = await prisma.project.create({
        data: {
          name: projectName,
        },
      })
      
      redirect(`/app/projects/${project.id}`)
    }

    Comment on lines 6 to 10
    type PageProps = {
    params: Promise<{
    id: string
    }>
    }
    Copy link
    Member Author

    @NoritakaIkeda NoritakaIkeda Mar 12, 2025

    Choose a reason for hiding this comment

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

    The build failed due to a type mismatch in PageProps. The params property was expected to be a Promise, but it was originally defined as a plain object { id: string }.

    https://github.com/liam-hq/liam/actions/runs/13803523229/job/38610118863

    data: {
    name: projectName,
    },
    })

    redirect(`/app/projects/${project.id}`)
    Copy link
    Member Author

    Choose a reason for hiding this comment

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

    Redirect to the project details page after creation

    @NoritakaIkeda NoritakaIkeda marked this pull request as ready for review March 12, 2025 06:09
    @NoritakaIkeda NoritakaIkeda requested a review from a team as a code owner March 12, 2025 06:09
    @NoritakaIkeda NoritakaIkeda removed the request for review from a team March 12, 2025 06:09
    Copy link
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Type Definition

    The PageProps type defines params as a Promise, but it's used directly in the function parameter. This could cause type errors as Next.js doesn't pass params as a Promise.

    type PageProps = {
      params: Promise<{
        id: string
      }>
    }
    Error Handling

    The Number(projectId) conversion could fail if projectId is not a valid number string, potentially causing runtime errors.

    id: Number(projectId),

    Copy link
    Contributor

    qodo-merge-pro-for-open-source bot commented Mar 12, 2025

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Fix incorrect type definition
    Suggestion Impact:The commit addressed the issue by completely refactoring the approach. Instead of fixing the type definition directly, it imported a PageProps type from elsewhere and implemented validation using valibot. The code now handles params differently but resolves the core issue identified in the suggestion.

    code diff:

    +import type { PageProps } from '@/app/types'
     import { ProjectDetailPage } from '@/features/projects/pages'
    -import { migrationFlag } from '@/libs'
     import { notFound } from 'next/navigation'
    -import React from 'react'
    +import * as v from 'valibot'
     
    -type PageProps = {
    -  params: Promise<{
    -    id: string
    -  }>
    -}
    +const paramsSchema = v.object({
    +  id: v.string(),
    +})
     
     export default async function Page({ params }: PageProps) {
    -  const { id } = await params
    -  const migrationEnabled = await migrationFlag()
    +  const parsedParams = v.safeParse(paramsSchema, await params)
    +  if (!parsedParams.success) return notFound()

    The params property should not be a Promise type. In Next.js, route parameters
    are directly available as an object, not as a Promise.

    frontend/apps/app/app/(app)/app/projects/[id]/page.tsx [6-10]

     type PageProps = {
    -  params: Promise<{
    +  params: {
         id: string
    -  }>
    +  }
     }

    [Suggestion has been applied]

    Suggestion importance[1-10]: 9

    __

    Why: The suggestion correctly identifies a critical issue in the type definition. In Next.js, route parameters are directly available as an object, not as a Promise, which would cause type errors and potential runtime issues.

    High
    Remove unnecessary await
    Suggestion Impact:The commit addressed the issue with awaiting params, but took a different approach. Instead of simply removing the await, it implemented validation using valibot and safely parsed the params.

    code diff:

     export default async function Page({ params }: PageProps) {
    -  const { id } = await params
    -  const migrationEnabled = await migrationFlag()
    +  const parsedParams = v.safeParse(paramsSchema, await params)
    +  if (!parsedParams.success) return notFound()

    Remove the await keyword before params since it's not a Promise. The params
    object is directly available in Next.js route components.

    frontend/apps/app/app/(app)/app/projects/[id]/page.tsx [12-21]

     export default async function Page({ params }: PageProps) {
    -  const { id } = await params
    +  const { id } = params
       const migrationEnabled = await migrationFlag()
     
       if (!migrationEnabled) {
         notFound()
       }
     
       return <ProjectDetailPage projectId={id} />
     }

    [Suggestion has been applied]

    Suggestion importance[1-10]: 9

    __

    Why: This suggestion correctly identifies a bug where params is being awaited unnecessarily. This aligns with the type correction in suggestion 1 and would fix a potential runtime error in the application.

    High
    Add numeric ID validation

    Add error handling for the case when projectId cannot be converted to a number.
    Currently, if an invalid ID is passed, Number(projectId) might return NaN, which
    could cause unexpected behavior.

    frontend/apps/app/features/projects/pages/ProjectDetailPage/ProjectDetailPage.tsx [11-21]

     async function getProject(projectId: string) {
    +  const id = Number(projectId);
    +  if (isNaN(id)) {
    +    notFound();
    +  }
    +  
       const project = await prisma.project.findUnique({
         where: {
    -      id: Number(projectId),
    +      id,
         },
         select: {
           id: true,
           name: true,
           createdAt: true,
         },
       })
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    __

    Why: This suggestion adds important validation to handle cases where projectId cannot be converted to a number, preventing potential runtime errors. While not fixing a critical bug, it improves error handling and user experience.

    Medium
    • Update

    Copy link
    Member

    @junkisai junkisai left a comment

    Choose a reason for hiding this comment

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

    I only left one nit comment, but it looked good!

    Comment on lines 14 to 19
    const migrationEnabled = await migrationFlag()

    if (!migrationEnabled) {
    notFound()
    }

    Copy link
    Member

    Choose a reason for hiding this comment

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

    [nits]
    Since the same functionality is implemented in the middleware, I believe that it's no longer necessary to include it in page.tsx.

    https://github.com/liam-hq/liam/blob/main/frontend/apps/app/middleware.ts#L13-L19

    Copy link
    Member

    Choose a reason for hiding this comment

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

    same comment 🙏
    #855 (comment)

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

    Successfully merging this pull request may close these issues.

    3 participants