Skip to content

Filter and stars #401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@
"id": "queryHistory",
"name": "Statement History",
"visibility": "visible",
"when": "code-for-ibmi:connected == true"
"when": "code-for-ibmi:connected == true && vscode-db2i:jobManager.hasJob"
},
{
"id": "jobManager",
Expand Down Expand Up @@ -581,6 +581,18 @@
"category": "Db2 for i",
"icon": "$(trash)"
},
{
"command": "vscode-db2i.queryHistory.find",
"title": "Search query history",
"category": "Db2 for i",
"icon": "$(search)"
},
{
"command": "vscode-db2i.queryHistory.toggleStar",
"title": "Star statement",
"category": "Db2 for i",
"icon": "$(star)"
},
{
"command": "vscode-db2i.openSqlDocument",
"title": "Open SQL Document",
Expand Down Expand Up @@ -860,6 +872,14 @@
"command": "vscode-db2i.queryHistory.remove",
"when": "never"
},
{
"command": "vscode-db2i.queryHistory.find",
"when": "never"
},
{
"command": "vscode-db2i.queryHistory.toggleStar",
"when": "never"
},
{
"command": "vscode-db2i.jobManager.closeJob",
"when": "never"
Expand Down Expand Up @@ -973,6 +993,11 @@
"group": "navigation",
"when": "view == queryHistory"
},
{
"command": "vscode-db2i.queryHistory.find",
"group": "navigation",
"when": "view == queryHistory"
},
{
"command": "vscode-db2i.jobManager.newJob",
"group": "navigation@1",
Expand Down Expand Up @@ -1144,6 +1169,11 @@
"when": "view == queryHistory && viewItem == query",
"group": "inline"
},
{
"command": "vscode-db2i.queryHistory.toggleStar",
"when": "view == queryHistory && viewItem == query",
"group": "inline"
},
{
"command": "vscode-db2i.jobManager.closeJob",
"when": "view == jobManager && viewItem == sqlJob",
Expand Down
19 changes: 1 addition & 18 deletions src/Storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const SERVERCOMPONENT_KEY = `serverVersion`
export interface QueryHistoryItem {
query: string;
unix: number;
starred?: boolean;
}

export type QueryList = QueryHistoryItem[];
Expand Down Expand Up @@ -59,24 +60,6 @@ export class ConnectionStorage extends Storage {
return this.set(SERVERCOMPONENT_KEY, name);
}

/**
* Eventually we will want to remove this function, but for now we need to fix the past queries
*/
fixPastQueries() {
const currentList = this.getPastQueries() as (string|QueryHistoryItem)[];
const hasOldFormat = currentList.some(item => typeof item === `string`);
if (hasOldFormat) {
const newList = currentList.map(item => {
if (typeof item === `string`) {
return { query: item, unix: Math.floor(Date.now() / 1000) - 86400 };
} else {
return item;
}
});
return this.setPastQueries(newList);
}
}

getPastQueries() {
return this.get<QueryList>(QUERIES_KEY) || [];
}
Expand Down
2 changes: 0 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ export async function onConnectOrServerInstall(): Promise<boolean> {

Config.setConnectionName(instance.getConnection().currentConnectionName);

await Config.fixPastQueries();

osDetail = new IBMiDetail();

await osDetail.fetchSystemInfo();
Expand Down
32 changes: 31 additions & 1 deletion src/views/queryHistoryView/contributes.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"id": "queryHistory",
"name": "Statement History",
"visibility": "visible",
"when": "code-for-ibmi:connected == true"
"when": "code-for-ibmi:connected == true && vscode-db2i:jobManager.hasJob"
}
]
},
Expand All @@ -28,27 +28,57 @@
"title": "Clear statement history",
"category": "Db2 for i",
"icon": "$(trash)"
},
{
"command": "vscode-db2i.queryHistory.find",
"title": "Search query history",
"category": "Db2 for i",
"icon": "$(search)"
},
{
"command": "vscode-db2i.queryHistory.toggleStar",
"title": "Star statement",
"category": "Db2 for i",
"icon": "$(star)"
}
],
"menus": {
"commandPalette": [
{
"command": "vscode-db2i.queryHistory.remove",
"when": "never"
},
{
"command": "vscode-db2i.queryHistory.find",
"when": "never"
},
{
"command": "vscode-db2i.queryHistory.toggleStar",
"when": "never"
}
],
"view/title": [
{
"command": "vscode-db2i.queryHistory.clear",
"group": "navigation",
"when": "view == queryHistory"
},
{
"command": "vscode-db2i.queryHistory.find",
"group": "navigation",
"when": "view == queryHistory"
}
],
"view/item/context": [
{
"command": "vscode-db2i.queryHistory.remove",
"when": "view == queryHistory && viewItem == query",
"group": "inline"
},
{
"command": "vscode-db2i.queryHistory.toggleStar",
"when": "view == queryHistory && viewItem == query",
"group": "inline"
}
]
}
Expand Down
69 changes: 50 additions & 19 deletions src/views/queryHistoryView/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { commands, EventEmitter, ExtensionContext, MarkdownString, ThemeIcon, TreeItem, TreeItemCollapsibleState, window, workspace, Event } from "vscode";
import { TreeDataProvider } from "vscode";
import { Config } from "../../config";
import { QueryHistoryItem } from "../../Storage";

const openSqlDocumentCommand = `vscode-db2i.openSqlDocument`;

