Merge branch 'develop' into feat/dev-settings

This commit is contained in:
Alexander Holliday
2025-06-21 18:00:23 +08:00
committed by GitHub
8 changed files with 238 additions and 14 deletions
+37 -1
View File
@@ -681,7 +681,7 @@ class MonitorController {
explain,
});
return res.success({
msg: "OK", // TODO
msg: "OK",
data: result,
});
} catch (error) {
@@ -698,6 +698,42 @@ class MonitorController {
next(handleError(error, SERVICE_NAME, "seedDb"));
}
};
exportMonitorsToCSV = async (req, res, next) => {
try {
const { teamId } = req.user;
const monitors = await this.db.getMonitorsByTeamId({ teamId });
if (!monitors || monitors.length === 0) {
return res.success({
msg: this.stringService.noMonitorsFound,
data: null,
});
}
const csvData = monitors?.filteredMonitors?.map((monitor) => ({
name: monitor.name,
description: monitor.description,
type: monitor.type,
url: monitor.url,
interval: monitor.interval,
port: monitor.port,
ignoreTlsErrors: monitor.ignoreTlsErrors,
isActive: monitor.isActive,
}));
const csv = pkg.unparse(csvData);
return res.file({
data: csv,
headers: {
"Content-Type": "text/csv",
"Content-Disposition": "attachment; filename=monitors.csv",
},
});
} catch (error) {
next(handleError(error, SERVICE_NAME, "exportMonitorsToCSV"));
}
};
}
export default MonitorController;
+21 -1
View File
@@ -16,7 +16,12 @@ const responseHandler = (req, res, next) => {
* @param {*} [options.data=null] - Response data payload
* @returns {Object} Express response object
*/
res.success = ({ status = 200, msg = "OK", data = null }) => {
res.success = ({ status = 200, msg = "OK", data = null, headers = {} }) => {
// Set custom headers if provided
Object.entries(headers).forEach(([key, value]) => {
res.set(key, value);
});
return res.status(status).json({
success: true,
msg: msg,
@@ -40,6 +45,21 @@ const responseHandler = (req, res, next) => {
data,
});
};
/**
* Sends a raw file response (for CSV, PDF, etc.)
* @param {Object} options
* @param {Buffer|string} options.data - The file content
* @param {Object} options.headers - Headers to set (e.g. Content-Type, Content-Disposition)
* @param {number} [options.status=200] - HTTP status code
*/
res.file = ({ data, headers = {}, status = 200 }) => {
Object.entries(headers).forEach(([key, value]) => {
res.setHeader(key, value);
});
return res.status(status).send(data);
};
next();
};
+5
View File
@@ -17,6 +17,11 @@ class MonitorRoutes {
initRoutes() {
this.router.get("/", this.monitorController.getAllMonitors);
this.router.get("/uptime", this.monitorController.getAllMonitorsWithUptimeStats);
this.router.get(
"/export",
isAllowed(["admin", "superadmin"]),
this.monitorController.exportMonitorsToCSV
);
this.router.get("/stats/:monitorId", this.monitorController.getMonitorStatsById);
this.router.get(
"/hardware/details/:monitorId",