Skip to content

Commit

Permalink
feat(ds): Sort by date modified, name, or user ID
Browse files Browse the repository at this point in the history
Signed-off-by: Trae Yelovich <[email protected]>
  • Loading branch information
traeok committed Oct 3, 2023
1 parent 4b30095 commit 6a268a7
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 26 deletions.
19 changes: 19 additions & 0 deletions packages/zowe-explorer-api/src/tree/IZoweTreeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ export enum NodeAction {
Download = "download",
}

export enum DatasetSort {
LastModified,
Name,
UserId,
}

export type DatasetStats = {
user: string;
m4date: Date;
};

/**
* The base interface for Zowe tree nodes that are implemented by vscode.TreeItem.
*
Expand Down Expand Up @@ -135,6 +146,14 @@ export interface IZoweDatasetTreeNode extends IZoweTreeNode {
* Search criteria for a Dataset member search
*/
memberPattern?: string;
/**
* Sort members of a node by the given sorting method
*/
sortMethod?: DatasetSort;
/**
* Additional statistics about this data set
*/
stats?: Partial<DatasetStats>;
/**
* Retrieves child nodes of this IZoweDatasetTreeNode
*
Expand Down
8 changes: 5 additions & 3 deletions packages/zowe-explorer/i18n/sample/package.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@
"createZoweSchema.reload.infoMessage": "Team Configuration file created. Location: {0}. \n Please reload your window.",
"copyFile": "Copy",
"pasteFile": "Paste",
"jobs.sortbyreturncode": "Sort by ReturnCode",
"jobs.sortbyname": "Sort by Name",
"jobs.sortbyid": "Sort by ID"
"jobs.sortbyreturncode": "Sort by Return Code",
"jobs.sortbyid": "Sort by ID",
"sortByName": "Sort by Name",
"ds.sortByUserId": "Sort by User ID",
"ds.sortByModified": "Sort by Date Modified"
}
32 changes: 31 additions & 1 deletion packages/zowe-explorer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
},
{
"command": "zowe.jobs.sortbyname",
"title": "%jobs.sortbyname%",
"title": "%sortByName%",
"category": "Zowe Explorer"
},
{
Expand Down Expand Up @@ -276,6 +276,21 @@
"title": "%deleteProfile%",
"category": "Zowe Explorer"
},
{
"command": "zowe.ds.sortByName",
"title": "%sortByName%",
"category": "Zowe Explorer"
},
{
"command": "zowe.ds.sortByModified",
"title": "%ds.sortByModified%",
"category": "Zowe Explorer"
},
{
"command": "zowe.ds.sortByUserId",
"title": "%ds.sortByUserId%",
"category": "Zowe Explorer"
},
{
"command": "zowe.cmd.deleteProfile",
"title": "%cmd.deleteProfile%",
Expand Down Expand Up @@ -1108,6 +1123,21 @@
"command": "zowe.ds.removeFavProfile",
"group": "002_zowe_dsWorkspace@4"
},
{
"when": "view == zowe.ds.explorer && viewItem =~ /^(pds).*/ && !listMultiSelection",
"command": "zowe.ds.sortByModified",
"group": "003_zowe_dsSort@1"
},
{
"when": "view == zowe.ds.explorer && viewItem =~ /^(pds).*/ && !listMultiSelection",
"command": "zowe.ds.sortByName",
"group": "003_zowe_dsSort@2"
},
{
"when": "view == zowe.ds.explorer && viewItem =~ /^(pds).*/ && !listMultiSelection",
"command": "zowe.ds.sortByUserId",
"group": "003_zowe_dsSort@3"
},
{
"when": "view == zowe.ds.explorer && viewItem =~ /^fileError.*/",
"command": "zowe.ds.showFileErrorDetails",
Expand Down
8 changes: 5 additions & 3 deletions packages/zowe-explorer/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@
"createZoweSchema.reload.infoMessage": "Team Configuration file created. Location: {0}. \n Please reload your window.",
"copyFile": "Copy",
"pasteFile": "Paste",
"jobs.sortbyreturncode": "Sort by ReturnCode",
"jobs.sortbyname": "Sort by Name",
"jobs.sortbyid": "Sort by ID"
"jobs.sortbyreturncode": "Sort by Return Code",
"jobs.sortbyid": "Sort by ID",
"sortByName": "Sort by Name",
"ds.sortByUserId": "Sort by User ID",
"ds.sortByModified": "Sort by Date Modified"
}
10 changes: 10 additions & 0 deletions packages/zowe-explorer/src/abstract/ZoweTreeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ export class ZoweTreeProvider {
}
}

