Skip to content

Add modern dashboard skeleton #2874

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

Open
wants to merge 1 commit into
base: alpha
Choose a base branch
from

Conversation

mtrezza
Copy link
Member

@mtrezza mtrezza commented Jul 7, 2025

Summary

  • set up a new React-based dashboard using Vite in new-dashboard/
  • add ability to switch between dashboards via a link in the sidebar
  • serve the new dashboard from Express
  • keep build artifacts ignored via .gitignore
  • ensure root scripts trigger build and lint for the new dashboard

Testing

  • npm test (fails: Config options test because of missing statusCode)
  • npm run build
  • npm run lint

https://chatgpt.com/codex/tasks/task_e_686c1f5d2440832da0761d91f4c3fd8f

Summary by CodeRabbit

  • New Features

    • Introduced a new dashboard accessible at the /new URL, featuring a modern React-based UI with Material UI components.
    • Added a sidebar link labeled "New Dashboard" for easy navigation.
    • The new dashboard allows viewing and updating cloud configuration parameters for Parse apps.
  • Improvements

    • Updated build, lint, and test scripts to include the new dashboard in project workflows.
    • Enhanced authentication handling for the new dashboard route.
  • Chores

    • Added and updated .gitignore files to exclude build artifacts and dependencies.
    • Added documentation and configuration files for the new dashboard setup.

@mtrezza mtrezza added the codex label Jul 7, 2025 — with ChatGPT Connector
Copy link

🚀 Thanks for opening this pull request!

Copy link

The label codex cannot be used here.

Copy link

coderabbitai bot commented Jul 7, 2025

📝 Walkthrough

Walkthrough

A new React-based dashboard ("new-dashboard") was introduced as a subproject, including its own build system, configuration, and UI. The main server was updated to serve this dashboard at /new, with authentication and static file handling. The main sidebar now links to the new dashboard, and build/test/lint scripts were updated to integrate its lifecycle.

Changes

File(s) Change Summary
.gitignore, new-dashboard/.gitignore Updated to ignore new-dashboard/node_modules/, dist/, editor/project files, logs, and build outputs.
Parse-Dashboard/app.js Added middleware and routes to serve the new dashboard at /new with authentication and static file serving.
src/components/Sidebar/Sidebar.react.js Added a "New Dashboard" link with icon to the sidebar footer for authenticated users.
package.json Updated scripts to build, lint, and install the new-dashboard as part of main project workflows.
new-dashboard/README.md Added documentation for the new React + Vite dashboard template and linting recommendations.
new-dashboard/package.json Added project metadata, scripts, dependencies, and devDependencies for the new-dashboard subproject.
new-dashboard/eslint.config.js, vite.config.js Added ESLint and Vite configuration for the new-dashboard React project.
new-dashboard/index.html Added HTML entry point for the new dashboard React app.
new-dashboard/src/App.jsx, src/CloudConfig.jsx Added main React app and cloud config management component for the dashboard UI.
new-dashboard/src/main.jsx Added React entry point mounting the app to the DOM.
new-dashboard/src/App.css, src/index.css Added CSS styles for the new dashboard UI.

Sequence Diagram(s)

sequenceDiagram
    participant Browser
    participant Server (Express)
    participant File System
    participant Auth

    Browser->>Server (Express): GET /new
    alt User is authenticated
        Server->>File System: Serve new-dashboard/dist/index.html
        File System-->>Server: index.html
        Server-->>Browser: index.html
    else User not authenticated
        Server->>Auth: Check authentication
        Auth-->>Server: Not authenticated
        Server-->>Browser: Redirect to /login?redirect=%2Fnew
    end
Loading
sequenceDiagram
    participant User
    participant New Dashboard (React)
    participant Parse Server

    User->>New Dashboard: Load UI (/new)
    New Dashboard->>Parse Server: GET /parse-dashboard-config.json
    Parse Server-->>New Dashboard: Dashboard config JSON
    User->>New Dashboard: Add or update cloud config param
    New Dashboard->>Parse Server: PUT /cloud-code-config (with masterKey)
    Parse Server-->>New Dashboard: Updated config
    New Dashboard-->>User: Updated config displayed
Loading

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error code ERR_SSL_WRONG_VERSION_NUMBER
npm error errno ERR_SSL_WRONG_VERSION_NUMBER
npm error request to https://10.0.0.28:4873/npm/-/npm-10.9.2.tgz failed, reason: C0EC0F8BFC7E0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:354:
npm error
npm error A complete log of this run can be found in: /.npm/_logs/2025-07-07T20_18_38_822Z-debug-0.log


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

