@trops/dash-core 0.1.85 → 0.1.87
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/dist/electron/index.js +364 -123
- package/dist/electron/index.js.map +1 -1
- package/package.json +1 -1
package/dist/electron/index.js
CHANGED
|
@@ -423,12 +423,14 @@ const REGISTRY_FETCH_INDEX = "registry:fetch-index";
|
|
|
423
423
|
const REGISTRY_SEARCH = "registry:search";
|
|
424
424
|
const REGISTRY_GET_PACKAGE = "registry:get-package";
|
|
425
425
|
const REGISTRY_CHECK_UPDATES = "registry:check-updates";
|
|
426
|
+
const REGISTRY_SEARCH_DASHBOARDS = "registry:search-dashboards";
|
|
426
427
|
|
|
427
428
|
var registryEvents$1 = {
|
|
428
429
|
REGISTRY_FETCH_INDEX,
|
|
429
430
|
REGISTRY_SEARCH,
|
|
430
431
|
REGISTRY_GET_PACKAGE,
|
|
431
432
|
REGISTRY_CHECK_UPDATES,
|
|
433
|
+
REGISTRY_SEARCH_DASHBOARDS,
|
|
432
434
|
};
|
|
433
435
|
|
|
434
436
|
/**
|
|
@@ -586,10 +588,12 @@ var clientCacheEvents$1 = {
|
|
|
586
588
|
|
|
587
589
|
const DASHBOARD_CONFIG_EXPORT$1 = "dashboard-config-export";
|
|
588
590
|
const DASHBOARD_CONFIG_IMPORT$1 = "dashboard-config-import";
|
|
591
|
+
const DASHBOARD_CONFIG_INSTALL$1 = "dashboard-config-install";
|
|
589
592
|
|
|
590
593
|
var dashboardConfigEvents$1 = {
|
|
591
|
-
|
|
592
|
-
|
|
594
|
+
DASHBOARD_CONFIG_EXPORT: DASHBOARD_CONFIG_EXPORT$1,
|
|
595
|
+
DASHBOARD_CONFIG_IMPORT: DASHBOARD_CONFIG_IMPORT$1,
|
|
596
|
+
DASHBOARD_CONFIG_INSTALL: DASHBOARD_CONFIG_INSTALL$1,
|
|
593
597
|
};
|
|
594
598
|
|
|
595
599
|
/**
|
|
@@ -6009,12 +6013,22 @@ async function fetchRegistryIndex(forceRefresh = false) {
|
|
|
6009
6013
|
* @param {string} filters.category - Filter by category
|
|
6010
6014
|
* @param {string} filters.author - Filter by author
|
|
6011
6015
|
* @param {string} filters.tag - Filter by tag
|
|
6016
|
+
* @param {string} filters.type - Filter by package type ("widget" or "dashboard")
|
|
6017
|
+
* @param {string[]} filters.compatibleWidgets - Only return dashboards whose required widgets are all in this list
|
|
6012
6018
|
* @returns {Promise<Object>} { packages: [...], totalWidgets: number }
|
|
6013
6019
|
*/
|
|
6014
6020
|
async function searchRegistry$1(query = "", filters = {}) {
|
|
6015
6021
|
const index = await fetchRegistryIndex();
|
|
6016
6022
|
let packages = index.packages || [];
|
|
6017
6023
|
|
|
6024
|
+
// Apply type filter — packages without an explicit type default to "widget"
|
|
6025
|
+
if (filters.type) {
|
|
6026
|
+
const typeLower = filters.type.toLowerCase();
|
|
6027
|
+
packages = packages.filter(
|
|
6028
|
+
(pkg) => (pkg.type || "widget").toLowerCase() === typeLower,
|
|
6029
|
+
);
|
|
6030
|
+
}
|
|
6031
|
+
|
|
6018
6032
|
// Apply search query
|
|
6019
6033
|
if (query) {
|
|
6020
6034
|
const q = query.toLowerCase();
|
|
@@ -6063,6 +6077,24 @@ async function searchRegistry$1(query = "", filters = {}) {
|
|
|
6063
6077
|
);
|
|
6064
6078
|
}
|
|
6065
6079
|
|
|
6080
|
+
// Apply compatibility filter — only dashboards whose required widgets
|
|
6081
|
+
// are all present in the user's installed widget list
|
|
6082
|
+
if (filters.compatibleWidgets && filters.compatibleWidgets.length) {
|
|
6083
|
+
const installedSet = new Set(
|
|
6084
|
+
filters.compatibleWidgets.map((w) => w.toLowerCase()),
|
|
6085
|
+
);
|
|
6086
|
+
packages = packages.filter((pkg) => {
|
|
6087
|
+
const requiredWidgets = (pkg.widgets || []).filter(
|
|
6088
|
+
(w) => w.required !== false,
|
|
6089
|
+
);
|
|
6090
|
+
return requiredWidgets.every(
|
|
6091
|
+
(w) =>
|
|
6092
|
+
installedSet.has((w.package || "").toLowerCase()) ||
|
|
6093
|
+
installedSet.has((w.name || "").toLowerCase()),
|
|
6094
|
+
);
|
|
6095
|
+
});
|
|
6096
|
+
}
|
|
6097
|
+
|
|
6066
6098
|
// Count total widgets across matched packages
|
|
6067
6099
|
const totalWidgets = packages.reduce(
|
|
6068
6100
|
(sum, pkg) => sum + (pkg.widgets || []).length,
|
|
@@ -6110,9 +6142,22 @@ async function checkUpdates(installedWidgets = []) {
|
|
|
6110
6142
|
return updates;
|
|
6111
6143
|
}
|
|
6112
6144
|
|
|
6145
|
+
/**
|
|
6146
|
+
* Search the registry for dashboard packages only.
|
|
6147
|
+
* Convenience wrapper around searchRegistry with type: "dashboard".
|
|
6148
|
+
*
|
|
6149
|
+
* @param {string} query - Search query string
|
|
6150
|
+
* @param {Object} filters - Optional filters (category, author, tag, compatibleWidgets)
|
|
6151
|
+
* @returns {Promise<Object>} { packages: [...], totalWidgets: number }
|
|
6152
|
+
*/
|
|
6153
|
+
async function searchDashboards(query = "", filters = {}) {
|
|
6154
|
+
return searchRegistry$1(query, { ...filters, type: "dashboard" });
|
|
6155
|
+
}
|
|
6156
|
+
|
|
6113
6157
|
var registryController$1 = {
|
|
6114
6158
|
fetchRegistryIndex,
|
|
6115
6159
|
searchRegistry: searchRegistry$1,
|
|
6160
|
+
searchDashboards,
|
|
6116
6161
|
getPackage: getPackage$1,
|
|
6117
6162
|
checkUpdates,
|
|
6118
6163
|
};
|
|
@@ -9931,134 +9976,292 @@ async function importDashboardConfig$1(win, appId, widgetRegistry = null) {
|
|
|
9931
9976
|
// Apply defaults to fill in optional fields
|
|
9932
9977
|
dashboardConfig = applyDefaults(dashboardConfig);
|
|
9933
9978
|
|
|
9934
|
-
//
|
|
9935
|
-
|
|
9936
|
-
|
|
9937
|
-
|
|
9938
|
-
|
|
9979
|
+
// Delegate to shared import pipeline
|
|
9980
|
+
return await processDashboardConfig(
|
|
9981
|
+
win,
|
|
9982
|
+
appId,
|
|
9983
|
+
dashboardConfig,
|
|
9984
|
+
widgetRegistry,
|
|
9985
|
+
);
|
|
9986
|
+
} catch (error) {
|
|
9987
|
+
console.error(
|
|
9988
|
+
"[DashboardConfigController] Error importing dashboard:",
|
|
9989
|
+
error,
|
|
9990
|
+
);
|
|
9991
|
+
return {
|
|
9992
|
+
success: false,
|
|
9993
|
+
error: error.message,
|
|
9939
9994
|
};
|
|
9995
|
+
}
|
|
9996
|
+
}
|
|
9940
9997
|
|
|
9941
|
-
|
|
9942
|
-
|
|
9943
|
-
|
|
9944
|
-
|
|
9945
|
-
|
|
9946
|
-
|
|
9947
|
-
|
|
9998
|
+
/**
|
|
9999
|
+
* Shared import pipeline: install widgets, create workspace, wire events.
|
|
10000
|
+
* Used by both importDashboardConfig (ZIP) and installDashboardFromRegistry.
|
|
10001
|
+
*
|
|
10002
|
+
* @param {BrowserWindow} win - The main window
|
|
10003
|
+
* @param {string} appId - Application identifier
|
|
10004
|
+
* @param {Object} dashboardConfig - Validated dashboard config object
|
|
10005
|
+
* @param {Object} widgetRegistry - WidgetRegistry instance
|
|
10006
|
+
* @param {Object} options - Additional options
|
|
10007
|
+
* @param {string} options.source - Source label ("zip" or "registry")
|
|
10008
|
+
* @returns {Promise<Object>} Result with success, workspace, and summary
|
|
10009
|
+
*/
|
|
10010
|
+
async function processDashboardConfig(
|
|
10011
|
+
win,
|
|
10012
|
+
appId,
|
|
10013
|
+
dashboardConfig,
|
|
10014
|
+
widgetRegistry = null,
|
|
10015
|
+
options = {},
|
|
10016
|
+
) {
|
|
10017
|
+
const source = options.source || "zip";
|
|
9948
10018
|
|
|
9949
|
-
|
|
9950
|
-
|
|
10019
|
+
// 1. Auto-install missing widgets from registry
|
|
10020
|
+
const installSummary = {
|
|
10021
|
+
installed: [],
|
|
10022
|
+
alreadyInstalled: [],
|
|
10023
|
+
failed: [],
|
|
10024
|
+
};
|
|
9951
10025
|
|
|
9952
|
-
|
|
9953
|
-
|
|
9954
|
-
|
|
9955
|
-
|
|
10026
|
+
if (
|
|
10027
|
+
widgetRegistry &&
|
|
10028
|
+
dashboardConfig.widgets &&
|
|
10029
|
+
dashboardConfig.widgets.length
|
|
10030
|
+
) {
|
|
10031
|
+
const installedWidgets = widgetRegistry.getWidgets();
|
|
10032
|
+
const installedPackages = new Set(installedWidgets.map((w) => w.name));
|
|
9956
10033
|
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
|
|
9973
|
-
|
|
9974
|
-
|
|
10034
|
+
for (const widgetDep of dashboardConfig.widgets) {
|
|
10035
|
+
const packageName = widgetDep.package;
|
|
10036
|
+
|
|
10037
|
+
if (installedPackages.has(packageName)) {
|
|
10038
|
+
installSummary.alreadyInstalled.push(packageName);
|
|
10039
|
+
continue;
|
|
10040
|
+
}
|
|
10041
|
+
|
|
10042
|
+
// Try to find the widget in the registry and install it
|
|
10043
|
+
try {
|
|
10044
|
+
const registryPkg = await getPackage(packageName);
|
|
10045
|
+
if (registryPkg && registryPkg.downloadUrl) {
|
|
10046
|
+
await widgetRegistry.downloadWidget(
|
|
10047
|
+
packageName,
|
|
10048
|
+
registryPkg.downloadUrl,
|
|
10049
|
+
registryPkg.dashConfigUrl || null,
|
|
10050
|
+
);
|
|
10051
|
+
installSummary.installed.push(packageName);
|
|
10052
|
+
installedPackages.add(packageName);
|
|
10053
|
+
} else {
|
|
9975
10054
|
installSummary.failed.push({
|
|
9976
10055
|
package: packageName,
|
|
9977
|
-
reason:
|
|
10056
|
+
reason: "Not found in registry",
|
|
9978
10057
|
});
|
|
9979
10058
|
}
|
|
10059
|
+
} catch (installError) {
|
|
10060
|
+
installSummary.failed.push({
|
|
10061
|
+
package: packageName,
|
|
10062
|
+
reason: installError.message,
|
|
10063
|
+
});
|
|
9980
10064
|
}
|
|
9981
10065
|
}
|
|
10066
|
+
}
|
|
9982
10067
|
|
|
9983
|
-
|
|
9984
|
-
|
|
10068
|
+
// 2. Build workspace from config
|
|
10069
|
+
const workspace = { ...dashboardConfig.workspace };
|
|
9985
10070
|
|
|
9986
|
-
|
|
10071
|
+
if (!workspace || !workspace.layout) {
|
|
10072
|
+
return {
|
|
10073
|
+
success: false,
|
|
10074
|
+
error: "Dashboard config has no workspace data",
|
|
10075
|
+
};
|
|
10076
|
+
}
|
|
10077
|
+
|
|
10078
|
+
// Generate a unique ID for the imported workspace
|
|
10079
|
+
workspace.id = Date.now();
|
|
10080
|
+
|
|
10081
|
+
// 3. Apply event wiring to layout
|
|
10082
|
+
const eventWiringSummary = [];
|
|
10083
|
+
if (
|
|
10084
|
+
dashboardConfig.eventWiring &&
|
|
10085
|
+
dashboardConfig.eventWiring.length &&
|
|
10086
|
+
workspace.layout
|
|
10087
|
+
) {
|
|
10088
|
+
applyEventWiringToLayout(workspace.layout, dashboardConfig.eventWiring);
|
|
10089
|
+
for (const wire of dashboardConfig.eventWiring) {
|
|
10090
|
+
eventWiringSummary.push(
|
|
10091
|
+
`${wire.source?.widget}.${wire.source?.event} → ${wire.target?.widget}.${wire.target?.handler}`,
|
|
10092
|
+
);
|
|
10093
|
+
}
|
|
10094
|
+
}
|
|
10095
|
+
|
|
10096
|
+
// 4. Mark as not shareable (imported dashboards cannot be re-published)
|
|
10097
|
+
workspace._dashboardConfig = {
|
|
10098
|
+
shareable: false,
|
|
10099
|
+
source,
|
|
10100
|
+
importedFrom: dashboardConfig.name,
|
|
10101
|
+
importedAt: new Date().toISOString(),
|
|
10102
|
+
originalAuthor: dashboardConfig.author,
|
|
10103
|
+
schemaVersion: dashboardConfig.schemaVersion,
|
|
10104
|
+
};
|
|
10105
|
+
|
|
10106
|
+
// Save workspace to workspaces.json
|
|
10107
|
+
const workspaceController = workspaceController_1;
|
|
10108
|
+
const saveResult = workspaceController.saveWorkspaceForApplication(
|
|
10109
|
+
win,
|
|
10110
|
+
appId,
|
|
10111
|
+
workspace,
|
|
10112
|
+
);
|
|
10113
|
+
|
|
10114
|
+
if (saveResult.error) {
|
|
10115
|
+
return {
|
|
10116
|
+
success: false,
|
|
10117
|
+
error: `Failed to save workspace: ${saveResult.message}`,
|
|
10118
|
+
};
|
|
10119
|
+
}
|
|
10120
|
+
|
|
10121
|
+
// Build provider requirements summary
|
|
10122
|
+
const providerSummary = (dashboardConfig.providers || []).map((p) => ({
|
|
10123
|
+
type: p.type,
|
|
10124
|
+
providerClass: p.providerClass,
|
|
10125
|
+
required: p.required,
|
|
10126
|
+
usedBy: p.usedBy,
|
|
10127
|
+
}));
|
|
10128
|
+
|
|
10129
|
+
console.log(
|
|
10130
|
+
`[DashboardConfigController] Imported dashboard "${dashboardConfig.name}" (${source}) as workspace ${workspace.id}`,
|
|
10131
|
+
);
|
|
10132
|
+
|
|
10133
|
+
return {
|
|
10134
|
+
success: true,
|
|
10135
|
+
workspace,
|
|
10136
|
+
summary: {
|
|
10137
|
+
name: dashboardConfig.name,
|
|
10138
|
+
description: dashboardConfig.description || "",
|
|
10139
|
+
author: dashboardConfig.author,
|
|
10140
|
+
widgets: installSummary,
|
|
10141
|
+
eventsWired: eventWiringSummary,
|
|
10142
|
+
providersRequired: providerSummary,
|
|
10143
|
+
},
|
|
10144
|
+
};
|
|
10145
|
+
}
|
|
10146
|
+
|
|
10147
|
+
/**
|
|
10148
|
+
* Install a dashboard from the registry by package name.
|
|
10149
|
+
*
|
|
10150
|
+
* Fetches the dashboard ZIP from the registry, extracts the .dashboard.json,
|
|
10151
|
+
* validates it, and delegates to the shared import pipeline.
|
|
10152
|
+
*
|
|
10153
|
+
* @param {BrowserWindow} win - The main window
|
|
10154
|
+
* @param {string} appId - Application identifier
|
|
10155
|
+
* @param {string} packageName - Registry package name for the dashboard
|
|
10156
|
+
* @param {Object} widgetRegistry - WidgetRegistry instance
|
|
10157
|
+
* @returns {Promise<Object>} Result with success, workspace, and summary
|
|
10158
|
+
*/
|
|
10159
|
+
async function installDashboardFromRegistry$1(
|
|
10160
|
+
win,
|
|
10161
|
+
appId,
|
|
10162
|
+
packageName,
|
|
10163
|
+
widgetRegistry = null,
|
|
10164
|
+
) {
|
|
10165
|
+
try {
|
|
10166
|
+
// 1. Look up the dashboard package in the registry
|
|
10167
|
+
const registryPkg = await getPackage(packageName);
|
|
10168
|
+
if (!registryPkg) {
|
|
9987
10169
|
return {
|
|
9988
10170
|
success: false,
|
|
9989
|
-
error:
|
|
10171
|
+
error: `Dashboard package not found in registry: ${packageName}`,
|
|
9990
10172
|
};
|
|
9991
10173
|
}
|
|
9992
10174
|
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
if (
|
|
9999
|
-
dashboardConfig.eventWiring &&
|
|
10000
|
-
dashboardConfig.eventWiring.length &&
|
|
10001
|
-
workspace.layout
|
|
10002
|
-
) {
|
|
10003
|
-
applyEventWiringToLayout(workspace.layout, dashboardConfig.eventWiring);
|
|
10004
|
-
for (const wire of dashboardConfig.eventWiring) {
|
|
10005
|
-
eventWiringSummary.push(
|
|
10006
|
-
`${wire.source?.widget}.${wire.source?.event} → ${wire.target?.widget}.${wire.target?.handler}`,
|
|
10007
|
-
);
|
|
10008
|
-
}
|
|
10175
|
+
if (!registryPkg.downloadUrl) {
|
|
10176
|
+
return {
|
|
10177
|
+
success: false,
|
|
10178
|
+
error: `Dashboard package has no download URL: ${packageName}`,
|
|
10179
|
+
};
|
|
10009
10180
|
}
|
|
10010
10181
|
|
|
10011
|
-
//
|
|
10012
|
-
|
|
10013
|
-
|
|
10014
|
-
|
|
10015
|
-
|
|
10016
|
-
originalAuthor: dashboardConfig.author,
|
|
10017
|
-
schemaVersion: dashboardConfig.schemaVersion,
|
|
10018
|
-
};
|
|
10182
|
+
// 2. Resolve the download URL and fetch the ZIP
|
|
10183
|
+
const version = registryPkg.version || "1.0.0";
|
|
10184
|
+
let downloadUrl = registryPkg.downloadUrl;
|
|
10185
|
+
downloadUrl = downloadUrl.replace("{version}", version);
|
|
10186
|
+
downloadUrl = downloadUrl.replace("{name}", packageName);
|
|
10019
10187
|
|
|
10020
|
-
//
|
|
10021
|
-
const
|
|
10022
|
-
|
|
10023
|
-
|
|
10024
|
-
|
|
10025
|
-
|
|
10188
|
+
// Enforce HTTPS
|
|
10189
|
+
const parsedUrl = new URL(downloadUrl);
|
|
10190
|
+
if (parsedUrl.protocol !== "https:") {
|
|
10191
|
+
return {
|
|
10192
|
+
success: false,
|
|
10193
|
+
error: `Dashboard downloads must use HTTPS. Refusing: ${downloadUrl}`,
|
|
10194
|
+
};
|
|
10195
|
+
}
|
|
10196
|
+
|
|
10197
|
+
console.log(
|
|
10198
|
+
`[DashboardConfigController] Fetching dashboard from: ${downloadUrl}`,
|
|
10026
10199
|
);
|
|
10027
10200
|
|
|
10028
|
-
|
|
10201
|
+
const response = await fetch(downloadUrl);
|
|
10202
|
+
if (!response.ok) {
|
|
10029
10203
|
return {
|
|
10030
10204
|
success: false,
|
|
10031
|
-
error: `Failed to
|
|
10205
|
+
error: `Failed to download dashboard: ${response.status} ${response.statusText}`,
|
|
10032
10206
|
};
|
|
10033
10207
|
}
|
|
10034
10208
|
|
|
10035
|
-
|
|
10036
|
-
const
|
|
10037
|
-
type: p.type,
|
|
10038
|
-
providerClass: p.providerClass,
|
|
10039
|
-
required: p.required,
|
|
10040
|
-
usedBy: p.usedBy,
|
|
10041
|
-
}));
|
|
10209
|
+
const buffer = await response.arrayBuffer();
|
|
10210
|
+
const zip = new AdmZip(Buffer.from(buffer));
|
|
10042
10211
|
|
|
10043
|
-
|
|
10044
|
-
|
|
10212
|
+
// 3. Validate ZIP entries
|
|
10213
|
+
const tempDir = path.join(app.getPath("temp"), "dash-registry-import");
|
|
10214
|
+
const { validateZipEntries } = widgetRegistryExports;
|
|
10215
|
+
validateZipEntries(zip, tempDir);
|
|
10216
|
+
|
|
10217
|
+
// 4. Find and parse .dashboard.json
|
|
10218
|
+
const entries = zip.getEntries();
|
|
10219
|
+
const configEntry = entries.find((e) =>
|
|
10220
|
+
e.entryName.endsWith(".dashboard.json"),
|
|
10045
10221
|
);
|
|
10046
10222
|
|
|
10047
|
-
|
|
10048
|
-
|
|
10049
|
-
|
|
10050
|
-
|
|
10051
|
-
|
|
10052
|
-
|
|
10053
|
-
|
|
10054
|
-
|
|
10055
|
-
|
|
10056
|
-
|
|
10223
|
+
if (!configEntry) {
|
|
10224
|
+
return {
|
|
10225
|
+
success: false,
|
|
10226
|
+
error: "No .dashboard.json file found in downloaded archive",
|
|
10227
|
+
};
|
|
10228
|
+
}
|
|
10229
|
+
|
|
10230
|
+
const configJson = configEntry.getData().toString("utf-8");
|
|
10231
|
+
let dashboardConfig;
|
|
10232
|
+
try {
|
|
10233
|
+
dashboardConfig = JSON.parse(configJson);
|
|
10234
|
+
} catch (parseError) {
|
|
10235
|
+
return {
|
|
10236
|
+
success: false,
|
|
10237
|
+
error: `Invalid JSON in dashboard config: ${parseError.message}`,
|
|
10238
|
+
};
|
|
10239
|
+
}
|
|
10240
|
+
|
|
10241
|
+
// 5. Validate against schema
|
|
10242
|
+
const validation = validateDashboardConfig(dashboardConfig);
|
|
10243
|
+
if (!validation.valid) {
|
|
10244
|
+
return {
|
|
10245
|
+
success: false,
|
|
10246
|
+
error: `Invalid dashboard config: ${validation.errors.join(", ")}`,
|
|
10247
|
+
};
|
|
10248
|
+
}
|
|
10249
|
+
|
|
10250
|
+
dashboardConfig = applyDefaults(dashboardConfig);
|
|
10251
|
+
|
|
10252
|
+
// 6. Delegate to shared import pipeline
|
|
10253
|
+
return await processDashboardConfig(
|
|
10254
|
+
win,
|
|
10255
|
+
appId,
|
|
10256
|
+
dashboardConfig,
|
|
10257
|
+
widgetRegistry,
|
|
10258
|
+
{
|
|
10259
|
+
source: "registry",
|
|
10057
10260
|
},
|
|
10058
|
-
|
|
10261
|
+
);
|
|
10059
10262
|
} catch (error) {
|
|
10060
10263
|
console.error(
|
|
10061
|
-
"[DashboardConfigController] Error
|
|
10264
|
+
"[DashboardConfigController] Error installing dashboard from registry:",
|
|
10062
10265
|
error,
|
|
10063
10266
|
);
|
|
10064
10267
|
return {
|
|
@@ -10071,6 +10274,7 @@ async function importDashboardConfig$1(win, appId, widgetRegistry = null) {
|
|
|
10071
10274
|
var dashboardConfigController$1 = {
|
|
10072
10275
|
exportDashboardConfig: exportDashboardConfig$1,
|
|
10073
10276
|
importDashboardConfig: importDashboardConfig$1,
|
|
10277
|
+
installDashboardFromRegistry: installDashboardFromRegistry$1,
|
|
10074
10278
|
};
|
|
10075
10279
|
|
|
10076
10280
|
/**
|
|
@@ -10162,6 +10366,7 @@ const { install: pluginInstall } = pluginController_1;
|
|
|
10162
10366
|
const {
|
|
10163
10367
|
exportDashboardConfig,
|
|
10164
10368
|
importDashboardConfig,
|
|
10369
|
+
installDashboardFromRegistry,
|
|
10165
10370
|
} = dashboardConfigController$1;
|
|
10166
10371
|
|
|
10167
10372
|
var controller = {
|
|
@@ -10207,6 +10412,7 @@ var controller = {
|
|
|
10207
10412
|
searchIndex,
|
|
10208
10413
|
exportDashboardConfig,
|
|
10209
10414
|
importDashboardConfig,
|
|
10415
|
+
installDashboardFromRegistry,
|
|
10210
10416
|
};
|
|
10211
10417
|
|
|
10212
10418
|
const { ipcRenderer: ipcRenderer$i } = require$$0$1;
|
|
@@ -11182,6 +11388,25 @@ const registryApi$2 = {
|
|
|
11182
11388
|
throw error;
|
|
11183
11389
|
}
|
|
11184
11390
|
},
|
|
11391
|
+
|
|
11392
|
+
/**
|
|
11393
|
+
* Search the registry for dashboard packages only
|
|
11394
|
+
* @param {string} query - Search query
|
|
11395
|
+
* @param {Object} filters - Optional filters { category, author, tag, compatibleWidgets }
|
|
11396
|
+
* @returns {Promise<Object>} { packages: [...], totalWidgets: number }
|
|
11397
|
+
*/
|
|
11398
|
+
searchDashboards: async (query = "", filters = {}) => {
|
|
11399
|
+
try {
|
|
11400
|
+
return await ipcRenderer$9.invoke(
|
|
11401
|
+
"registry:search-dashboards",
|
|
11402
|
+
query,
|
|
11403
|
+
filters,
|
|
11404
|
+
);
|
|
11405
|
+
} catch (error) {
|
|
11406
|
+
console.error("[RegistryApi] Error searching dashboards:", error);
|
|
11407
|
+
throw error;
|
|
11408
|
+
}
|
|
11409
|
+
},
|
|
11185
11410
|
};
|
|
11186
11411
|
|
|
11187
11412
|
var registryApi_1 = registryApi$2;
|
|
@@ -11564,36 +11789,52 @@ var clientCacheApi_1 = clientCacheApi$2;
|
|
|
11564
11789
|
|
|
11565
11790
|
const { ipcRenderer: ipcRenderer$1 } = require$$0$1;
|
|
11566
11791
|
const {
|
|
11567
|
-
|
|
11568
|
-
|
|
11792
|
+
DASHBOARD_CONFIG_EXPORT,
|
|
11793
|
+
DASHBOARD_CONFIG_IMPORT,
|
|
11794
|
+
DASHBOARD_CONFIG_INSTALL,
|
|
11569
11795
|
} = events$8;
|
|
11570
11796
|
|
|
11571
11797
|
const dashboardConfigApi$2 = {
|
|
11572
|
-
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
|
|
11576
|
-
|
|
11577
|
-
|
|
11578
|
-
|
|
11579
|
-
|
|
11580
|
-
|
|
11581
|
-
|
|
11582
|
-
|
|
11583
|
-
|
|
11584
|
-
|
|
11585
|
-
|
|
11586
|
-
|
|
11587
|
-
|
|
11588
|
-
|
|
11589
|
-
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
11595
|
-
|
|
11596
|
-
|
|
11798
|
+
/**
|
|
11799
|
+
* Export a workspace as a dashboard config ZIP file.
|
|
11800
|
+
*
|
|
11801
|
+
* @param {string} appId - Application identifier
|
|
11802
|
+
* @param {number|string} workspaceId - ID of the workspace to export
|
|
11803
|
+
* @param {Object} options - Export options (authorName, authorId, description, tags, icon)
|
|
11804
|
+
* @returns {Promise<Object>} Result with success, filePath, and config
|
|
11805
|
+
*/
|
|
11806
|
+
exportDashboardConfig: (appId, workspaceId, options = {}) =>
|
|
11807
|
+
ipcRenderer$1.invoke(DASHBOARD_CONFIG_EXPORT, {
|
|
11808
|
+
appId,
|
|
11809
|
+
workspaceId,
|
|
11810
|
+
options,
|
|
11811
|
+
}),
|
|
11812
|
+
|
|
11813
|
+
/**
|
|
11814
|
+
* Import a dashboard config from a ZIP file.
|
|
11815
|
+
* Shows a file picker, validates the config, installs missing widgets,
|
|
11816
|
+
* creates the workspace, and applies event wiring.
|
|
11817
|
+
*
|
|
11818
|
+
* @param {string} appId - Application identifier
|
|
11819
|
+
* @returns {Promise<Object>} Result with success, workspace, and summary
|
|
11820
|
+
*/
|
|
11821
|
+
importDashboardConfig: (appId) =>
|
|
11822
|
+
ipcRenderer$1.invoke(DASHBOARD_CONFIG_IMPORT, { appId }),
|
|
11823
|
+
|
|
11824
|
+
/**
|
|
11825
|
+
* Install a dashboard from the registry by package name.
|
|
11826
|
+
* Fetches the dashboard ZIP, validates config, installs widgets,
|
|
11827
|
+
* creates workspace, and applies event wiring.
|
|
11828
|
+
*
|
|
11829
|
+
* @param {string} appId - Application identifier
|
|
11830
|
+
* @param {string} packageName - Registry package name
|
|
11831
|
+
* @returns {Promise<Object>} Result with success, workspace, and summary
|
|
11832
|
+
*/
|
|
11833
|
+
installDashboardFromRegistry: (appId, packageName) =>
|
|
11834
|
+
ipcRenderer$1.invoke(DASHBOARD_CONFIG_INSTALL, {
|
|
11835
|
+
appId,
|
|
11836
|
+
packageName,
|
|
11837
|
+
}),
|
|
11597
11838
|
};
|
|
11598
11839
|
|
|
11599
11840
|
var dashboardConfigApi_1 = dashboardConfigApi$2;
|