From 03da4c1baa5c0bfb10b06ab06feb63120452b5d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?BOURREAU=20S=C3=A9bastien?= Date: Mon, 23 Jan 2023 13:00:05 +0100 Subject: [PATCH 1/3] Add SBSD viewer --- package.json | 3 + src/objectProvider.ts | 4 + src/types/subSystem.ts | 506 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 513 insertions(+) create mode 100644 src/types/subSystem.ts diff --git a/package.json b/package.json index a5ec923..00816af 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,9 @@ }, { "filenamePattern": "object*/**/*.FILE" + }, + { + "filenamePattern": "object*/**/*.SBSD" } ], "priority": "default" diff --git a/src/objectProvider.ts b/src/objectProvider.ts index 84f037a..43e9441 100644 --- a/src/objectProvider.ts +++ b/src/objectProvider.ts @@ -7,6 +7,7 @@ import BindingDirectory from './types/bindingDirectory'; import { Command } from './types/command'; import { DataArea } from './types/dataarea'; import { DataQueue } from './types/dataqueue'; +import { SubSystem } from './types/subSystem'; import Program from './types/program'; import { SaveFile } from './types/saveFile'; import { generatePage, generateError } from './webviewToolkit'; @@ -112,6 +113,9 @@ function getTypeFile(uri: vscode.Uri): Base | undefined { if (uri.fragment.toUpperCase() === 'SAVF') { return new SaveFile(uri, library, objectName); } + + case `SBSD`: + return new SubSystem(uri, library, objectName); } } else { throw new Error(`Invalid path.`); diff --git a/src/types/subSystem.ts b/src/types/subSystem.ts new file mode 100644 index 0000000..ecc29c2 --- /dev/null +++ b/src/types/subSystem.ts @@ -0,0 +1,506 @@ +import * as vscode from 'vscode'; +import Base from "./base"; +import { Code4i } from '../tools'; + +interface SubSystemInfo { + subsystemDescriptionLibrary: string + subsystemDescription: string + status: string + maximumActiveJobs: number + currentActiveJobs: number + subsystemMonitorJob: string + textDescription: string + controllingSubsystem: string + workloadGroup: string + signonDeviceFileLibrary: string + signonDeviceFile: string + secondaryLanguageLibrary: string + iaspName: string +} + +interface ActiveJobInfo { + jobName: string + jobNameShort: string + jobUser: string + jobNumber: string + jobInformation: string + jobStatus: string + jobType: string + jobTypeEnhanced: string + jobSubsystem: string + jobDate: string + jobDescriptionLibrary: string + jobDescription: string + jobAccountingCode: string + submitterJobName: string + submitterMessageQueueLibrary: string + submitterMessageQueue: string + serverType: string + jobEnteredSystemTime: string + jobScheduledTime: string + jobActiveTime: string + jobEndTime: string + jobEndSeverity: string + completionStatus: string +} + +interface AutostartJobInfo { + subsystemDescriptionLibrary: string + subsystemDescription: string + autostartJobName: string + jobDescriptionLibrary: string + jobDescription: string +} + +interface PrestartJobInfo { + subsystemDescriptionLibrary: string + subsystemDescription: string + prestartJobProgramLibrary: string + prestartJobProgram: string + subsystemActive: string + userProfile: string + prestartJobName: string + jobDescriptionLibrary: string + jobDescription: string + startJobs: string + initialJobs: number +} + +interface RoutingEntryInfo { + subsystemDescriptionLibrary: string + subsystemDescription: string + sequenceNumber: number + programLibrary: string + programName: string + classLibrary: string + class: string + maximumSteps: number + poolId: number + comparisonData: string + comparisonStart: number +} + +export class SubSystem extends Base { + private subSystemInfo: SubSystemInfo | undefined; + private activeJobsInfo: ActiveJobInfo[] | undefined; + private autostartJobsInfo: AutostartJobInfo[] | undefined; + private prestartJobsInfo: PrestartJobInfo[] | undefined; + private routingEntriesInfo: RoutingEntryInfo[] | undefined; + + async fetch(): Promise { + const connection = Code4i.getConnection(); + const content = Code4i.getContent(); + if (connection && content) { + // Subsystem Description + const subSystemInfo = await Code4i.getContent().runSQL([`SELECT ifnull(SUBSYSTEM_DESCRIPTION_LIBRARY, '') "subsystemDescriptionLibrary", + ifnull(SUBSYSTEM_DESCRIPTION, '') "subsystemDescription", + ifnull(STATUS, '') "status", + ifnull(MAXIMUM_ACTIVE_JOBS, 0) "maximumActiveJobs", + ifnull(CURRENT_ACTIVE_JOBS, 0) "currentActiveJobs", + ifnull(SUBSYSTEM_MONITOR_JOB, '') "subsystemMonitorJob", + ifnull(TEXT_DESCRIPTION, '') "textDescription", + ifnull(CONTROLLING_SUBSYSTEM, '') "controllingSubsystem", + ifnull(WORKLOAD_GROUP, '') "workloadGroup", + ifnull(SIGNON_DEVICE_FILE_LIBRARY, '') "signonDeviceFileLibrary", + ifnull(SIGNON_DEVICE_FILE, '') "signonDeviceFile", + ifnull(SECONDARY_LANGUAGE_LIBRARY, '') "secondaryLanguageLibrary", + ifnull(IASP_NAME, '') "iaspName" + FROM QSYS2.SUBSYSTEM_INFO + where SUBSYSTEM_DESCRIPTION_LIBRARY = '${this.library}' AND SUBSYSTEM_DESCRIPTION = '${this.name}' LIMIT 1`].join(` `)); + + if (subSystemInfo && subSystemInfo.length > 0) { + const resultSubSystemInfo: SubSystemInfo[] = subSystemInfo.map(row => ({ + subsystemDescriptionLibrary: String(row.subsystemDescriptionLibrary), + subsystemDescription: String(row.subsystemDescription), + status: String(row.status), + maximumActiveJobs: Number(row.maximumActiveJobs), + currentActiveJobs: Number(row.currentActiveJobs), + subsystemMonitorJob: String(row.subsystemMonitorJob), + textDescription: String(row.textDescription), + controllingSubsystem: String(row.controllingSubsystem), + workloadGroup: String(row.workloadGroup), + signonDeviceFileLibrary: String(row.signonDeviceFileLibrary), + signonDeviceFile: String(row.signonDeviceFile), + secondaryLanguageLibrary: String(row.secondaryLanguageLibrary), + iaspName: String(row.iaspName) + })); + this.subSystemInfo = resultSubSystemInfo[0]; + } + + // Active job + const activeJobsInfo = await Code4i.getContent().runSQL([`SELECT ifnull(X.JOB_NAME, '') jobName, + ifnull(X.JOB_NAME_SHORT, '') "jobNameShort", + ifnull(X.JOB_USER, '') "jobUser", + ifnull(X.JOB_NUMBER, '') "jobNumber", + ifnull(X.JOB_INFORMATION, '') "jobInformation", + ifnull(X.JOB_STATUS, '') "jobStatus", + ifnull(X.JOB_TYPE, '') "jobType", + ifnull(X.JOB_TYPE_ENHANCED, '') "jobTypeEnhanced", + ifnull(X.JOB_SUBSYSTEM, '') "jobSubsystem", + ifnull(X.JOB_DATE, '') "jobDate", + ifnull(X.JOB_DESCRIPTION_LIBRARY, '') "jobDescriptionLibrary", + ifnull(X.JOB_DESCRIPTION, '') "jobDescription", + ifnull(X.JOB_ACCOUNTING_CODE, '') "jobAccountingCode", + ifnull(X.SUBMITTER_JOB_NAME, '') "submitterJobName", + ifnull(X.SUBMITTER_MESSAGE_QUEUE_LIBRARY, '') "submitterMessageQueueLibrary", + ifnull(X.SUBMITTER_MESSAGE_QUEUE, '') "submitterMessageQueue", + ifnull(X.SERVER_TYPE, '') "serverType", + X.JOB_ENTERED_SYSTEM_TIME "jobEnteredSystemTime", + X.JOB_SCHEDULED_TIME "jobScheduledTime", + X.JOB_ACTIVE_TIME "jobActiveTime", + X.JOB_END_TIME "jobEndTime", + ifnull(X.JOB_END_SEVERITY, '') "jobEndSeverity", + ifnull(X.COMPLETION_STATUS, '') "completionStatus" + FROM TABLE (QSYS2.JOB_INFO(JOB_SUBSYSTEM_FILTER => '${this.name}', JOB_USER_FILTER => '*ALL')) X;`].join(` `)); + + if (activeJobsInfo && activeJobsInfo.length > 0) { + const resultActiveJobInfo: ActiveJobInfo[] = activeJobsInfo.map(row => ({ + jobName: String(row.jobName), + jobNameShort: String(row.jobNameShort), + jobUser: String(row.jobUser), + jobNumber: String(row.jobNumber), + jobInformation: String(row.jobInformation), + jobStatus: String(row.jobStatus), + jobType: String(row.jobType), + jobTypeEnhanced: String(row.jobTypeEnhanced), + jobSubsystem: String(row.jobSubsystem), + jobDate: String(row.jobDate), + jobDescriptionLibrary: String(row.jobDescriptionLibrary), + jobDescription: String(row.jobDescription), + jobAccountingCode: String(row.jobAccountingCode), + submitterJobName: String(row.submitterJobName), + submitterMessageQueueLibrary: String(row.submitterMessageQueueLibrary), + submitterMessageQueue: String(row.submitterMessageQueue), + serverType: String(row.serverType), + jobEnteredSystemTime: String(row.jobEnteredSystemTime), + jobScheduledTime: String(row.jobScheduledTime), + jobActiveTime: String(row.jobActiveTime), + jobEndTime: String(row.jobEndTime), + jobEndSeverity: String(row.jobEndSeverity), + completionStatus: String(row.completionStatus) + })); + this.activeJobsInfo = resultActiveJobInfo; + } + + // Autostart job + const autostartJobsInfo = await Code4i.getContent().runSQL([`SELECT SUBSYSTEM_DESCRIPTION_LIBRARY "subsystemDescriptionLibrary", + SUBSYSTEM_DESCRIPTION "subsystemDescription", + AUTOSTART_JOB_NAME "autostartJobName", + JOB_DESCRIPTION_LIBRARY "jobDescriptionLibrary", + JOB_DESCRIPTION "jobDescription" + FROM QSYS2.AUTOSTART_JOB_INFO + where SUBSYSTEM_DESCRIPTION_LIBRARY = '${this.library}' AND SUBSYSTEM_DESCRIPTION = '${this.name}' ORDER BY 1, 2, 3`].join(` `)); + + if (autostartJobsInfo && autostartJobsInfo.length > 0) { + const resultAutostartJobsInfo: AutostartJobInfo[] = autostartJobsInfo.map(row => ({ + subsystemDescriptionLibrary: String(row.subsystemDescriptionLibrary), + subsystemDescription: String(row.subsystemDescription), + autostartJobName: String(row.autostartJobName), + jobDescriptionLibrary: String(row.jobDescriptionLibrary), + jobDescription: String(row.jobDescription) + })); + this.autostartJobsInfo = resultAutostartJobsInfo; + } + + // Prestart job + const prestartJobsInfo = await Code4i.getContent().runSQL([`SELECT SUBSYSTEM_DESCRIPTION_LIBRARY "subsystemDescriptionLibrary", + SUBSYSTEM_DESCRIPTION "subsystemDescription", + PRESTART_JOB_PROGRAM_LIBRARY "prestartJobProgramLibrary", + PRESTART_JOB_PROGRAM "prestartJobProgram", + SUBSYSTEM_ACTIVE "subsystemActive", + USER_PROFILE "userProfile", + PRESTART_JOB_NAME "prestartJobName", + JOB_DESCRIPTION_LIBRARY "jobDescriptionLibrary", + JOB_DESCRIPTION "jobDescription", + START_JOBS "startJobs", + INITIAL_JOBS "initialJobs" + FROM QSYS2.PRESTART_JOB_INFO + where SUBSYSTEM_DESCRIPTION_LIBRARY = '${this.library}' AND SUBSYSTEM_DESCRIPTION = '${this.name}' ORDER BY 1, 2, 3`].join(` `)); + + if (prestartJobsInfo && prestartJobsInfo.length > 0) { + const resultPrestartJobsInfo: PrestartJobInfo[] = prestartJobsInfo.map(row => ({ + subsystemDescriptionLibrary: String(row.subsystemDescriptionLibrary), + subsystemDescription: String(row.subsystemDescription), + prestartJobProgramLibrary: String(row.prestartJobProgramLibrary), + prestartJobProgram: String(row.prestartJobProgram), + subsystemActive: String(row.subsystemActive), + userProfile: String(row.userProfile), + prestartJobName: String(row.prestartJobName), + jobDescriptionLibrary: String(row.jobDescriptionLibrary), + jobDescription: String(row.jobDescription), + startJobs: String(row.startJobs), + initialJobs: Number(row.initialJobs), + })); + this.prestartJobsInfo = resultPrestartJobsInfo; + } + + // Routing entries + const routingEntriesInfo = await Code4i.getContent().runSQL([`SELECT SUBSYSTEM_DESCRIPTION_LIBRARY "subsystemDescriptionLibrary", + SUBSYSTEM_DESCRIPTION "subsystemDescription", + ifnull(SEQUENCE_NUMBER, 0) "sequenceNumber", + ifnull(PROGRAM_LIBRARY, '') "programLibrary", + ifnull(PROGRAM_NAME, '') "programName", + ifnull(CLASS_LIBRARY, '') "classLibrary", + ifnull(CLASS, '') "class", + ifnull(MAXIMUM_STEPS, 0) "maximumSteps", + ifnull(POOL_ID, 0) "poolId", + ifnull(COMPARISON_DATA, '') "comparisonData", + ifnull(COMPARISON_START, 0) "comparisonStart" + FROM QSYS2.ROUTING_ENTRY_INFO + where SUBSYSTEM_DESCRIPTION_LIBRARY = '${this.library}' AND SUBSYSTEM_DESCRIPTION = '${this.name}' ORDER BY 1, 2, 3`].join(` `)); + + if (routingEntriesInfo && routingEntriesInfo.length > 0) { + const resultRoutingEntryInfo: RoutingEntryInfo[] = routingEntriesInfo.map(row => ({ + subsystemDescriptionLibrary: String(row.subsystemDescriptionLibrary), + subsystemDescription: String(row.subsystemDescription), + sequenceNumber: Number(row.sequenceNumber), + programLibrary: String(row.programLibrary), + programName: String(row.programName), + classLibrary: String(row.classLibrary), + class: String(row.class), + maximumSteps: Number(row.maximumSteps), + poolId: Number(row.poolId), + comparisonData: String(row.comparisonData), + comparisonStart: Number(row.comparisonStart), + })); + this.routingEntriesInfo = resultRoutingEntryInfo; + } + + } else { + throw new Error("No connection."); + } + } + + generateHTML(): string { + const descriptionTab = `

Description

+ + + + + + + Description + ${this.subSystemInfo?.textDescription} + + + Status + ${this.subSystemInfo?.status} + + + Monitor job + ${this.subSystemInfo?.subsystemMonitorJob} + + + Maximum active job + ${this.subSystemInfo?.maximumActiveJobs} + + + Current active job + ${this.subSystemInfo?.currentActiveJobs} + + + Controlling subsystem + ${this.subSystemInfo?.controllingSubsystem} + + + Workload group + ${this.subSystemInfo?.workloadGroup} + + + Signon device file library + ${this.subSystemInfo?.signonDeviceFileLibrary} + + + Signon device file + ${this.subSystemInfo?.signonDeviceFile} + + + Secondary language library + ${this.subSystemInfo?.secondaryLanguageLibrary} + + + iASP + ${this.subSystemInfo?.iaspName} + + + `; + + const activeJobTab = `

Auto start

+ + + Name + User + Number + Information ? + Status + Type + Date + Library + JOBD + Accounting code + Entered system time + Scheduled time + Active time + End time + End severity + Completion status + + ${this.activeJobsInfo?.map(activeJobInfo => { + return /*html*/` + + ${activeJobInfo.jobNameShort} + ${activeJobInfo.jobUser} + ${activeJobInfo.jobNumber} + ${activeJobInfo.jobInformation} + ${activeJobInfo.jobStatus} + ${activeJobInfo.jobTypeEnhanced} + ${activeJobInfo.jobDate} + ${activeJobInfo.jobDescriptionLibrary} + ${activeJobInfo.jobDescription} + ${activeJobInfo.jobAccountingCode} + ${activeJobInfo.jobEnteredSystemTime} + ${activeJobInfo.jobScheduledTime} + ${activeJobInfo.jobActiveTime} + ${activeJobInfo.jobEndTime} + ${activeJobInfo.jobEndSeverity} + ${activeJobInfo.completionStatus} + `; + }).join("")} + + `; + + const autostartTab = `

Autostart

+ + + Library + Description + Job name + JOBD Library + JOBD + + ${this.autostartJobsInfo?.map(autostartJobInfo => { + return /*html*/` + + ${autostartJobInfo.subsystemDescriptionLibrary} + ${autostartJobInfo.subsystemDescription} + ${autostartJobInfo.autostartJobName} + ${autostartJobInfo.jobDescriptionLibrary} + ${autostartJobInfo.jobDescription} + `; + }).join("")} + + `; + + const prestartTab = `

Prestart

+ + + Library + Description + Program library + Program + Subsystem active + User profile + Job name + Library + Job description + Start jobs + Initial jobs + + ${this.prestartJobsInfo?.map(prestartJobInfo => { + return /*html*/` + + ${prestartJobInfo.subsystemDescriptionLibrary} + ${prestartJobInfo.subsystemDescription} + ${prestartJobInfo.prestartJobProgramLibrary} + ${prestartJobInfo.prestartJobProgram} + ${prestartJobInfo.subsystemActive} + ${prestartJobInfo.userProfile} + ${prestartJobInfo.prestartJobName} + ${prestartJobInfo.jobDescriptionLibrary} + ${prestartJobInfo.jobDescription} + ${prestartJobInfo.startJobs} + ${prestartJobInfo.initialJobs} + `; + }).join("")} + + `; + + const routingTab = `

Routing entry

+ + + Library + Description + Number + Program library + Program + Class library + Class + Maximum steps + Pool id + Comparison data + Comparison start + + ${this.routingEntriesInfo?.map(routingEntrieInfo => { + return /*html*/` + + ${routingEntrieInfo.subsystemDescriptionLibrary} + ${routingEntrieInfo.subsystemDescription} + ${routingEntrieInfo.sequenceNumber} + ${routingEntrieInfo.programLibrary} + ${routingEntrieInfo.programName} + ${routingEntrieInfo.classLibrary} + ${routingEntrieInfo.class} + ${routingEntrieInfo.maximumSteps} + ${routingEntrieInfo.poolId} + ${routingEntrieInfo.comparisonData} + ${routingEntrieInfo.comparisonStart} + `; + }).join("")} + + `; + + const panels = /*html*/` + + + DESCRIPTION + + + ACTIVE JOB + ${this.activeJobsInfo?.length ? this.activeJobsInfo?.length: 0} + + + AUTOSTART JOB + ${this.autostartJobsInfo?.length ? this.autostartJobsInfo?.length: 0} + + + PRESTART JOB + ${this.prestartJobsInfo?.length ? this.prestartJobsInfo?.length: 0} + + + ROUTING ENTRY + ${this.routingEntriesInfo?.length ? this.routingEntriesInfo?.length: 0} + + ${descriptionTab} + ${activeJobTab} + ${autostartTab} + ${prestartTab} + ${routingTab} + + `; + + return panels; + } + + // We do the same action when use the button or Save document + async handleAction(data: any): Promise { + // Nothing to do + return { + dirty: true + }; + } + + async save(): Promise { + // Nothing to do + } + +} \ No newline at end of file From 3379e899dd413f7b3315f639da0563ae3bfcba7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BOURREAU?= Date: Tue, 21 Feb 2023 15:40:20 +0100 Subject: [PATCH 2/3] Fix: Subsystem not active --- src/types/subSystem.ts | 259 ++++++++++++++--------------------------- 1 file changed, 89 insertions(+), 170 deletions(-) diff --git a/src/types/subSystem.ts b/src/types/subSystem.ts index ecc29c2..8749cae 100644 --- a/src/types/subSystem.ts +++ b/src/types/subSystem.ts @@ -1,22 +1,7 @@ import * as vscode from 'vscode'; import Base from "./base"; import { Code4i } from '../tools'; - -interface SubSystemInfo { - subsystemDescriptionLibrary: string - subsystemDescription: string - status: string - maximumActiveJobs: number - currentActiveJobs: number - subsystemMonitorJob: string - textDescription: string - controllingSubsystem: string - workloadGroup: string - signonDeviceFileLibrary: string - signonDeviceFile: string - secondaryLanguageLibrary: string - iaspName: string -} +import { Components } from "../webviewToolkit"; interface ActiveJobInfo { jobName: string @@ -81,7 +66,7 @@ interface RoutingEntryInfo { } export class SubSystem extends Base { - private subSystemInfo: SubSystemInfo | undefined; + private subSystemInfo: Record = {}; private activeJobsInfo: ActiveJobInfo[] | undefined; private autostartJobsInfo: AutostartJobInfo[] | undefined; private prestartJobsInfo: PrestartJobInfo[] | undefined; @@ -92,7 +77,7 @@ export class SubSystem extends Base { const content = Code4i.getContent(); if (connection && content) { // Subsystem Description - const subSystemInfo = await Code4i.getContent().runSQL([`SELECT ifnull(SUBSYSTEM_DESCRIPTION_LIBRARY, '') "subsystemDescriptionLibrary", + const [subSystemInfo] = await Code4i.getContent().runSQL([`SELECT ifnull(SUBSYSTEM_DESCRIPTION_LIBRARY, '') "subsystemDescriptionLibrary", ifnull(SUBSYSTEM_DESCRIPTION, '') "subsystemDescription", ifnull(STATUS, '') "status", ifnull(MAXIMUM_ACTIVE_JOBS, 0) "maximumActiveJobs", @@ -108,78 +93,78 @@ export class SubSystem extends Base { FROM QSYS2.SUBSYSTEM_INFO where SUBSYSTEM_DESCRIPTION_LIBRARY = '${this.library}' AND SUBSYSTEM_DESCRIPTION = '${this.name}' LIMIT 1`].join(` `)); - if (subSystemInfo && subSystemInfo.length > 0) { - const resultSubSystemInfo: SubSystemInfo[] = subSystemInfo.map(row => ({ - subsystemDescriptionLibrary: String(row.subsystemDescriptionLibrary), - subsystemDescription: String(row.subsystemDescription), - status: String(row.status), - maximumActiveJobs: Number(row.maximumActiveJobs), - currentActiveJobs: Number(row.currentActiveJobs), - subsystemMonitorJob: String(row.subsystemMonitorJob), - textDescription: String(row.textDescription), - controllingSubsystem: String(row.controllingSubsystem), - workloadGroup: String(row.workloadGroup), - signonDeviceFileLibrary: String(row.signonDeviceFileLibrary), - signonDeviceFile: String(row.signonDeviceFile), - secondaryLanguageLibrary: String(row.secondaryLanguageLibrary), - iaspName: String(row.iaspName) - })); - this.subSystemInfo = resultSubSystemInfo[0]; + if (subSystemInfo) { + this.subSystemInfo["Library"] = String(subSystemInfo.subsystemDescriptionLibrary); + this.subSystemInfo["Description"] = String(subSystemInfo.textDescription); + this.subSystemInfo["Status"] = String(subSystemInfo.status); + this.subSystemInfo["Monitor job"] = String(subSystemInfo.subsystemMonitorJob); + this.subSystemInfo["Maximum active job"] = String(subSystemInfo.maximumActiveJobs); + this.subSystemInfo["Current active job"] = String(subSystemInfo.currentActiveJobs); + this.subSystemInfo["Controlling subsystem"] = String(subSystemInfo.controllingSubsystem); + this.subSystemInfo["Workload group"] = String(subSystemInfo.workloadGroup); + this.subSystemInfo["Signon device file library"] = String(subSystemInfo.signonDeviceFileLibrary); + this.subSystemInfo["Signon device file"] = String(subSystemInfo.signonDeviceFile); + this.subSystemInfo["Secondary language library"] = String(subSystemInfo.secondaryLanguageLibrary); + this.subSystemInfo["iASP"] = String(subSystemInfo.iaspName); } // Active job - const activeJobsInfo = await Code4i.getContent().runSQL([`SELECT ifnull(X.JOB_NAME, '') jobName, - ifnull(X.JOB_NAME_SHORT, '') "jobNameShort", - ifnull(X.JOB_USER, '') "jobUser", - ifnull(X.JOB_NUMBER, '') "jobNumber", - ifnull(X.JOB_INFORMATION, '') "jobInformation", - ifnull(X.JOB_STATUS, '') "jobStatus", - ifnull(X.JOB_TYPE, '') "jobType", - ifnull(X.JOB_TYPE_ENHANCED, '') "jobTypeEnhanced", - ifnull(X.JOB_SUBSYSTEM, '') "jobSubsystem", - ifnull(X.JOB_DATE, '') "jobDate", - ifnull(X.JOB_DESCRIPTION_LIBRARY, '') "jobDescriptionLibrary", - ifnull(X.JOB_DESCRIPTION, '') "jobDescription", - ifnull(X.JOB_ACCOUNTING_CODE, '') "jobAccountingCode", - ifnull(X.SUBMITTER_JOB_NAME, '') "submitterJobName", - ifnull(X.SUBMITTER_MESSAGE_QUEUE_LIBRARY, '') "submitterMessageQueueLibrary", - ifnull(X.SUBMITTER_MESSAGE_QUEUE, '') "submitterMessageQueue", - ifnull(X.SERVER_TYPE, '') "serverType", - X.JOB_ENTERED_SYSTEM_TIME "jobEnteredSystemTime", - X.JOB_SCHEDULED_TIME "jobScheduledTime", - X.JOB_ACTIVE_TIME "jobActiveTime", - X.JOB_END_TIME "jobEndTime", - ifnull(X.JOB_END_SEVERITY, '') "jobEndSeverity", - ifnull(X.COMPLETION_STATUS, '') "completionStatus" - FROM TABLE (QSYS2.JOB_INFO(JOB_SUBSYSTEM_FILTER => '${this.name}', JOB_USER_FILTER => '*ALL')) X;`].join(` `)); + try { + const activeJobsInfo = await Code4i.getContent().runSQL([`SELECT ifnull(X.JOB_NAME, '') jobName, + ifnull(X.JOB_NAME_SHORT, '') "jobNameShort", + ifnull(X.JOB_USER, '') "jobUser", + ifnull(X.JOB_NUMBER, '') "jobNumber", + ifnull(X.JOB_INFORMATION, '') "jobInformation", + ifnull(X.JOB_STATUS, '') "jobStatus", + ifnull(X.JOB_TYPE, '') "jobType", + ifnull(X.JOB_TYPE_ENHANCED, '') "jobTypeEnhanced", + ifnull(X.JOB_SUBSYSTEM, '') "jobSubsystem", + ifnull(X.JOB_DATE, '') "jobDate", + ifnull(X.JOB_DESCRIPTION_LIBRARY, '') "jobDescriptionLibrary", + ifnull(X.JOB_DESCRIPTION, '') "jobDescription", + ifnull(X.JOB_ACCOUNTING_CODE, '') "jobAccountingCode", + ifnull(X.SUBMITTER_JOB_NAME, '') "submitterJobName", + ifnull(X.SUBMITTER_MESSAGE_QUEUE_LIBRARY, '') "submitterMessageQueueLibrary", + ifnull(X.SUBMITTER_MESSAGE_QUEUE, '') "submitterMessageQueue", + ifnull(X.SERVER_TYPE, '') "serverType", + X.JOB_ENTERED_SYSTEM_TIME "jobEnteredSystemTime", + X.JOB_SCHEDULED_TIME "jobScheduledTime", + X.JOB_ACTIVE_TIME "jobActiveTime", + X.JOB_END_TIME "jobEndTime", + ifnull(X.JOB_END_SEVERITY, '') "jobEndSeverity", + ifnull(X.COMPLETION_STATUS, '') "completionStatus" + FROM TABLE (QSYS2.JOB_INFO(JOB_SUBSYSTEM_FILTER => '${this.name}', JOB_USER_FILTER => '*ALL')) X;`].join(` `)); - if (activeJobsInfo && activeJobsInfo.length > 0) { - const resultActiveJobInfo: ActiveJobInfo[] = activeJobsInfo.map(row => ({ - jobName: String(row.jobName), - jobNameShort: String(row.jobNameShort), - jobUser: String(row.jobUser), - jobNumber: String(row.jobNumber), - jobInformation: String(row.jobInformation), - jobStatus: String(row.jobStatus), - jobType: String(row.jobType), - jobTypeEnhanced: String(row.jobTypeEnhanced), - jobSubsystem: String(row.jobSubsystem), - jobDate: String(row.jobDate), - jobDescriptionLibrary: String(row.jobDescriptionLibrary), - jobDescription: String(row.jobDescription), - jobAccountingCode: String(row.jobAccountingCode), - submitterJobName: String(row.submitterJobName), - submitterMessageQueueLibrary: String(row.submitterMessageQueueLibrary), - submitterMessageQueue: String(row.submitterMessageQueue), - serverType: String(row.serverType), - jobEnteredSystemTime: String(row.jobEnteredSystemTime), - jobScheduledTime: String(row.jobScheduledTime), - jobActiveTime: String(row.jobActiveTime), - jobEndTime: String(row.jobEndTime), - jobEndSeverity: String(row.jobEndSeverity), - completionStatus: String(row.completionStatus) - })); - this.activeJobsInfo = resultActiveJobInfo; + if (activeJobsInfo && activeJobsInfo.length > 0) { + const resultActiveJobInfo: ActiveJobInfo[] = activeJobsInfo.map(row => ({ + jobName: String(row.jobName), + jobNameShort: String(row.jobNameShort), + jobUser: String(row.jobUser), + jobNumber: String(row.jobNumber), + jobInformation: String(row.jobInformation), + jobStatus: String(row.jobStatus), + jobType: String(row.jobType), + jobTypeEnhanced: String(row.jobTypeEnhanced), + jobSubsystem: String(row.jobSubsystem), + jobDate: String(row.jobDate), + jobDescriptionLibrary: String(row.jobDescriptionLibrary), + jobDescription: String(row.jobDescription), + jobAccountingCode: String(row.jobAccountingCode), + submitterJobName: String(row.submitterJobName), + submitterMessageQueueLibrary: String(row.submitterMessageQueueLibrary), + submitterMessageQueue: String(row.submitterMessageQueue), + serverType: String(row.serverType), + jobEnteredSystemTime: String(row.jobEnteredSystemTime), + jobScheduledTime: String(row.jobScheduledTime), + jobActiveTime: String(row.jobActiveTime), + jobEndTime: String(row.jobEndTime), + jobEndSeverity: String(row.jobEndSeverity), + completionStatus: String(row.completionStatus) + })); + this.activeJobsInfo = resultActiveJobInfo; + } + } catch (error) { + } // Autostart job @@ -272,60 +257,15 @@ export class SubSystem extends Base { } generateHTML(): string { - const descriptionTab = `

Description

- - - - - - - Description - ${this.subSystemInfo?.textDescription} - - - Status - ${this.subSystemInfo?.status} - - - Monitor job - ${this.subSystemInfo?.subsystemMonitorJob} - - - Maximum active job - ${this.subSystemInfo?.maximumActiveJobs} - - - Current active job - ${this.subSystemInfo?.currentActiveJobs} - - - Controlling subsystem - ${this.subSystemInfo?.controllingSubsystem} - - - Workload group - ${this.subSystemInfo?.workloadGroup} - - - Signon device file library - ${this.subSystemInfo?.signonDeviceFileLibrary} - - - Signon device file - ${this.subSystemInfo?.signonDeviceFile} - - - Secondary language library - ${this.subSystemInfo?.secondaryLanguageLibrary} - - - iASP - ${this.subSystemInfo?.iaspName} - - - `; + const descriptionTab = /* html */ ` + ${Components.dataGrid<[string, string]>({ + columns: [ + { title: "", cellValue: entry => entry[0] }, + { title: "", cellValue: entry => entry[1] } + ] + }, Object.entries(this.subSystemInfo))}`; - const activeJobTab = `

Auto start

+ const activeJobTab = ` Name @@ -369,7 +309,7 @@ export class SubSystem extends Base { `; - const autostartTab = `

Autostart

+ const autostartTab = ` Library @@ -391,7 +331,7 @@ export class SubSystem extends Base { `; - const prestartTab = `

Prestart

+ const prestartTab = ` Library @@ -425,7 +365,7 @@ export class SubSystem extends Base { `; - const routingTab = `

Routing entry

+ const routingTab = ` Library @@ -459,34 +399,13 @@ export class SubSystem extends Base { `; - const panels = /*html*/` - - - DESCRIPTION - - - ACTIVE JOB - ${this.activeJobsInfo?.length ? this.activeJobsInfo?.length: 0} - - - AUTOSTART JOB - ${this.autostartJobsInfo?.length ? this.autostartJobsInfo?.length: 0} - - - PRESTART JOB - ${this.prestartJobsInfo?.length ? this.prestartJobsInfo?.length: 0} - - - ROUTING ENTRY - ${this.routingEntriesInfo?.length ? this.routingEntriesInfo?.length: 0} - - ${descriptionTab} - ${activeJobTab} - ${autostartTab} - ${prestartTab} - ${routingTab} - - `; + const panels = Components.panels([ + { title: "DESCRIPTION", content: descriptionTab }, + { title: "ACTIVE JOB", content: activeJobTab, badge: this.activeJobsInfo?.length ? this.activeJobsInfo?.length : 0 }, + { title: "AUTOSTART JOB", content: autostartTab, badge: this.autostartJobsInfo?.length ? this.autostartJobsInfo?.length : 0 }, + { title: "PRESTART JOB", content: prestartTab, badge: this.prestartJobsInfo?.length ? this.prestartJobsInfo?.length : 0 }, + { title: "ROUTING ENTRY", content: routingTab, badge: this.routingEntriesInfo?.length ? this.routingEntriesInfo?.length : 0 } + ]); return panels; } From 5f8a95579ed4a8bfe661ac373642b361e941bb14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BOURREAU?= Date: Wed, 22 Feb 2023 14:33:56 +0100 Subject: [PATCH 3/3] Fix: Use dataGrid function --- src/types/subSystem.ts | 219 +++++++++++++++-------------------------- 1 file changed, 77 insertions(+), 142 deletions(-) diff --git a/src/types/subSystem.ts b/src/types/subSystem.ts index 8749cae..109294d 100644 --- a/src/types/subSystem.ts +++ b/src/types/subSystem.ts @@ -67,10 +67,10 @@ interface RoutingEntryInfo { export class SubSystem extends Base { private subSystemInfo: Record = {}; - private activeJobsInfo: ActiveJobInfo[] | undefined; - private autostartJobsInfo: AutostartJobInfo[] | undefined; - private prestartJobsInfo: PrestartJobInfo[] | undefined; - private routingEntriesInfo: RoutingEntryInfo[] | undefined; + private activeJobsInfo: ActiveJobInfo[] | undefined = []; + private autostartJobsInfo: AutostartJobInfo[] | undefined = []; + private prestartJobsInfo: PrestartJobInfo[] | undefined = []; + private routingEntriesInfo: RoutingEntryInfo[] | undefined = []; async fetch(): Promise { const connection = Code4i.getConnection(); @@ -110,7 +110,7 @@ export class SubSystem extends Base { // Active job try { - const activeJobsInfo = await Code4i.getContent().runSQL([`SELECT ifnull(X.JOB_NAME, '') jobName, + const activeJobsInfo = await Code4i.getContent().runSQL([`SELECT ifnull(X.JOB_NAME, '') "jobName", ifnull(X.JOB_NAME_SHORT, '') "jobNameShort", ifnull(X.JOB_USER, '') "jobUser", ifnull(X.JOB_NUMBER, '') "jobNumber", @@ -128,14 +128,15 @@ export class SubSystem extends Base { ifnull(X.SUBMITTER_MESSAGE_QUEUE, '') "submitterMessageQueue", ifnull(X.SERVER_TYPE, '') "serverType", X.JOB_ENTERED_SYSTEM_TIME "jobEnteredSystemTime", - X.JOB_SCHEDULED_TIME "jobScheduledTime", + ifnull(cast(X.JOB_SCHEDULED_TIME as char(19)), '') "jobScheduledTime", X.JOB_ACTIVE_TIME "jobActiveTime", - X.JOB_END_TIME "jobEndTime", + ifnull(cast(X.JOB_END_TIME as char(19)), '') "jobEndTime", ifnull(X.JOB_END_SEVERITY, '') "jobEndSeverity", ifnull(X.COMPLETION_STATUS, '') "completionStatus" FROM TABLE (QSYS2.JOB_INFO(JOB_SUBSYSTEM_FILTER => '${this.name}', JOB_USER_FILTER => '*ALL')) X;`].join(` `)); if (activeJobsInfo && activeJobsInfo.length > 0) { + if (activeJobsInfo[0].jobUser!.toString().length > 0) { const resultActiveJobInfo: ActiveJobInfo[] = activeJobsInfo.map(row => ({ jobName: String(row.jobName), jobNameShort: String(row.jobNameShort), @@ -162,6 +163,7 @@ export class SubSystem extends Base { completionStatus: String(row.completionStatus) })); this.activeJobsInfo = resultActiveJobInfo; + } } } catch (error) { @@ -265,146 +267,79 @@ export class SubSystem extends Base { ] }, Object.entries(this.subSystemInfo))}`; - const activeJobTab = ` - - - Name - User - Number - Information ? - Status - Type - Date - Library - JOBD - Accounting code - Entered system time - Scheduled time - Active time - End time - End severity - Completion status - - ${this.activeJobsInfo?.map(activeJobInfo => { - return /*html*/` - - ${activeJobInfo.jobNameShort} - ${activeJobInfo.jobUser} - ${activeJobInfo.jobNumber} - ${activeJobInfo.jobInformation} - ${activeJobInfo.jobStatus} - ${activeJobInfo.jobTypeEnhanced} - ${activeJobInfo.jobDate} - ${activeJobInfo.jobDescriptionLibrary} - ${activeJobInfo.jobDescription} - ${activeJobInfo.jobAccountingCode} - ${activeJobInfo.jobEnteredSystemTime} - ${activeJobInfo.jobScheduledTime} - ${activeJobInfo.jobActiveTime} - ${activeJobInfo.jobEndTime} - ${activeJobInfo.jobEndSeverity} - ${activeJobInfo.completionStatus} - `; - }).join("")} - - `; + const activeJobTab = /* html */ ` + ${Components.dataGrid({ + columns: [ + { title: "Name", cellValue: l => String(l.jobNameShort) }, + { title: "User", cellValue: l => l.jobUser }, + { title: "Number", cellValue: l => l.jobNumber }, + { title: "Information ?", cellValue: l => l.jobInformation }, + { title: "Status", cellValue: l => l.jobStatus }, + { title: "Type", cellValue: l => l.jobTypeEnhanced }, + { title: "Date", cellValue: l => l.jobDate }, + { title: "Library", cellValue: l => l.jobDescriptionLibrary }, + { title: "JOBD", cellValue: l => l.jobDescription }, + { title: "Accounting code", cellValue: l => l.jobAccountingCode }, + { title: "Entered system time", cellValue: l => l.jobEnteredSystemTime }, + { title: "Scheduled time", cellValue: l => l.jobScheduledTime }, + { title: "Active time", cellValue: l => l.jobActiveTime }, + { title: "End time", cellValue: l => l.jobEndTime }, + { title: "End severity", cellValue: l => l.jobEndSeverity }, + { title: "Completion status", cellValue: l => l.completionStatus } + ] + }, this.activeJobsInfo!)}`; - const autostartTab = ` - - - Library - Description - Job name - JOBD Library - JOBD - - ${this.autostartJobsInfo?.map(autostartJobInfo => { - return /*html*/` - - ${autostartJobInfo.subsystemDescriptionLibrary} - ${autostartJobInfo.subsystemDescription} - ${autostartJobInfo.autostartJobName} - ${autostartJobInfo.jobDescriptionLibrary} - ${autostartJobInfo.jobDescription} - `; - }).join("")} - - `; + const autostartTab = /* html */ ` + ${Components.dataGrid({ + columns: [ + { title: "Library", cellValue: l => String(l.subsystemDescriptionLibrary) }, + { title: "Description", cellValue: l => l.subsystemDescription }, + { title: "Job name", cellValue: l => l.autostartJobName }, + { title: "JOBD Library", cellValue: l => l.jobDescriptionLibrary }, + { title: "JOBD", cellValue: l => l.jobDescription } + ] + }, this.autostartJobsInfo!)}`; - const prestartTab = ` - - - Library - Description - Program library - Program - Subsystem active - User profile - Job name - Library - Job description - Start jobs - Initial jobs - - ${this.prestartJobsInfo?.map(prestartJobInfo => { - return /*html*/` - - ${prestartJobInfo.subsystemDescriptionLibrary} - ${prestartJobInfo.subsystemDescription} - ${prestartJobInfo.prestartJobProgramLibrary} - ${prestartJobInfo.prestartJobProgram} - ${prestartJobInfo.subsystemActive} - ${prestartJobInfo.userProfile} - ${prestartJobInfo.prestartJobName} - ${prestartJobInfo.jobDescriptionLibrary} - ${prestartJobInfo.jobDescription} - ${prestartJobInfo.startJobs} - ${prestartJobInfo.initialJobs} - `; - }).join("")} - - `; + const prestartTab = /* html */ ` + ${Components.dataGrid({ + columns: [ + { title: "Library", cellValue: l => String(l.subsystemDescriptionLibrary) }, + { title: "Description", cellValue: l => l.subsystemDescription }, + { title: "Program library", cellValue: l => l.prestartJobProgramLibrary }, + { title: "Program", cellValue: l => l.prestartJobProgram }, + { title: "Subsystem active", cellValue: l => l.subsystemActive }, + { title: "User profile", cellValue: l => l.userProfile }, + { title: "Job name", cellValue: l => l.prestartJobName }, + { title: "Library", cellValue: l => l.jobDescriptionLibrary }, + { title: "Job description", cellValue: l => l.jobDescription }, + { title: "Start jobs", cellValue: l => l.startJobs }, + { title: "Initial jobs", cellValue: l => String(l.initialJobs) } + ] + }, this.prestartJobsInfo!)}`; - const routingTab = ` - - - Library - Description - Number - Program library - Program - Class library - Class - Maximum steps - Pool id - Comparison data - Comparison start - - ${this.routingEntriesInfo?.map(routingEntrieInfo => { - return /*html*/` - - ${routingEntrieInfo.subsystemDescriptionLibrary} - ${routingEntrieInfo.subsystemDescription} - ${routingEntrieInfo.sequenceNumber} - ${routingEntrieInfo.programLibrary} - ${routingEntrieInfo.programName} - ${routingEntrieInfo.classLibrary} - ${routingEntrieInfo.class} - ${routingEntrieInfo.maximumSteps} - ${routingEntrieInfo.poolId} - ${routingEntrieInfo.comparisonData} - ${routingEntrieInfo.comparisonStart} - `; - }).join("")} - - `; + const routingTab = /* html */ ` + ${Components.dataGrid({ + columns: [ + { title: "Library", cellValue: l => String(l.subsystemDescriptionLibrary) }, + { title: "Description", cellValue: l => l.subsystemDescription }, + { title: "Number", cellValue: l => String(l.sequenceNumber) }, + { title: "Program library", cellValue: l => l.programLibrary }, + { title: "Program", cellValue: l => l.programName }, + { title: "Class library", cellValue: l => l.classLibrary }, + { title: "Class", cellValue: l => l.class }, + { title: "Maximum steps", cellValue: l => String(l.maximumSteps) }, + { title: "Pool id", cellValue: l => String(l.poolId) }, + { title: "Comparison data", cellValue: l => l.comparisonData }, + { title: "Comparison start", cellValue: l => String(l.comparisonStart) } + ] + }, this.routingEntriesInfo!)}`; const panels = Components.panels([ - { title: "DESCRIPTION", content: descriptionTab }, - { title: "ACTIVE JOB", content: activeJobTab, badge: this.activeJobsInfo?.length ? this.activeJobsInfo?.length : 0 }, - { title: "AUTOSTART JOB", content: autostartTab, badge: this.autostartJobsInfo?.length ? this.autostartJobsInfo?.length : 0 }, - { title: "PRESTART JOB", content: prestartTab, badge: this.prestartJobsInfo?.length ? this.prestartJobsInfo?.length : 0 }, - { title: "ROUTING ENTRY", content: routingTab, badge: this.routingEntriesInfo?.length ? this.routingEntriesInfo?.length : 0 } + { title: "DESCRIPTION", content: descriptionTab }, + { title: "ACTIVE JOB", content: activeJobTab, badge: this.activeJobsInfo?.length ? this.activeJobsInfo?.length : 0 }, + { title: "AUTOSTART JOB", content: autostartTab, badge: this.autostartJobsInfo?.length ? this.autostartJobsInfo?.length : 0 }, + { title: "PRESTART JOB", content: prestartTab, badge: this.prestartJobsInfo?.length ? this.prestartJobsInfo?.length : 0 }, + { title: "ROUTING ENTRY", content: routingTab, badge: this.routingEntriesInfo?.length ? this.routingEntriesInfo?.length : 0 } ]); return panels;