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): plugin playground/reflect code editor to viewer #1224

Merged
merged 41 commits into from
Nov 20, 2024

Conversation

devshun
Copy link
Contributor

@devshun devshun commented Nov 5, 2024

Overview

What I've done

I implemented the process to execute reearth.yml and other JS files and reflect the plugins in the visualizer.

2024-11-07.22.12.10.mov

What I haven't done

How I tested

Which point I want you to review particularly

Memo

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a code execution functionality within the Plugin Playground, allowing users to run JavaScript and parse YAML files.
    • Enhanced the Code component for improved interaction with source code changes and execution capabilities.
    • Added a demo widget to the plugin management system, enabling dynamic updates to file source code.
  • Improvements

    • Enhanced type safety and prop management for the Viewer component.
    • Improved widget alignment and organization based on YAML configurations.
    • Integrated code execution capabilities and improved file management processes in the plugin playground.
  • Bug Fixes

    • Implemented structured error handling for YAML parsing errors.

Copy link

coderabbitai bot commented Nov 5, 2024

Walkthrough

The changes introduce a new React functional component in hook.ts that manages JavaScript code execution and YAML file parsing for widgets. It includes structured error handling and widget alignment based on parsed YAML data. The Code component in index.tsx is updated to include new props for handling source code changes and executing code. Additionally, modifications in constants.ts, hook.ts, and Viewer/index.tsx enhance the structure and functionality of the plugin management system, allowing for dynamic updates to file source codes and better type safety.

Changes

File Path Change Summary
web/src/beta/features/PluginPlayground/Code/hook.ts Introduced a new React component managing code execution and YAML parsing, added types for YAML structure and props, and implemented structured error handling.
web/src/beta/features/PluginPlayground/Code/index.tsx Updated Props type to include onChangeSourceCode and executeCode functions, modified Button and CodeInput to utilize these new props for enhanced interactivity.
web/src/beta/features/PluginPlayground/Plugins/constants.ts Modified REEARTH_YML_FILE constant's sourceCode property to include a new structure with id, name, description, and widgetLayout, while maintaining existing properties.
web/src/beta/features/PluginPlayground/Plugins/hook.ts Enhanced functionality by adding a demo file object to the plugins state, introduced updateFileSourceCode function for dynamic updates to file source code, and updated the return object to include this new method.
web/src/beta/features/PluginPlayground/Viewer/index.tsx Defined a new Props type for the Viewer component to enhance type safety, updated the component signature to accept this type, and passed widgets to the Visualizer component.
web/src/beta/features/PluginPlayground/hooks.tsx Integrated useCode hook for managing code execution and widget retrieval, updated MainAreaTabs to include widgets in the Viewer, and added executeCode as a dependency in RightAreaTabs.

Possibly related PRs

Suggested reviewers

  • mkumbobeaty
  • airslice
  • mulengawilfred

Poem

🐰 In the playground where plugins play,
New hooks and types brighten the day.
Code executes, errors take flight,
Widgets align, all feels just right!
With YAML and JavaScript in tow,
Let’s hop along, watch our features grow! 🌟


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

netlify bot commented Nov 5, 2024

Deploy Preview for reearth-web ready!

Name Link
🔨 Latest commit f97df89
🔍 Latest deploy log https://app.netlify.com/sites/reearth-web/deploys/673d2dc33652db0008dec035
😎 Deploy Preview https://deploy-preview-1224--reearth-web.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@github-actions github-actions bot added the web label Nov 5, 2024
@devshun devshun changed the title Playground/reflect code to visual feat(web): plugin playground/reflect code editor to viewer Nov 5, 2024
@devshun devshun changed the base branch from main to playground/display-code-editor November 5, 2024 23:31
@devshun devshun marked this pull request as ready for review November 7, 2024 13:10
mulengawilfred
mulengawilfred previously approved these changes Nov 10, 2024
Copy link
Contributor

@mulengawilfred mulengawilfred left a comment

Choose a reason for hiding this comment

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

Changes look good. Approved 👍

@devshun devshun changed the base branch from playground/display-code-editor to main November 11, 2024 01:33
@devshun devshun dismissed mulengawilfred’s stale review November 11, 2024 01:33

