Skip to content

Commit

Permalink
fix(v2): Update migrated and recalled data sets in tree (#3333)
Browse files Browse the repository at this point in the history
* fix(ds): Fix migrated & recalled node behavior

Signed-off-by: Trae Yelovich <[email protected]>

* chore: update changelog

Signed-off-by: Trae Yelovich <[email protected]>

* rename to ZoweDatasetNode.{datasetMigrated,datasetRecalled}

Signed-off-by: Trae Yelovich <[email protected]>

* tests: ZoweDatasetNode.{datasetMigrated,datasetRecalled}

Signed-off-by: Trae Yelovich <[email protected]>

* refactor: remove static from dataset{Migrated,Recalled}

Signed-off-by: Trae Yelovich <[email protected]>

* refactor: add open command to PS if recalled

Signed-off-by: Trae Yelovich <[email protected]>

* fix: remove extra curly brace in ZoweDatasetNode

Signed-off-by: Trae Yelovich <[email protected]>

* tests: use toStrictEqual in datasetRecalled case

Signed-off-by: Trae Yelovich <[email protected]>

* use refresh for migrate instead of refreshElement

Signed-off-by: Trae Yelovich <[email protected]>

* chore: update typedoc and comments

Signed-off-by: Trae Yelovich <[email protected]>

* refactor: make datasetMigrated public to reuse logic

Signed-off-by: Trae Yelovich <[email protected]>

* fix: do not mark ds as migrated right away

Signed-off-by: Trae Yelovich <[email protected]>

* refactor: move ui messages before migrate/recall request

Signed-off-by: Trae Yelovich <[email protected]>

* fix: handle favorited DS for context value

Signed-off-by: Trae Yelovich <[email protected]>

---------

Signed-off-by: Trae Yelovich <[email protected]>
  • Loading branch information
traeok authored Nov 25, 2024
1 parent ed4f867 commit 4e42361
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 25 deletions.
3 changes: 3 additions & 0 deletions packages/zowe-explorer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ All notable changes to the "vscode-extension-for-zowe" extension will be documen
- Fixed an issue where the `Create Directory` and `Create File` features would continue processing when the first prompt was dismissed, causing an incorrect path to be generated. [#3183](https://github.com/zowe/zowe-explorer-vscode/pull/3183)
- Fixed an issue where the `Create Directory` and `Create File` features would incorrectly handle user-specified locations with trailing slashes. [#3183](https://github.com/zowe/zowe-explorer-vscode/pull/3183)
- Fixed an issue where renaming a data set with unsaved changes did not cancel the rename operation. Now, when renaming a data set with unsaved changes, you are prompted to resolve them before continuing. [#3328](https://github.com/zowe/zowe-explorer-vscode/pull/3328)
- Fixed an issue where a migrated data set is unusable after it is recalled through Zowe Explorer. [#3294](https://github.com/zowe/zowe-explorer-vscode/issues/3294)
- Fixed an issue where a recalled PDS is expandable after it is migrated through Zowe Explorer. [#3294](https://github.com/zowe/zowe-explorer-vscode/issues/3294)
- Fixed an issue where data set nodes did not update if migrated or recalled outside of Zowe Explorer. [#3294](https://github.com/zowe/zowe-explorer-vscode/issues/3294)

## `2.18.0`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import * as sharedUtils from "../../../src/shared/utils";
import { Profiles } from "../../../src/Profiles";
import { ZoweLogger } from "../../../src/utils/LoggerUtils";
import { LocalFileManagement } from "../../../src/utils/LocalFileManagement";
import { getIconById, IconId } from "../../../src/generators/icons";

// Missing the definition of path module, because I need the original logic for tests
jest.mock("fs");
Expand Down Expand Up @@ -435,3 +436,86 @@ describe("ZoweDatasetNode Unit Tests - Function node.setIcon()", () => {
expect(mocked(vscode.commands.executeCommand)).toHaveBeenCalledWith("zowe.ds.refreshDataset", node);
});
});

describe("ZoweDatasetNode Unit Tests - function datasetRecalled", () => {
it("changes the collapsible state", async () => {
const dsNode = new ZoweDatasetNode({
label: "MIGRATED.PDS",
collapsibleState: vscode.TreeItemCollapsibleState.None,
contextOverride: globals.DS_MIGRATED_FILE_CONTEXT,
profile: createIProfile(),
});
await (dsNode as any).datasetRecalled(true);
expect(dsNode.collapsibleState).toBe(vscode.TreeItemCollapsibleState.Collapsed);
});

it("adds the open command to the node - PS", async () => {
const dsNode = new ZoweDatasetNode({
label: "MIGRATED.PS",
collapsibleState: vscode.TreeItemCollapsibleState.None,
contextOverride: globals.DS_MIGRATED_FILE_CONTEXT,
profile: createIProfile(),
});
await (dsNode as any).datasetRecalled(false);
expect(dsNode.command).toStrictEqual({ command: "zowe.ds.ZoweNode.openPS", title: "", arguments: [dsNode] });
});

it("updates the icon to folder - PDS", async () => {
const dsNode = new ZoweDatasetNode({
label: "MIGRATED.PDS",
collapsibleState: vscode.TreeItemCollapsibleState.None,
contextOverride: globals.DS_MIGRATED_FILE_CONTEXT,
profile: createIProfile(),
});
await (dsNode as any).datasetRecalled(true);
expect(dsNode.iconPath).toBe(getIconById(IconId.folder).path);
});

it("updates the icon to file - PS", async () => {
const dsNode = new ZoweDatasetNode({
label: "MIGRATED.PS",
collapsibleState: vscode.TreeItemCollapsibleState.None,
contextOverride: globals.DS_MIGRATED_FILE_CONTEXT,
profile: createIProfile(),
});
await (dsNode as any).datasetRecalled(false);
expect(dsNode.iconPath).toBe(getIconById(IconId.document).path);
});
});

describe("ZoweDatasetNode Unit Tests - function datasetMigrated", () => {
it("changes the collapsible state", () => {
const dsNode = new ZoweDatasetNode({
label: "SOME.PDS",
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
contextOverride: globals.DS_PDS_CONTEXT,
profile: createIProfile(),
});
dsNode.datasetMigrated();
expect(dsNode.collapsibleState).toBe(vscode.TreeItemCollapsibleState.None);
});

it("removes the node command", () => {
const dsNode = new ZoweDatasetNode({
label: "SOME.PDS",
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
contextOverride: globals.DS_PDS_CONTEXT,
parentNode: createDatasetSessionNode(createISession(), createIProfile()),
profile: createIProfile(),
});
dsNode.datasetMigrated();
expect(dsNode.resourceUri).toBeUndefined();
expect(dsNode.command).toBeUndefined();
});

it("changes the icon to the migrated icon", () => {
const dsNode = new ZoweDatasetNode({
label: "MIGRATED.PDS",
collapsibleState: vscode.TreeItemCollapsibleState.None,
contextOverride: globals.DS_MIGRATED_FILE_CONTEXT,
profile: createIProfile(),
});
dsNode.datasetMigrated();
expect(dsNode.iconPath).toBe(getIconById(IconId.migrated).path);
});
});
78 changes: 65 additions & 13 deletions packages/zowe-explorer/src/dataset/ZoweDatasetNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,53 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod
}
}

/**
* Updates an existing data set node that was recalled so it can be interacted with.
* @param isPds Whether the data set is a PDS
*/
private datasetRecalled(isPds: boolean): void {
// Change context value to match dsorg, update collapsible state
// Preserve favorite context and any additional context values
this.contextValue = this.contextValue.replace(globals.DS_MIGRATED_FILE_CONTEXT, isPds ? globals.DS_PDS_CONTEXT : globals.DS_DS_CONTEXT);
this.collapsibleState = isPds ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None;

// For sequential data sets, re-apply the command so that they can be opened
if (!isPds) {
this.command = { command: "zowe.ds.ZoweNode.openPS", title: "", arguments: [this] };
}

// Replace icon on existing node with new one
const icon = getIconByNode(this);
if (icon) {
this.setIcon(icon.path);
}
}

/**
* Updates a data set node so it is marked as migrated.
*/
public datasetMigrated(): void {
// Change the context value and collapsible state to represent a migrated data set
// Preserve favorite context and any additional context values
const isBinary = contextually.isBinary(this);
const isPds = this.collapsibleState !== vscode.TreeItemCollapsibleState.None;
let previousContext = isBinary ? globals.DS_DS_BINARY_CONTEXT : globals.DS_DS_CONTEXT;
if (isPds) {
previousContext = globals.DS_PDS_CONTEXT;
}
this.contextValue = this.contextValue.replace(previousContext, globals.DS_MIGRATED_FILE_CONTEXT);
this.collapsibleState = vscode.TreeItemCollapsibleState.None;

// Remove the node's command
this.command = undefined;

// Assign migrated icon to the data set node
const icon = getIconByNode(this);
if (icon) {
this.setIcon(icon.path);
}
}

/**
* Retrieves child nodes of this ZoweDatasetNode
*
Expand Down Expand Up @@ -182,41 +229,46 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod
const dsEntry = item.dsname ?? item.member;
const existing = this.children.find((element) => element.label.toString() === dsEntry);
if (existing) {
if (contextually.isMigrated(existing) && item.migr?.toUpperCase() !== "YES") {
existing.datasetRecalled(item.dsorg === "PO" || item.dsorg === "PO-E");
} else if (!contextually.isMigrated(existing) && item.migr?.toUpperCase() === "YES") {
existing.datasetMigrated();
}
existing.updateStats(item);
elementChildren[existing.label.toString()] = existing;
// Creates a ZoweDatasetNode for a PDS
} else if (item.dsorg === "PO" || item.dsorg === "PO-E") {
} else if (item.migr && item.migr.toUpperCase() === "YES") {
// Creates a ZoweDatasetNode for a migrated dataset
const temp = new ZoweDatasetNode({
label: item.dsname,
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
collapsibleState: vscode.TreeItemCollapsibleState.None,
parentNode: this,
contextOverride: globals.DS_MIGRATED_FILE_CONTEXT,
profile: this.getProfile(),
});
elementChildren[temp.label.toString()] = temp;
// Creates a ZoweDatasetNode for a dataset with imperative errors
} else if (item.error instanceof zowe.imperative.ImperativeError) {
} else if (item.dsorg === "PO" || item.dsorg === "PO-E") {
// Creates a ZoweDatasetNode for a PDS
const temp = new ZoweDatasetNode({
label: item.dsname,
collapsibleState: vscode.TreeItemCollapsibleState.None,
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
parentNode: this,
contextOverride: globals.DS_FILE_ERROR_CONTEXT,
profile: this.getProfile(),
});
temp.command = { command: "zowe.placeholderCommand", title: "" };
temp.errorDetails = item.error; // Save imperative error to avoid extra z/OS requests
elementChildren[temp.label.toString()] = temp;
// Creates a ZoweDatasetNode for a migrated dataset
} else if (item.migr && item.migr.toUpperCase() === "YES") {
} else if (item.error instanceof zowe.imperative.ImperativeError) {
// Creates a ZoweDatasetNode for a dataset with imperative errors
const temp = new ZoweDatasetNode({
label: item.dsname,
collapsibleState: vscode.TreeItemCollapsibleState.None,
parentNode: this,
contextOverride: globals.DS_MIGRATED_FILE_CONTEXT,
contextOverride: globals.DS_FILE_ERROR_CONTEXT,
profile: this.getProfile(),
});
temp.command = { command: "zowe.placeholderCommand", title: "" };
temp.errorDetails = item.error; // Save imperative error to avoid extra z/OS requests
elementChildren[temp.label.toString()] = temp;
// Creates a ZoweDatasetNode for a VSAM file
} else if (item.dsorg === "VS") {
// Creates a ZoweDatasetNode for a VSAM file
let altLabel = item.dsname;
let endPoint = altLabel.indexOf(".DATA");
if (endPoint === -1) {
Expand Down
16 changes: 4 additions & 12 deletions packages/zowe-explorer/src/dataset/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1357,11 +1357,9 @@ export async function hMigrateDataSet(
if (Profiles.getInstance().validProfile !== api.ValidProfileEnum.INVALID) {
const { dataSetName } = dsUtils.getNodeLabels(node);
try {
const response = await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).hMigrateDataSet(dataSetName);
api.Gui.showMessage(localize("hMigrateDataSet.requestSent", "Migration of data set {0} requested.", dataSetName));
node.contextValue = globals.DS_MIGRATED_FILE_CONTEXT;
node.setIcon(getIconByNode(node).path);
datasetProvider.refresh();
const response = await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).hMigrateDataSet(dataSetName);
datasetProvider.refreshElement(node.getParent());
return response;
} catch (err) {
ZoweLogger.error(err);
Expand All @@ -1388,15 +1386,9 @@ export async function hRecallDataSet(
if (Profiles.getInstance().validProfile !== api.ValidProfileEnum.INVALID) {
const { dataSetName } = dsUtils.getNodeLabels(node);
try {
const response = await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).hRecallDataSet(dataSetName);
api.Gui.showMessage(localize("hRecallDataSet.requestSent", "Recall of data set {0} requested.", dataSetName));
if (node.collapsibleState !== vscode.TreeItemCollapsibleState.None) {
node.contextValue = globals.DS_PDS_CONTEXT;
} else {
node.contextValue = node.binary ? globals.DS_DS_BINARY_CONTEXT : globals.DS_DS_CONTEXT;
}
node.setIcon(getIconByNode(node).path);
datasetProvider.refresh();
const response = await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).hRecallDataSet(dataSetName);
datasetProvider.refreshElement(node.getSessionNode());
return response;
} catch (err) {
ZoweLogger.error(err);
Expand Down

0 comments on commit 4e42361

Please sign in to comment.