Skip to content

Commit

Permalink
add actions Edit, Copy to clipboard for features; use type instead of…
Browse files Browse the repository at this point in the history
… value in the tree item view
  • Loading branch information
tinahollygb committed Nov 4, 2022
1 parent 607a915 commit c480ee7
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 39 deletions.
6 changes: 6 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,11 @@
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_"
}
]
}
}
28 changes: 28 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@
"when": "true",
"group": "navigation"
}
],
"view/item/context": [
{
"command": "growthbook.copyFeatureKey",
"when": "view == featuresList",
"group": "inline"
},
{
"command": "growthbook.editFeature",
"when": "view == featuresList",
"group": "inline"
}
]
},
"viewsWelcome": [
Expand Down Expand Up @@ -51,6 +63,22 @@
{
"command": "growthbook.createConfig",
"title": "GrowthBook: Create a .growthbook.json configuration file"
},
{
"command": "growthbook.copyFeatureKey",
"title": "Copy feature key",
"icon": {
"light": "resources/ic_copy_light.png",
"dark": "resources/ic_copy_dark.png"
}
},
{
"command": "growthbook.editFeature",
"title": "Open feature in browser",
"icon": {
"light": "resources/ic_pencil_light.png",
"dark": "resources/ic_pencil_dark.png"
}
}
]
},
Expand Down
Binary file added resources/ic_copy_dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/ic_copy_light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/ic_pencil_dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/ic_pencil_light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions src/commands/copy-feature-key-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as vscode from "vscode";
import { Disposable } from "vscode";
import { ICommand } from "./ICommand";
import { FeatureListTreeItem } from "../features/FeatureListTreeDataProvider";
import {
getGrowthBookConfig,
getWorkspaceRootPath,
} from "../utils/vscode-utils";

export class CopyFeatureKeyCommand implements ICommand {
register(): Disposable {
return vscode.commands.registerCommand(
"growthbook.copyFeatureKey",
(treeItem: FeatureListTreeItem) => {
const rootPath = getWorkspaceRootPath();
if (!rootPath) {
vscode.window.showErrorMessage(
"Must be in a folder in order to create a GrowthBook configuration file"
);
return;
}

const config = getGrowthBookConfig(rootPath);
if (!config) {
vscode.window.showErrorMessage(
"The .growthbook.json file appears to be misconfigured"
);
return;
}

const feature = treeItem.getFeature();

vscode.env.clipboard.writeText(feature.id);
vscode.window.showInformationMessage(
`Feature key "${feature.id}" copied to clipboard`
);
}
);
}
}
72 changes: 38 additions & 34 deletions src/commands/create-config-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,47 @@ import {
GrowthBookConfig,
} from "../utils/vscode-utils";
import { ICommand } from "./ICommand";
import { FeatureListTreeItem } from "../features/FeatureListTreeDataProvider";