/**
* Fire the "onDidChangeTreeData" event to signal that a node in the tree has changed.
* Unlike `refreshElement`, this function does NOT signal a refresh for the given node -
* it simply tells VS Code to repaint the node in the tree.
* @param node The node that should be repainted
*/
public nodeDataChanged(node: IZoweTreeNode): void {
this.mOnDidChangeTreeData.fire(node);
}

/**
* Called whenever the tree needs to be refreshed, and fires the data change event
*
Expand Down
17 changes: 17 additions & 0 deletions packages/zowe-explorer/src/dataset/DatasetTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
PersistenceSchemaEnum,
NodeInteraction,
IZoweTreeNode,
DatasetSort,
} from "@zowe/zowe-explorer-api";
import { Profiles } from "../Profiles";
import { ZoweExplorerApiRegister } from "../ZoweExplorerApiRegister";
Expand Down Expand Up @@ -1287,4 +1288,20 @@ export class DatasetTree extends ZoweTreeProvider implements IZoweTree<IZoweData
this.mHistory.addSession(profile.name);
}
}

/**
* Sorts the children for a node with the given sorting method.
* @param method The sorting method to use
* @param node The node whose children should be sorted
*/
public sortBy(method: DatasetSort, node: IZoweDatasetTreeNode): void {
node.sortMethod = method;
if (node.children && node.children.length > 0) {
// If children nodes already exist, sort now and avoid extra refresh
node.children.sort(ZoweDatasetNode.sortBy(method));
this.nodeDataChanged(node);
} else {
this.refreshElement(node);
}
}
}
34 changes: 29 additions & 5 deletions packages/zowe-explorer/src/dataset/ZoweDatasetNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import * as zowe from "@zowe/cli";
import * as vscode from "vscode";
import * as globals from "../globals";
import { errorHandling } from "../utils/ProfilesUtils";
import { Gui, NodeAction, IZoweDatasetTreeNode, ZoweTreeNode } from "@zowe/zowe-explorer-api";
import { DatasetSort, DatasetStats, Gui, NodeAction, IZoweDatasetTreeNode, ZoweTreeNode } from "@zowe/zowe-explorer-api";
import { ZoweExplorerApiRegister } from "../ZoweExplorerApiRegister";
import { getIconByNode } from "../generators/icons";
import * as contextually from "../shared/context";
Expand Down Expand Up @@ -43,6 +43,8 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod
public errorDetails: zowe.imperative.ImperativeError;
public ongoingActions: Record<NodeAction | string, Promise<any>> = {};
public wasDoubleClicked: boolean = false;
public sortMethod: DatasetSort = DatasetSort.Name;
public stats: DatasetStats;