The base branch was changed.

@devshun devshun changed the base branch from main to playground/display-code-editor November 11, 2024 01:34
@devshun devshun requested a review from ZTongci November 11, 2024 01:36
ZTongci
ZTongci previously approved these changes Nov 11, 2024
Copy link
Contributor

@ZTongci ZTongci left a comment

Choose a reason for hiding this comment

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

Great job, I find a small typo. Please check.

web/src/beta/features/PluginPlayground/Viewer/index.tsx Outdated Show resolved Hide resolved
@devshun devshun changed the base branch from playground/display-code-editor to main November 13, 2024 01:56
@devshun devshun dismissed ZTongci’s stale review November 13, 2024 01:56

The base branch was changed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Outside diff range and nitpick comments (9)
web/src/beta/features/PluginPlayground/Plugins/constants.ts (1)

18-31: LGTM! Consider enhancing maintainability.

The YAML structure is well-organized with clear separation of plugin metadata and extension configuration. However, consider these improvements:

  1. Use template literals with proper YAML indentation for better readability
  2. Add comments explaining the expected schema
  3. Consider a more descriptive widget description

Here's a suggested improvement:

   sourceCode: `id: demo-widget
name: Test plugin
version: 1.0.0
+# Plugin extensions define the components and their configurations
extensions:
   - id: demo-widget
     type: widget
     name: Demo Widget
-    description: Demo widget
+    description: A demo widget showcasing plugin reflection capabilities
     widgetLayout:
       defaultLocation:
         zone: outer
         section: left
         area: top
   `,
web/src/beta/features/PluginPlayground/Code/index.tsx (2)

34-34: Consider adding execution feedback states

The execute button could benefit from visual feedback during code execution. Consider:

  • Adding a loading state while code is executing
  • Providing visual feedback for successful/failed execution
  • Disabling the button during execution
-        <Button icon="playRight" iconButton onClick={executeCode} />
+        <Button
+          icon={isExecuting ? "loading" : "playRight"}
+          iconButton
+          onClick={executeCode}
+          disabled={isExecuting}
+        />

37-41: Consider debouncing source code changes

For better performance, consider debouncing the onChangeSourceCode callback to prevent excessive updates when typing rapidly.

