diff --git a/.vscode/launch.json b/.vscode/launch.json index 099f9cf..0d8dd57 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -223,46 +223,46 @@ // ------------------------------------ // Get task tree // ------------------------------------ - // "args": [ - // "task-get", - // // "--auth-type", - // // "cert", - // "--host", - // "192.168.100.109", - // // "--auth-cert-file", - // // "./cert/client.pem", - // // "--auth-cert-key-file", - // // "./cert/client_key.pem", - // "--auth-user-dir", - // "LAB", - // "--auth-user-id", - // "goran", - // // "--task-id", - // // "82bc3e66-c899-4e44-b52f-552145da5ee0", - // // "--task-tag", - // // "Test data", - // // "--output-format", - // // "table", - // // "tree", - // // "--tree-icons", - // // "--tree-details", - // // "taskid", - // // "appname", - // // "--task-type", - // // "reload", - // // "ext-program", - - // // "--output-dest", - // // "screen", - // // "file", - // // "--output-file-name", - // // "tasks.json", - // // "--output-file-format", - // // "json", + "args": [ + "task-get", + // "--auth-type", + // "cert", + "--host", + "192.168.100.109", + // "--auth-cert-file", + // "./cert/client.pem", + // "--auth-cert-key-file", + // "./cert/client_key.pem", + "--auth-user-dir", + "LAB", + "--auth-user-id", + "goran", + // "--task-id", + // "82bc3e66-c899-4e44-b52f-552145da5ee0", + // "--task-tag", + // "Test data", + "--output-format", + // "table", + "tree", + "--tree-icons", + "--tree-details", + // "taskid", + // "appname", + "--task-type", + "reload", + "ext-program", + + // "--output-dest", + // "screen", + // "file", + // "--output-file-name", + // "tasks.json", + // "--output-file-format", + // "json", - // // "--text-color", - // // "no", - // ] + // "--text-color", + // "no", + ] // ------------------------------------ // Get reload tasks as table @@ -321,65 +321,65 @@ // ------------------------------------ // Get reload tasks as CSV/Excel/JSON file // ------------------------------------ - "args": [ - "task-get", - "--auth-type", - "cert", - "--host", - "192.168.100.109", - // "--auth-cert-file", - // "./cert/client.pem", - // "--auth-cert-key-file", - // "./cert/client_key.pem", - "--auth-user-dir", - "LAB", - "--auth-user-id", - "goran", - // "--task-id", - // "82bc3e66-c899-4e44-b52f-552145da5ee0", - // "82bc3e66-c899-4e44-b52f-552145da5ee1", - // "5748afa9-3abe-43ab-bb1f-127c48ced075", - // "5520e710-91ad-41d2-aeb6-434cafbf366b", - // "--task-tag", - // "Ctrl-Q demo", - // "Butler 5.0 demo", + // "args": [ + // "task-get", + // "--auth-type", + // "cert", + // "--host", + // "192.168.100.109", + // // "--auth-cert-file", + // // "./cert/client.pem", + // // "--auth-cert-key-file", + // // "./cert/client_key.pem", + // "--auth-user-dir", + // "LAB", + // "--auth-user-id", + // "goran", + // // "--task-id", + // // "82bc3e66-c899-4e44-b52f-552145da5ee0", + // // "82bc3e66-c899-4e44-b52f-552145da5ee1", + // // "5748afa9-3abe-43ab-bb1f-127c48ced075", + // // "5520e710-91ad-41d2-aeb6-434cafbf366b", + // // "--task-tag", + // // "Ctrl-Q demo", + // // "Butler 5.0 demo", - "--output-format", - "table", - "--output-dest", - "file", - "--output-file-name", - // "tasks.xlsx", - "tasks.csv", - // "tasks2.json", - // "tasks2.xlsx", - "--output-file-format", - // "excel", - // "json", - "csv", + // "--output-format", + // "table", + // "--output-dest", + // "file", + // "--output-file-name", + // // "tasks.xlsx", + // "tasks.csv", + // // "tasks2.json", + // // "tasks2.xlsx", + // "--output-file-format", + // // "excel", + // // "json", + // "csv", - "--output-file-name", - // "reload-tasks.xlsx", - "reload-tasks.csv", + // "--output-file-name", + // // "reload-tasks.xlsx", + // "reload-tasks.csv", - // "--text-color", - // "no", + // // "--text-color", + // // "no", - // "--output-file-overwrite", + // // "--output-file-overwrite", - "--table-details", - // "common", - // "lastexecution", - // "tag", - // "customproperty", - // "schematrigger", - // "compositetrigger", - // "comptimeconstraint", - // "comprule", + // "--table-details", + // // "common", + // // "lastexecution", + // // "tag", + // // "customproperty", + // // "schematrigger", + // // "compositetrigger", + // // "comptimeconstraint", + // // "comprule", - // "--log-level", - // "debug" - ] + // // "--log-level", + // // "debug" + // ] // ------------------------------------ // Create custom property with user activity buckets diff --git a/src/lib/cmd/gettask.js b/src/lib/cmd/gettask.js index 840b477..bc3d1db 100644 --- a/src/lib/cmd/gettask.js +++ b/src/lib/cmd/gettask.js @@ -115,8 +115,39 @@ const getTask = async (options) => { // Get all tasks that have a schedule associated with them // Schedules are represented by "meta nodes" that are linked to the task node in Ctrl-Q's internal data model + // There is one meta-node per schema trigger, meaning that a task with several schema triggers will have several top-level meta nodes. + // We only want the task to show up once in the tree, so we have do de-duplicate the top level task nodes. + const topLevelTasksWithSchemaTriggers = taskModel.nodes.filter((node) => { + if (node.metaNode && node.metaNodeType === 'schedule') { + return true; + } + // Exclude all non-meta nodes + return false; + }); + + // Remove all duplicates from the topLevelTasksWithSchemaTriggers array. + // Use completeSchemaEvent.reloadTask.id as the key to determine if the task is a duplicate or not. + const topLevelTasksWithSchemaTriggersUnique = topLevelTasksWithSchemaTriggers.filter((task, index, self) => { + // Handle reload tasks, external program tasks + if (task.completeSchemaEvent.reloadTask) { + return ( + index === self.findIndex((t) => t.completeSchemaEvent?.reloadTask?.id === task.completeSchemaEvent.reloadTask.id) + ); + } + if (task.completeSchemaEvent.externalProgramTask) { + return ( + index === + self.findIndex( + (t) => t.completeSchemaEvent?.externalProgramTask?.id === task.completeSchemaEvent.externalProgramTask.id + ) + ); + } + return false; + }); + // eslint-disable-next-line no-restricted-syntax - for (const task of taskModel.nodes) { + for (const task of topLevelTasksWithSchemaTriggersUnique) { + // for (const task of taskModel.nodes) { if (task.metaNode && task.metaNodeType === 'schedule') { const subTree = qlikSenseTasks.getTaskSubTree(task, 0); subTree[0].isTopLevelNode = true;