Skip to content

Commit

Permalink
Merge pull request #2599 from SanthoshiBoyina/ZDPT-8744
Browse files Browse the repository at this point in the history
feat: Local Filtering of Jobs Tree
  • Loading branch information
JillieBeanSim authored Dec 1, 2023
2 parents 5c96535 + 1555e1b commit 6972cc3
Show file tree
Hide file tree
Showing 18 changed files with 250 additions and 13 deletions.
1 change: 1 addition & 0 deletions packages/zowe-explorer-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ All notable changes to the "zowe-explorer-api" extension will be documented in t
### New features and enhancements

- Added new optional boolean parameter `hideFromAllTrees` to `IZoweTree.deleteSession` for specifying whether to hide from all trees or current tree. [#2567](https://github.com/zowe/vscode-extension-for-zowe/issues/2567)
- Added optional `filter` and `actualJobs` variables to `IZoweJobTreeNode` to track local filter search.

### Bug fixes

Expand Down
8 changes: 8 additions & 0 deletions packages/zowe-explorer-api/src/tree/IZoweTreeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,14 @@ export interface IZoweJobTreeNode extends IZoweTreeNode {
* Returns whether the job node is a filtered search
*/
filtered?: boolean;
/**
* Filter method for this job search
*/
filter?: string;
/**
* Array of original filter search results job's children
*/
actualJobs?: IZoweTreeNode[];
/**
* Retrieves child nodes of this IZoweJobTreeNode
*
Expand Down
3 changes: 2 additions & 1 deletion packages/zowe-explorer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ All notable changes to the "vscode-extension-for-zowe" extension will be documen
- Added support for hiding a Zowe profile across all trees [#2567](https://github.com/zowe/vscode-extension-for-zowe/issues/2567)
- Added support for enabling/disabling validation for a Zowe profile across all trees [#2570](https://github.com/zowe/vscode-extension-for-zowe/issues/2570)
- Added Display confirmation dialog when submitting local JCL. [#2061](https://github.com/zowe/vscode-extension-for-zowe/issues/2061)
- Added "Sort Jobs" feature in Jobs tree view: accessible via sort icon or right-clicking on session node. [#2257](https://github.com/zowe/vscode-extension-for-zowe/issues/2257)
- Added "Filter Jobs" feature in Jobs tree view: accessible via filter icon or right-clicking on session node. [#2599](https://github.com/zowe/vscode-extension-for-zowe/issues/2599)

### Bug fixes

Expand Down Expand Up @@ -36,7 +38,6 @@ All notable changes to the "vscode-extension-for-zowe" extension will be documen

### New features and enhancements

- Added "Sort Jobs" feature in Jobs tree view: accessible via sort icon or right-clicking on session node. [#2257](https://github.com/zowe/vscode-extension-for-zowe/issues/2257)
- Introduce a new user interface for managing profiles via right-click action "Manage Profile".
- Added new edit feature on `Edit Attributes` view for changing file tags on USS. [#2113](https://github.com/zowe/vscode-extension-for-zowe/issues/2113)
- Added new API {ZE Extender MetaData} to allow extenders to have the metadata of registered extenders to aid in team configuration file creation from a view that isn't Zowe Explorer's. [#2394](https://github.com/zowe/vscode-extension-for-zowe/issues/2394)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ async function createGlobalMocks() {
"zowe.jobs.stopPolling",
"zowe.jobs.cancelJob",
"zowe.jobs.sortBy",
"zowe.jobs.filterJobs",
"zowe.manualPoll",
"zowe.editHistory",
"zowe.promptCredentials",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,46 @@ import { jobStringValidator } from "../../../src/shared/utils";
import { ZoweLogger } from "../../../src/utils/LoggerUtils";
import { Poller } from "@zowe/zowe-explorer-api/src/utils";
import { SettingsConfig } from "../../../src/utils/SettingsConfig";
import { TreeProviders } from "../../../src/shared/TreeProviders";

jest.mock("vscode");
const showMock = jest.fn();
const onDidChangeValueMock = {
event: (callback: (value: string) => void): vscode.Disposable => {
const disposable = {
dispose: jest.fn(),
};
callback("");
return disposable;
},
};
const mockInputBox: vscode.InputBox = {
title: "",
value: "",
placeholder: "",
password: false,
onDidChangeValue: onDidChangeValueMock.event,
onDidAccept: jest.fn(),
show: showMock,
hide: jest.fn(),
dispose: jest.fn(),
buttons: [],
onDidTriggerButton: jest.fn(),
prompt: "",
validationMessage: "",
step: 1,
totalSteps: 100,
enabled: true,
busy: false,
ignoreFocusOut: false,
onDidHide: jest.fn(),
};
function setJobObjects(job: zowe.IJob, newJobName: string, newJobId: string, newRetCode: string) {
job.jobname = newJobName;
job.jobid = newJobId;
job.retcode = newRetCode;
return job;
}

async function createGlobalMocks() {
const globalMocks = {
Expand Down Expand Up @@ -126,6 +166,11 @@ async function createGlobalMocks() {
value: globalMocks.mockGetSpoolFiles,
configurable: true,
});
Object.defineProperty(vscode.window, "createInputBox", {
value: jest.fn(() => mockInputBox),
configurable: true,
});

Object.defineProperty(vscode.window, "createTreeView", { value: globalMocks.createTreeView, configurable: true });
Object.defineProperty(vscode.window, "showQuickPick", { value: globalMocks.mockShowQuickPick, configurable: true });
Object.defineProperty(vscode, "ConfigurationTarget", { value: globalMocks.enums, configurable: true });
Expand Down Expand Up @@ -973,3 +1018,81 @@ describe("getFavorites", () => {
expect(tree.getFavorites()).toEqual(["test1", "test2", "test3"]);
});
});

describe("ZosJobsProvider Unit Test - Filter Jobs", () => {
const node1: IZoweJobTreeNode = new Job(
"jobnew",
vscode.TreeItemCollapsibleState.None,
null,
null,
setJobObjects(createIJobObject(), "ZOWEUSR1", "JOB04945", "CC 0000"),
null
);
const node2: IZoweJobTreeNode = new Job(
"jobnew",
vscode.TreeItemCollapsibleState.None,
null,
null,
setJobObjects(createIJobObject(), "ZOWEUSR2", "JOB05037", "CC 0000"),
null
);
const node3: IZoweJobTreeNode = new Job(
"jobnew",
vscode.TreeItemCollapsibleState.None,
null,
null,
setJobObjects(createIJobObject(), "ZOWEUSR3", "TSU07707", "ABEND S222"),
null
);

let globalMocks;
beforeEach(async () => {
globalMocks = await createGlobalMocks();
const mockTreeProvider = {
refresh: jest.fn(),
} as any;
jest.spyOn(TreeProviders, "job", "get").mockReturnValue(mockTreeProvider);
});

afterEach(() => {
jest.restoreAllMocks();
jest.resetAllMocks();
jest.clearAllMocks();
});

it("To show showInformationMessage", async () => {
const testTree = new ZosJobsProvider();
node1.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
const infoMessageSpy = jest.spyOn(Gui, "infoMessage");
await testTree.filterJobsDialog(node1);
expect(infoMessageSpy).toHaveBeenCalled();
});

it("To filter jobs based on a combination of JobName, JobId and Return code", async () => {
const testTree = new ZosJobsProvider();
node1.collapsibleState = vscode.TreeItemCollapsibleState.Expanded;
node1.children = [node2, node3];
const createInputBoxSpy = jest.spyOn(vscode.window, "createInputBox");
mockInputBox.value = "ZOWEUSR2(JOB05037) - CC 0000";
createInputBoxSpy.mockReturnValue(mockInputBox);
globalMocks.mockShowQuickPick.mockReturnValueOnce("Go to Local Filtering");
const filterJobsSpy = jest.spyOn(testTree, "filterJobsDialog");
await testTree.filterJobsDialog(node1);
expect(filterJobsSpy).toHaveBeenCalled();
expect(filterJobsSpy).toBeCalledWith(node1);
});

it("To check Clear filter for profile", async () => {
const testTree = new ZosJobsProvider();
node1.collapsibleState = vscode.TreeItemCollapsibleState.Expanded;
node1.children = [node2, node3];
const createInputBoxSpy = jest.spyOn(vscode.window, "createInputBox");
mockInputBox.value = "ZOWEUSR2(JOB05037) - CC 0000";
createInputBoxSpy.mockReturnValue(mockInputBox);
globalMocks.mockShowQuickPick.mockReturnValueOnce("$(clear-all) Clear filter for profile");
const filterJobsSpy = jest.spyOn(testTree, "filterJobsDialog");
await testTree.filterJobsDialog(node1);
expect(filterJobsSpy).toHaveBeenCalled();
expect(filterJobsSpy).toBeCalledWith(node1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ describe("Test src/jobs/extension", () => {
onDidChangeConfiguration: jest.fn(),
pollData: jest.fn(),
refreshElement: jest.fn(),
filterJobsDialog: jest.fn(),
};
const commands: IJestIt[] = [
{
Expand Down Expand Up @@ -219,6 +220,10 @@ describe("Test src/jobs/extension", () => {
mock: [{ spy: jest.spyOn(jobActions, "cancelJobs"), arg: [jobsProvider, [exampleData.job]] }],
parm: [exampleData.job],
},
{
name: "zowe.jobs.filterJobs",
mock: [{ spy: jest.spyOn(jobsProvider, "filterJobsDialog"), arg: [test.value] }],
},
];

beforeAll(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"sort.selectDirection": "Select a sorting direction",
"sort.updated": "$(check) Sorting updated for {0}",
"filter.description": "Filter: {0}",
"ds.clearProfileFilter": "$(clear-all) Clear filter for profile",
"filter.clearForProfile": "$(clear-all) Clear filter for profile",
"ds.clearPdsFilter": "$(clear-all) Clear filter for PDS",
"ds.selectFilterOpt": "Set a filter for {0}",
"filter.cleared": "$(check) Filter cleared for {0}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
"zowe.polling.intervalOption": "Poll interval (in ms) for: {0}",
"zowe.polling.cancelled": "Polling dismissed for {0}; operation cancelled.",
"zowe.polling.statusBar": "$(sync~spin) Polling: {0}...",
"filter.description": "Filter: {0}",
"filterJobs.message": "Use the search button to display jobs",
"filterJobs.placeholder": "Set a filter...",
"filter.clearForProfile": "$(clear-all) Clear filter for profile",
"filter.cleared": "$(check) Filter cleared for {0}",
"filterJobs.prompt.message": "Enter local filter...",
"filter.updated": "$(check) Filter updated for {0}",
"zosJobsProvider.specifyCriteria": "Create new...",
"zosJobsProvider.option.submit": "$(check) Submit this query"
}
4 changes: 3 additions & 1 deletion packages/zowe-explorer/i18n/sample/src/job/utils.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
"jobs.sortByDateSubmitted": "$(calendar) Date Submitted",
"jobs.sortByName": "$(case-sensitive) Job Name",
"jobs.sortByReturnCode": "$(symbol-numeric) Return Code",
"setSortDirection": "$(fold) Sort Direction"
"setSortDirection": "$(fold) Sort Direction",
"filterJobs.quickpick.message": "Go to Local Filtering",
"filter.clearForProfile": "$(clear-all) Clear filter for profile"
}
16 changes: 16 additions & 0 deletions packages/zowe-explorer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,12 @@
"title": "%cancelJobs%",
"category": "Zowe Explorer"
},
{
"command": "zowe.jobs.filterJobs",
"title": "Filter Jobs",
"category": "Zowe Explorer",
"icon": "$(list-filter)"
},
{
"command": "zowe.jobs.search",
"title": "%jobs.search%",
Expand Down Expand Up @@ -1229,6 +1235,11 @@
"command": "zowe.jobs.removeSearchFavorite",
"group": "inline"
},
{
"when": "view == zowe.jobs.explorer && viewItem =~ /^(?!.*_fav.*)server.*/ && !listMultiSelection",
"command": "zowe.jobs.filterJobs",
"group": "inline"
},
{
"when": "view == zowe.jobs.explorer && viewItem =~ /^(?!.*_fav.*)server.*/ && !listMultiSelection",
"command": "zowe.jobs.search",
Expand Down Expand Up @@ -1284,6 +1295,11 @@
"command": "zowe.jobs.addFavorite",
"group": "002_zowe_jobsWorkspace@0"
},
{
"when": "view == zowe.jobs.explorer && viewItem =~ /^(?!.*_fav.*)server.*/ && !listMultiSelection",
"command": "zowe.jobs.filterJobs",
"group": "002_zowe_jobsProfileModification@99"
},
{
"when": "view == zowe.jobs.explorer && viewItem =~ /^job.*_fav.*/",
"command": "zowe.jobs.removeFavorite",
Expand Down
2 changes: 1 addition & 1 deletion packages/zowe-explorer/src/abstract/ZoweTreeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export class ZoweTreeProvider {
* Called whenever the tree needs to be refreshed, and fires the data change event
*
*/
public refreshElement(element: IZoweDatasetTreeNode): void {
public refreshElement(element: IZoweTreeNode): void {
ZoweLogger.trace("ZoweTreeProvider.refreshElement called.");
element.dirty = true;
this.mOnDidChangeTreeData.fire(element);
Expand Down
2 changes: 1 addition & 1 deletion packages/zowe-explorer/src/dataset/DatasetTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1487,7 +1487,7 @@ export class DatasetTree extends ZoweTreeProvider implements IZoweTree<IZoweData
? localize("ds.allPdsSort", "all PDS members in {0}", node.label as string)
: localize("ds.singlePdsSort", "the PDS members in {0}", node.label as string);
const clearFilter = isSession
? localize("ds.clearProfileFilter", "$(clear-all) Clear filter for profile")
? localize("filter.clearForProfile", "$(clear-all) Clear filter for profile")
: localize("ds.clearPdsFilter", "$(clear-all) Clear filter for PDS");
const selection = (
await Gui.showQuickPick(
Expand Down
6 changes: 3 additions & 3 deletions packages/zowe-explorer/src/dataset/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1636,8 +1636,8 @@ export async function saveFile(doc: vscode.TextDocument, datasetProvider: api.IZ
await errorHandling(err, sesName);
}
// Get specific node based on label and parent tree (session / favorites)
const nodes: api.IZoweNodeType[] = concatChildNodes(sesNode ? [sesNode] : datasetProvider.mSessionNodes);
const node: api.IZoweDatasetTreeNode = nodes.find((zNode) => {
const nodes = concatChildNodes(sesNode ? [sesNode] : datasetProvider.mSessionNodes);
const node = nodes.find((zNode) => {
if (contextually.isDsMember(zNode)) {
const zNodeDetails = dsUtils.getProfileAndDataSetName(zNode);
return `${zNodeDetails.profileName}(${zNodeDetails.dataSetName})` === `${label}`;
Expand All @@ -1646,7 +1646,7 @@ export async function saveFile(doc: vscode.TextDocument, datasetProvider: api.IZ
} else {
return false;
}
});
}) as api.IZoweDatasetTreeNode;

// define upload options
const uploadOptions: IUploadOptions = {
Expand Down
2 changes: 1 addition & 1 deletion packages/zowe-explorer/src/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export let DS_DIR: string;
export let CONFIG_PATH; // set during activate
export let ISTHEIA = false; // set during activate
export let LOG: imperative.Logger;
export const COMMAND_COUNT = 115;
export const COMMAND_COUNT = 116;
export const MAX_SEARCH_HISTORY = 5;
export const MAX_FILE_HISTORY = 10;
export const MS_PER_SEC = 1000;
Expand Down
Loading

0 comments on commit 6972cc3

Please sign in to comment.