+import { useCallback } from "react";
+import debounce from "lodash/debounce";

 const Code: FC<Props> = ({ ... }) => {
+  const debouncedOnChange = useCallback(
+    debounce((value: string | undefined) => onChangeSourceCode(value), 300),
+    [onChangeSourceCode]
+  );
+
   return (
     ...
     <CodeInput
       language={getLanguageByFileExtension(fileTitle)}
       value={sourceCode}
-      onChange={onChangeSourceCode}
+      onChange={debouncedOnChange}
     />
web/src/beta/features/PluginPlayground/hooks.tsx (2)

97-103: Consider optimizing the source code update handler

While the implementation is functional, consider these improvements:

  1. The callback could be simplified
  2. Consider debouncing source code updates to prevent excessive updates during typing

Here's a suggested improvement:

- executeCode={executeCode}
- onChangeSourceCode={(value) => {
-   updateFileSourceCode(
-     value ?? selectedFile.sourceCode,
-     selectedFile.id
-   );
- }}
+ executeCode={executeCode}
+ onChangeSourceCode={useCallback(
+   (value) => updateFileSourceCode(value ?? selectedFile.sourceCode, selectedFile.id),
+   [selectedFile.id, selectedFile.sourceCode, updateFileSourceCode]
+ )}

Consider adding debouncing:

const debouncedUpdateSourceCode = useMemo(
  () => debounce(updateFileSourceCode, 300),
  [updateFileSourceCode]
);

115-115: Consider consistent dependency ordering

For better maintainability, consider grouping related dependencies together.

- [selectedFile, handlePluginDownload, executeCode, updateFileSourceCode]
+ [selectedFile, executeCode, updateFileSourceCode, handlePluginDownload]
web/src/beta/features/PluginPlayground/Plugins/hook.ts (2)

15-41: Consider improving the demo widget implementation.

The demo widget implementation could be enhanced in several ways:

  1. Move the demo widget template to a separate constants file for better maintainability
  2. Consider using CSS-in-JS or a separate stylesheet instead of inline styles
  3. Clean up unnecessary whitespace in the template literal

Here's a suggested refactor:

+ // In constants.ts
+ export const DEMO_WIDGET_SOURCE = `reearth.ui.show(\`
+   <style>
+     body { margin: 0; }
+     #wrapper {
+       background: #232226;
+       height: 100%;
+       color: white;
+       border: 3px dotted red;
+       border-radius: 5px;
+       padding: 20px 0;
+     }
+   </style>
+   <div id="wrapper">
+     <h2 style="text-align: center; margin: 0;">Hello World</h2>
+   </div>
+ \`);`;

- sourceCode: `reearth.ui.show(\`
-   <style>
-     body {
-       margin: 0;
-     }
-     #wrapper {
-       background: #232226;
-       height: 100%;
-       color: white;
-       border: 3px dotted red;
-       border-radius: 5px;
-       padding: 20px 0;
-     }
-   </style>
-   <div id="wrapper">
-     <h2 style="text-align: center; margin: 0;">Hello World</h2>
-   </div>
- \`);
-           
-           `
+ sourceCode: DEMO_WIDGET_SOURCE

131-147: Consider adding error handling for invalid file IDs.

The implementation looks good and follows the established patterns in the codebase. However, consider adding error handling for cases where the file ID doesn't exist.

Here's a suggested enhancement:

  const updateFileSourceCode = useCallback(
    (sourceCode: string, id: string) => {
+     const fileExists = selectedPlugin.files.some(file => file.id === id);
+     if (!fileExists) {
+       setNotification({ 
+         type: "error", 
+         text: "Cannot update source code: File not found" 
+       });
+       return;
+     }
      setPlugins((plugins) =>
        plugins.map((plugin) =>
          plugin.id === selectedPlugin.id
            ? {
                ...plugin,
                files: plugin.files.map((file) =>
                  file.id === id ? { ...file, sourceCode } : file
                )
              }
            : plugin
        )
      );
    },
-   [selectedPlugin]
+   [selectedPlugin, setNotification]
  );
web/src/beta/features/PluginPlayground/Code/hook.ts (2)

51-51: Name the exported functional component for better debugging and clarity.

Naming the exported functional component can improve stack traces and enhance code readability.

Apply this diff to name the component:

-export default ({ files }: Props) => {
+export default function PluginExecutor({ files }: Props) {

93-95: Handle the case where the JavaScript file corresponding to the extension is not found.

When the corresponding JavaScript file for an extension is not found, it might be helpful to notify the user or log a warning. This improves debuggability and user feedback.

Consider adding a notification:

if (!file) {
+ setNotification({
+   type: "warning",
+   text: `JavaScript file for extension "${cur.id}" not found.`,
+ });
  return prv;
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between dff7dc3 and f940da6.

📒 Files selected for processing (6)
  • web/src/beta/features/PluginPlayground/Code/hook.ts (1 hunks)
  • web/src/beta/features/PluginPlayground/Code/index.tsx (2 hunks)
  • web/src/beta/features/PluginPlayground/Plugins/constants.ts (1 hunks)
  • web/src/beta/features/PluginPlayground/Plugins/hook.ts (3 hunks)
  • web/src/beta/features/PluginPlayground/Viewer/index.tsx (2 hunks)
  • web/src/beta/features/PluginPlayground/hooks.tsx (4 hunks)
🧰 Additional context used
🪛 GitHub Check: ci-web / ci
web/src/beta/features/PluginPlayground/Code/hook.ts

[failure] 60-60:
'outputs' is assigned a value but never used. Allowed unused vars must match /^_/u

🪛 Biome
web/src/beta/features/PluginPlayground/Code/hook.ts

[error] 108-108: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

🔇 Additional comments (9)
web/src/beta/features/PluginPlayground/Viewer/index.tsx (3)

6-8: LGTM! Well-structured type definition.

The Props type is well-defined using ComponentProps utility type, ensuring type safety by properly extracting the widgets type from the Visualizer component.


10-10: LGTM! Component signature follows React best practices.

The functional component signature is properly typed with FC and correctly destructures the widgets prop.


29-29: Verify widget integration with Visualizer component.

The widgets prop is correctly passed to the Visualizer component. However, let's verify the widget integration implementation.

web/src/beta/features/PluginPlayground/Plugins/constants.ts (1)

26-30: Verify widget layout configuration compatibility.

The widget layout configuration specifies positioning in the outer zone's left section. Let's verify this is a valid configuration and that all specified zones/sections are supported.

✅ Verification successful

Widget layout configuration is compatible.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for widget layout configuration patterns and documentation

# Check for layout configuration patterns
echo "Searching for other widget layout configurations..."
rg -A 3 'widgetLayout:\s*defaultLocation:' 

# Check for zone/section/area definitions or documentation
echo "Searching for layout zone definitions..."
rg -A 5 'zone:\s*(outer|inner)' 

# Check for any layout-related type definitions
echo "Searching for layout type definitions..."
ast-grep --pattern 'type $_ = {
  $$$
  zone?: $_
  $$$
}'

Length of output: 5227


Script:

#!/bin/bash
# Description: Verify sections and areas in widget layout configurations

# Check for section definitions and usages
echo "Searching for section definitions..."
rg -A 3 'section:\s*(left|right|center)'

# Check for area definitions and usages
echo "Searching for area definitions..."
rg -A 3 'area:\s*(top|bottom)'

Length of output: 2838

web/src/beta/features/PluginPlayground/Code/index.tsx (2)

25-30: LGTM! Clean component signature

The component signature follows React best practices with proper TypeScript typing and clean props destructuring.


8-9: Verify handling of undefined sourceCode values

The onChangeSourceCode callback accepts undefined as a valid value. Ensure that the parent component properly handles this case to prevent potential runtime issues.

web/src/beta/features/PluginPlayground/hooks.tsx (2)

21-21: LGTM!

The addition of updateFileSourceCode aligns well with the PR's objective of implementing plugin reflection.


38-38: LGTM!

The Viewer component props and dependency array are correctly updated to handle the widgets prop.

Also applies to: 41-41

web/src/beta/features/PluginPlayground/Plugins/hook.ts (1)

239-239: LGTM!

The new function is properly exposed in the return object, maintaining consistency with the existing pattern.

web/src/beta/features/PluginPlayground/Code/hook.ts Outdated Show resolved Hide resolved
web/src/beta/features/PluginPlayground/Code/hook.ts Outdated Show resolved Hide resolved
web/src/beta/features/PluginPlayground/Code/hook.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@mulengawilfred mulengawilfred left a comment

Choose a reason for hiding this comment

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

Looks good. Added a few issues identified by code-rabbit. Kindly take a look at those potential issues and see which ones need to be resolved.

Also if we can, lets add a to yml in variable names. e.g ReearthYML -> ReearthYAML , getYmlResult -> getYamlResult, ymlJson -> yamlJson.

The minor extra verbosity can bring more clarity to the reader.

The eslint ci-build seems to fail for this but mention me or Shaun to investigate if the fix is not obvious as we have quite a number of issues there.

web/src/beta/features/PluginPlayground/Code/hook.ts Outdated Show resolved Hide resolved
web/src/beta/features/PluginPlayground/Code/hook.ts Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f940da6 and 3b75842.

📒 Files selected for processing (1)
  • web/src/beta/features/PluginPlayground/Code/hook.ts (1 hunks)
🧰 Additional context used
🪛 Biome
web/src/beta/features/PluginPlayground/Code/hook.ts

[error] 96-96: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

Copy link
Contributor

@mulengawilfred mulengawilfred left a comment

Choose a reason for hiding this comment

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

Marked as approved. Let's get this PR in to main if we can. Thank you!

@devshun devshun merged commit 49df88a into main Nov 20, 2024
13 checks passed
@devshun devshun deleted the playground/reflect-code-to-visual branch November 20, 2024 13:46
hexaforce pushed a commit that referenced this pull request Nov 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants