Refactor Workspace Files: Accordion & Syntax Highlighting

by Admin 58 views
Refactoring Workspace Files: Creating a Reusable Accordion Component with Enhanced Code Display

Hey guys! Let's dive into a neat little project: refactoring the workspace files accordion in our application. The goal is to make it more organized, reusable, and visually appealing, especially when displaying code. We'll be extracting the accordion UI into a separate component, replacing the basic <pre> tag with the powerful ProsePre component from @nuxtjs/mdc for beautiful syntax highlighting. Sounds good, right?

The Current State of Affairs

Currently, the workspace files accordion is embedded directly within DraftWorkspace.vue. This means that the code responsible for displaying files, including the MDX content within a <pre> tag, is all in one place. This isn't ideal for a few reasons. First, it makes the code harder to read and maintain. Second, it limits reusability; if we want to display workspace files in another part of the application, we'd have to duplicate the code. Finally, the plain <pre> tag, while functional, doesn't offer any syntax highlighting, making the code harder to read and understand.

We're talking about lines 1148-1192 in DraftWorkspace.vue. This section is responsible for rendering the accordion, displaying file names, and showing the file content. The content itself is currently displayed using a simple <pre> tag:

<pre class="whitespace-pre-wrap text-xs bg-muted px-3 py-2 rounded-md overflow-x-auto max-h-[500px]">
  {{ item.file.fullMdx }}
</pre>

This works, but it's not the best. No syntax highlighting, which is a bummer when dealing with code, MDX, or any other kind of formatted text. We can do better, and we will!

The Refactoring Plan: Step-by-Step

Step 1: Creating the WorkspaceFilesAccordion Component

The first step involves creating a new component specifically for the workspace files accordion. This will encapsulate all the logic and UI related to displaying the files. Here's what we'll do:

  1. Create the Component: We'll start by creating a new file: app/components/chat/WorkspaceFilesAccordion.vue. This will be the home of our new component.
  2. Extract the Accordion UI: We'll take the code from DraftWorkspace.vue (lines 1148-1192) that's responsible for the accordion and move it into this new component. This includes the UAccordion and the file metadata display.
  3. Accept files as a Prop: The new component needs to receive the array of files to display. We'll define a prop named files that will accept an array matching the WorkspaceFilePayload interface (defined in server/services/content/workspaceFiles.ts). This ensures that the component knows what data it's working with.
  4. Maintain Existing Functionality and Styling: The new component should function exactly like the old one, but now it is independent. The accordion should open and close correctly, and the file metadata (filename, sections, word count, etc.) should display as before.

This extraction is a fundamental principle of good software design: separating concerns. The DraftWorkspace.vue component will no longer be cluttered with the details of file display; it will simply pass the file data to the WorkspaceFilesAccordion component.

Step 2: Integrating ProsePre for Stunning Code Display

This is where things get interesting, and the visual quality of the app gets a massive upgrade. We will swap out the basic <pre> tag with the ProsePre component from @nuxtjs/mdc. This is like giving our code a fresh coat of paint and some serious readability improvements.

  1. Replace <pre> with ProsePre: Inside WorkspaceFilesAccordion.vue, we'll replace the <pre> tag with <ProsePre>. This is where the magic happens.
  2. Ensure Syntax Highlighting: ProsePre automatically provides syntax highlighting based on the content inside it. This means your code snippets, MDX content, and any other formatted text will be beautifully rendered with appropriate colors and styles.
  3. Maintain Copy-to-Clipboard: We need to make sure the copy-to-clipboard functionality, if there is one, continues to work. If there's a button to copy the code, it must keep working after the change.
  4. Support Light/Dark Theme Switching: Our application probably has light and dark themes. ProsePre should adapt to the current theme, ensuring the code display looks great in both.

This step leverages the power of Shiki, the syntax highlighting engine used by @nuxtjs/mdc. Shiki will analyze the code and apply the correct styles to make it easy to read and understand.

Step 3: Updating DraftWorkspace.vue

Once the WorkspaceFilesAccordion component is ready, we'll update DraftWorkspace.vue to use it. This is a straightforward process:

  1. Remove the Inline Accordion Code: Delete the accordion code (lines 1148-1192) from DraftWorkspace.vue.
  2. Import and Use the New Component: Import WorkspaceFilesAccordion.vue into DraftWorkspace.vue and use it in your template.
  3. Pass the files Prop: The DraftWorkspace.vue component will receive the file data (likely from message.payload.files). Pass this data as the files prop to the WorkspaceFilesAccordion component.

This is the final step, tying everything together. DraftWorkspace.vue will now delegate the responsibility of displaying files to the new, reusable component.

Technical Details and Considerations

Component Requirements

  • files Prop: The WorkspaceFilesAccordion component must accept a files array prop matching the WorkspaceFilePayload interface. This interface defines the structure of the file data we're working with.
  • Nuxt UI Components: The component should use UAccordion and UBadge from Nuxt UI. These components are likely already in use in your project, so we'll continue to use them.
  • ProsePre for Code Display: ProsePre should be used to display the code with proper syntax highlighting.
  • Metadata Display: The component should maintain the existing file metadata display (filename, sections, word count).
  • Styling and Behavior: All existing styling and behavior should be preserved.
  • Syntax Highlighting: The code should be properly syntax-highlighted in the accordion dropdown.
  • Copy Button: The copy button (if one exists) should work correctly for code blocks.

Related Files and Documentation

  • app/components/chat/DraftWorkspace.vue: The file we're modifying to integrate the new component.
  • server/services/content/workspaceFiles.ts: This file defines the WorkspaceFilePayload interface. This is important because it dictates the data structure of the files array.
  • server/api/chat/index.post.ts: This file likely creates the files payload, which is where the data comes from.
  • Nuxt UI Code Documentation: You can find more information about the ProsePre component and other Nuxt UI components at the official documentation: https://ui.nuxt.com/docs/typography/code.

Additional Notes

  • Component Focus: The WorkspaceFilesAccordion component should be focused on displaying files and should be minimal. Avoid adding unnecessary complexity.
  • Reusability: Consider making the component reusable for other contexts where workspace files are displayed. This will save you time in the long run.
  • Module Configuration: Make sure the @nuxtjs/mdc module is configured in nuxt.config.ts if it's not already present. This is essential for ProsePre to work.

Benefits of Refactoring

  • Improved Code Readability: The code becomes more organized and easier to understand.
  • Increased Reusability: The WorkspaceFilesAccordion component can be used in other parts of the application.
  • Enhanced User Experience: Syntax highlighting makes code easier to read and understand.
  • Simplified Maintenance: Changes to the file display logic only need to be made in one place.
  • Better Visuals: The code snippets will look professional and well-formatted.

Conclusion: Making Things Better

This refactoring project is a great example of how we can improve the quality and maintainability of our codebase. By extracting the accordion UI into a separate component and using ProsePre for code display, we'll create a more organized, reusable, and visually appealing workspace files section. This will result in better code readability, a better user experience, and a more maintainable application overall. It's a win-win for everyone involved!

So, let's get to it! Good luck, and happy coding, everyone!