-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
feat: Add custom data views with aggregation query #2888
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
Conversation
The label |
I will reformat the title to use the proper commit message syntax. |
📝 WalkthroughWalkthroughThe changes introduce a new "Views" feature to the dashboard, allowing users to create, manage, and display custom data views. This includes new routing for "views," a sidebar entry, a React component for the views table, modals for creating, editing, and deleting views, a localStorage-backed utility for persisting view preferences per application, and associated styling. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Dashboard
participant ViewsComponent
participant ViewPreferences
participant ModalDialog
participant ParseServer
User->>Dashboard: Navigates to /views
Dashboard->>ViewsComponent: Render Views component
ViewsComponent->>ViewPreferences: getViews(appId)
ViewPreferences-->>ViewsComponent: Return saved views
ViewsComponent->>ParseServer: Fetch schema and counts for views (if needed)
ParseServer-->>ViewsComponent: Return schema and count data
ViewsComponent->>User: Display views list and table
User->>ViewsComponent: Click "Create View"
ViewsComponent->>ModalDialog: Show CreateViewDialog
User->>ModalDialog: Fill form and confirm
ModalDialog->>ViewsComponent: onConfirm(newView)
ViewsComponent->>ViewPreferences: saveViews(appId, updatedViews)
ViewsComponent->>ViewsComponent: Reload views and data
ViewsComponent->>User: Update UI with new view
User->>ViewsComponent: Select view and click "Edit"
ViewsComponent->>ModalDialog: Show EditViewDialog
User->>ModalDialog: Modify form and confirm
ModalDialog->>ViewsComponent: onConfirm(updatedView)
ViewsComponent->>ViewPreferences: saveViews(appId, updatedViews)
ViewsComponent->>ViewsComponent: Reload views and data
ViewsComponent->>User: Update UI with edited view
User->>ViewsComponent: Select view and click "Delete"
ViewsComponent->>ModalDialog: Show DeleteViewDialog
User->>ModalDialog: Confirm deletion by typing name
ModalDialog->>ViewsComponent: onConfirm(viewName)
ViewsComponent->>ViewPreferences: saveViews(appId, updatedViews)
ViewsComponent->>ViewsComponent: Reload views and data
ViewsComponent->>User: Update UI removing deleted view
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
npm error code ERR_SSL_WRONG_VERSION_NUMBER 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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
🚀 Thanks for opening this pull request! |
🎉 Snyk checks have passed. No issues have been found so far.✅ security/snyk check is complete. No issues have been found. (View Details) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (3)
src/lib/ViewPreferences.js (1)
17-21
: Consider logging errors instead of silently catching themThe empty catch block could hide important errors such as quota exceeded or security exceptions. Consider logging these errors for debugging purposes.
export function saveViews(appId, views) { try { localStorage.setItem(path(appId), JSON.stringify(views)); - } catch {} + } catch (error) { + console.error('Failed to save views:', error); + } }src/dashboard/Data/Views/Views.react.js (1)
103-103
: Consider using a stable key for table rowsUsing
JSON.stringify(row)
as a key could cause performance issues with large datasets and may not be stable if object property order changes.Consider using a unique identifier from the row data if available, or generate stable IDs when loading the data.
src/dashboard/Data/Views/CreateViewDialog.react.js (1)
10-17
: Consider reusing the existing isValidJSON utilityThere's already an
isValidJSON
function insrc/dashboard/Push/PushNew.react.js
that has similar functionality. Consider extracting it to a shared utility module to avoid duplication.Would you like me to help extract this function to a shared utilities module?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/dashboard/Dashboard.js
(2 hunks)src/dashboard/DashboardView.react.js
(2 hunks)src/dashboard/Data/Views/CreateViewDialog.react.js
(1 hunks)src/dashboard/Data/Views/Views.react.js
(1 hunks)src/lib/ViewPreferences.js
(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
src/lib/ViewPreferences.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2769
File: src/lib/ClassPreferences.js:26-26
Timestamp: 2025-05-02T11:55:52.809Z
Learning: Preference reads and writes in the ClassPreferences.js module are expected to be infrequent operations, so optimizing for performance (like caching) is unnecessary in this context.
src/dashboard/Data/Views/CreateViewDialog.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
🧬 Code Graph Analysis (1)
src/dashboard/Data/Views/CreateViewDialog.react.js (1)
src/dashboard/Push/PushNew.react.js (1)
isValidJSON
(55-68)
🪛 GitHub Check: Lint
src/dashboard/DashboardView.react.js
[failure] 70-70:
Expected indentation of 4 spaces but found 6
src/dashboard/Data/Views/Views.react.js
[failure] 87-87:
Expected { after 'else'
[failure] 86-86:
Expected { after 'if' condition
[failure] 85-85:
Expected { after 'if' condition
[failure] 84-84:
Expected { after 'if' condition
[failure] 83-83:
Expected { after 'if' condition
[failure] 81-81:
Expected { after 'if' condition
[failure] 80-80:
Expected { after 'if' condition
[failure] 77-77:
Expected { after 'if' condition
[failure] 61-61:
'app' is assigned a value but never used
⏰ 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). (2)
- GitHub Check: Node 18
- GitHub Check: Docker linux/amd64
🔇 Additional comments (5)
src/lib/ViewPreferences.js (1)
1-25
: LGTM! Clean implementation for view preferences storageThe implementation follows a similar pattern to
ClassPreferences.js
and appropriately handles localStorage operations with error handling. The versioned storage key is a good practice for future migrations.Based on past learnings from
ClassPreferences.js
, these preference operations are expected to be infrequent, so the current implementation without caching is appropriate.src/dashboard/DashboardView.react.js (1)
79-82
: Views section correctly integratedThe new Views section is properly added to the core subsections and will appear in the sidebar navigation.
src/dashboard/Dashboard.js (1)
47-47
: Routing properly configured for Views featureThe Views component is correctly imported and integrated into the routing configuration with appropriate paths for both the views list and individual view pages.
Also applies to: 274-275
src/dashboard/Data/Views/Views.react.js (1)
49-49
: Verify the use of master key for aggregate queriesThe queries use
useMasterKey: true
which bypasses all security rules. Please ensure this is intentional and that proper access controls are in place.Also applies to: 72-72
src/dashboard/Data/Views/CreateViewDialog.react.js (1)
19-111
: Well-structured dialog componentThe component properly validates inputs, handles state management, and provides a clean interface for creating views. The use of controlled components and validation logic ensures data integrity.
componentWillMount() { | ||
this.loadViews(this.context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace deprecated lifecycle methods
componentWillMount
and componentWillReceiveProps
are deprecated. Use componentDidMount
and componentDidUpdate
instead.
- componentWillMount() {
+ componentDidMount() {
this.loadViews(this.context);
}
- componentWillReceiveProps(nextProps, nextContext) {
- if (this.context !== nextContext) {
- this.loadViews(nextContext);
- }
- if (this.props.params.name !== nextProps.params.name || this.context !== nextContext) {
- this.loadData(nextProps.params.name, nextContext);
- }
+ componentDidUpdate(prevProps, prevState, prevContext) {
+ if (this.context !== prevContext) {
+ this.loadViews(this.context);
+ }
+ if (this.props.params.name !== prevProps.params.name || this.context !== prevContext) {
+ this.loadData(this.props.params.name, this.context);
+ }
}
Also applies to: 34-41
🤖 Prompt for AI Agents
In src/dashboard/Data/Views/Views.react.js around lines 30 to 41, replace the
deprecated lifecycle methods componentWillMount and componentWillReceiveProps
with componentDidMount and componentDidUpdate respectively. Move the logic
inside componentWillMount to componentDidMount, and move the logic inside
componentWillReceiveProps to componentDidUpdate, adjusting the method signatures
and conditions as needed to maintain the same behavior.
There was a problem hiding this 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
♻️ Duplicate comments (3)
src/dashboard/Data/Views/Views.react.js (3)
34-49
: Replace deprecated lifecycle methods with modern alternatives.The deprecated lifecycle methods
componentWillMount
andcomponentWillReceiveProps
should be replaced withcomponentDidMount
andcomponentDidUpdate
.
56-63
: Add error handling for Parse aggregate queries.The Parse query lacks error handling, which could lead to unhandled promise rejections if the query fails.
79-112
: Add error handling for data loading Parse queries.The Parse query in
loadData
method lacks error handling, which could cause unhandled promise rejections.
🧹 Nitpick comments (5)
src/dashboard/Data/Views/Views.react.js (5)
123-123
: Improve cell value rendering for better user experience.Converting all values to strings may not provide the best user experience, especially for dates, booleans, and objects.
- <td key={name}>{String(row[name])}</td> + <td key={name}>{this.formatCellValue(row[name], this.state.columns[name])}</td>Consider adding a
formatCellValue
method to handle different data types appropriately:formatCellValue(value, column) { if (value === null || value === undefined) return ''; switch (column?.type) { case 'Date': return new Date(value).toLocaleString(); case 'Boolean': return value ? 'true' : 'false'; case 'Object': return JSON.stringify(value); default: return String(value); } }
131-131
: Use dynamic width calculation for table headers.The hardcoded width of 20 for table headers may not be appropriate for all column types and content lengths.
- <TableHeader key={name} width={20} > + <TableHeader key={name} width={column.width || 150} >
176-185
: Optimize state updates and reduce unnecessary re-renders.The current implementation calls
loadViews
again after saving, which could cause unnecessary re-renders and data fetching.onConfirm={view => { - this.setState( - state => ({ showCreate: false, views: [...state.views, view] }), - () => { - ViewPreferences.saveViews( - this.context.applicationId, - this.state.views - ); - this.loadViews(this.context); - } - ); + const newViews = [...this.state.views, view]; + ViewPreferences.saveViews(this.context.applicationId, newViews); + this.setState({ showCreate: false, views: newViews }); }}
74-74
: Handle undefined state consistently.The fallback to empty array suggests
this.state.views
might be undefined, but this should be handled at the state initialization level.Since
views
is initialized as an empty array in the constructor, the||
fallback is unnecessary:- const view = (this.state.views || []).find(v => v.name === name); + const view = this.state.views.find(v => v.name === name);
165-165
: Use consistent optional chaining throughout the component.Optional chaining is used here but not consistently throughout the component where similar checks are needed.
Consider applying optional chaining consistently, such as in the
loadViews
method whereviews
array is accessed.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/dashboard/Data/Views/Views.react.js
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/dashboard/Data/Views/Views.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
⏰ 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). (1)
- GitHub Check: Docker linux/amd64
|
||
renderRow(row) { | ||
return ( | ||
<tr key={JSON.stringify(row)}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use a more efficient key for table rows.
Using JSON.stringify(row)
as a React key is inefficient and potentially problematic for large datasets. Consider using a unique identifier from the data.
- <tr key={JSON.stringify(row)}>
+ <tr key={row.objectId || row.id || JSON.stringify(row)}>
📝 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.
<tr key={JSON.stringify(row)}> | |
<tr key={row.objectId || row.id || JSON.stringify(row)}> |
🤖 Prompt for AI Agents
In src/dashboard/Data/Views/Views.react.js at line 121, replace the use of
JSON.stringify(row) as the key for the table row with a unique and stable
identifier from the row data, such as an ID property. This change improves
rendering performance and avoids potential issues with key collisions or
inefficiency when handling large datasets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
src/dashboard/Data/Views/Views.react.js (2)
39-54
: Replace deprecated lifecycle methods
componentWillMount
andcomponentWillReceiveProps
are deprecated. UsecomponentDidMount
andcomponentDidUpdate
instead.
139-139
: Use a more efficient key for table rowsUsing
JSON.stringify(row)
as a React key is inefficient and potentially problematic for large datasets. Consider using a unique identifier from the data.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/dashboard/Data/Views/Views.react.js
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/dashboard/Data/Views/Views.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
🪛 GitHub Check: Lint
src/dashboard/Data/Views/Views.react.js
[failure] 122-122:
Expected indentation of 8 spaces but found 6
[failure] 121-121:
Expected indentation of 8 spaces but found 6
[failure] 120-120:
Expected indentation of 8 spaces but found 6
[failure] 119-119:
Expected indentation of 10 spaces but found 8
[failure] 118-118:
Expected indentation of 12 spaces but found 10
⏰ 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). (1)
- GitHub Check: Docker linux/amd64
There was a problem hiding this 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
♻️ Duplicate comments (3)
src/dashboard/Data/Views/Views.react.js (3)
39-54
: Replace deprecated lifecycle methods with modern alternatives.The component still uses deprecated lifecycle methods that were flagged in previous reviews. These methods will be removed in future React versions.
- componentWillMount() { + componentDidMount() { this.props.schema .dispatch(SchemaActionTypes.FETCH) .then(() => this.loadViews(this.context)); } - componentWillReceiveProps(nextProps, nextContext) { - if (this.context !== nextContext) { - this.props.schema - .dispatch(SchemaActionTypes.FETCH) - .then(() => this.loadViews(nextContext)); - } - if (this.props.params.name !== nextProps.params.name || this.context !== nextContext) { - this.loadData(nextProps.params.name); - } + componentDidUpdate(prevProps, prevState, prevContext) { + if (this.context !== prevContext) { + this.props.schema + .dispatch(SchemaActionTypes.FETCH) + .then(() => this.loadViews(this.context)); + } + if (this.props.params.name !== prevProps.params.name || this.context !== prevContext) { + this.loadData(this.props.params.name); + } }
90-132
: Fix critical logic error - code executing outside Promise chain.The code that processes columns and updates state is incorrectly placed outside the
.then()
block, causing it to execute before the query completes. This will result in undefined behavior and empty data.new Parse.Query(view.className) .aggregate(view.query, { useMasterKey: true }) .then(results => { const columns = {}; results.forEach(item => { Object.keys(item).forEach(key => { if (columns[key]) { return; } const val = item[key]; let type = 'String'; if (typeof val === 'number') { type = 'Number'; } else if (typeof val === 'boolean') { type = 'Boolean'; } else if (val && typeof val === 'object') { if (val.__type === 'Date') { type = 'Date'; } else if (val.__type === 'Pointer') { type = 'Pointer'; } else if (val.__type === 'File') { type = 'File'; } else if (val.__type === 'GeoPoint') { type = 'GeoPoint'; } else { type = 'Object'; } } - columns[key] = { type }; - }); - }); - const colNames = Object.keys(columns); - const width = colNames.length > 0 ? 100 / colNames.length : 0; - const order = colNames.map(name => ({ name, width })); - this.setState({ data: results, order, columns }); + columns[key] = { type }; + }); + }); + const colNames = Object.keys(columns); + const width = colNames.length > 0 ? 100 / colNames.length : 0; + const order = colNames.map(name => ({ name, width })); + this.setState({ data: results, order, columns }); }) .catch(error => { this.showNote( `Request failed: ${error.message || 'Unknown error occurred'}`, true ); this.setState({ data: [], order: [], columns: {} }); });
141-141
: Optimize React key for better performance.Using
JSON.stringify(row)
as a React key is inefficient for rendering performance, especially with large datasets.- <tr key={JSON.stringify(row)}> + <tr key={row.objectId || row.id || JSON.stringify(row)}>
🧹 Nitpick comments (1)
src/dashboard/Data/Views/Views.react.js (1)
122-123
: Consider width calculation edge cases.The width calculation
100 / colNames.length
could result in very narrow columns when there are many columns, potentially making the table unusable.Consider implementing a minimum column width or using a more sophisticated width calculation:
- const width = colNames.length > 0 ? 100 / colNames.length : 0; + const minWidth = 10; // minimum 10% width + const calculatedWidth = colNames.length > 0 ? Math.max(minWidth, 100 / colNames.length) : 0; + const width = calculatedWidth;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/dashboard/Data/Views/Views.react.js
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/dashboard/Data/Views/Views.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
🧬 Code Graph Analysis (1)
src/dashboard/Data/Views/Views.react.js (5)
src/lib/withRouter.js (1)
withRouter
(4-26)src/dashboard/TableView.react.js (1)
TableView
(13-66)src/components/CategoryList/CategoryList.react.js (1)
CategoryList
(15-177)src/dashboard/Data/Views/CreateViewDialog.react.js (1)
CreateViewDialog
(19-111)src/dashboard/Data/Browser/Notification.react.js (1)
Notification
(13-80)
🪛 GitHub Check: Lint
src/dashboard/Data/Views/Views.react.js
[failure] 124-124:
Expected indentation of 8 spaces but found 6
[failure] 123-123:
Expected indentation of 8 spaces but found 6
[failure] 122-122:
Expected indentation of 8 spaces but found 6
[failure] 121-121:
Expected indentation of 8 spaces but found 6
[failure] 120-120:
Expected indentation of 8 spaces but found 6
[failure] 119-119:
Expected indentation of 10 spaces but found 8
[failure] 118-118:
Expected indentation of 12 spaces but found 10
⏰ 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). (2)
- GitHub Check: Node 18
- GitHub Check: Docker linux/amd64
🔇 Additional comments (1)
src/dashboard/Data/Views/Views.react.js (1)
225-238
: LGTM: Well-implemented notification system.The notification system properly handles both error and success messages with appropriate timeouts and cleanup.
There was a problem hiding this 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
♻️ Duplicate comments (3)
src/dashboard/Data/Views/Views.react.js (3)
43-47
: Replace deprecated lifecycle method
componentWillMount
is deprecated and should be replaced withcomponentDidMount
.- componentWillMount() { + componentDidMount() { this.props.schema .dispatch(SchemaActionTypes.FETCH) .then(() => this.loadViews(this.context)); }
49-58
: Replace deprecated lifecycle method
componentWillReceiveProps
is deprecated and should be replaced withcomponentDidUpdate
.- componentWillReceiveProps(nextProps, nextContext) { - if (this.context !== nextContext) { - this.props.schema - .dispatch(SchemaActionTypes.FETCH) - .then(() => this.loadViews(nextContext)); - } - if (this.props.params.name !== nextProps.params.name || this.context !== nextContext) { - this.loadData(nextProps.params.name); - } - } + componentDidUpdate(prevProps, prevState, prevContext) { + if (this.context !== prevContext) { + this.props.schema + .dispatch(SchemaActionTypes.FETCH) + .then(() => this.loadViews(this.context)); + } + if (this.props.params.name !== prevProps.params.name || this.context !== prevContext) { + this.loadData(this.props.params.name); + } + }
145-145
: Use more efficient React keyUsing
JSON.stringify(row)
as a React key is inefficient for large datasets and can cause performance issues.- <tr key={JSON.stringify(row)}> + <tr key={row.objectId || row.id || JSON.stringify(row)}>
🧹 Nitpick comments (1)
src/dashboard/Data/Views/Views.react.js (1)
17-17
: Fix typo in constant nameThere's a typo in the constant name that could cause confusion.
-const BROWSER_LAST_LOCATION = 'brower_last_location'; +const BROWSER_LAST_LOCATION = 'browser_last_location';
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/dashboard/Data/Views/Views.react.js
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/dashboard/Data/Views/Views.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
🪛 GitHub Check: Lint
src/dashboard/Data/Views/Views.react.js
[failure] 128-128:
Expected indentation of 8 spaces but found 6
[failure] 127-127:
Expected indentation of 8 spaces but found 6
[failure] 126-126:
Expected indentation of 8 spaces but found 6
[failure] 125-125:
Expected indentation of 8 spaces but found 6
[failure] 124-124:
Expected indentation of 8 spaces but found 6
[failure] 123-123:
Expected indentation of 10 spaces but found 8
[failure] 122-122:
Expected indentation of 12 spaces but found 10
⏰ 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). (1)
- GitHub Check: Docker linux/amd64
There was a problem hiding this 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
♻️ Duplicate comments (2)
src/dashboard/Data/Views/Views.react.js (2)
43-58
: Replace deprecated lifecycle methods with modern alternativesThe deprecated lifecycle methods
componentWillMount
andcomponentWillReceiveProps
should be replaced with their modern equivalents to ensure compatibility with current React versions.Apply this diff to update the lifecycle methods:
- componentWillMount() { + componentDidMount() { this.props.schema .dispatch(SchemaActionTypes.FETCH) .then(() => this.loadViews(this.context)); } - componentWillReceiveProps(nextProps, nextContext) { + componentDidUpdate(prevProps, prevState, prevContext) { - if (this.context !== nextContext) { + if (this.context !== prevContext) { this.props.schema .dispatch(SchemaActionTypes.FETCH) - .then(() => this.loadViews(nextContext)); + .then(() => this.loadViews(this.context)); } - if (this.props.params.name !== nextProps.params.name || this.context !== nextContext) { + if (this.props.params.name !== prevProps.params.name || this.context !== prevContext) { - this.loadData(nextProps.params.name); + this.loadData(this.props.params.name); } }
154-154
: Use a more efficient key for table rowsUsing
JSON.stringify(row)
as a React key is inefficient and potentially problematic for large datasets. Consider using a unique identifier from the data.- <tr key={JSON.stringify(row)} className={styles.tableRow}> + <tr key={row.objectId || row.id || `row-${JSON.stringify(row)}`} className={styles.tableRow}>
🧹 Nitpick comments (3)
src/dashboard/Data/Views/Views.react.js (3)
98-99
: Consider extracting width computation logicThe
computeWidth
function is defined inline within theloadData
method. Consider extracting it as a class method for better readability and reusability.+ computeWidth(str) { + return Math.min(100, Math.max((String(str).length + 2) * 8, 40)); + } loadData(name) { // ... existing code ... new Parse.Query(view.className) .aggregate(view.query, { useMasterKey: true }) .then(results => { const columns = {}; - const computeWidth = str => - Math.min(100, Math.max((String(str).length + 2) * 8, 40)); results.forEach(item => { Object.keys(item).forEach(key => { // ... existing code ... - const width = computeWidth(content || key); + const width = this.computeWidth(content || key); // ... rest of the code ...
128-133
: Optimize column width calculation logicThe current logic for updating column widths could be streamlined. Instead of checking if columns[key] exists and then updating width, consider using a more concise approach.
- if (!columns[key]) { - columns[key] = { type, width }; - } else if (width > columns[key].width) { - columns[key].width = width; - } + columns[key] = columns[key] + ? { ...columns[key], type, width: Math.max(columns[key].width, width) } + : { type, width };
243-253
: Consider using useCallback for onConfirm handlerThe
onConfirm
handler in theCreateViewDialog
is recreated on every render. For better performance, consider extracting it as a class method.Add this method to the class:
+ handleCreateView = (view) => { + this.setState( + state => ({ showCreate: false, views: [...state.views, view] }), + () => { + ViewPreferences.saveViews( + this.context.applicationId, + this.state.views + ); + this.loadViews(this.context); + } + ); + }Then use it in the render method:
- onConfirm={view => { - this.setState( - state => ({ showCreate: false, views: [...state.views, view] }), - () => { - ViewPreferences.saveViews( - this.context.applicationId, - this.state.views - ); - this.loadViews(this.context); - } - ); - }} + onConfirm={this.handleCreateView}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/dashboard/Data/Views/Views.react.js
(1 hunks)src/dashboard/Data/Views/Views.scss
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/dashboard/Data/Views/Views.scss
🧰 Additional context used
🧠 Learnings (1)
src/dashboard/Data/Views/Views.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
⏰ 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). (1)
- GitHub Check: Docker linux/amd64
🔇 Additional comments (3)
src/dashboard/Data/Views/Views.react.js (3)
22-41
: LGTM - Well-structured component initializationThe component setup follows React best practices with proper state initialization and sidebar action configuration.
60-82
: LGTM - Robust view loading implementationThe
loadViews
method properly handles loading views from preferences and includes error handling for counter queries.
272-281
: LGTM - Clean navigation handlingThe pointer click handler properly constructs filters and navigates to the browser view with appropriate URL encoding.
There was a problem hiding this 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
♻️ Duplicate comments (3)
src/dashboard/Data/Views/Views.react.js (3)
46-61
: Replace deprecated lifecycle methods
componentWillMount
andcomponentWillReceiveProps
are long-deprecated and may be removed in upcoming React versions. Migrate the logic tocomponentDidMount
andcomponentDidUpdate
respectively to avoid unexpected breakage.
191-199
: Use a stable ID instead ofJSON.stringify(row)
for React keys
Serialising the whole row on every render hurts performance and risks key collisions for large or cyclic objects. Prefer a unique field such asrow.objectId || row.id
.
335-348
: ClearnoteTimeout
on unmount to prevent memory leaks
showNote
creates asetTimeout
, but the timer isn’t cleared when the component unmounts. Add acomponentWillUnmount
(oruseEffect
cleanup if converted to hooks) to callclearTimeout(this.noteTimeout)
.
🧹 Nitpick comments (1)
src/dashboard/Data/Views/Views.react.js (1)
194-194
: Remove unused variablewidth
to satisfy lint
width
is destructured but never referenced, triggering the lint error you can see in CI.- {this.state.order.map(({ name, width }) => { + {this.state.order.map(({ name }) => {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/dashboard/Data/Views/Views.react.js
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/dashboard/Data/Views/Views.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
🪛 GitHub Check: Lint
src/dashboard/Data/Views/Views.react.js
[failure] 194-194:
'width' is defined but never used
⏰ 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). (1)
- GitHub Check: Docker linux/amd64
There was a problem hiding this 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
♻️ Duplicate comments (4)
src/dashboard/Data/Views/Views.react.js (4)
49-53
: Replace deprecated lifecycle method componentWillMount
componentWillMount
is deprecated. UsecomponentDidMount
instead.
70-79
: Replace deprecated lifecycle method componentWillReceiveProps
componentWillReceiveProps
is deprecated. UsecomponentDidUpdate
instead.
65-68
: Add cleanup for timeout in componentWillUnmountThe component creates a timeout in
showNote
but doesn't clean it up when the component unmounts, which could lead to memory leaks.
212-212
: Use a more efficient key for table rowsUsing
JSON.stringify(row)
as a React key is inefficient and potentially problematic for large datasets. Consider using a unique identifier from the data.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/dashboard/Data/Views/Views.react.js
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/dashboard/Data/Views/Views.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
🪛 GitHub Check: Lint
src/dashboard/Data/Views/Views.react.js
[failure] 213-213:
'width' is defined but never used
⏰ 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). (1)
- GitHub Check: Docker linux/amd64
There was a problem hiding this 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
♻️ Duplicate comments (2)
src/dashboard/Data/Views/Views.react.js (2)
55-59
: Replace deprecated lifecycle methods
componentWillMount
andcomponentWillReceiveProps
are deprecated. UsecomponentDidMount
andcomponentDidUpdate
instead.Also applies to: 65-74
243-243
: Use a more efficient key for table rows.Using
JSON.stringify(row)
as a React key is inefficient and potentially problematic for large datasets. Consider using a unique identifier from the data.
🧹 Nitpick comments (1)
src/dashboard/Data/Views/Views.react.js (1)
26-513
: Consider splitting this component for better maintainability.This component is handling many responsibilities and has grown to over 500 lines. Consider extracting:
- Table rendering logic (renderRow, renderHeaders, renderColGroup) into a separate
ViewsTable
component- Column type detection logic (duplicated in lines 133-150 and 246-263) into a utility function
- Dialog management into a custom hook or container component
Example of extracting column type detection:
// In lib/columnUtils.js export function getColumnType(value) { if (typeof value === 'number') return 'Number'; if (typeof value === 'boolean') return 'Boolean'; if (value && typeof value === 'object') { if (value.__type === 'Date') return 'Date'; if (value.__type === 'Pointer') return 'Pointer'; if (value.__type === 'File') return 'File'; if (value.__type === 'GeoPoint') return 'GeoPoint'; return 'Object'; } return 'String'; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/dashboard/DashboardView.react.js
(1 hunks)src/dashboard/Data/Views/DeleteViewDialog.react.js
(1 hunks)src/dashboard/Data/Views/EditViewDialog.react.js
(1 hunks)src/dashboard/Data/Views/Views.react.js
(1 hunks)src/dashboard/Data/Views/Views.scss
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/dashboard/DashboardView.react.js
- src/dashboard/Data/Views/Views.scss
🧰 Additional context used
🧠 Learnings (3)
src/dashboard/Data/Views/DeleteViewDialog.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
src/dashboard/Data/Views/EditViewDialog.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
src/dashboard/Data/Views/Views.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
🧬 Code Graph Analysis (1)
src/dashboard/Data/Views/EditViewDialog.react.js (1)
src/dashboard/Push/PushNew.react.js (1)
isValidJSON
(55-68)
⏰ 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). (1)
- GitHub Check: Docker linux/amd64
🔇 Additional comments (2)
src/dashboard/Data/Views/Views.react.js (2)
114-129
: Well-implemented column width calculation.The dynamic column width calculation using canvas text measurement is a sophisticated approach that provides accurate results. The fallback for non-browser environments and canvas caching for performance are excellent touches.
265-275
: Good implementation of pointer navigation.The clickable pointer values that navigate to filtered browser views provide excellent user experience for exploring related data.
Also applies to: 488-497
export default class DeleteViewDialog extends React.Component { | ||
constructor() { | ||
super(); | ||
this.state = { | ||
confirmation: '', | ||
}; | ||
} | ||
|
||
valid() { | ||
return this.state.confirmation === this.props.name; | ||
} | ||
|
||
render() { | ||
return ( | ||
<Modal | ||
type={Modal.Types.DANGER} | ||
icon="warn-outline" | ||
title="Delete view?" | ||
subtitle="This action cannot be undone!" | ||
disabled={!this.valid()} | ||
confirmText="Delete" | ||
cancelText="Cancel" | ||
onCancel={this.props.onCancel} | ||
onConfirm={this.props.onConfirm} | ||
> | ||
<Field | ||
label={<Label text="Confirm this action" description="Enter the view name to continue." />} | ||
input={ | ||
<TextInput | ||
placeholder="View name" | ||
value={this.state.confirmation} | ||
onChange={confirmation => this.setState({ confirmation })} | ||
/> | ||
} | ||
/> | ||
</Modal> | ||
); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add prop validation for required props.
The component expects name
, onCancel
, and onConfirm
props but doesn't validate them. Consider adding PropTypes validation to ensure proper usage.
Add prop validation after the component class:
DeleteViewDialog.propTypes = {
name: PropTypes.string.isRequired,
onCancel: PropTypes.func.isRequired,
onConfirm: PropTypes.func.isRequired,
};
And import PropTypes at the top:
+import PropTypes from 'prop-types';
import Field from 'components/Field/Field.react';
🤖 Prompt for AI Agents
In src/dashboard/Data/Views/DeleteViewDialog.react.js from lines 7 to 45, the
component uses props name, onCancel, and onConfirm but lacks prop validation. To
fix this, import PropTypes at the top of the file and add a static propTypes
object or assign DeleteViewDialog.propTypes after the class definition,
specifying name as a required string and onCancel and onConfirm as required
functions to ensure proper prop usage and catch errors early.
function isValidJSON(value) { | ||
try { | ||
JSON.parse(value); | ||
return true; | ||
} catch { | ||
return false; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Extract isValidJSON to a shared utility.
This function is duplicated from src/dashboard/Push/PushNew.react.js
. Consider extracting it to a shared utility module to follow DRY principles.
Create a new utility file src/lib/jsonUtils.js
:
export function isValidJSON(value) {
try {
JSON.parse(value);
return true;
} catch {
return false;
}
}
Then import and use it in both files:
-function isValidJSON(value) {
- try {
- JSON.parse(value);
- return true;
- } catch {
- return false;
- }
-}
+import { isValidJSON } from 'lib/jsonUtils';
🤖 Prompt for AI Agents
In src/dashboard/Data/Views/EditViewDialog.react.js lines 10 to 17, the
isValidJSON function is duplicated from src/dashboard/Push/PushNew.react.js.
Extract this function into a new shared utility file at src/lib/jsonUtils.js by
moving the function there and exporting it. Then, replace the local isValidJSON
function in both files with an import statement that imports isValidJSON from
the new utility module.
export default class EditViewDialog extends React.Component { | ||
constructor(props) { | ||
super(); | ||
const view = props.view || {}; | ||
this.state = { | ||
name: view.name || '', | ||
className: view.className || '', | ||
query: JSON.stringify(view.query || [], null, 2), | ||
showCounter: !!view.showCounter, | ||
}; | ||
} | ||
|
||
valid() { | ||
return ( | ||
this.state.name.length > 0 && | ||
this.state.className.length > 0 && | ||
isValidJSON(this.state.query) | ||
); | ||
} | ||
|
||
render() { | ||
const { classes, onConfirm, onCancel } = this.props; | ||
return ( | ||
<Modal | ||
type={Modal.Types.INFO} | ||
icon="edit-solid" | ||
iconSize={40} | ||
title="Edit view?" | ||
subtitle="Update the custom query." | ||
confirmText="Save" | ||
cancelText="Cancel" | ||
disabled={!this.valid()} | ||
onCancel={onCancel} | ||
onConfirm={() => | ||
onConfirm({ | ||
name: this.state.name, | ||
className: this.state.className, | ||
query: JSON.parse(this.state.query), | ||
showCounter: this.state.showCounter, | ||
}) | ||
} | ||
> | ||
<Field | ||
label={<Label text="Name" />} | ||
input={ | ||
<TextInput | ||
value={this.state.name} | ||
onChange={name => this.setState({ name })} | ||
/> | ||
} | ||
/> | ||
<Field | ||
label={<Label text="Class" />} | ||
input={ | ||
<Dropdown | ||
value={this.state.className} | ||
onChange={className => this.setState({ className })} | ||
> | ||
{classes.map(c => ( | ||
<Option key={c} value={c}> | ||
{c} | ||
</Option> | ||
))} | ||
</Dropdown> | ||
} | ||
/> | ||
<Field | ||
label={ | ||
<Label | ||
text="Query" | ||
description="An aggregation pipeline that returns an array of items." | ||
/> | ||
} | ||
input={ | ||
<TextInput | ||
multiline={true} | ||
value={this.state.query} | ||
onChange={query => this.setState({ query })} | ||
/> | ||
} | ||
/> | ||
<Field | ||
label={<Label text="Show object counter" />} | ||
input={ | ||
<Checkbox | ||
checked={this.state.showCounter} | ||
onChange={showCounter => this.setState({ showCounter })} | ||
/> | ||
} | ||
/> | ||
</Modal> | ||
); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add prop validation for component props.
The component expects several props but doesn't validate them.
Add prop validation after the component class:
EditViewDialog.propTypes = {
classes: PropTypes.arrayOf(PropTypes.string).isRequired,
view: PropTypes.shape({
name: PropTypes.string,
className: PropTypes.string,
query: PropTypes.array,
showCounter: PropTypes.bool,
}),
onCancel: PropTypes.func.isRequired,
onConfirm: PropTypes.func.isRequired,
};
And import PropTypes:
+import PropTypes from 'prop-types';
import Dropdown from 'components/Dropdown/Dropdown.react';
🤖 Prompt for AI Agents
In src/dashboard/Data/Views/EditViewDialog.react.js from lines 19 to 112, the
EditViewDialog component lacks prop validation which can lead to runtime errors.
To fix this, import PropTypes at the top of the file and add a static propTypes
object after the component class definition specifying the expected types for
classes, view, onCancel, and onConfirm props as described. This ensures proper
validation and better maintainability.
There was a problem hiding this 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
♻️ Duplicate comments (2)
src/dashboard/Data/Views/Views.react.js (2)
63-80
: Replace deprecated React lifecycle methodsThe code still uses deprecated lifecycle methods
componentWillMount
andcomponentWillReceiveProps
that were flagged in previous reviews. These should be replaced with their modern equivalents.Apply this diff to fix the deprecated lifecycle methods:
- componentWillMount() { + componentDidMount() { this.props.schema.dispatch(SchemaActionTypes.FETCH).then(() => this.loadViews(this.context)); } - componentWillReceiveProps(nextProps, nextContext) { - if (this.context !== nextContext) { - this.props.schema.dispatch(SchemaActionTypes.FETCH).then(() => this.loadViews(nextContext)); - } - if (this.props.params.name !== nextProps.params.name || this.context !== nextContext) { - window.scrollTo({ top: 0 }); - this.loadData(nextProps.params.name); - } + componentDidUpdate(prevProps, prevState, prevContext) { + if (this.context !== prevContext) { + this.props.schema.dispatch(SchemaActionTypes.FETCH).then(() => this.loadViews(this.context)); + } + if (this.props.params.name !== prevProps.params.name || this.context !== prevContext) { + window.scrollTo({ top: 0 }); + this.loadData(this.props.params.name); + } }
267-267
: Use a more efficient React keyThe table row still uses
JSON.stringify(row)
as a React key, which was flagged in previous reviews as inefficient for large datasets.- <tr key={JSON.stringify(row)} className={styles.tableRow}> + <tr key={row.objectId || row.id || JSON.stringify(row)} className={styles.tableRow}>
🧹 Nitpick comments (1)
src/dashboard/Data/Views/Views.react.js (1)
308-308
: Use optional chaining for cleaner codeThe static analysis tool suggests using optional chaining for better readability and safety.
- content = value && value.iso ? value.iso : String(value); + content = value?.iso ?? String(value);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/dashboard/Data/Views/Views.react.js
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/dashboard/Data/Views/Views.react.js (1)
Learnt from: mtrezza
PR: parse-community/parse-dashboard#2828
File: src/dashboard/Data/Browser/Browser.react.js:1605-1607
Timestamp: 2025-05-27T12:09:47.644Z
Learning: In script execution dialogs in Parse Dashboard (specifically the `confirmExecuteScriptRows` method in `src/dashboard/Data/Browser/Browser.react.js`), individual `setState` calls to update `processedScripts` counter should be kept as-is rather than batched, because this provides real-time progress feedback to users in the dialog UI.
🧬 Code Graph Analysis (1)
src/dashboard/Data/Views/Views.react.js (10)
src/lib/withRouter.js (1)
withRouter
(4-26)src/dashboard/TableView.react.js (1)
TableView
(13-66)src/components/CategoryList/CategoryList.react.js (1)
CategoryList
(15-177)src/components/BrowserMenu/MenuItem.react.js (1)
MenuItem
(11-27)src/dashboard/Data/Views/ViewValueDialog.react.js (1)
ViewValueDialog
(7-37)src/dashboard/Data/Views/CreateViewDialog.react.js (1)
CreateViewDialog
(19-111)src/dashboard/Data/Views/EditViewDialog.react.js (1)
EditViewDialog
(19-112)src/dashboard/Data/Views/DeleteViewDialog.react.js (1)
DeleteViewDialog
(7-45)src/lib/generatePath.js (2)
generatePath
(3-34)filters
(8-8)src/dashboard/Data/Browser/Notification.react.js (1)
Notification
(13-80)
🪛 Biome (1.9.4)
src/dashboard/Data/Views/Views.react.js
[error] 308-308: 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). (1)
- GitHub Check: Docker linux/amd64
🔇 Additional comments (3)
src/dashboard/Data/Views/Views.react.js (3)
82-195
: Well-implemented data loading with proper error handlingThe data loading methods are well-structured with comprehensive error handling, proper cleanup using
_isMounted
checks, and sophisticated column width calculation using canvas text measurement. The type inference logic correctly handles all Parse data types.
371-471
: Well-designed UI rendering with good UX patternsThe rendering methods provide excellent user experience with helpful empty states, clear navigation, and appropriate toolbar functionality. The separation of concerns between different rendering methods is well-maintained.
584-599
: Proper notification handling with cleanupThe notification system is well-implemented with proper timeout management and cleanup. Good user feedback patterns are maintained throughout.
# [7.3.0-alpha.11](7.3.0-alpha.10...7.3.0-alpha.11) (2025-07-13) ### Features * Add custom data views with aggregation query ([#2888](#2888)) ([b1679db](b1679db))
🎉 This change has been released in version 7.3.0-alpha.11 |
Summary
Testing
npm test
https://chatgpt.com/codex/tasks/task_e_686f92867e84832da406a36bad1fbe19
Summary by CodeRabbit