• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

statuscompliance / status-backend / 15132641868

20 May 2025 08:26AM UTC coverage: 53.287% (+0.4%) from 52.927%
15132641868

push

github

alvarobernal2412
test(scopes): added model

363 of 758 branches covered (47.89%)

Branch coverage included in aggregate %.

950 of 1706 relevant lines covered (55.69%)

8.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/controllers/dashboard.controller.js
1
import { methods } from '../config/grafana.js';
2
import { models } from '../models/models.js';
3
import createPanelTemplate from '../utils/panelStructures.js';
4
import { getSQLFromSequelize } from '../utils/sqlQueryBuilder.js';
5
import { handleControllerError } from '../utils/errorHandler.js';
6

7
export async function createDashboard(req, res) {
8
  try {
×
9
    const response = await methods.dashboard.postDashboard({
×
10
      dashboard: {
11
        annotations: req.body.dashboard.annotations || {
×
12
          list: [],
13
        },
14
        editable: req.body.dashboard.editable || true,
×
15
        fiscalYearStartMonth:
16
                    req.body.dashboard.fiscalYearStartMonth || 0,
×
17
        graphTooltip: req.body.dashboard.graphTooltip || 0,
×
18
        id: null,
19
        links: [],
20
        panels: req.body.dashboard.panels,
21
        schemaVersion: req.body.dashboard.schemaVersion || 16,
×
22
        tags: req.body.dashboard.tags || [],
×
23
        templating: req.body.dashboard.templating || {
×
24
          list: [],
25
        },
26
        time: req.body.dashboard.time || {
×
27
          from: 'now-6h',
28
          to: 'now',
29
        },
30
        timepicker: req.body.dashboard.timepicker || {},
×
31
        timezone: req.body.dashboard.timezone || 'browser',
×
32
        title: req.body.dashboard.title,
33
        version: req.body.dashboard.version || 0,
×
34
        weekStart: req.body.dashboard.weekStart || '',
×
35
      },
36
      overwrite: req.body.overwrite || true,
×
37
      inputs: req.body.inputs || [],
×
38
      folderUid: req.body.folderUid,
39
      message: 'Dashboard created successfully',
40
    });
41
    return res.status(201).json(response.data);
×
42
  } catch (error) {
43
    return handleControllerError(res, error, 'Failed to create dashboard in Grafana');
×
44
  }
45
}
46

47
export async function importDashboard(req, res) {
48
  try {
×
49
    const response = await methods.dashboard.importDashboard({
×
50
      dashboard: {
51
        annotations: req.body.dashboard.annotations || {
×
52
          list: [],
53
        },
54
        editable: req.body.dashboard.editable || true,
×
55
        fiscalYearStartMonth:
56
                    req.body.dashboard.fiscalYearStartMonth || 0,
×
57
        graphTooltip: req.body.dashboard.graphTooltip || 0,
×
58
        id: null,
59
        links: [],
60
        panels: req.body.dashboard.panels,
61
        schemaVersion: req.body.dashboard.schemaVersion || 16,
×
62
        tags: req.body.dashboard.tags || [],
×
63
        templating: req.body.dashboard.templating || {
×
64
          list: [],
65
        },
66
        time: req.body.dashboard.time || {
×
67
          from: 'now-6h',
68
          to: 'now',
69
        },
70
        timepicker: req.body.dashboard.timepicker || {},
×
71
        timezone: req.body.dashboard.timezone || 'browser',
×
72
        title: req.body.dashboard.title,
73
        version: req.body.dashboard.version || 0,
×
74
        weekStart: req.body.dashboard.weekStart || '',
×
75
      },
76
      overwrite: req.body.overwrite || true,
×
77
      inputs: req.body.inputs || [],
×
78
      folderUid: req.body.folderUid,
79
    });
80
    return res.status(201).json(response.data);
×
81
  } catch (error) {
82
    return handleControllerError(res, error, 'Failed to import dashboard in Grafana');
×
83
  }
84
}
85

86
export async function getDashboardByUID(req, res) {
87
  try {
×
88
    const response = await methods.dashboard.getDashboardByUID(
×
89
      req.params.uid
90
    );
91
    return res.status(200).json(response.data);
×
92
  } catch (error) {
93
    return handleControllerError(res, error, 'Failed to retrieve dashboard in Grafana');
×
94
  }
95
}
96

97
export async function deleteDashboardByUID(req, res) {
98
  try {
×
99
    const response = await methods.dashboard.deleteDashboardByUID(
×
100
      req.params.uid
101
    );
102
    return res.status(200).json(response.data);
×
103
  } catch (error) {
104
    return handleControllerError(res, error, 'Failed to delete dashboard in Grafana');
×
105
  }
106
}
107

