parse-dashboard 7.3.0-alpha.4 → 7.3.0-alpha.40

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.
@@ -321,6 +321,18 @@
321
321
  <symbol id="rtos" viewBox="0 0 32 29">
322
322
  <path d="M22.2507228,5.13932004 C22.2507228,6.01438998 21.5190958,6.72381712 20.6164538,6.72381712 C19.7140006,6.72381712 18.9825623,6.01438998 18.9825623,5.13932004 C18.9825623,4.26425009 19.7140006,3.55482295 20.6164538,3.55482295 C21.5190958,3.55482295 22.2507228,4.26425009 22.2507228,5.13932004 L22.2507228,5.13932004 Z M29.9027937,6.91471817 C27.7237684,5.63423515 24.8185901,5.6982959 23.3659066,6.14653818 L22.7058189,9.53974499 L24.8846555,9.53974499 L24.2904445,12.6130141 L22.1114192,12.6130141 L21.18707,17.286887 C20.7908664,19.2076115 21.8473464,18.82343 22.6397535,18.82343 L22.3096154,20.616033 C16.4990699,23.1131213 15.3765246,19.2716723 15.7066628,17.5429469 L16.6312007,12.6130141 L13.7258336,12.6130141 L14.3200446,9.53974499 L17.2254117,9.53974499 L17.9517535,5.89029514 C15.3765246,5.05805439 15.5747208,4.92993287 15.5747208,2.94514757 L15.5747208,0 L7.84941158,0 L7.84941158,11.6526518 L0.0580370154,11.6526518 C-0.272101176,12.8690741 0.850444177,14.7897986 2.30293896,15.1739801 C3.75562251,15.5581616 4.74603708,18.56737 5.27418268,19.2076115 C5.80251704,19.847853 7.12306981,20.6800938 8.44362257,20.5521553 C9.89630611,18.7593692 10.0943135,18.5033092 10.7545899,18.7593692 C11.1507935,18.82343 11.9432006,19.0154292 12.5374116,18.9515515 C16.3010625,28.6832957 21.1210046,29.899718 24.0263717,28.4911135 C19.8665172,21.5125176 29.176452,18.82343 31.1574699,18.1191277 C31.7516809,16.2624639 31.8177463,13.8294363 31.6195501,12.4208318 C29.3746481,11.332531 29.7047863,8.64344348 29.9027937,6.91471817 L29.9027937,6.91471817 Z M16.648944,17.6611848 L20.1483333,17.6611848 L22.1952278,7.35307679 L18.6297731,7.35307679 L16.648944,17.6611848 L16.648944,17.6611848 Z"/>
323
323
  </symbol>
