parse-dashboard 7.3.0-alpha.9 → 7.3.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/Parse-Dashboard/app.js +866 -4
- package/Parse-Dashboard/public/bundles/dashboard.bundle.js +1 -1
- package/Parse-Dashboard/public/bundles/dashboard.bundle.js.LICENSE.txt +9 -0
- package/Parse-Dashboard/public/bundles/login.bundle.js +1 -1
- package/Parse-Dashboard/public/bundles/sprites.svg +19 -0
- package/Parse-Dashboard/public/sw.js +46 -0
- package/Parse-Dashboard/server.js +16 -0
- package/README.md +304 -29
- package/package.json +12 -11
|
@@ -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>
|
|
@@ -338,6 +350,13 @@
|
|
|
338
350
|
<path d="M58 75.25H7.81v-50.5H66V17H0v66h66V51h-8"/>
|
|
339
351
|
<path d="M80.613 18.543l-7.732 7.733L79.07 32H47.52C36.73 32 28 41.24 28 52.03V66h10.885V52.03c0-4.76 3.873-9.03 8.634-9.03h31.543l-6.187 6.583 7.732 7.733L100 37.93 80.613 18.542z"/>
|
|
340
352
|
</symbol>
|
|
353
|
+
<symbol id="sparkle-solid" viewBox="0 0 512 512">
|
|
354
|
+
<g>
|
|
355
|
+
<path class="st0" d="M247.355,106.9C222.705,82.241,205.833,39.18,197.46,0c-8.386,39.188-25.24,82.258-49.899,106.917
		c-24.65,24.642-67.724,41.514-106.896,49.904c39.188,8.373,82.254,25.235,106.904,49.895c24.65,24.65,41.522,67.72,49.908,106.9
		c8.373-39.188,25.24-82.258,49.886-106.917c24.65-24.65,67.724-41.514,106.896-49.904
		C315.08,148.422,272.014,131.551,247.355,106.9z"/>
|
|
356
|
+
<path class="st0" d="M407.471,304.339c-14.714-14.721-24.81-40.46-29.812-63.864c-5.011,23.404-15.073,49.142-29.803,63.872
		c-14.73,14.714-40.464,24.801-63.864,29.812c23.408,5.01,49.134,15.081,63.864,29.811c14.73,14.722,24.81,40.46,29.82,63.864
		c5.001-23.413,15.081-49.142,29.802-63.872c14.722-14.722,40.46-24.802,63.856-29.82
		C447.939,329.14,422.201,319.061,407.471,304.339z"/>
|
|
357
|
+
<path class="st0" d="M146.352,354.702c-4.207,19.648-12.655,41.263-25.019,53.626c-12.362,12.354-33.968,20.82-53.613,25.027
		c19.645,4.216,41.251,12.656,53.613,25.027c12.364,12.362,20.829,33.96,25.036,53.618c4.203-19.658,12.655-41.255,25.023-53.626
		c12.354-12.362,33.964-20.82,53.605-25.035c-19.64-4.2-41.251-12.656-53.613-25.019
		C159.024,395.966,150.555,374.351,146.352,354.702z"/>