export class CreateGrowthBookConfigCommand implements ICommand {
register(): Disposable {
return vscode.commands.registerCommand("growthbook.createConfig", () => {
const rootPath = getWorkspaceRootPath();

if (!rootPath) {
vscode.window.showErrorMessage(
"Must be in a folder in order to create a GrowthBook configuration file"
);
return;
return vscode.commands.registerCommand(
"growthbook.createConfig",
(_treeItem: FeatureListTreeItem) => {
const rootPath = getWorkspaceRootPath();

if (!rootPath) {
vscode.window.showErrorMessage(
"Must be in a folder in order to create a GrowthBook configuration file"
);
return;
}

const configPath = `${rootPath}/.growthbook.json`;

const configFileExists = doesPathExist(configPath);
if (configFileExists) {
vscode.window.showWarningMessage(
"A .growthbook.json file already exists in the project root. Skipping."
);
return;
}

try {
const defaultConfig: GrowthBookConfig = {
featuresEndpoint: "",
appHost: "https://app.growthbook.io",
};

const buffer = Buffer.from(JSON.stringify(defaultConfig, null, 2));

const configUri = vscode.Uri.parse(configPath);

vscode.workspace.fs.writeFile(configUri, buffer);
} catch (e) {
onExtensionError("Unable to write configuration file");
}
}

const configPath = `${rootPath}/.growthbook.json`;

const configFileExists = doesPathExist(configPath);
if (configFileExists) {
vscode.window.showWarningMessage(
"A .growthbook.json file already exists in the project root. Skipping."
);
return;
}

try {
const defaultConfig: GrowthBookConfig = {
featuresEndpoint: "",
appHost: "https://app.growthbook.io",
};

const buffer = Buffer.from(JSON.stringify(defaultConfig, null, 2));

const configUri = vscode.Uri.parse(configPath);

vscode.workspace.fs.writeFile(configUri, buffer);
} catch (e) {
onExtensionError("Unable to write configuration file");
}
});
);
}
}
39 changes: 39 additions & 0 deletions src/commands/edit-feature-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as vscode from "vscode";
import { Disposable, Uri } from "vscode";
import { ICommand } from "./ICommand";
import {
getGrowthBookConfig,
getWorkspaceRootPath,
} from "../utils/vscode-utils";
import { FeatureListTreeItem } from "../features/FeatureListTreeDataProvider";

export class EditFeatureCommand implements ICommand {
register(): Disposable {
return vscode.commands.registerCommand(
"growthbook.editFeature",
(treeItem: FeatureListTreeItem) => {
const rootPath = getWorkspaceRootPath();
if (!rootPath) {
vscode.window.showErrorMessage(
"Must be in a folder in order to create a GrowthBook configuration file"
);
return;
}

const config = getGrowthBookConfig(rootPath);
if (!config) {
vscode.window.showErrorMessage(
"The .growthbook.json file appears to be misconfigured"
);
return;
}

const feature = treeItem.getFeature();
const url = `${config.appHost}/features/${feature.id}`;
const uri = Uri.parse(url);

vscode.env.openExternal(uri);
}
);
}
}
10 changes: 7 additions & 3 deletions src/commands/refresh-growthbook-command.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import * as vscode from "vscode";
import { Disposable } from "vscode";
import { ICommand } from "./ICommand";
import { FeatureListTreeItem } from "../features/FeatureListTreeDataProvider";

export class RefreshGrowthBookCommand implements ICommand {
constructor(private performRefresh: () => Promise<void>) {}

register(): Disposable {
return vscode.commands.registerCommand("growthbook.refreshFeatures", () => {
this.performRefresh();
});
return vscode.commands.registerCommand(
"growthbook.refreshFeatures",
(_treeItem: FeatureListTreeItem) => {
this.performRefresh();
}
);
}
}
6 changes: 5 additions & 1 deletion src/features/FeatureListTreeDataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ export class FeatureListTreeItem extends TreeItem {
) {
super(label, collapsibleState);
this.tooltip = this.feature.raw || "";
this.description = `(default: ${this.feature.defaultValue})`;
this.description = typeof JSON.parse(feature.raw).defaultValue;
}

getFeature() {
return this.feature;
}

iconPath = {
Expand Down
7 changes: 6 additions & 1 deletion src/services/ExtensionInitialization.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as vscode from "vscode";
import { ApiClient } from "../api/api-client";
import { CopyFeatureKeyCommand } from "../commands/copy-feature-key-command";
import { CreateGrowthBookConfigCommand } from "../commands/create-config-command";
import { EditFeatureCommand } from "../commands/edit-feature-command";
import { RefreshGrowthBookCommand } from "../commands/refresh-growthbook-command";
import {
FeatureListTreeDataProvider,
Expand Down Expand Up @@ -107,7 +109,9 @@ export class ExtensionManagement implements IExtensionManagement {
new RefreshGrowthBookCommand(
this.refreshFeatures.bind(this)
).register(),
new CreateGrowthBookConfigCommand().register()
new CreateGrowthBookConfigCommand().register(),
new EditFeatureCommand().register(),
new CopyFeatureKeyCommand().register()
);

// Initialize the tree view
Expand All @@ -118,6 +122,7 @@ export class ExtensionManagement implements IExtensionManagement {

return Promise.resolve();
} catch (e) {
console.error("Fetch error", e);
return Promise.reject("GrowthBook: Cannot fetch features");
}
}
Expand Down

0 comments on commit c480ee7

Please sign in to comment.