@parseplatformorg
Copy link
Contributor

🎉 Snyk checks have passed. No issues have been found so far.

security/snyk check is complete. No issues have been found. (View Details)

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: 3

🔭 Outside diff range comments (1)
src/components/Sidebar/Sidebar.react.js (1)

40-42: Fix unhandled fetch promise for better error handling.

The fetch call lacks proper error handling and could cause unhandled promise rejections. Consider adding proper error handling.

- fetch(mountPath).then(response => {
-   setDashboardUser(response.headers.get('username'));
- });
+ fetch(mountPath)
+   .then(response => {
+     setDashboardUser(response.headers.get('username'));
+   })
+   .catch(error => {
+     console.error('Failed to fetch dashboard user:', error);
+   });
🧹 Nitpick comments (8)
new-dashboard/vite.config.js (1)

1-7: LGTM: Basic Vite configuration is appropriate for getting started.

The minimal configuration with React plugin is suitable for a new dashboard skeleton. Consider adding build-specific configurations (like base or build.outDir) if needed for integration with the main application.

new-dashboard/README.md (1)

1-12: Consider customizing README for Parse Dashboard context.

While the standard React + Vite template documentation is functional, consider adding Parse Dashboard-specific information such as:

  • Purpose of the new dashboard
  • How it integrates with the existing Parse Dashboard
  • Development setup instructions specific to this project
  • Any Parse Dashboard-specific configurations or dependencies
new-dashboard/index.html (1)

5-7: Prefer project-specific metadata over boilerplate text

The <title> still reads “Vite + React”. Rename it to something meaningful (e.g. “Parse Dashboard Next”) so browser tabs, history and accessibility tools show a relevant label.

new-dashboard/.gitignore (1)

10-14: Add secrets & tooling artifacts to ignore list

Consider extending the ignore set:

+# Environment variables / caches
+.env*
+.eslintcache

This prevents accidental commits of secrets and large linter caches.

new-dashboard/eslint.config.js (1)

26-27: varsIgnorePattern too broad – hides real dead code

Ignoring every variable that starts with an uppercase letter or underscore masks genuine mistakes (e.g. stray constants).
Narrow the pattern to _-prefixed placeholders only:

-'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
+'no-unused-vars': ['error', { varsIgnorePattern: '^_' }],
new-dashboard/package.json (1)

6-11: Add type-check:new-dashboard script for CI symmetry

You already wired build & lint into the root scripts; consider adding a TypeScript/tsc or eslint --max-warnings 0 pipeline step for the new dashboard to keep quality bars aligned with the legacy UI.

new-dashboard/src/CloudConfig.jsx (1)

14-16: Consider using public Parse SDK methods instead of private API.

Using Parse._request directly accesses a private API that may change without notice. Consider using the public Parse SDK methods if available for cloud config operations.

new-dashboard/src/App.jsx (1)

11-11: Apply optional chaining for cleaner code.

The static analysis suggestion is valid - using optional chaining would be more concise and readable.

-    fetch(basePath + 'parse-dashboard-config.json').then(r => r.json()).then(data => {
-      if (data.apps && data.apps.length) {
-        setApp(data.apps[0]);
-      }
-    });
+    fetch(basePath + 'parse-dashboard-config.json').then(r => r.json()).then(data => {
+      if (data.apps?.length) {
+        setApp(data.apps[0]);
+      }
+    });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cfd0bce and b4923b5.

⛔ Files ignored due to path filters (3)
  • new-dashboard/package-lock.json is excluded by !**/package-lock.json
  • new-dashboard/public/vite.svg is excluded by !**/*.svg
  • new-dashboard/src/assets/react.svg is excluded by !**/*.svg
