parse-dashboard 8.5.0-alpha.6 → 8.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,7 +51,6 @@ Parse Dashboard is a standalone dashboard for managing your [Parse Server](https
51
51
  - [Custom order in the filter popup](#custom-order-in-the-filter-popup)
52
52
  - [Persistent Filters](#persistent-filters)
53
53
  - [Keyboard Shortcuts](#keyboard-shortcuts)
54
- - [Scripts](#scripts)
55
54
  - [Resource Cache](#resource-cache)
56
55
  - [Running as Express Middleware](#running-as-express-middleware)
57
56
  - [Browser Control API (Development Only)](#browser-control-api-development-only)
@@ -88,6 +87,11 @@ Parse Dashboard is a standalone dashboard for managing your [Parse Server](https
88
87
  - [Panel Item](#panel-item)
89
88
  - [Auto-Scroll](#auto-scroll)
90
89
  - [Prefetching](#prefetching)
90
+ - [Scripts](#scripts)
91
+ - [Script Response Form](#script-response-form)
92
+ - [Response Fields](#response-fields)
93
+ - [Form Elements](#form-elements)
94
+ - [Drop-Down](#drop-down)
91
95
  - [Graph](#graph)
92
96
  - [Calculated Values](#calculated-values)
93
97
  - [Formula Operator](#formula-operator)
@@ -550,110 +554,6 @@ Configure custom keyboard shortcuts for dashboard actions in **App Settings > Ke
550
554
 
551
555
  Delete a shortcut key to disable the shortcut.
552
556
 
553
- ### Scripts
554
-
555
- You can specify scripts to execute Cloud Functions with the `scripts` option:
556
-
557
- ```json
558
- "apps": [
559
- {
560
- "scripts": [
561
- {
562
- "title": "Delete Account",
563
- "classes": ["_User"],
564
- "cloudCodeFunction": "deleteAccount",
565
- "showConfirmationDialog": true,
566
- "confirmationDialogStyle": "critical"
567
- }
568
- ]
569
- }
570
- ]
571
- ```
572
-
573
- You can also specify custom fields with the `scrips` option:
574
-
575
- ```json
576
- "apps": [
577
- {
578
- "scripts": [
579
- {
580
- "title": "Delete account",
581
- "classes": [
582
- {
583
- "name": "_User",
584
- "fields": [
585
- { "name": "createdAt", "validator": "value => value > new Date(\"2025\")" }
586
- ]
587
- }
588
- ],
589
- "cloudCodeFunction": "deleteAccount"
590
- }
591
- ]
592
- }
593
- ]
594
-
595
- ```
596
-
597
- Next, define the Cloud Function in Parse Server that will be called. The object that has been selected in the data browser will be made available as a request parameter:
598
-
599
- ```js
600
- Parse.Cloud.define('deleteAccount', async (req) => {
601
- req.params.object.set('deleted', true);
602
- await req.params.object.save(null, {useMasterKey: true});
603
- }, {
604
- requireMaster: true
605
- });
606
- ```
607
-
608
- The field which the script was invoked on can be accessed by `selectedField`:
609
-
610
- ```js
611
- Parse.Cloud.define('deleteAccount', async (req) => {
612
- if (req.params.selectedField !== 'objectId') {
613
- throw new Parse.Error(Parse.Error.SCRIPT_FAILED, 'Deleting accounts is only available on the objectId field.');
614
- }
615
- req.params.object.set('deleted', true);
616
- await req.params.object.save(null, {useMasterKey: true});
617
- }, {
618
- requireMaster: true
619
- });
620
- ```
621
-
622
- ⚠️ Depending on your Parse Server version you may need to set the Parse Server option `encodeParseObjectInCloudFunction` to `true` so that the selected object in the data browser is made available in the Cloud Function as an instance of `Parse.Object`. If the option is not set, is set to `false`, or you are using an older version of Parse Server, the object is made available as a plain JavaScript object and needs to be converted from a JSON object to a `Parse.Object` instance with `req.params.object = Parse.Object.fromJSON(req.params.object);`, before you can call any `Parse.Object` properties and methods on it.
623
-
624
- For older versions of Parse Server:
625
-
626
- <details>
627
- <summary>Parse Server &gt;=4.4.0 &lt;6.2.0</summary>
628
-
629
- ```js
630
- Parse.Cloud.define('deleteAccount', async (req) => {
631
- req.params.object = Parse.Object.fromJSON(req.params.object);
632
- req.params.object.set('deleted', true);
633
- await req.params.object.save(null, {useMasterKey: true});
634
- }, {
635
- requireMaster: true
636
- });
637
- ```
638
-
639
- </details>
640
-
641
- <details>
642
- <summary>Parse Server &gt;=2.1.4 &lt;4.4.0</summary>
643
-
644
- ```js
645
- Parse.Cloud.define('deleteAccount', async (req) => {
646
- if (!req.master || !req.params.object) {
647
- throw 'Unauthorized';
648
- }
649
- req.params.object = Parse.Object.fromJSON(req.params.object);
650
- req.params.object.set('deleted', true);
651
- await req.params.object.save(null, {useMasterKey: true});
652
- });
653
- ```
654
-
655
- </details>
656
-
657
557
  ### Resource Cache
658
558
 
659
559
  Parse Dashboard can cache its resources such as bundles in the browser, so that opening the dashboard in another tab does not reload the dashboard resources from the server but from the local browser cache. Caching only starts after login in the dashboard.
@@ -1480,6 +1380,191 @@ Prefetching is particularly useful when navigating through lists of objects. To
1480
1380
 
1481
1381
  When `prefetchObjects` is enabled, media content (images, videos, and audio) in the info panel can also be prefetched to improve loading performance. By default, all media types are prefetched, but you can selectively disable prefetching for specific media types using the `prefetchImage`, `prefetchVideo`, and `prefetchAudio` options.
1482
1382
 
1383
+ ### Scripts
1384
+
1385
+ You can specify scripts to execute Cloud Functions with the `scripts` option:
1386
+
1387
+ ```json
1388
+ "apps": [
1389
+ {
1390
+ "scripts": [
1391
+ {
1392
+ "title": "Delete Account",
1393
+ "classes": ["_User"],
1394
+ "cloudCodeFunction": "deleteAccount",
1395
+ "showConfirmationDialog": true,
1396
+ "confirmationDialogStyle": "critical"
1397
+ }
1398
+ ]
1399
+ }
1400
+ ]
1401
+ ```
1402
+
1403
+ You can also specify custom fields with the `scripts` option:
1404
+
1405
+ ```json
1406
+ "apps": [
1407
+ {
1408
+ "scripts": [
1409
+ {
1410
+ "title": "Delete account",
1411
+ "classes": [
1412
+ {
1413
+ "name": "_User",
1414
+ "fields": [
1415
+ { "name": "createdAt", "validator": "value => value > new Date(\"2025\")" }
1416
+ ]
1417
+ }
1418
+ ],
1419
+ "cloudCodeFunction": "deleteAccount"
1420
+ }
1421
+ ]
1422
+ }
1423
+ ]
1424
+
1425
+ ```
1426
+
1427
+ Next, define the Cloud Function in Parse Server that will be called. The object that has been selected in the data browser will be made available as a request parameter:
1428
+
1429
+ ```js
1430
+ Parse.Cloud.define('deleteAccount', async (req) => {
1431
+ req.params.object.set('deleted', true);
1432
+ await req.params.object.save(null, {useMasterKey: true});
1433
+ }, {
1434
+ requireMaster: true
1435
+ });
1436
+ ```
1437
+
1438
+ The field which the script was invoked on can be accessed by `selectedField`:
1439
+
1440
+ ```js
1441
+ Parse.Cloud.define('deleteAccount', async (req) => {
1442
+ if (req.params.selectedField !== 'objectId') {
1443
+ throw new Parse.Error(Parse.Error.SCRIPT_FAILED, 'Deleting accounts is only available on the objectId field.');
1444
+ }
1445
+ req.params.object.set('deleted', true);
1446
+ await req.params.object.save(null, {useMasterKey: true});
1447
+ }, {
1448
+ requireMaster: true
1449
+ });
1450
+ ```
1451
+
1452
+ ⚠️ Depending on your Parse Server version you may need to set the Parse Server option `encodeParseObjectInCloudFunction` to `true` so that the selected object in the data browser is made available in the Cloud Function as an instance of `Parse.Object`. If the option is not set, is set to `false`, or you are using an older version of Parse Server, the object is made available as a plain JavaScript object and needs to be converted from a JSON object to a `Parse.Object` instance with `req.params.object = Parse.Object.fromJSON(req.params.object);`, before you can call any `Parse.Object` properties and methods on it.
1453
+
1454
+ For older versions of Parse Server:
1455
+
1456
+ <details>
1457
+ <summary>Parse Server &gt;=4.4.0 &lt;6.2.0</summary>
1458
+
1459
+ ```js
1460
+ Parse.Cloud.define('deleteAccount', async (req) => {
1461
+ req.params.object = Parse.Object.fromJSON(req.params.object);
1462
+ req.params.object.set('deleted', true);
1463
+ await req.params.object.save(null, {useMasterKey: true});
1464
+ }, {
1465
+ requireMaster: true
1466
+ });
1467
+ ```
1468
+
1469
+ </details>
1470
+
1471
+ <details>
1472
+ <summary>Parse Server &gt;=2.1.4 &lt;4.4.0</summary>
1473
+
1474
+ ```js
1475
+ Parse.Cloud.define('deleteAccount', async (req) => {
1476
+ if (!req.master || !req.params.object) {
1477
+ throw 'Unauthorized';
1478
+ }
1479
+ req.params.object = Parse.Object.fromJSON(req.params.object);
1480
+ req.params.object.set('deleted', true);
1481
+ await req.params.object.save(null, {useMasterKey: true});
1482
+ });
1483
+ ```
1484
+
1485
+ </details>
1486
+
1487
+ #### Script Response Form
1488
+
1489
+ A Cloud Function invoked by a script can return a structured response that shows a modal dialog with form elements. When the user submits the form, the values are sent to a callback Cloud Function specified in the response.
1490
+
1491
+ Return a `ScriptResponse` from the Cloud Function:
1492
+
1493
+ ```js
1494
+ Parse.Cloud.define('assignRole', async (req) => {
1495
+ return {
1496
+ __type: 'ScriptResponse',
1497
+ payload: {
1498
+ requestId: '123-456-789'
1499
+ },
1500
+ form: {
1501
+ title: 'Assign Role',
1502
+ icon: 'gears',
1503
+ cloudCodeFunction: 'assignRoleCallback',
1504
+ elements: [
1505
+ {
1506
+ element: 'dropDown',
1507
+ name: 'role',
1508
+ label: 'Role',
1509
+ items: [
1510
+ { title: 'Admin', value: 'admin' },
1511
+ { title: 'User', value: 'user' }
1512
+ ]
1513
+ }
1514
+ ]
1515
+ }
1516
+ };
1517
+ }, {
1518
+ requireMaster: true
1519
+ });
1520
+ ```
1521
+
1522
+ Then define the callback Cloud Function that receives the form data:
1523
+
1524
+ ```js
1525
+ Parse.Cloud.define('assignRoleCallback', async (req) => {
1526
+ const { object, payload, formData } = req.params;
1527
+ const role = formData.role;
1528
+ object.set('role', role);
1529
+ await object.save(null, { useMasterKey: true });
1530
+ return `Assigned role "${role}" to ${object.id} (request ${payload.requestId}).`;
1531
+ }, {
1532
+ requireMaster: true
1533
+ });
1534
+ ```
1535
+
1536
+ > [!NOTE]
1537
+ > When executing a script on multiple selected rows, the Cloud Function is called for the first object. If the response is a `ScriptResponse`, the modal is shown once. On submission, the callback Cloud Function is called for all selected objects.
1538
+
1539
+ ##### Response Fields
1540
+
1541
+ | Field | Type | Optional | Default | Description |
1542
+ |---|---|---|---|---|
1543
+ | `__type` | `String` | No | - | Must be `"ScriptResponse"` to indicate a structured response. |
1544
+ | `payload` | `Object` | Yes | - | Pass-through data forwarded to the callback Cloud Function. |
1545
+ | `form.title` | `String` | Yes | `"Script"` | The modal title. |
1546
+ | `form.icon` | `String` | Yes | `"gears"` | The modal icon. |
1547
+ | `form.cloudCodeFunction` | `String` | Yes | Script `cloudCodeFunction` | The callback Cloud Function to invoke on form submission. |
1548
+ | `form.elements` | `Array` | No | - | The form elements to display in the modal. |
1549
+
1550
+ ##### Form Elements
1551
+
1552
+ | Parameter | Value | Optional | Description |
1553
+ |-----------|--------|----------|----------------------------------|
1554
+ | `elements` | `Array` | No | The form elements. Elements are rendered in the order they are defined. |
1555
+
1556
+ ###### Drop-Down
1557
+
1558
+ A drop-down to select a single item from a list.
1559
+
1560
+ | Parameter | Value | Optional | Description |
1561
+ |-----------|--------|----------|----------------------------------|
1562
+ | `element` | `String` | No | Must be `"dropDown"`. |
1563
+ | `label` | `String` | No | The display label shown next to the dropdown. |
1564
+ | `items` | `Array` | No | The selectable options. |
1565
+ | `items[].title` | `String` | No | The display text of the option. |
1566
+ | `items[].value` | `String` | No | The value of the option. |
1567
+
1483
1568
  ### Graph
1484
1569
 
1485
1570
  ▶️ *Core > Browser > Graph*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "parse-dashboard",
3
- "version": "8.5.0-alpha.6",
3
+ "version": "8.5.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/parse-community/parse-dashboard"
@@ -84,7 +84,7 @@
84
84
  "devDependencies": {
85
85
  "@actions/core": "2.0.1",
86
86
  "@babel/core": "7.29.0",
87
- "@babel/eslint-parser": "7.28.0",
87
+ "@babel/eslint-parser": "7.28.6",
88
88
  "@babel/plugin-proposal-decorators": "7.29.0",
89
89
  "@babel/plugin-transform-runtime": "7.29.0",
90
90
  "@babel/preset-env": "7.29.0",
@@ -101,11 +101,11 @@
101
101
  "all-node-versions": "13.0.1",
102
102
  "babel-loader": "10.0.0",
103
103
  "css-loader": "6.7.3",
104
- "eslint": "9.39.1",
104
+ "eslint": "9.39.2",
105
105
  "eslint-plugin-jest": "29.5.0",
106
106
  "eslint-plugin-react": "7.37.5",
107
107
  "get-port": "7.1.0",
108
- "globals": "16.5.0",
108
+ "globals": "17.3.0",
109
109
  "http-server": "14.1.1",
110
110
  "husky": "9.1.7",
111
111
  "jest": "30.0.4",
@@ -116,7 +116,7 @@
116
116
  "null-loader": "4.0.1",
117
117
  "parse-server": "9.2.0",
118
118
  "prettier": "3.8.1",
119
- "puppeteer": "24.36.1",
119
+ "puppeteer": "24.37.2",
120
120
  "react-test-renderer": "16.13.1",
121
121
  "request": "2.88.2",
122
122
  "request-promise": "4.2.6",
@@ -127,9 +127,9 @@
127
127
  "style-loader": "3.3.1",
128
128
  "svg-prep": "1.0.4",
129
129
  "typescript": "5.9.3",
130
- "webpack": "5.104.1",
130
+ "webpack": "5.105.1",
131
131
  "webpack-cli": "6.0.1",
132
- "ws": "8.18.0",
132
+ "ws": "8.19.0",
133
133
  "yaml": "2.8.2"
134
134
  },
135
135
  "scripts": {