Expand All @@ -18,6 +19,10 @@ export class queryHistory implements TreeDataProvider<any> {
window.showTextDocument(doc);
});
}),
commands.registerCommand(`vscode-db2i.queryHistory.find`, async () => {
commands.executeCommand('queryHistory.focus');
commands.executeCommand('list.find');
}),

commands.registerCommand(`vscode-db2i.queryHistory.prepend`, async (newQuery?: string) => {
if (newQuery && Config.ready) {
Expand All @@ -43,12 +48,28 @@ export class queryHistory implements TreeDataProvider<any> {
}
}),

commands.registerCommand(`vscode-db2i.queryHistory.toggleStar`, async (node: PastQueryNode) => {
if (node && Config.ready) {
let currentList = Config.getPastQueries();
const existingQuery = currentList.findIndex(queryItem =>
queryItem.unix === node.item.unix
);

// If it exists, remove it
if (existingQuery >= 0) {
// Toggle the starred status
currentList[existingQuery].starred = !(currentList[existingQuery].starred === true);
await Config.setPastQueries(currentList);
this.refresh();
}
}
}),

commands.registerCommand(`vscode-db2i.queryHistory.remove`, async (node: PastQueryNode) => {
if (node && Config.ready) {
let currentList = Config.getPastQueries();
const chosenQuery = node.query;
const existingQuery = currentList.findIndex(queryItem =>
queryItem.query.trim() === chosenQuery.trim()
queryItem.unix === node.item.unix
);

// If it exists, remove it
Expand All @@ -61,10 +82,15 @@ export class queryHistory implements TreeDataProvider<any> {
}),

commands.registerCommand(`vscode-db2i.queryHistory.clear`, async () => {
if (Config.ready) {
await Config.setPastQueries([]);
this.refresh();
}
window.showInformationMessage(`Statement history`, {detail: `Are you sure you want to clear your statement history? This will not remove starred items.`, modal: true}, `Clear`).then(async (result) => {
if (result) {
if (Config.ready) {
const starredItems = Config.getPastQueries().filter(queryItem => queryItem.starred === true);
await Config.setPastQueries(starredItems);
this.refresh();
}
}
});
}),
)
}
Expand Down Expand Up @@ -98,24 +124,29 @@ export class queryHistory implements TreeDataProvider<any> {
let pastWeekQueries: PastQueryNode[] = [];
let pastMonthQueries: PastQueryNode[] = [];
let olderQueries: PastQueryNode[] = [];
const starredQueries = currentList.filter(queryItem => queryItem.starred);
const hasStarredQueries = starredQueries.length > 0;

currentList.forEach(queryItem => {
// The smaller the unix value, the older it is
if (queryItem.unix < monthAgo) {
olderQueries.push(new PastQueryNode(queryItem.query));
olderQueries.push(new PastQueryNode(queryItem));
} else if (queryItem.unix < weekAgo) {
pastMonthQueries.push(new PastQueryNode(queryItem.query));
pastMonthQueries.push(new PastQueryNode(queryItem));
} else if (queryItem.unix < dayAgo) {
pastWeekQueries.push(new PastQueryNode(queryItem.query));
pastWeekQueries.push(new PastQueryNode(queryItem));
} else {
pastDayQueries.push(new PastQueryNode(queryItem.query));
pastDayQueries.push(new PastQueryNode(queryItem));
}
});

let nodes: TimePeriodNode[] = [];

if (hasStarredQueries) {
nodes.push(new TimePeriodNode(`Starred`, starredQueries.map(q => new PastQueryNode(q)), {expanded: true, stars: true}));
}
if (pastDayQueries.length > 0) {
nodes.push(new TimePeriodNode(`Past day`, pastDayQueries, true));
nodes.push(new TimePeriodNode(`Past day`, pastDayQueries, {expanded: !hasStarredQueries}));
}
if (pastWeekQueries.length > 0) {
nodes.push(new TimePeriodNode(`Past week`, pastWeekQueries));
Expand All @@ -137,11 +168,11 @@ export class queryHistory implements TreeDataProvider<any> {
}

class TimePeriodNode extends TreeItem {
constructor(public period: string, private nodes: PastQueryNode[], expanded = false) {
super(period, expanded ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.Collapsed);
constructor(title: string, private nodes: PastQueryNode[], opts: { expanded?: boolean, stars?: boolean } = {}) {
super(title, opts.expanded ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.Collapsed);
this.contextValue = `timePeriod`;

this.iconPath = new ThemeIcon(`calendar`);
this.iconPath = new ThemeIcon(opts.stars ? `star-full` : `calendar`);
}

getChildren() {
Expand All @@ -150,19 +181,19 @@ class TimePeriodNode extends TreeItem {
}

class PastQueryNode extends TreeItem {
constructor(public query: string) {
super(query.length > 63 ? query.substring(0, 60) + `...` : query);
constructor(public item: QueryHistoryItem) {
super(item.query);

this.contextValue = `query`;

this.tooltip = new MarkdownString(['```sql', query, '```'].join(`\n`));
this.tooltip = new MarkdownString(['```sql', item.query, '```'].join(`\n`));

this.command = {
command: openSqlDocumentCommand,
arguments: [query],
arguments: [item.query],
title: `Open into new document`
};

this.iconPath = new ThemeIcon(`go-to-file`);
this.iconPath = new ThemeIcon(item.starred ? `star` : `go-to-file`);
}
}
Loading