|
|
358
|
+
</g>
|
|
359
|
+
</symbol>
|
|
341
360
|
<symbol id="trash-outline" viewBox="0 0 100 100">
|
|
342
361
|
<path d="M88 20.994C88 14.834 82.524 10 76.363 10H60.48c-.453-5.49-5.056-10-10.66-10S39.61 4.51 39.156 10h-15.52C17.474 10 12 14.833 12 20.994v15.874h4.024v51.96c0 6.16 5.013 11.172 11.174 11.172h45.604c6.16 0 11.173-5.012 11.173-11.173v-51.96H88V20.995zM49.82 5.932c2.328 0 4.266 1.86 4.684 4.068h-9.37c.417-2.21 2.356-4.068 4.685-4.068zM23.635 19h52.727C77.62 19 79 19.738 79 20.994V28H21v-7.006C21 19.738 22.38 19 23.636 19zM75.08 88.827c0 1.255-1.023 2.277-2.278 2.277H27.198c-1.256 0-2.278-1.022-2.278-2.277v-51.96h6.148V83c0 1.64 1.328 2.966 2.966 2.966C35.672 85.966 37 84.64 37 83V36.868h10.034V83c0 1.64 1.328 2.966 2.966 2.966 1.64 0 2.966-1.328 2.966-2.966V36.868H63V83c0 1.64 1.36 2.966 3 2.966s3-1.328 3-2.966V36.868h6.08v51.96z"/>
|
|
343
362
|
</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
|
+
});
|
|
@@ -39,6 +39,7 @@ module.exports = (options) => {
|
|
|
39
39
|
const configUserPassword = options.userPassword || process.env.PARSE_DASHBOARD_USER_PASSWORD;
|
|
40
40
|
const configSSLKey = options.sslKey || process.env.PARSE_DASHBOARD_SSL_KEY;
|
|
41
41
|
const configSSLCert = options.sslCert || process.env.PARSE_DASHBOARD_SSL_CERT;
|
|
42
|
+
const configAgent = options.agent || process.env.PARSE_DASHBOARD_AGENT;
|
|
42
43
|
|
|
43
44
|
function handleSIGs(server) {
|
|
44
45
|
const signals = {
|
|
@@ -83,6 +84,21 @@ module.exports = (options) => {
|
|
|
83
84
|
}
|
|
84
85
|
];
|
|
85
86
|
}
|
|
87
|
+
// Add agent configuration from environment variables
|
|
88
|
+
if (configAgent) {
|
|
89
|
+
// If it's already an object (from JS config), use it directly
|
|
90
|
+
if (typeof configAgent === 'object') {
|
|
91
|
+
configFromCLI.data.agent = configAgent;
|
|
92
|
+
} else {
|
|
93
|
+
// Otherwise, try to parse it as JSON
|
|
94
|
+
try {
|
|
95
|
+
configFromCLI.data.agent = JSON.parse(configAgent);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
console.error('Failed to parse PARSE_DASHBOARD_AGENT:', error.message);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
86
102
|
} else if (!configServerURL && !configMasterKey && !configAppName) {
|
|
87
103
|
configFile = path.join(__dirname, 'parse-dashboard-config.json');
|
|
88
104
|
}
|
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,34 @@ 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
|
-
- [
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
- [Browse as User](#browse-as-user)
|
|
78
|
+
- [Change Pointer Key](#change-pointer-key)
|
|
79
|
+
- [Limitations](#limitations)
|
|
80
|
+
- [CSV Export](#csv-export)
|
|
81
|
+
- [AI Agent](#ai-agent)
|
|
82
|
+
- [Configuration](#configuration)
|
|
83
|
+
- [Providers](#providers)
|
|
84
|
+
- [OpenAI](#openai)
|
|
85
|
+
- [Views](#views)
|
|
86
|
+
- [Data Sources](#data-sources)
|
|
87
|
+
- [Aggregation Pipeline](#aggregation-pipeline)
|
|
88
|
+
- [Cloud Function](#cloud-function)
|
|
89
|
+
- [View Table](#view-table)
|
|
90
|
+
- [Pointer](#pointer)
|
|
91
|
+
- [Link](#link)
|
|
92
|
+
- [Image](#image)
|
|
78
93
|
- [Contributing](#contributing)
|
|
79
94
|
|
|
80
95
|
# Getting Started
|
|
@@ -139,6 +154,8 @@ Parse Dashboard is continuously tested with the most recent releases of Node.js
|
|
|
139
154
|
| `infoPanel[*].title` | String | no | - | `User Details` | The panel title. |
|
|
140
155
|
| `infoPanel[*].classes` | Array<String> | no | - | `["_User"]` | The classes for which the info panel should be displayed. |
|
|
141
156
|
| `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. |
|
|
157
|
+
| `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. |
|
|
158
|
+
| `infoPanel[*].prefetchStale` | Number | yes | `0` | `10` | Duration in seconds after which prefetched data is discarded as stale. |
|
|
142
159
|
| `apps.scripts` | Array<Object> | yes | `[]` | `[{ ... }, { ... }]` | The scripts that can be executed for that app. |
|
|
143
160
|
| `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
161
|
| `apps.scripts.classes` | Array<String> | no | - | `['_User']` | The classes of Parse Objects for which the scripts can be executed. |
|
|
@@ -196,6 +213,7 @@ PARSE_DASHBOARD_SSL_KEY: "sslKey"
|
|
|
196
213
|
PARSE_DASHBOARD_SSL_CERT: "sslCert"
|
|
197
214
|
PARSE_DASHBOARD_CONFIG: undefined // Only for reference, it must not exist
|
|
198
215
|
PARSE_DASHBOARD_COOKIE_SESSION_SECRET: undefined // set the cookie session secret, defaults to a random string. Use this option if you want sessions to work across multiple servers, or across restarts
|
|
216
|
+
PARSE_DASHBOARD_AGENT: undefined // JSON string containing the full agent configuration with models array
|
|
199
217
|
|
|
200
218
|
```
|
|
201
219
|
|
|
@@ -444,7 +462,6 @@ You can also specify custom fields with the `scrips` option:
|
|
|
444
462
|
|
|
445
463
|
```
|
|
446
464
|
|
|
447
|
-
|
|
448
465
|
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
466
|
|
|
450
467
|
```js
|
|
@@ -505,6 +522,37 @@ Parse.Cloud.define('deleteAccount', async (req) => {
|
|
|
505
522
|
|
|
506
523
|
</details>
|
|
507
524
|
|
|
525
|
+
### Resource Cache
|
|
526
|
+
|
|
527
|
+
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.
|
|
528
|
+
|
|
529
|
+
| Parameter | Type | Optional | Default | Example | Description |
|
|
530
|
+
|-----------------------|---------|----------|---------|---------|----------------------------------------------------------------------------------------------------------------|
|
|
531
|
+
| `enableResourceCache` | Boolean | yes | `false` | `true` | Enables caching of dashboard resources in the browser for faster dashboard loading in additional browser tabs. |
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
Example configuration:
|
|
535
|
+
|
|
536
|
+
```javascript
|
|
537
|
+
const dashboard = new ParseDashboard({
|
|
538
|
+
enableResourceCache: true,
|
|
539
|
+
apps: [
|
|
540
|
+
{
|
|
541
|
+
serverURL: 'http://localhost:1337/parse',
|
|
542
|
+
appId: 'myAppId',
|
|
543
|
+
masterKey: 'myMasterKey',
|
|
544
|
+
appName: 'MyApp'
|
|
545
|
+
}
|
|
546
|
+
]
|
|
547
|
+
});
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
> [!Warning]
|
|
551
|
+
> 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.
|
|
552
|
+
|
|
553
|
+
> [!Note]
|
|
554
|
+
> 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.
|
|
555
|
+
|
|
508
556
|
# Running as Express Middleware
|
|
509
557
|
|
|
510
558
|
Instead of starting Parse Dashboard with the CLI, you can also run it as an [express](https://github.com/expressjs/express) middleware.
|
|
@@ -872,7 +920,9 @@ The following example dashboard configuration shows an info panel for the `_User
|
|
|
872
920
|
{
|
|
873
921
|
"title": "User Details",
|
|
874
922
|
"classes": ["_User"],
|
|
875
|
-
"cloudCodeFunction": "getUserDetails"
|
|
923
|
+
"cloudCodeFunction": "getUserDetails",
|
|
924
|
+
"prefetchObjects": 2,
|
|
925
|
+
"prefetchStale": 10
|
|
876
926
|
}
|
|
877
927
|
]
|
|
878
928
|
}
|
|
@@ -881,7 +931,9 @@ The following example dashboard configuration shows an info panel for the `_User
|
|
|
881
931
|
|
|
882
932
|
The Cloud Code Function receives the selected object in the payload and returns a response that can include various items.
|
|
883
933
|
|
|
884
|
-
####
|
|
934
|
+
#### Response
|
|
935
|
+
|
|
936
|
+
##### Segments
|
|
885
937
|
|
|
886
938
|
The info panel can contain multiple segments to display different groups of information.
|
|
887
939
|
|
|
@@ -917,7 +969,7 @@ Example:
|
|
|
917
969
|
|
|
918
970
|
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
971
|
|
|
920
|
-
|
|
972
|
+
##### Text Item
|
|
921
973
|
|
|
922
974
|
A simple text field.
|
|
923
975
|
|
|
@@ -937,7 +989,7 @@ Example:
|
|
|
937
989
|
}
|
|
938
990
|
```
|
|
939
991
|
|
|
940
|
-
|
|
992
|
+
##### Key-Value Item
|
|
941
993
|
|
|
942
994
|
A text item that consists of a key and a value. The value can optionally be linked to a URL.
|
|
943
995
|
|
|
@@ -948,6 +1000,7 @@ A text item that consists of a key and a value. The value can optionally be link
|
|
|
948
1000
|
| `value` | String | - | No | The value text to display. |
|
|
949
1001
|
| `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
1002
|
| `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>/`. |
|
|
1003
|
+
| `values` | Array | - | Yes | Additional values to display after `value`. Each item is an object with `value`, optional `url` and `isRelativeUrl`. |
|
|
951
1004
|
| `style` | Object | - | Yes | The CSS style definition. |
|
|
952
1005
|
|
|
953
1006
|
Examples:
|
|
@@ -980,6 +1033,17 @@ Examples:
|
|
|
980
1033
|
}
|
|
981
1034
|
```
|
|
982
1035
|
|
|
1036
|
+
```json
|
|
1037
|
+
{
|
|
1038
|
+
"type": "keyValue",
|
|
1039
|
+
"key": "Purchase Value",
|
|
1040
|
+
"value": "123",
|
|
1041
|
+
"url": "browser/Purchase",
|
|
1042
|
+
"isRelativeUrl": true,
|
|
1043
|
+
"values": [{ "value": "456" }]
|
|
1044
|
+
}
|
|
1045
|
+
```
|
|
1046
|
+
|
|
983
1047
|
To navigate to a specific object using a relative URL, the query parameters must be URL encoded:
|
|
984
1048
|
|
|
985
1049
|
```js
|
|
@@ -996,7 +1060,7 @@ const item = {
|
|
|
996
1060
|
}
|
|
997
1061
|
```
|
|
998
1062
|
|
|
999
|
-
|
|
1063
|
+
##### Table Item
|
|
1000
1064
|
|
|
1001
1065
|
A table with columns and rows to display data in a structured format.
|
|
1002
1066
|
|
|
@@ -1038,7 +1102,7 @@ Example:
|
|
|
1038
1102
|
}
|
|
1039
1103
|
```
|
|
1040
1104
|
|
|
1041
|
-
|
|
1105
|
+
##### Image Item
|
|
1042
1106
|
|
|
1043
1107
|
An image to be displayed in the panel.
|
|
1044
1108
|
|
|
@@ -1058,7 +1122,7 @@ Example:
|
|
|
1058
1122
|
}
|
|
1059
1123
|
```
|
|
1060
1124
|
|
|
1061
|
-
|
|
1125
|
+
##### Video Item
|
|
1062
1126
|
|
|
1063
1127
|
A video to be displayed in the panel.
|
|
1064
1128
|
|
|
@@ -1078,7 +1142,7 @@ Example:
|
|
|
1078
1142
|
}
|
|
1079
1143
|
```
|
|
1080
1144
|
|
|
1081
|
-
|
|
1145
|
+
##### Audio Item
|
|
1082
1146
|
|
|
1083
1147
|
An audio file to be played in the panel.
|
|
1084
1148
|
|
|
@@ -1098,7 +1162,7 @@ Example:
|
|
|
1098
1162
|
}
|
|
1099
1163
|
```
|
|
1100
1164
|
|
|
1101
|
-
|
|
1165
|
+
##### Button Item
|
|
1102
1166
|
|
|
1103
1167
|
A button that triggers an action when clicked.
|
|
1104
1168
|
|
|
@@ -1133,7 +1197,7 @@ Example:
|
|
|
1133
1197
|
}
|
|
1134
1198
|
```
|
|
1135
1199
|
|
|
1136
|
-
|
|
1200
|
+
##### Panel Item
|
|
1137
1201
|
|
|
1138
1202
|
A sub-panel whose data is loaded on-demand by expanding the item.
|
|
1139
1203
|
|
|
@@ -1155,13 +1219,24 @@ Example:
|
|
|
1155
1219
|
}
|
|
1156
1220
|
```
|
|
1157
1221
|
|
|
1222
|
+
#### Prefetching
|
|
1223
|
+
|
|
1224
|
+
To reduce the time for info panel data to appear, data can be prefetched.
|
|
1225
|
+
|
|
1226
|
+
| Parameter | Type | Optional | Default | Example | Description |
|
|
1227
|
+
|--------------------------------|--------|----------|---------|---------|-----------------------------------------------------------------------------------------------------------------------------------|
|
|
1228
|
+
| `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. |
|
|
1229
|
+
| `infoPanel[*].prefetchStale` | Number | yes | `0` | `10` | Duration in seconds after which prefetched data is discarded as stale. |
|
|
1230
|
+
|
|
1231
|
+
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.
|
|
1232
|
+
|
|
1158
1233
|
### Freeze Columns
|
|
1159
1234
|
|
|
1160
1235
|
▶️ *Core > Browser > Freeze column*
|
|
1161
1236
|
|
|
1162
1237
|
Right-click on a table column header to freeze columns from the left up to the clicked column in the data browser. When scrolling horizontally, the frozen columns remain visible while the other columns scroll underneath.
|
|
1163
1238
|
|
|
1164
|
-
|
|
1239
|
+
### Browse as User
|
|
1165
1240
|
|
|
1166
1241
|
▶️ *Core > Browser > Browse*
|
|
1167
1242
|
|
|
@@ -1169,20 +1244,21 @@ This feature allows you to use the data browser as another user, respecting that
|
|
|
1169
1244
|
|
|
1170
1245
|
> ⚠️ Logging in as another user will trigger the same Cloud Triggers as if the user logged in themselves using any other login method. Logging in as another user requires to enter that user's password.
|
|
1171
1246
|
|
|
1172
|
-
|
|
1247
|
+
### Change Pointer Key
|
|
1173
1248
|
|
|
1174
1249
|
▶️ *Core > Browser > Edit > Change pointer key*
|
|
1175
1250
|
|
|
1176
1251
|
This feature allows you to change how a pointer is represented in the browser. By default, a pointer is represented by the `objectId` of the linked object. You can change this to any other column of the object class. For example, if class `Installation` has a field that contains a pointer to class `User`, the pointer will show the `objectId` of the user by default. You can change this to display the field `email` of the user, so that a pointer displays the user's email address instead.
|
|
1177
1252
|
|
|
1178
|
-
|
|
1253
|
+
#### Limitations
|
|
1179
1254
|
|
|
1180
1255
|
- This does not work for an array of pointers; the pointer will always display the `objectId`.
|
|
1181
1256
|
- System columns like `createdAt`, `updatedAt`, `ACL` cannot be set as pointer key.
|
|
1182
1257
|
- This feature uses browser storage; switching to a different browser resets the pointer key to `objectId`.
|
|
1183
1258
|
|
|
1184
1259
|
> ⚠️ For each custom pointer key in each row, a server request is triggered to resolve the custom pointer key. For example, if the browser shows a class with 50 rows and each row contains 3 custom pointer keys, a total of 150 separate server requests are triggered.
|
|
1185
|
-
|
|
1260
|
+
|
|
1261
|
+
### CSV Export
|
|
1186
1262
|
|
|
1187
1263
|
▶️ *Core > Browser > Export*
|
|
1188
1264
|
|
|
@@ -1190,6 +1266,205 @@ This feature will take either selected rows or all rows of an individual class a
|
|
|
1190
1266
|
|
|
1191
1267
|
> ⚠️ 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
1268
|
|
|
1269
|
+
## AI Agent
|
|
1270
|
+
|
|
1271
|
+
The Parse Dashboard includes an AI agent that can help manage your Parse Server data through natural language commands. The agent can perform operations like creating classes, adding data, querying records, and more.
|
|
1272
|
+
|
|
1273
|
+
> [!Caution]
|
|
1274
|
+
> The AI agent has full access to your database using the master key. It can read, modify, and delete any data. This feature is highly recommended for development environments only. Always back up important data before using the AI agent.
|
|
1275
|
+
|
|
1276
|
+
### Configuration
|
|
1277
|
+
|
|
1278
|
+
To configure the AI agent for your dashboard, you need to add the `agent` configuration to your Parse Dashboard config:
|
|
1279
|
+
|
|
1280
|
+
```json
|
|
1281
|
+
{
|
|
1282
|
+
"apps": [
|
|
1283
|
+
// ...
|
|
1284
|
+
],
|
|
1285
|
+
"agent": {
|
|
1286
|
+
"models": [
|
|
1287
|
+
{
|
|
1288
|
+
"name": "ChatGPT 4.1",
|
|
1289
|
+
"provider": "openai",
|
|
1290
|
+
"model": "gpt-4.1",
|
|
1291
|
+
"apiKey": "YOUR_OPENAI_API_KEY"
|
|
1292
|
+
},
|
|
1293
|
+
]
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
```
|
|
1297
|
+
|
|
1298
|
+
| Parameter | Type | Required | Description |
|
|
1299
|
+
|----------------------------|--------|----------|-------------------------------------------------------------------------------------------------------------------------------------|
|
|
1300
|
+
| `agent` | Object | Yes | The AI agent configuration object. When using the environment variable, provide the complete agent configuration as a JSON string. |
|
|
1301
|
+
| `agent.models` | Array | Yes | Array of AI model configurations available to the agent. |
|
|
1302
|
+
| `agent.models[*].name` | String | Yes | The display name for the model (e.g., `ChatGPT 4.1`). |
|
|
1303
|
+
| `agent.models[*].provider` | String | Yes | The AI provider identifier (e.g., "openai"). |
|
|
1304
|
+
| `agent.models[*].model` | String | Yes | The specific model name from the provider (e.g., `gpt-4.1`). |
|
|
1305
|
+
| `agent.models[*].apiKey` | String | Yes | The API key for authenticating with the AI provider. |
|
|
1306
|
+
|
|
1307
|
+
The agent will use the configured models to process natural language commands and perform database operations using the master key from your app configuration.
|
|
1308
|
+
|
|
1309
|
+
### Providers
|
|
1310
|
+
|
|
1311
|
+
> [!Note]
|
|
1312
|
+
> Currently, only OpenAI models are supported. Support for additional providers may be added in future releases.
|
|
1313
|
+
|
|
1314
|
+
#### OpenAI
|
|
1315
|
+
|
|
1316
|
+
To get an OpenAI API key for use with the AI agent:
|
|
1317
|
+
|
|
1318
|
+
1. **Create an OpenAI account**: Visit [platform.openai.com](https://platform.openai.com) and sign up for an account if you don't already have one.
|
|
1319
|
+
|
|
1320
|
+
2. **Access the API section**: Once logged in, navigate to the API section of your OpenAI dashboard.
|
|
1321
|
+
|
|
1322
|
+
3. **Create a new project**:
|
|
1323
|
+
- Go to the "Projects" section
|
|
1324
|
+
- Click "Create project"
|
|
1325
|
+
- Name your project "Parse-Dashboard" (or any descriptive name)
|
|
1326
|
+
- Complete the project setup
|
|
1327
|
+
|
|
1328
|
+
4. **Configure model access**:
|
|
1329
|
+
- In your project, navigate to "Limits > Model Usage"
|
|
1330
|
+
- Select the AI models you want to use (e.g., `gpt-4`, `gpt-3.5-turbo`)
|
|
1331
|
+
- These model names will be used as the `agent.models[*].model` parameter in your dashboard configuration
|
|
1332
|
+
|
|
1333
|
+
5. **Generate an API key**:
|
|
1334
|
+
- Go to the "API Keys" page in your project settings
|
|
1335
|
+
- Click "Create new secret key"
|
|
1336
|
+
- Give your key a descriptive name (e.g., "Parse Dashboard Agent")
|
|
1337
|
+
- Copy the generated API key immediately (you won't be able to see it again)
|
|
1338
|
+
|
|
1339
|
+
6. **Set up billing**: Make sure you have a valid payment method added to your OpenAI account, as API usage incurs charges.
|
|
1340
|
+
|
|
1341
|
+
7. **Configure the dashboard**: Add the API key to your Parse Dashboard configuration as shown in the example above.
|
|
1342
|
+
|
|
1343
|
+
> [!Important]
|
|
1344
|
+
> Keep your API key secure and never commit it to version control. Consider using environment variables or secure configuration management for production deployments.
|
|
1345
|
+
|
|
1346
|
+
## Views
|
|
1347
|
+
|
|
1348
|
+
▶️ *Core > Views*
|
|
1349
|
+
|
|
1350
|
+
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.
|
|
1351
|
+
|
|
1352
|
+
> [!Caution]
|
|
1353
|
+
> 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).
|
|
1354
|
+
|
|
1355
|
+
### Data Sources
|
|
1356
|
+
|
|
1357
|
+
Views can pull their data from the following data sources.
|
|
1358
|
+
|
|
1359
|
+
#### Aggregation Pipeline
|
|
1360
|
+
|
|
1361
|
+
Display aggregated data from your classes using a MongoDB aggregation pipeline. Create a view by selecting a class and defining an aggregation pipeline.
|
|
1362
|
+
|
|
1363
|
+
#### Cloud Function
|
|
1364
|
+
|
|
1365
|
+
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.
|
|
1366
|
+
|
|
1367
|
+
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.
|
|
1368
|
+
|
|
1369
|
+
Cloud Function example:
|
|
1370
|
+
|
|
1371
|
+
```js
|
|
1372
|
+
Parse.Cloud.define("myViewFunction", request => {
|
|
1373
|
+
const text = request.params.text;
|
|
1374
|
+
const fileData = request.params.fileData;
|
|
1375
|
+
return processDataWithTextAndFile(text, fileData);
|
|
1376
|
+
});
|
|
1377
|
+
```
|
|
1378
|
+
|
|
1379
|
+
> [!Note]
|
|
1380
|
+
> 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%.
|
|
1381
|
+
|
|
1382
|
+
### View Table
|
|
1383
|
+
|
|
1384
|
+
When designing the aggregation pipeline, consider that some values are rendered specially in the output table.
|
|
1385
|
+
|
|
1386
|
+
#### Pointer
|
|
1387
|
+
|
|
1388
|
+
Parse Object pointers are automatically displayed as links to the target object.
|
|
1389
|
+
|
|
1390
|
+
Example:
|
|
1391
|
+
|
|
1392
|
+
```json
|
|
1393
|
+
{ "__type": "Pointer", "className": "_User", "objectId": "xWMyZ4YEGZ" }
|
|
1394
|
+
```
|
|
1395
|
+
|
|
1396
|
+
#### Link
|
|
1397
|
+
|
|
1398
|
+
Links are rendered as hyperlinks that open in a new browser tab.
|
|
1399
|
+
|
|
1400
|
+
Example:
|
|
1401
|
+
|
|
1402
|
+
```json
|
|
1403
|
+
{
|
|
1404
|
+
"__type": "Link",
|
|
1405
|
+
"url": "https://example.com",
|
|
1406
|
+
"text": "Link"
|
|
1407
|
+
}
|
|
1408
|
+
```
|
|
1409
|
+
|
|
1410
|
+
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.
|
|
1411
|
+
|
|
1412
|
+
Example:
|
|
1413
|
+
|
|
1414
|
+
```json
|
|
1415
|
+
{
|
|
1416
|
+
"__type": "Link",
|
|
1417
|
+
"url": "browser/_Installation",
|
|
1418
|
+
"isRelativeUrl": true,
|
|
1419
|
+
"text": "Link"
|
|
1420
|
+
}
|
|
1421
|
+
```
|
|
1422
|
+
|
|
1423
|
+
A query part of the URL can be easily added using the `urlQuery` key which will automatically escape the query string.
|
|
1424
|
+
|
|
1425
|
+
Example:
|
|
1426
|
+
|
|
1427
|
+
```json
|
|
1428
|
+
{
|
|
1429
|
+
"__type": "Link",
|
|
1430
|
+
"url": "browser/_Installation",
|
|
1431
|
+
"urlQuery": "filters=[{\"field\":\"objectId\",\"constraint\":\"eq\",\"compareTo\":\"xWMyZ4YEGZ\",\"class\":\"_Installation\"}]",
|
|
1432
|
+
"isRelativeUrl": true,
|
|
1433
|
+
"text": "Link"
|
|
1434
|
+
}
|
|
1435
|
+
```
|
|
1436
|
+
|
|
1437
|
+
In the example above, the query string will be escaped and added to the url, resulting in the complete URL:
|
|
1438
|
+
|
|
1439
|
+
```js
|
|
1440
|
+
"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"
|
|
1441
|
+
```
|
|
1442
|
+
|
|
1443
|
+
> [!Tip]
|
|
1444
|
+
> 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.
|
|
1445
|
+
|
|
1446
|
+
> [!Note]
|
|
1447
|
+
> 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.
|
|
1448
|
+
|
|
1449
|
+
#### Image
|
|
1450
|
+
|
|
1451
|
+
Images are rendered directly in the output table with an `<img>` tag. The content mode is always "scale to fit", meaning that if the image file is 100x50px and the specified dimensions are 50x50px, it would display as 50x25px, since it's scaled maintaining aspect ratio.
|
|
1452
|
+
|
|
1453
|
+
Example:
|
|
1454
|
+
|
|
1455
|
+
```json
|
|
1456
|
+
{
|
|
1457
|
+
"__type": "Image",
|
|
1458
|
+
"url": "https://example.com/image.png",
|
|
1459
|
+
"width": "50",
|
|
1460
|
+
"height": "50",
|
|
1461
|
+
"alt": "Image"
|
|
1462
|
+
}
|
|
1463
|
+
```
|
|
1464
|
+
|
|
1465
|
+
> [!Warning]
|
|
1466
|
+
> The URL will be directly invoked by the browser when trying to display the image. For security reasons, make sure you either control the full URL, including the image file name, or sanitize the URL before returning it to the dashboard. URLs containing `javascript:` or `<script` will be blocked automatically and replaced with a placeholder.
|
|
1467
|
+
|
|
1193
1468
|
# Contributing
|
|
1194
1469
|
|
|
1195
1470
|
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 +1475,4 @@ As of April 5, 2017, Parse, LLC has transferred this code to the parse-community
|
|
|
1200
1475
|
|
|
1201
1476
|
[license-svg]: https://img.shields.io/badge/license-BSD-lightgrey.svg
|
|
1202
1477
|
[license-link]: LICENSE
|
|
1203
|
-
[open-collective-link]: https://opencollective.com/parse-server
|
|
1478
|
+
[open-collective-link]: https://opencollective.com/parse-server
|