324
+ <symbol id="script-solid" viewBox="0 0 100 100">
325
+ <defs/>
326
+ <path class="st0" d="M50,0C22.4,0,0,22.4,0,50s22.4,50,50,50,50-22.4,50-50S77.6,0,50,0ZM45,32.8h-1.5c-1.4,0-2.4.2-3.1.7-.7.5-1.2,1.2-1.4,2.3-.2.6-.2,2.1-.3,4.6,0,2.5-.3,4.5-.9,5.9-.4,1.1-1.1,2-1.9,2.6-.6.5-1.6,1-3,1.5,1.5.6,2.5,1.2,3.2,1.8.7.6,1.3,1.6,1.8,2.8.5,1.3.8,3.3.8,6.1s.2,4.1.5,4.9c.3.8.8,1.3,1.5,1.6.7.3,2.1.5,4.3.5v9h-4.1c-4.2,0-7.3-.4-9-1.2-1.8-.8-3.1-1.9-3.8-3.5-.8-1.5-1.1-3.8-1.1-6.8s0-1.3,0-2c0-.4,0-.8,0-1.3,0-2.2-.2-3.7-.7-4.6-.5-.9-1.1-1.6-2-2-.9-.4-2.1-.6-3.7-.7v-9.6c1.7,0,2.9-.2,3.8-.7s1.5-1.1,1.9-2c.4-.9.7-2.5.7-4.7v-.9c0-.4,0-.9,0-1.3,0-3.3.3-5.7,1-7.1.6-1.5,1.5-2.6,2.7-3.4.8-.6,2-1,3.5-1.3,1.9-.4,4.1-.6,6.6-.6h4.4v9.1ZM78.5,55.2c-1.6,0-2.9.3-3.7.7-.9.4-1.5,1.1-2,2-.5.9-.7,2.4-.7,4.6s0,.8,0,1.3c0,.7,0,1.3,0,2,0,3-.4,5.3-1.1,6.8-.8,1.5-2,2.7-3.8,3.5-1.8.8-4.8,1.2-9,1.2h-4.1v-9c2.1,0,3.6-.2,4.3-.5.7-.3,1.2-.9,1.5-1.6.3-.8.5-2.4.5-4.9s.2-4.8.8-6.1c.5-1.3,1.1-2.2,1.8-2.8.7-.6,1.8-1.2,3.2-1.8-1.4-.5-2.4-1-3-1.5-.8-.7-1.4-1.5-1.9-2.6-.6-1.4-.9-3.4-.9-5.9,0-2.5-.1-4-.3-4.6-.3-1-.8-1.8-1.4-2.3-.7-.5-1.7-.7-3.1-.7h-1.5v-9.1h4.4c2.5,0,4.7.2,6.6.6,1.5.3,2.6.7,3.5,1.3,1.1.8,2,1.9,2.7,3.4.6,1.5,1,3.8,1,7.1s0,.9,0,1.3v.9c0,2.2.2,3.7.7,4.7.4.9,1.1,1.6,1.9,2s2.1.7,3.8.7v9.6Z"/>
327
+ </symbol>
328
+ <symbol id="script" viewBox="0 0 100 100">
329
+ <defs/>
330
+ <path d="M50,100C22.4,100,0,77.6,0,50S22.4,0,50,0s50,22.4,50,50-22.4,50-50,50ZM50,8.1c-23.1,0-41.9,18.8-41.9,41.9s18.8,41.9,41.9,41.9,41.9-18.8,41.9-41.9S73.1,8.1,50,8.1Z"/>
331
+ <g>
332
+ <path class="st0" d="M45,23.6v9.1h-1.5c-1.4,0-2.4.2-3.1.7-.7.5-1.2,1.2-1.4,2.3-.2.6-.2,2.1-.3,4.6,0,2.5-.3,4.5-.9,5.9-.4,1.1-1.1,2-1.9,2.6-.6.5-1.6,1-3,1.5,1.5.6,2.5,1.2,3.2,1.8.7.6,1.3,1.6,1.8,2.8.5,1.3.8,3.3.8,6.1s.2,4.1.5,4.9c.3.8.8,1.3,1.5,1.6.7.3,2.1.5,4.3.5v9h-4.1c-4.2,0-7.3-.4-9-1.2-1.8-.8-3.1-1.9-3.8-3.5-.8-1.5-1.1-3.8-1.1-6.8s0-1.3,0-2c0-.4,0-.8,0-1.3,0-2.2-.2-3.7-.7-4.6-.5-.9-1.1-1.6-2-2-.9-.4-2.1-.6-3.7-.7v-9.6c1.7,0,2.9-.2,3.8-.7s1.5-1.1,1.9-2c.4-.9.7-2.5.7-4.7v-.9c0-.4,0-.9,0-1.3,0-3.3.3-5.7,1-7.1.6-1.5,1.5-2.6,2.7-3.4.8-.6,2-1,3.5-1.3,1.9-.4,4.1-.6,6.6-.6h4.4Z"/>
333
+ <path class="st0" d="M58.4,23.6c2.5,0,4.7.2,6.6.6,1.5.3,2.6.7,3.5,1.3,1.1.8,2,1.9,2.7,3.4.6,1.5,1,3.8,1,7.1s0,.9,0,1.3v.9c0,2.2.2,3.7.7,4.7.4.9,1.1,1.6,1.9,2s2.1.7,3.8.7v9.6c-1.6,0-2.9.3-3.7.7-.9.4-1.5,1.1-2,2-.5.9-.7,2.4-.7,4.6s0,.8,0,1.3c0,.7,0,1.3,0,2,0,3-.4,5.3-1.1,6.8-.8,1.5-2,2.7-3.8,3.5-1.8.8-4.8,1.2-9,1.2h-4.1v-9c2.1,0,3.6-.2,4.3-.5.7-.3,1.2-.9,1.5-1.6.3-.8.5-2.4.5-4.9s.2-4.8.8-6.1c.5-1.3,1.1-2.2,1.8-2.8.7-.6,1.8-1.2,3.2-1.8-1.4-.5-2.4-1-3-1.5-.8-.7-1.4-1.5-1.9-2.6-.6-1.4-.9-3.4-.9-5.9,0-2.5-.1-4-.3-4.6-.3-1-.8-1.8-1.4-2.3-.7-.5-1.7-.7-3.1-.7h-1.5v-9.1h4.4Z"/>
334
+ </g>
335
+ </symbol>
324
336
  <symbol id="search-outline" viewBox="0 0 100 100">
325
337
  <path d="M59.038.217c-21.828 0-39.586 17.758-39.586 39.586 0 8.93 2.975 17.175 7.98 23.806L3.472 87.57c-2.794 2.795-2.794 7.324 0 10.118 2.794 2.794 7.323 2.794 10.117 0l24.39-24.39c6.1 3.85 13.32 6.09 21.06 6.09 21.824 0 39.582-17.758 39.582-39.586S80.862.217 59.038.217zm0 69.142C42.74 69.36 29.48 56.1 29.48 39.8s13.26-29.555 29.56-29.555 29.557 13.26 29.557 29.557S75.335 69.36 59.037 69.36z"/>
326
338
  </symbol>
@@ -0,0 +1,46 @@
1
+ const CACHE_NAME = 'dashboard-cache-v1';
2
+
3
+ self.addEventListener('install', () => {
4
+ self.skipWaiting();
5
+ });
6
+
7
+ self.addEventListener('activate', event => {
8
+ event.waitUntil(
9
+ Promise.all([
10
+ self.clients.claim(),
11
+ caches.keys().then(cacheNames => {
12
+ return Promise.all(
13
+ cacheNames.map(cacheName => {
14
+ if (cacheName !== CACHE_NAME) {
15
+ return caches.delete(cacheName);
16
+ }
17
+ })
18
+ );
19
+ })
20
+ ])
21
+ );
22
+ });
23
+
24
+ self.addEventListener('fetch', event => {
25
+ const req = event.request;
26
+ if (req.destination === 'script' || req.destination === 'style' || req.url.includes('/bundles/')) {
27
+ event.respondWith(
28
+ caches.match(req).then(cached => {
29
+ return (
30
+ cached ||
31
+ fetch(req).then(resp => {
32
+ const resClone = resp.clone();
33
+ caches.open(CACHE_NAME).then(cache => cache.put(req, resClone));
34
+ return resp;
35
+ })
36
+ );
37
+ })
38
+ );
39
+ }
40
+ });
41
+
42
+ self.addEventListener('message', event => {
43
+ if (event.data === 'unregister') {
44
+ self.registration.unregister();
45
+ }
46
+ });
package/README.md CHANGED
@@ -43,6 +43,7 @@ Parse Dashboard is a standalone dashboard for managing your [Parse Server](https
43
43
  - [Custom order in the filter popup](#custom-order-in-the-filter-popup)
44
44
  - [Persistent Filters](#persistent-filters)
45
45
  - [Scripts](#scripts)
46
+ - [Resource Cache](#resource-cache)
46
47
  - [Running as Express Middleware](#running-as-express-middleware)
47
48
  - [Deploying Parse Dashboard](#deploying-parse-dashboard)
48
49
  - [Preparing for Deployment](#preparing-for-deployment)
@@ -61,20 +62,29 @@ Parse Dashboard is a standalone dashboard for managing your [Parse Server](https
61
62
  - [Data Browser](#data-browser)
62
63
  - [Filters](#filters)
63
64
  - [Info Panel](#info-panel)
64
- - [Segments](#segments)
65
- - [Text Item](#text-item)
66
- - [Key-Value Item](#key-value-item)
67
- - [Table Item](#table-item)
68
- - [Image Item](#image-item)
69
- - [Video Item](#video-item)
70
- - [Audio Item](#audio-item)
71
- - [Button Item](#button-item)
72
- - [Panel Item](#panel-item)
65
+ - [Response](#response)
66
+ - [Segments](#segments)
67
+ - [Text Item](#text-item)
68
+ - [Key-Value Item](#key-value-item)
69
+ - [Table Item](#table-item)
70
+ - [Image Item](#image-item)
71
+ - [Video Item](#video-item)
72
+ - [Audio Item](#audio-item)
73
+ - [Button Item](#button-item)
74
+ - [Panel Item](#panel-item)
75
+ - [Prefetching](#prefetching)
73
76
  - [Freeze Columns](#freeze-columns)
74
77
  - [Browse as User](#browse-as-user)
75
78
  - [Change Pointer Key](#change-pointer-key)
76
79
  - [Limitations](#limitations)
77
80
  - [CSV Export](#csv-export)
81
+ - [Views](#views)
82
+ - [Data Sources](#data-sources)
83
+ - [Aggregation Pipeline](#aggregation-pipeline)
84
+ - [Cloud Function](#cloud-function)
85
+ - [View Table](#view-table)
86
+ - [Pointer](#pointer)
87
+ - [Link](#link)
78
88
  - [Contributing](#contributing)
79
89
 
80
90
  # Getting Started
@@ -139,6 +149,8 @@ Parse Dashboard is continuously tested with the most recent releases of Node.js
139
149
  | `infoPanel[*].title` | String | no | - | `User Details` | The panel title. |
140
150
  | `infoPanel[*].classes` | Array&lt;String&gt; | no | - | `["_User"]` | The classes for which the info panel should be displayed. |
141
151
  | `infoPanel[*].cloudCodeFunction` | String | no | - | `getUserDetails` | The Cloud Code Function which received the selected object in the data browser and returns the response to be displayed in the info panel. |
152
+ | `infoPanel[*].prefetchObjects` | Number | yes | `0` | `2` | Number of next rows to prefetch when browsing sequential rows. For example, `2` means the next 2 rows will be fetched in advance. |
153
+ | `infoPanel[*].prefetchStale` | Number | yes | `0` | `10` | Duration in seconds after which prefetched data is discarded as stale. |
142
154
  | `apps.scripts` | Array&lt;Object&gt; | yes | `[]` | `[{ ... }, { ... }]` | The scripts that can be executed for that app. |
143
155
  | `apps.scripts.title` | String | no | - | `'Delete User'` | The title that will be displayed in the data browser context menu and the script run confirmation dialog. |
144
156
  | `apps.scripts.classes` | Array&lt;String&gt; | no | - | `['_User']` | The classes of Parse Objects for which the scripts can be executed. |
@@ -444,7 +456,6 @@ You can also specify custom fields with the `scrips` option:
444
456
 
445
457
  ```
446
458
 
447
-
448
459
  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:
449
460
 
450
461
  ```js
@@ -505,6 +516,37 @@ Parse.Cloud.define('deleteAccount', async (req) => {
505
516
 
506
517
  </details>
507
518
 
519
+ ### Resource Cache
520
+
521
+ 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.
522
+
523
+ | Parameter | Type | Optional | Default | Example | Description |
524
+ |-----------------------|---------|----------|---------|---------|-----------------------------------------------------------------------------------------------------------------------------------------|
525
+ | `enableResourceCache` | Boolean | yes | `false` | `true` | Enables caching of dashboard resources in the browser for faster dashboard loading in additional browser tabs. |
526
+
527
+
528
+ Example configuration:
529
+
530
+ ```javascript
531
+ const dashboard = new ParseDashboard({
532
+ enableResourceCache: true,
533
+ apps: [
534
+ {
535
+ serverURL: 'http://localhost:1337/parse',
536
+ appId: 'myAppId',
537
+ masterKey: 'myMasterKey',
538
+ appName: 'MyApp'
539
+ }
540
+ ]
541
+ });
542
+ ```
543
+
544
+ > [!Warning]
545
+ > This feature can make it more difficult to push dashboard updates to users. Enabling the resource cache will start a browser service worker that caches dashboard resources locally only once. As long as the service worker is running, it will prevent loading any dashboard updates from the server, even if the user reloads the browser tab. The service worker is automatically stopped, once the last dashboard browser tab is closed. On the opening of the first dashboard browser tab, a new service worker is started and the dashboard resources are loaded from the server.
546
+
547
+ > [!Note]
548
+ > For developers: during dashboard development, the resource cache should be disabled to ensure reloading the dashboard tab in the browser loads the new dashboard bundle with any changes you made in the source code. You can inspect the service worker in the developer tools of most browsers. For example in Google Chrome, go to *Developer Tools > Application tab > Service workers* to see whether the dashboard service worker is currently running and to debug it.
549
+
508
550
  # Running as Express Middleware
509
551
 
510
552
  Instead of starting Parse Dashboard with the CLI, you can also run it as an [express](https://github.com/expressjs/express) middleware.
@@ -872,7 +914,9 @@ The following example dashboard configuration shows an info panel for the `_User
872
914
  {
873
915
  "title": "User Details",
874
916
  "classes": ["_User"],
875
- "cloudCodeFunction": "getUserDetails"
917
+ "cloudCodeFunction": "getUserDetails",
918
+ "prefetchObjects": 2,
919
+ "prefetchStale": 10
876
920
  }
877
921
  ]
878
922
  }
@@ -881,7 +925,9 @@ The following example dashboard configuration shows an info panel for the `_User
881
925
 
882
926
  The Cloud Code Function receives the selected object in the payload and returns a response that can include various items.
883
927
 
884
- #### Segments
928
+ #### Response
929
+
930
+ ##### Segments
885
931
 
886
932
  The info panel can contain multiple segments to display different groups of information.
887
933
 
@@ -917,7 +963,7 @@ Example:
917
963
 
918
964
  The items array can include various types of content such as text, key-value pairs, tables, images, videos, audios, and buttons. Each type offers a different way to display information within the info panel, allowing for a customizable and rich user experience. Below is a detailed explanation of each type.
919
965
 
920
- #### Text Item
966
+ ##### Text Item
921
967
 
922
968
  A simple text field.
923
969
 
@@ -937,7 +983,7 @@ Example:
937
983
  }
938
984
  ```
939
985
 
940
- #### Key-Value Item
986
+ ##### Key-Value Item
941
987
 
942
988
  A text item that consists of a key and a value. The value can optionally be linked to a URL.
943
989
 
@@ -948,6 +994,7 @@ A text item that consists of a key and a value. The value can optionally be link
948
994
  | `value` | String | - | No | The value text to display. |
949
995
  | `url` | String | `undefined` | Yes | The URL that will be opened in a new browser tab when clicking on the value text. It can be set to an absolute URL or a relative URL in which case the base URL is `<PROTOCOL>://<HOST>/<MOUNT_PATH>/`. |
950
996
  | `isRelativeUrl` | Boolean | `false` | Yes | Set this to `true` when linking to another dashboard page, in which case the base URL for the relative URL will be `<PROTOCOL>://<HOST>/<MOUNT_PATH>/apps/<APP_NAME>/`. |
997
+ | `values` | Array | - | Yes | Additional values to display after `value`. Each item is an object with `value`, optional `url` and `isRelativeUrl`. |
951
998
  | `style` | Object | - | Yes | The CSS style definition. |
952
999
 
953
1000
  Examples:
@@ -980,6 +1027,17 @@ Examples:
980
1027
  }
981
1028
  ```
982
1029
 
1030
+ ```json
1031
+ {
1032
+ "type": "keyValue",
1033
+ "key": "Purchase Value",
1034
+ "value": "123",
1035
+ "url": "browser/Purchase",
1036
+ "isRelativeUrl": true,
1037
+ "values": [{ "value": "456" }]
1038
+ }
1039
+ ```
1040
+
983
1041
  To navigate to a specific object using a relative URL, the query parameters must be URL encoded:
984
1042
 
985
1043
  ```js
@@ -996,7 +1054,7 @@ const item = {
996
1054
  }
997
1055
  ```
998
1056
 
999
- #### Table Item
1057
+ ##### Table Item
1000
1058
 
1001
1059
  A table with columns and rows to display data in a structured format.
1002
1060
 
@@ -1038,7 +1096,7 @@ Example:
1038
1096
  }
1039
1097
  ```
1040
1098
 
1041
- #### Image Item
1099
+ ##### Image Item
1042
1100
 
1043
1101
  An image to be displayed in the panel.
1044
1102
 
@@ -1058,7 +1116,7 @@ Example:
1058
1116
  }
1059
1117
  ```
1060
1118
 
1061
- #### Video Item
1119
+ ##### Video Item
1062
1120
 
1063
1121
  A video to be displayed in the panel.
1064
1122
 
@@ -1078,7 +1136,7 @@ Example:
1078
1136
  }
1079
1137
  ```
1080
1138
 
1081
- #### Audio Item
1139
+ ##### Audio Item
1082
1140
 
1083
1141
  An audio file to be played in the panel.
1084
1142
 
@@ -1098,7 +1156,7 @@ Example:
1098
1156
  }
1099
1157
  ```
1100
1158
 
1101
- #### Button Item
1159
+ ##### Button Item
1102
1160
 
1103
1161
  A button that triggers an action when clicked.
1104
1162
 
@@ -1133,7 +1191,7 @@ Example:
1133
1191
  }
1134
1192
  ```
1135
1193
 
1136
- #### Panel Item
1194
+ ##### Panel Item
1137
1195
 
1138
1196
  A sub-panel whose data is loaded on-demand by expanding the item.
1139
1197
 
@@ -1155,6 +1213,17 @@ Example:
1155
1213
  }
1156
1214
  ```
1157
1215
 
1216
+ #### Prefetching
1217
+
1218
+ To reduce the time for info panel data to appear, data can be prefetched.
1219
+
1220
+ | Parameter | Type | Optional | Default | Example | Description |
1221
+ |--------------------------------|--------|----------|---------|---------|-----------------------------------------------------------------------------------------------------------------------------------|
1222
+ | `infoPanel[*].prefetchObjects` | Number | yes | `0` | `2` | Number of next rows to prefetch when browsing sequential rows. For example, `2` means the next 2 rows will be fetched in advance. |
1223
+ | `infoPanel[*].prefetchStale` | Number | yes | `0` | `10` | Duration in seconds after which prefetched data is discarded as stale. |
1224
+
1225
+ Prefetching is particularly useful when navigating through lists of objects. To optimize performance and avoid unnecessary data loading, prefetching is triggered only after the user has moved through 3 consecutive rows using the keyboard down-arrow key or by mouse click.
1226
+
1158
1227
  ### Freeze Columns
1159
1228
 
1160
1229
  ▶️ *Core > Browser > Freeze column*
@@ -1190,6 +1259,109 @@ This feature will take either selected rows or all rows of an individual class a
1190
1259
 
1191
1260
  > ⚠️ There is currently a 10,000 row limit when exporting all data. If more than 10,000 rows are present in the class, the CSV file will only contain 10,000 rows.
1192
1261
 
1262
+ ## Views
1263
+
1264
+ ▶️ *Core > Views*
1265
+
1266
+ Views are saved queries that display data in a table format. Saved views appear in the sidebar, where you can select, edit, or delete them. Optionally you can enable the object counter to show in the sidebar how many items match the view.
1267
+
1268
+ > [!Caution]
1269
+ > Values are generally rendered without sanitization in the resulting data table. If rendered values come from user input or untrusted data, make sure to remove potentially dangerous HTML or JavaScript, to prevent an attacker from injecting malicious code, to exploit vulnerabilities like Cross-Site Scripting (XSS).
1270
+
1271
+ ### Data Sources
1272
+
1273
+ Views can pull their data from the following data sources.
1274
+
1275
+ #### Aggregation Pipeline
1276
+
1277
+ Display aggregated data from your classes using a MongoDB aggregation pipeline. Create a view by selecting a class and defining an aggregation pipeline.
1278
+
1279
+ #### Cloud Function
1280
+
1281
+ Display data returned by a Parse Cloud Function. Create a view specifying a Cloud Function that returns an array of objects. Cloud Functions enable custom business logic, computed fields, and complex data transformations.
1282
+
1283
+ Cloud Function views can prompt users for text input and/or file upload when opened. Enable "Require text input" or "Require file upload" checkboxes when creating the view. The user provided data will then be available in the Cloud Function as parameters.
1284
+
1285
+ Cloud Function example:
1286
+
1287
+ ```js
1288
+ Parse.Cloud.define("myViewFunction", request => {
1289
+ const text = request.params.text;
1290
+ const fileData = request.params.fileData;
1291
+ return processDataWithTextAndFile(text, fileData);
1292
+ });
1293
+ ```
1294
+
1295
+ > [!Note]
1296
+ > Text and file data are ephemeral and only available to the Cloud Function during that request. Files are base64 encoded, increasing the data during transfer by ~33%.
1297
+
1298
+ ### View Table
1299
+
1300
+ When designing the aggregation pipeline, consider that some values are rendered specially in the output table.
1301
+
1302
+ #### Pointer
1303
+
1304
+ Parse Object pointers are automatically displayed as links to the target object.
1305
+
1306
+ Example:
1307
+
1308
+ ```json
1309
+ { "__type": "Pointer", "className": "_User", "objectId": "xWMyZ4YEGZ" }
1310
+ ```
1311
+
1312
+ #### Link
1313
+
1314
+ Links are rendered as hyperlinks that open in a new browser tab.
1315
+
1316
+ Example:
1317
+
1318
+ ```json
1319
+ {
1320
+ "__type": "Link",
1321
+ "url": "https://example.com",
1322
+ "text": "Link"
1323
+ }
1324
+ ```
1325
+
1326
+ Set `isRelativeUrl: true` when linking to another dashboard page, in which case the base URL for the relative URL will be `<PROTOCOL>://<HOST>/<MOUNT_PATH>/apps/<APP_NAME>/`. The key `isRelativeUrl` is optional and `false` by default.
1327
+
1328
+ Example:
1329
+
1330
+ ```json
1331
+ {
1332
+ "__type": "Link",
1333
+ "url": "browser/_Installation",
1334
+ "isRelativeUrl": true,
1335
+ "text": "Link"
1336
+ }
1337
+ ```
1338
+
1339
+ A query part of the URL can be easily added using the `urlQuery` key which will automatically escape the query string.
1340
+
1341
+ Example:
1342
+
1343
+ ```json
1344
+ {
1345
+ "__type": "Link",
1346
+ "url": "browser/_Installation",
1347
+ "urlQuery": "filters=[{\"field\":\"objectId\",\"constraint\":\"eq\",\"compareTo\":\"xWMyZ4YEGZ\",\"class\":\"_Installation\"}]",
1348
+ "isRelativeUrl": true,
1349
+ "text": "Link"
1350
+ }
1351
+ ```
1352
+
1353
+ In the example above, the query string will be escaped and added to the url, resulting in the complete URL:
1354
+
1355
+ ```js
1356
+ "browser/_Installation?filters=%5B%7B%22field%22%3A%22objectId%22%2C%22constraint%22%3A%22eq%22%2C%22compareTo%22%3A%22xWMyZ4YEGZ%22%2C%22class%22%3A%22_Installation%22%7D%5D"
1357
+ ```
1358
+
1359
+ > [!Tip]
1360
+ > For guidance on how to create the URL query for a dashboard data browser filter, open the data browser and set the filter. Then copy the browser URL and unescape it. The query constraints in `?filters=[...]` will give you an idea of the constraint syntax.
1361
+
1362
+ > [!Note]
1363
+ > For security reasons, the link `<a>` tag contains the `rel="noreferrer"` attribute, which prevents the target website to know the referring website which in this case is the Parse Dashboard URL. That attribute is widely supported across modern browsers, but if in doubt check your browser's compatibility.
1364
+
1193
1365
  # Contributing
1194
1366
 
1195
1367
  We really want Parse to be yours, to see it grow and thrive in the open source community. Please see the [Contributing to Parse Dashboard guide](CONTRIBUTING.md).
@@ -1200,4 +1372,4 @@ As of April 5, 2017, Parse, LLC has transferred this code to the parse-community
1200
1372
 
1201
1373
  [license-svg]: https://img.shields.io/badge/license-BSD-lightgrey.svg
1202
1374
  [license-link]: LICENSE
1203
- [open-collective-link]: https://opencollective.com/parse-server
1375
+ [open-collective-link]: https://opencollective.com/parse-server
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "parse-dashboard",
3
- "version": "7.3.0-alpha.4",
3
+ "version": "7.3.0-alpha.40",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/parse-community/parse-dashboard"
@@ -41,7 +41,7 @@
41
41
  "body-parser": "2.2.0",
42
42
  "commander": "13.1.0",
43
43
  "connect-flash": "0.1.1",
44
- "cookie-session": "2.1.0",
44
+ "cookie-session": "2.1.1",
45
45
  "copy-to-clipboard": "3.3.3",
46
46
  "core-js": "3.42.0",
47
47
  "csurf": "1.11.0",
@@ -49,7 +49,7 @@
49
49
  "fast-deep-equal": "3.1.3",
50
50
  "graphiql": "2.0.8",
51
51
  "graphql": "16.11.0",
52
- "immutable": "5.1.2",
52
+ "immutable": "5.1.3",
53
53
  "immutable-devtools": "0.1.5",
54
54
  "inquirer": "12.6.3",
55
55
  "js-beautify": "1.15.4",
@@ -66,7 +66,7 @@
66
66
  "react-dnd": "10.0.2",
67
67
  "react-dnd-html5-backend": "16.0.1",
68
68
  "react-dom": "16.14.0",
69
- "react-draggable": "4.4.6",
69
+ "react-draggable": "4.5.0",
70
70
  "react-helmet": "6.1.0",
71
71
  "react-json-view": "1.21.3",
72
72
  "react-popper-tooltip": "4.4.2",
@@ -79,10 +79,10 @@
79
79
  "@babel/core": "7.27.4",
80
80
  "@babel/eslint-parser": "7.28.0",
81
81
  "@babel/plugin-proposal-decorators": "7.27.1",
82
- "@babel/plugin-transform-runtime": "7.27.3",
82
+ "@babel/plugin-transform-runtime": "7.28.0",
83
83
  "@babel/preset-env": "7.27.2",
84
84
  "@babel/preset-react": "7.27.1",
85
- "@eslint/compat": "1.2.9",
85
+ "@eslint/compat": "1.3.1",
86
86
  "@saithodev/semantic-release-backmerge": "4.0.1",
87
87
  "@semantic-release/changelog": "6.0.3",
88
88
  "@semantic-release/commit-analyzer": "13.0.1",
@@ -106,13 +106,13 @@
106
106
  "marked": "15.0.12",
107
107
  "null-loader": "4.0.1",
108
108
  "prettier": "3.5.3",
109
- "puppeteer": "24.9.0",
109
+ "puppeteer": "24.12.1",
110
110
  "react-test-renderer": "16.13.1",
111
111
  "request": "2.88.2",
112
- "request-promise": "4.2.5",
113
- "sass": "1.89.1",
112
+ "request-promise": "4.2.6",
113
+ "sass": "1.89.2",
114
114
  "sass-loader": "13.2.0",
115
- "semantic-release": "24.2.3",
115
+ "semantic-release": "24.2.7",
116
116
  "semver": "7.7.2",
117
117
  "style-loader": "3.3.1",
118
118
  "svg-prep": "1.0.4",