add support for multiple spaces
This commit is contained in:
parent
7988853b57
commit
351c4e4ef4
10 changed files with 498 additions and 92 deletions
205
src/blocks/sigma/sigma_search_results_block.js
Normal file
205
src/blocks/sigma/sigma_search_results_block.js
Normal file
|
@ -0,0 +1,205 @@
|
|||
/**
|
||||
* sigma_search_results_block.js
|
||||
*
|
||||
* Generates Slack Block Kit blocks for displaying Sigma rule search results
|
||||
* Includes pagination controls for navigating large result sets
|
||||
*
|
||||
*/
|
||||
const logger = require('../../utils/logger');
|
||||
|
||||
const { getFileName } = require('../../utils/file_utils');
|
||||
const FILE_NAME = getFileName(__filename);
|
||||
|
||||
/**
|
||||
* Generate blocks for Slack UI to display search results with pagination
|
||||
*
|
||||
* @param {string} keyword - The search keyword used for the query
|
||||
* @param {Array} results - Array of rule results from the search
|
||||
* @param {Object} pagination - Pagination information object
|
||||
* @returns {Array} - Slack blocks for displaying results
|
||||
*/
|
||||
const getSearchResultBlocks = (keyword, results, pagination = {}) => {
|
||||
|
||||
logger.debug(`${FILE_NAME}: Creating search result blocks for keyword: "${keyword}"`);
|
||||
|
||||
// Add debug for input validation
|
||||
logger.debug(`${FILE_NAME}: Results type: ${typeof results}, isArray: ${Array.isArray(results)}, length: ${Array.isArray(results) ? results.length : 'N/A'}`);
|
||||
logger.debug(`${FILE_NAME}: Pagination: ${JSON.stringify(pagination)}`);
|
||||
|
||||
// Ensure results is always an array
|
||||
const safeResults = Array.isArray(results) ? results : [];
|
||||
|
||||
// Default pagination values if not provided
|
||||
const pagingInfo = {
|
||||
currentPage: pagination.currentPage || 1,
|
||||
pageSize: pagination.pageSize || 10,
|
||||
totalPages: pagination.totalPages || 0,
|
||||
totalResults: pagination.totalResults || 0,
|
||||
hasMore: pagination.hasMore || false
|
||||
};
|
||||
|
||||
logger.debug(`${FILE_NAME}: Processing ${safeResults.length} search results (page ${pagingInfo.currentPage} of ${pagingInfo.totalPages}, total: ${pagingInfo.totalResults})`);
|
||||
|
||||
// Initialize with header block that includes pagination info
|
||||
const blocks = [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": `*Search Results for "${keyword}"*\n${
|
||||
pagingInfo.totalResults > 0
|
||||
? `Showing ${safeResults.length} of ${pagingInfo.totalResults} matching rules (page ${pagingInfo.currentPage} of ${pagingInfo.totalPages})`
|
||||
: `Found ${safeResults.length} matching rules:`
|
||||
}`
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// Debug log as we build blocks
|
||||
logger.debug(`${FILE_NAME}: Added header block`);
|
||||
|
||||
// Add blocks for each result if we have any
|
||||
if (safeResults.length === 0) {
|
||||
logger.debug(`${FILE_NAME}: No search results to display`);
|
||||
blocks.push({
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": pagingInfo.totalResults > 0
|
||||
? "No rules on this page. Try a different page."
|
||||
: "No matching rules found."
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logger.debug(`${FILE_NAME}: Creating blocks for ${safeResults.length} search results`);
|
||||
safeResults.forEach((rule, index) => {
|
||||
// Ensure rule is an object with expected properties
|
||||
const safeRule = rule || {};
|
||||
const ruleId = safeRule.id || 'unknown';
|
||||
logger.debug(`${FILE_NAME}: Adding result #${index + 1}: ${ruleId} - ${safeRule.title || 'Untitled'}`);
|
||||
|
||||
// Combine rule information and action button into a single line
|
||||
blocks.push({
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": `*${safeRule.title || 'Untitled Rule'}*\nID: \`${ruleId}\``
|
||||
},
|
||||
"accessory": {
|
||||
"type": "button",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "Details",
|
||||
"emoji": true
|
||||
},
|
||||
"value": ruleId,
|
||||
"action_id": "view_rule_details"
|
||||
}
|
||||
});
|
||||
|
||||
// Add a divider between results (except after the last one)
|
||||
if (index < safeResults.length - 1) {
|
||||
blocks.push({
|
||||
"type": "divider"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Debug log for pagination controls
|
||||
logger.debug(`${FILE_NAME}: Checking if pagination controls needed (totalPages: ${pagingInfo.totalPages})`);
|
||||
|
||||
// Add pagination navigation if there are multiple pages
|
||||
if (pagingInfo.totalPages > 1) {
|
||||
// Add a divider before pagination controls
|
||||
blocks.push({
|
||||
"type": "divider"
|
||||
});
|
||||
|
||||
// Create pagination navigation buttons
|
||||
const paginationButtons = [];
|
||||
|
||||
// Previous page button (if not on first page)
|
||||
if (pagingInfo.currentPage > 1) {
|
||||
paginationButtons.push({
|
||||
"type": "button",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "Previous",
|
||||
"emoji": true
|
||||
},
|
||||
"value": JSON.stringify({
|
||||
keyword,
|
||||
page: pagingInfo.currentPage - 1,
|
||||
pageSize: pagingInfo.pageSize
|
||||
}),
|
||||
"action_id": "search_prev_page"
|
||||
});
|
||||
logger.debug(`${FILE_NAME}: Added Previous page button for page ${pagingInfo.currentPage - 1}`);
|
||||
}
|
||||
|
||||
// Next page button (if there are more pages)
|
||||
if (pagingInfo.hasMore) {
|
||||
paginationButtons.push({
|
||||
"type": "button",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "Next",
|
||||
"emoji": true
|
||||
},
|
||||
"value": JSON.stringify({
|
||||
keyword,
|
||||
page: pagingInfo.currentPage + 1,
|
||||
pageSize: pagingInfo.pageSize
|
||||
}),
|
||||
"action_id": "search_next_page"
|
||||
});
|
||||
logger.debug(`${FILE_NAME}: Added Next page button for page ${pagingInfo.currentPage + 1}`);
|
||||
}
|
||||
|
||||
// Add the pagination buttons block if we have buttons to show
|
||||
if (paginationButtons.length > 0) {
|
||||
blocks.push({
|
||||
"type": "actions",
|
||||
"elements": paginationButtons
|
||||
});
|
||||
logger.debug(`${FILE_NAME}: Added ${paginationButtons.length} pagination buttons`);
|
||||
}
|
||||
|
||||
// Add page indicator text
|
||||
blocks.push({
|
||||
"type": "context",
|
||||
"elements": [
|
||||
{
|
||||
"type": "plain_text",
|
||||
"text": `Page ${pagingInfo.currentPage} of ${pagingInfo.totalPages}`,
|
||||
"emoji": true
|
||||
}
|
||||
]
|
||||
});
|
||||
logger.debug(`${FILE_NAME}: Added page indicator text`);
|
||||
}
|
||||
|
||||
logger.debug(`${FILE_NAME}: Created ${blocks.length} blocks for search results`);
|
||||
|
||||
// Final validation of blocks array
|
||||
if (!Array.isArray(blocks) || blocks.length === 0) {
|
||||
logger.error(`${FILE_NAME}: Generated blocks is not a valid array or is empty`);
|
||||
// Return a minimal valid blocks array
|
||||
return [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": `Search Results for "${keyword}": Unable to generate proper blocks. Please try again.`
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
return blocks;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getSearchResultBlocks
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue