Skip to content

Commit 00325bf

Browse files
committed
Chart for incs by categories over weeks
1 parent 985f30c commit 00325bf

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

app/db.js

+33
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,39 @@ export async function getIncNumberByWeek(numberOfDaysAgo) {
117117
return await client.query(queryText);
118118
}
119119

120+
export async function getIncCountForCategoryByWeek(category, numberOfDaysAgo) {
121+
let queryText;
122+
123+
if (numberOfDaysAgo === undefined) {
124+
queryText = `
125+
SELECT DATE_TRUNC('week', created_at) AS week, COUNT(*) AS count
126+
FROM incs
127+
WHERE category = $1
128+
GROUP BY week
129+
ORDER BY week;
130+
`;
131+
} else {
132+
// Calculate the date range
133+
const dateAgo = new Date();
134+
dateAgo.setDate(dateAgo.getDate() - numberOfDaysAgo);
135+
const formattedDateAgo = dateAgo.toISOString(); // ISO8601 format
136+
137+
// Construct the SQL query with parameterized query
138+
queryText = {
139+
text: `
140+
SELECT DATE_TRUNC('week', created_at) AS week, COUNT(*) AS count
141+
FROM incs
142+
WHERE category = $1 AND created_at >= $2
143+
GROUP BY week
144+
ORDER BY week;
145+
`,
146+
values: [category, formattedDateAgo],
147+
};
148+
}
149+
150+
return await client.query(queryText);
151+
}
152+
120153
export async function getCategoriesArray() {
121154
try {
122155
const result = await client.query("SELECT name FROM categories");

app/server.js

+130
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
getIncByCategory,
88
getCategoriesArray,
99
addCategory,
10+
getIncCountForCategoryByWeek
1011
} from "./db.js";
1112
import QuickChart from "quickchart-js";
1213

@@ -175,13 +176,26 @@ app.command("/inc_stats", async ({ ack, body, client }) => {
175176
const chartUrlByWeek = await generateIncByWeekChart(numberOfDays);
176177
const chartUrlByCategory = await generateIncByCategoryChart(numberOfDays);
177178

179+
const categories = await getCategoriesArray();
180+
181+
182+
// Format the options
183+
const categoryOptions = categories.map((category) => ({
184+
text: {
185+
type: "plain_text",
186+
text: category,
187+
},
188+
value: category,
189+
}));
190+
178191
// Post a response in the channel where the command was invoked
179192
try {
180193
await client.views.open({
181194
trigger_id: body.trigger_id,
182195
view: {
183196
type: "modal",
184197
callback_id: "inc_stats_modal",
198+
private_metadata: JSON.stringify({ numberOfDays }), // Store the number of days in the metadata
185199
title: {
186200
type: "plain_text",
187201
text: `Inc stats ${numberOfDays ? `siste ${numberOfDays} dager` : ""}`,
@@ -205,6 +219,23 @@ app.command("/inc_stats", async ({ ack, body, client }) => {
205219
image_url: chartUrlByWeek,
206220
alt_text: "Incidents per Week",
207221
},
222+
{
223+
type: "input",
224+
block_id: "category_select",
225+
element: {
226+
type: "static_select",
227+
action_id: "category_select_modal",
228+
placeholder: {
229+
type: "plain_text",
230+
text: "Select a category",
231+
},
232+
options: categoryOptions,
233+
},
234+
label: {
235+
type: "plain_text",
236+
text: "Category",
237+
},
238+
},
208239
],
209240
},
210241
});
@@ -213,6 +244,64 @@ app.command("/inc_stats", async ({ ack, body, client }) => {
213244
}
214245
});
215246

247+
app.action("category_select_modal", async ({ ack, body, client }) => {
248+
await ack();
249+
250+
const selectedCategory = body.actions[0].selected_option.value;
251+
const numberOfDays = body?.view?.metadata?.numberOfDays;
252+
const chartUrl = await generateIncByCategoryOverWeeksChart(selectedCategory, numberOfDays);
253+
254+
try {
255+
await client.views.update({
256+
view_id: body.view.id,
257+
view: {
258+
type: "modal",
259+
callback_id: "inc_stats_modal",
260+
private_metadata: JSON.stringify({ numberOfDays }), // Store the number of days in the metadata
261+
title: {
262+
type: "plain_text",
263+
text: "Inc stats",
264+
},
265+
blocks: [
266+
...body.view.blocks.filter(block => block.block_id !== "chart_block_category_by_week"),
267+
{
268+
type: "input",
269+
block_id: "category_select",
270+
element: {
271+
type: "static_select",
272+
action_id: "category",
273+
placeholder: {
274+
type: "plain_text",
275+
text: "Select a category",
276+
},
277+
options: body.view.blocks[0].element.options,
278+
initial_option: {
279+
text: {
280+
type: "plain_text",
281+
text: selectedCategory,
282+
},
283+
value: selectedCategory,
284+
},
285+
},
286+
label: {
287+
type: "plain_text",
288+
text: "Category",
289+
},
290+
},
291+
{
292+
type: "image",
293+
block_id: "chart_block_category_by_week",
294+
image_url: chartUrl,
295+
alt_text: "Incidents per Week",
296+
},
297+
],
298+
},
299+
});
300+
} catch (error) {
301+
console.error("Error updating modal:", error);
302+
}
303+
});
304+
216305
(async () => {
217306
await app.start(process.env.PORT || 3000);
218307
console.log("⚡️ Bolt app started");
@@ -301,3 +390,44 @@ async function generateIncByCategoryChart(numberOfDays) {
301390
console.log("url", chart.getUrl());
302391
return chart.getUrl();
303392
}
393+
394+
async function generateIncByCategoryOverWeeksChart(category, numberOfDays) {
395+
const dbResponse = await getIncCountForCategoryByWeek(category, numberOfDays);
396+
397+
const labels = dbResponse.rows.map((row) => row.category);
398+
const data = dbResponse.rows.map((row) => parseInt(row.count, 10));
399+
400+
// Generate the bar chart URL using QuickChart
401+
const chart = new QuickChart();
402+
chart.setConfig({
403+
type: "line",
404+
data: {
405+
labels: labels,
406+
datasets: [
407+
{
408+
label: `Incidents for ${category}`,
409+
data: data,
410+
backgroundColor: "rgba(75, 192, 192, 0.2)",
411+
borderColor: "rgba(75, 192, 192, 1)",
412+
borderWidth: 1,
413+
},
414+
],
415+
},
416+
options: {
417+
scales: {
418+
yAxes: [{
419+
ticks: {
420+
beginAtZero: true,
421+
min: 0,
422+
stepSize: 1,
423+
precision: 0
424+
}
425+
}]
426+
}
427+
}
428+
});
429+
chart.setWidth(800);
430+
chart.setHeight(400);
431+
console.log("url", chart.getUrl());
432+
return chart.getUrl();
433+
}

0 commit comments

Comments
 (0)