/**
* Creates an instance of ZoweDatasetNode
Expand Down Expand Up @@ -77,8 +79,8 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod
if (icon) {
this.iconPath = icon.path;
}
if (!globals.ISTHEIA && this.getParent() && contextually.isSession(this.getParent())) {
this.id = `${mParent?.id ?? mParent?.label?.toString() ?? "<root>"}.${this.label as string}`;
if (!globals.ISTHEIA && contextually.isSession(this)) {
this.id = this.label as string;
}
}

Expand Down Expand Up @@ -235,6 +237,12 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod
msg: localize("getChildren.invalidMember", "Cannot access member with control characters in the name: {0}", item.member),
});
}
if (item.m4date) {
temp.stats = {
user: item.user,
m4date: new Date(`${item.m4date.replace(/\//g, "-")}T${item.mtime as string}:${item.msec as string}`),

Check failure on line 243 in packages/zowe-explorer/src/dataset/ZoweDatasetNode.ts

View workflow job for this annotation

GitHub Actions / lint

Invalid type "any" of template literal expression
};
}
elementChildren[temp.label.toString()] = temp;
}
}
Expand All @@ -253,16 +261,32 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod
];
} else {
const newChildren = Object.keys(elementChildren)
.sort()
.filter((label) => this.children.find((c) => (c.label as string) === label) == null)
.map((label) => elementChildren[label]);

this.children = this.children.concat(newChildren).filter((c) => (c.label as string) in elementChildren);
this.children = this.children
.concat(newChildren)
.filter((c) => (c.label as string) in elementChildren)
.sort(ZoweDatasetNode.sortBy(this.sortMethod));
}

return this.children;
}

public static sortBy(method: DatasetSort): (a: IZoweDatasetTreeNode, b: IZoweDatasetTreeNode) => number {
return (a, b): number => {
switch (method) {
case DatasetSort.LastModified:
return a.stats?.m4date < b.stats?.m4date ? -1 : 1;
case DatasetSort.UserId:
return a.stats?.user < b.stats?.user ? -1 : 1;
case DatasetSort.Name:
default:
return (a.label as string) < (b.label as string) ? -1 : 1;
}
};
}

public getSessionNode(): IZoweDatasetTreeNode {
ZoweLogger.trace("ZoweDatasetNode.getSessionNode called.");
return this.getParent() ? this.getParent().getSessionNode() : this;
Expand Down
41 changes: 27 additions & 14 deletions packages/zowe-explorer/src/dataset/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import * as globals from "../globals";
import * as vscode from "vscode";
import * as dsActions from "./actions";
import * as refreshActions from "../shared/refresh";
import { IZoweDatasetTreeNode, IZoweTreeNode, IZoweTree } from "@zowe/zowe-explorer-api";
import { IZoweDatasetTreeNode, IZoweTreeNode, IZoweTree, DatasetSort } from "@zowe/zowe-explorer-api";
import { Profiles } from "../Profiles";
import { createDatasetTree } from "./DatasetTree";
import { ZoweDatasetNode } from "./ZoweDatasetNode";
Expand All @@ -25,7 +25,7 @@ import { TreeViewUtils } from "../utils/TreeViewUtils";

export async function initDatasetProvider(context: vscode.ExtensionContext): Promise<IZoweTree<IZoweDatasetTreeNode>> {
ZoweLogger.trace("dataset.init.initDatasetProvider called.");
const datasetProvider: IZoweTree<IZoweDatasetTreeNode> = await createDatasetTree(globals.LOG);
const datasetProvider = await createDatasetTree(globals.LOG);
if (datasetProvider == null) {
return null;
}
Expand All @@ -37,10 +37,10 @@ export async function initDatasetProvider(context: vscode.ExtensionContext): Pro
);
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.addSession", async () => datasetProvider.createZoweSession(datasetProvider)));
context.subscriptions.push(
vscode.commands.registerCommand("zowe.ds.addFavorite", (node, nodeList) => {
vscode.commands.registerCommand("zowe.ds.addFavorite", async (node, nodeList) => {
const selectedNodes = getSelectedNodeList(node, nodeList);
for (const item of selectedNodes) {
datasetProvider.addFavorite(item);
await datasetProvider.addFavorite(item);
}
})
);
Expand All @@ -67,7 +67,7 @@ export async function initDatasetProvider(context: vscode.ExtensionContext): Pro
}
})
);
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.pattern", (node): void => datasetProvider.filterPrompt(node)));
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.pattern", (node) => datasetProvider.filterPrompt(node)));
context.subscriptions.push(
vscode.commands.registerCommand("zowe.ds.editSession", async (node) => datasetProvider.editSession(node, datasetProvider))
);
Expand Down Expand Up @@ -126,10 +126,10 @@ export async function initDatasetProvider(context: vscode.ExtensionContext): Pro
}
})
);
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.saveSearch", (node): void => datasetProvider.addFavorite(node)));
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.removeSavedSearch", (node): void => datasetProvider.removeFavorite(node)));
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.saveSearch", (node) => datasetProvider.addFavorite(node)));
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.removeSavedSearch", (node) => datasetProvider.removeFavorite(node)));
context.subscriptions.push(
vscode.commands.registerCommand("zowe.ds.removeFavProfile", (node): void => datasetProvider.removeFavProfile(node.label, true))
vscode.commands.registerCommand("zowe.ds.removeFavProfile", (node) => datasetProvider.removeFavProfile(node.label, true))
);
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.submitJcl", async () => dsActions.submitJcl(datasetProvider)));
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.submitMember", async (node) => dsActions.submitMember(node)));
Expand All @@ -143,7 +143,7 @@ export async function initDatasetProvider(context: vscode.ExtensionContext): Pro
}
})
);
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.renameDataSet", (node): void => datasetProvider.rename(node)));
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.renameDataSet", (node) => datasetProvider.rename(node)));
context.subscriptions.push(
vscode.commands.registerCommand("zowe.ds.copyDataSets", async (node, nodeList) => dsActions.copyDataSets(node, nodeList, datasetProvider))
);
Expand All @@ -156,7 +156,7 @@ export async function initDatasetProvider(context: vscode.ExtensionContext): Pro
await dsActions.refreshDataset(node.getParent(), datasetProvider);
})
);
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.renameDataSetMember", (node): void => datasetProvider.rename(node)));
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.renameDataSetMember", (node) => datasetProvider.rename(node)));
context.subscriptions.push(
vscode.commands.registerCommand("zowe.ds.hMigrateDataSet", async (node, nodeList) => {
let selectedNodes = getSelectedNodeList(node, nodeList);
Expand Down Expand Up @@ -196,11 +196,24 @@ export async function initDatasetProvider(context: vscode.ExtensionContext): Pro
datasetProvider.refreshElement(node);
})
);
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.ssoLogin", (node: IZoweTreeNode): void => datasetProvider.ssoLogin(node)));
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.ssoLogout", (node: IZoweTreeNode): void => datasetProvider.ssoLogout(node)));
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.ssoLogin", (node: IZoweTreeNode) => datasetProvider.ssoLogin(node)));
context.subscriptions.push(vscode.commands.registerCommand("zowe.ds.ssoLogout", (node: IZoweTreeNode) => datasetProvider.ssoLogout(node)));
context.subscriptions.push(
vscode.workspace.onDidChangeConfiguration((e) => {
datasetProvider.onDidChangeConfiguration(e);
vscode.commands.registerCommand("zowe.ds.sortByName", (node: IZoweDatasetTreeNode): void => datasetProvider.sortBy(DatasetSort.Name, node))
);
context.subscriptions.push(
vscode.commands.registerCommand("zowe.ds.sortByModified", (node: IZoweDatasetTreeNode): void =>
datasetProvider.sortBy(DatasetSort.LastModified, node)
)
);
context.subscriptions.push(
vscode.commands.registerCommand("zowe.ds.sortByUserId", (node: IZoweDatasetTreeNode): void =>
datasetProvider.sortBy(DatasetSort.UserId, node)
)
);
context.subscriptions.push(
vscode.workspace.onDidChangeConfiguration(async (e) => {
await datasetProvider.onDidChangeConfiguration(e);
})
);

Expand Down

0 comments on commit 6a268a7

Please sign in to comment.