📒 Files selected for processing (15)
  • .gitignore (1 hunks)
  • Parse-Dashboard/app.js (1 hunks)
  • new-dashboard/.gitignore (1 hunks)
  • new-dashboard/README.md (1 hunks)
  • new-dashboard/eslint.config.js (1 hunks)
  • new-dashboard/index.html (1 hunks)
  • new-dashboard/package.json (1 hunks)
  • new-dashboard/src/App.css (1 hunks)
  • new-dashboard/src/App.jsx (1 hunks)
  • new-dashboard/src/CloudConfig.jsx (1 hunks)
  • new-dashboard/src/index.css (1 hunks)
  • new-dashboard/src/main.jsx (1 hunks)
  • new-dashboard/vite.config.js (1 hunks)
  • package.json (1 hunks)
  • src/components/Sidebar/Sidebar.react.js (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: mtrezza
PR: parse-community/parse-dashboard#0
File: :0-0
Timestamp: 2025-05-11T16:43:27.354Z
Learning: The bcryptjs library is used in Parse Dashboard for password encryption and validation in three files: Parse-Dashboard/Authentication.js (compareSync), Parse-Dashboard/CLI/mfa.js (genSaltSync, hashSync), and src/dashboard/Settings/DashboardSettings/DashboardSettings.react.js (genSaltSync, hashSync).
new-dashboard/src/CloudConfig.jsx (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#0
File: :0-0
Timestamp: 2025-05-11T16:43:27.354Z
Learning: The bcryptjs library is used in Parse Dashboard for password encryption and validation in three files: Parse-Dashboard/Authentication.js (compareSync), Parse-Dashboard/CLI/mfa.js (genSaltSync, hashSync), and src/dashboard/Settings/DashboardSettings/DashboardSettings.react.js (genSaltSync, hashSync).
Parse-Dashboard/app.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#0
File: :0-0
Timestamp: 2025-05-11T16:43:27.354Z
Learning: The bcryptjs library is used in Parse Dashboard for password encryption and validation in three files: Parse-Dashboard/Authentication.js (compareSync), Parse-Dashboard/CLI/mfa.js (genSaltSync, hashSync), and src/dashboard/Settings/DashboardSettings/DashboardSettings.react.js (genSaltSync, hashSync).
🧬 Code Graph Analysis (2)
new-dashboard/src/main.jsx (1)
new-dashboard/src/App.jsx (1)
  • App (5-42)
src/components/Sidebar/Sidebar.react.js (1)
Parse-Dashboard/app.js (1)
  • mountPath (75-75)
🪛 Biome (1.9.4)
new-dashboard/src/App.jsx

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Node 18
  • GitHub Check: Node 22
  • GitHub Check: Docker linux/amd64
  • GitHub Check: Node 20
🔇 Additional comments (9)
src/components/Sidebar/Sidebar.react.js (1)

189-192: LGTM: New dashboard link follows existing patterns correctly.

The implementation is consistent with the existing logout link pattern, uses appropriate styling, and correctly constructs the URL with the mount path.

.gitignore (1)

20-21: LGTM: Proper exclusion of build artifacts.

Correctly excludes node_modules and dist directories from the new-dashboard subproject, following standard practices for React/Vite projects.

new-dashboard/src/main.jsx (1)

1-10: LGTM: Standard React 19 entry point implementation.

The code follows modern React best practices with createRoot API and StrictMode wrapper. The structure is appropriate for a Vite-based React application.

new-dashboard/index.html (1)

11-11: Absolute /src/main.jsx breaks when the app is served from /new

When Express mounts the built dashboard under /new, the leading slash makes the browser request
https://<host>/src/main.jsx instead of https://<host>/new/src/main.jsx.
During production builds Vite rewrites this anyway, but the path is used in dev mode.
Either:

-    <script type="module" src="/src/main.jsx"></script>
+    <script type="module" src="./src/main.jsx"></script>

or set base: '/new/' in vite.config.js and keep the absolute path.
Please verify the current config to avoid 404s while developing behind the main server proxy.

new-dashboard/src/App.css (1)

1-42: CSS looks good – no obvious specificity clashes or a11y issues
Styles are scoped only to the #root subtree and should not leak into the legacy dashboard.

new-dashboard/package.json (1)

12-19: React 19 is still experimental – confirm willingness to track canary releases

[email protected] is currently a canary tag; breaking changes land without notice.
If stability is paramount, pin to the latest 18.x LTS until 19 is officially released.

-    "react": "^19.1.0",
-    "react-dom": "^19.1.0"
+    "react": "^18.3.0",
+    "react-dom": "^18.3.0"

At minimum, document in the README why the bleeding-edge version is required.

new-dashboard/src/index.css (1)

1-69: LGTM! Clean CSS foundation with modern features.

The CSS provides a solid foundation with modern features like color-scheme support, optimized text rendering, and proper accessibility focus states. The dark/light theme support is well-implemented.

Parse-Dashboard/app.js (1)

234-248: LGTM! Proper integration of new dashboard with authentication.

The implementation correctly:

  • Serves static files from the new dashboard build directory
  • Enforces authentication consistently with the existing dashboard
  • Handles redirects properly with query parameters
  • Sets the username header for authenticated users
  • Serves the React app's entry point for all /new/* routes

The authentication flow matches the existing pattern and maintains security.

package.json (1)

130-139: LGTM! Proper integration of new dashboard into build pipeline.

The script changes correctly:

  • Add dedicated build and lint scripts for the new dashboard
  • Update existing scripts to include new dashboard in the workflow
  • Add postinstall script to handle new dashboard dependencies
  • Maintain proper sequencing (new dashboard builds before main build)

The integration follows npm best practices and ensures the new dashboard is properly built and linted as part of the main project lifecycle.

Comment on lines +11 to +15
extends: [
js.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Missing eslint-plugin-react – many core React rules not enforced

react-hooks only validates hook usage; it does not cover standard React best-practice rules (prop-types, jsx-no-undef, etc.).
Add the main plugin:

-import reactHooks from 'eslint-plugin-react-hooks'
+import react from 'eslint-plugin-react'
+import reactHooks from 'eslint-plugin-react-hooks'
 ...
       js.configs.recommended,
+      react.configs['recommended'],
       reactHooks.configs['recommended-latest'],

This tightens linting without additional maintenance.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
extends: [
js.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
// at the top of new-dashboard/eslint.config.js
-import reactHooks from 'eslint-plugin-react-hooks'
+import react from 'eslint-plugin-react'
+import reactHooks from 'eslint-plugin-react-hooks'
...
// later in your config object
extends: [
js.configs.recommended,
+ react.configs['recommended'],
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
🤖 Prompt for AI Agents
In new-dashboard/eslint.config.js around lines 11 to 15, the ESLint
configuration extends react-hooks rules but is missing the main
eslint-plugin-react plugin, which enforces core React best-practice rules. To
fix this, add eslint-plugin-react to the plugins array and include
react.configs.recommended in the extends array to enable standard React linting
rules alongside react-hooks.

Comment on lines +14 to +16
Parse._request('GET', 'config', {}, { useMasterKey: true })
.then(res => setParams(res.params || {}));
}, [app]);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for API requests.

The component lacks error handling for network failures or API errors. Consider adding try-catch blocks or .catch() handlers to provide user feedback when operations fail.

  useEffect(() => {
    if (!app) return;
    Parse.serverURL = app.serverURL;
    Parse.initialize(app.appId, app.javascriptKey || '', app.masterKey);
    Parse._request('GET', 'config', {}, { useMasterKey: true })
-     .then(res => setParams(res.params || {}));
+     .then(res => setParams(res.params || {}))
+     .catch(err => console.error('Failed to load config:', err));
  }, [app]);
  const saveParam = () => {
    if (!key) return;
    Parse._request('PUT', 'config', { params: { [key]: value } }, { useMasterKey: true })
      .then(() => {
        setParams(prev => ({ ...prev, [key]: value }));
        setKey('');
        setValue('');
-     });
+     })
+     .catch(err => console.error('Failed to save config:', err));
  };

Also applies to: 20-26

🤖 Prompt for AI Agents
In new-dashboard/src/CloudConfig.jsx around lines 14 to 16 and 20 to 26, the API
requests using Parse._request lack error handling for network or API failures.
Add .catch() handlers to these promises to catch errors and handle them
appropriately, such as setting error state or displaying user feedback. This
will ensure the component gracefully manages failures instead of silently
failing.

Comment on lines +9 to +15
useEffect(() => {
fetch(basePath + 'parse-dashboard-config.json').then(r => r.json()).then(data => {
if (data.apps && data.apps.length) {
setApp(data.apps[0]);
}
});
}, []);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for configuration fetch.

The component should handle potential network errors or invalid responses when fetching the dashboard configuration.

  useEffect(() => {
    fetch(basePath + 'parse-dashboard-config.json').then(r => r.json()).then(data => {
      if (data.apps?.length) {
        setApp(data.apps[0]);
      }
-   });
+   }).catch(err => {
+     console.error('Failed to load dashboard config:', err);
+   });
  }, []);

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Biome (1.9.4)

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🤖 Prompt for AI Agents
In new-dashboard/src/App.jsx around lines 9 to 15, the fetch call for the
dashboard configuration lacks error handling for network failures or invalid
JSON responses. Add a catch block to the promise chain to handle fetch errors
and JSON parsing errors. Inside the catch block, log the error or update the
component state to reflect the failure, ensuring the app can gracefully handle
fetch issues without crashing.

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

Successfully merging this pull request may close these issues.

2 participants