108
export async function createDashboardTemplate(req, res) {
109
  try {
×
110
    const { name, folderId, startDate, endDate } = req.body;
×
111

112
    // Set time range based on startDate and endDate parameters
113
    let timeRange = {
×
114
      from: 'now-6h',
115
      to: 'now'
116
    };
117

118
    if (startDate) {
×
119
      const startDateObj = new Date(startDate);
×
120
      timeRange.from = startDateObj.toISOString();
×
121
    }
122

123
    if (endDate) {
×
124
      const endDateObj = new Date(endDate);
×
125
      timeRange.to = endDateObj.toISOString();
×
126
    }
127

128
    const dashboardTemplate = {
×
129
      dashboard: {
130
        annotations: {
131
          list: []
132
        },
133
        editable: true,
134
        fiscalYearStartMonth: 0,
135
        graphTooltip: 0,
136
        panels: [],
137
        schemaVersion: 27,
138
        tags: [],
139
        templating: {
140
          list: []
141
        },
142
        time: timeRange,
143
        timepicker: null,
144
        timezone: 'browser',
145
        title: name || 'New Dashboard Template',
×
146
        version: 0,
147
        weekStart: ''
148
      },
149
      overwrite: false,
150
      inputs: [{}],
151
      folderUid: folderId || null
×
152
    };
153

154
    const response = await methods.dashboard.postDashboard(dashboardTemplate);
×
155
    return res.status(201).json({
×
156
      message: 'Dashboard template created successfully',
157
      dashboard: response.data
158
    });
159
  } catch (error) {
160
    return handleControllerError(res, error, 'Failed to create dashboard template in Grafana');
×
161
  }
162
}
163

164
export async function createTemporaryDashboard(req, res) {
165
  try {
×
166
    const { panelConfig, baseDashboardUid, timeRange, autoCleanup } = req.body;
×
167
    let title = req.body.title;
×
168
    
169
    if (baseDashboardUid) {
×
170
      title = `tmp-${baseDashboardUid}`;
×
171
    } else {
172
      title = title || `tmp-${new Date().toISOString()}`;
×
173
    }
174
    
175
    let dashboardTemplate = {
×
176
      annotations: { list: [] },
177
      editable: true,
178
      fiscalYearStartMonth: 0,
179
      graphTooltip: 0,
180
      panels: [],
181
      schemaVersion: 27,
182
      tags: ['temp', 'preview'],
183
      templating: { list: [] },
184
      time: timeRange || { from: 'now-6h', to: 'now' },
×
185
      timepicker: {},
186
      timezone: 'browser',
187
      title: title,
188
      version: 0,
189
      weekStart: '',
190
      refresh: '5s'
191
    };
192

193
    if (baseDashboardUid) {
×
194
      try {
×
195
        const baseResponse = await methods.dashboard.getDashboardByUID(baseDashboardUid);
×
196
        if (baseResponse.data && baseResponse.data.dashboard) {
×
197
          const baseDashboard = baseResponse.data.dashboard;
×
198
          dashboardTemplate = {
×
199
            ...baseDashboard,
200
            id: null,
201
            uid: null,
202
            title: title,
203
            tags: [...(baseDashboard.tags || []), 'temp', 'preview'],
×
204
            panels: []
205
          };
206
        }
207
      } catch (error) {
208
        console.warn('Error while fetching base dashboard', error.message);
×
209
      }
210
    }
211

212
    if (panelConfig) {
×
213
      try {
×
214
        const newPanel = createPanelTemplate(panelConfig.type || 'gauge');
×
215
        newPanel.id = 1;
×
216
        newPanel.title = panelConfig.title || 'Panel Preview';
×
217
        newPanel.gridPos = panelConfig.gridPos || { x: 0, y: 0, w: 24, h: 15 };
×
218
        if (panelConfig.displayName) {
×
219
          newPanel.fieldConfig.defaults.displayName = panelConfig.displayName;
×
220
        }
221
        if (panelConfig.targets) {
×
222
          newPanel.targets = panelConfig.targets;
×
223
        } else if (panelConfig.sqlQuery && newPanel.targets && newPanel.targets.length > 0) {
×
224
          const { model, operation, options } = panelConfig.sqlQuery;
×
225
          const generatedSQLquery = await getSQLFromSequelize(
×
226
            models[model],
227
            operation,
228
            options
229
          );
230
          newPanel.targets[0].rawSql = typeof panelConfig.sqlQuery === 'string'
×
231
            ? panelConfig.sqlQuery
232
            : generatedSQLquery;
233
          newPanel.targets[0].table = panelConfig.table || 'Points';
×
234
        }
235
        dashboardTemplate.panels.push(newPanel);
×
236
      } catch (error) {
237
        return res.status(400).json({
×
238
          message: error.message || `Panel type "${panelConfig.type}" is not supported`,
×
239
        });
240
      }
241
    }
242

243
    const dashboardData = {
×
244
      dashboard: dashboardTemplate,
245
      overwrite: false,
246
      message: 'Temporary dashboard created successfully',
247
      folderUid: null,
248
      refresh: '5s'
249
    };
250
    const response = await methods.dashboard.postDashboard(dashboardData);
×
251

252
    return res.status(201).json({
×
253
      message: 'Temporary dashboard created successfully',
254
      dashboard: response.data,
255
      isTemporary: true,
256
      created: new Date().toISOString(),
257
      autoCleanup: autoCleanup !== false
258
    });
259
  } catch (error) {
260
    return handleControllerError(res, error, 'Error creating temporary dashboard in Grafana');
×
261
  }
262
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc