initial work for components view

Signed-off-by: Sanjula Ganepola <sanjulagane@gmail.com>
This commit is contained in:
Sanjula Ganepola
2024-09-24 23:47:53 -04:00
parent 0d5ab6ae00
commit ecc5041e31
8 changed files with 192 additions and 24 deletions

View File

@@ -41,24 +41,54 @@
"views": { "views": {
"github-local-actions-container": [ "github-local-actions-container": [
{ {
"id": "status", "id": "component",
"name": "Status" "name": "Component",
"icon": "$(telescope)"
}, },
{ {
"id": "workflows", "id": "workflows",
"name": "Workflows" "name": "Workflows",
"icon": "$(remote-explorer)"
}, },
{ {
"id": "events", "id": "events",
"name": "Events" "name": "Events",
"icon": "$(rocket)"
}, },
{ {
"id": "settings", "id": "settings",
"name": "Settings" "name": "Settings",
"icon": "$(server-environment)"
} }
] ]
}, },
"commands": [ "commands": [
],
"colors": [
{
"id": "GitHubLocalActions.enabled",
"description": "Color for a component success state",
"defaults": {
"dark": "#89d185",
"light": "#89d185"
}
},
{
"id": "GitHubLocalActions.warning",
"description": "Color for a component warning state",
"defaults": {
"dark": "#cca700",
"light": "#cca700"
}
},
{
"id": "GitHubLocalActions.disabled",
"description": "Color for a component disabled state",
"defaults": {
"dark": "#f48771",
"light": "#f48771"
}
}
] ]
}, },
"scripts": { "scripts": {

View File

@@ -1,26 +1,15 @@
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { window } from 'vscode';
import ComponentTreeDataProvider from './views/component/componentTreeDataProvider';
// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) { export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "github-local-actions" is now active!'); console.log('Congratulations, your extension "github-local-actions" is now active!');
// The command has been defined in the package.json file const componentTreeDataProvider = new ComponentTreeDataProvider(context);
// Now provide the implementation of the command with registerCommand const componentTreeView = window.createTreeView(ComponentTreeDataProvider.VIEW_ID, { treeDataProvider: componentTreeDataProvider });
// The commandId parameter must match the command field in package.json context.subscriptions.push(
const disposable = vscode.commands.registerCommand('github-local-actions.helloWorld', () => { componentTreeView
// The code you place here will be executed every time your command is executed );
// Display a message box to the user
vscode.window.showInformationMessage('Hello World from github-local-actions!');
});
context.subscriptions.push(disposable);
} }
// This method is called when your extension is deactivated
export function deactivate() { } export function deactivate() { }

12
src/types.ts Normal file
View File

@@ -0,0 +1,12 @@
export interface Component {
name: string,
status: Status,
icon: string,
message?: string
}
export enum Status {
Enabled = 'Enabled',
Warning = 'Warning',
Disabled = 'Disabled'
}

View File

@@ -0,0 +1,24 @@
import { ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from "vscode";
import { Component } from "../../types";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
export default class ComponentTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'component';
component: Component;
constructor(component: Component) {
super(component.name, TreeItemCollapsibleState.Collapsed);
this.component = component;
this.collapsibleState = TreeItemCollapsibleState.None;
this.contextValue = ComponentTreeItem.contextValue;
this.iconPath = new ThemeIcon(component.icon);
this.resourceUri = Uri.parse(`${ComponentTreeItem.contextValue}:${component.name}?status=${component.status}`, true);
this.tooltip = `Name: ${component.name}\n` +
`Status: ${component.status}\n` +
(component.message ? `Message: ${component.message}` : ``);
}
async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
return [];
}
}

View File

@@ -0,0 +1,46 @@
import { CancellationToken, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem, window } from "vscode";
import { ComponentManager } from "../componentManager";
import { DecorationProvider } from "../decorationProvider";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
import ComponentTreeItem from "./component";
export default class ComponentTreeDataProvider implements TreeDataProvider<GithubLocalActionsTreeItem> {
private _onDidChangeTreeData = new EventEmitter<GithubLocalActionsTreeItem | undefined | null | void>();
readonly onDidChangeTreeData = this._onDidChangeTreeData.event;
public static VIEW_ID = 'component';
private componentManager: ComponentManager;
constructor(context: ExtensionContext) {
this.componentManager = new ComponentManager();
const decorationProvider = new DecorationProvider();
context.subscriptions.push(
window.registerFileDecorationProvider(decorationProvider),
);
}
refresh(element?: GithubLocalActionsTreeItem) {
this._onDidChangeTreeData.fire(element);
}
getTreeItem(element: GithubLocalActionsTreeItem): GithubLocalActionsTreeItem | Thenable<GithubLocalActionsTreeItem> {
return element;
}
async resolveTreeItem(item: TreeItem, element: GithubLocalActionsTreeItem, token: CancellationToken): Promise<GithubLocalActionsTreeItem> {
if (element.getToolTip) {
element.tooltip = await element.getToolTip();
}
return element;
}
async getChildren(element?: GithubLocalActionsTreeItem): Promise<GithubLocalActionsTreeItem[]> {
if (element) {
return element.getChildren();
} else {
const components = await this.componentManager.getComponents();
return components.map(component => new ComponentTreeItem(component));
}
}
}

View File

@@ -0,0 +1,32 @@
import { Component, Status } from "../types";
export class ComponentManager {
components: Component[] = [
{
name: 'nektos/act',
status: Status.Enabled,
icon: 'package'
},
{
name: 'Docker Engine',
status: Status.Disabled,
icon: 'dashboard'
},
{
name: 'GitHub Actions Extension',
status: Status.Warning,
icon: 'extensions',
message: 'GitHub Actions extension is not required but is recommended to take advantage of workflow editor features'
},
{
name: 'GitHub Actions CLI',
status: Status.Warning,
icon: 'terminal',
message: 'GitHub Actions CLI is not required but is recommended if you plan to use it to retrieve GitHub tokens'
}
];
async getComponents(): Promise<Component[]> {
return this.components;
}
}

View File

@@ -0,0 +1,28 @@
import { CancellationToken, Event, FileDecoration, FileDecorationProvider, ProviderResult, ThemeColor, Uri } from "vscode";
import { Status } from "../types";
import ComponentTreeItem from "./component/component";
export class DecorationProvider implements FileDecorationProvider {
onDidChangeFileDecorations?: Event<Uri | Uri[] | undefined> | undefined;
provideFileDecoration(uri: Uri, token: CancellationToken): ProviderResult<FileDecoration> {
if (uri.scheme === ComponentTreeItem.contextValue) {
const params = new URLSearchParams(uri.query);
if (params.get('status') === Status.Enabled) {
return {
badge: '✅',
color: new ThemeColor('GitHubLocalActions.enabled')
};
} else if (params.get('status') === Status.Warning) {
return {
badge: '⚠️',
color: new ThemeColor('GitHubLocalActions.warning')
};
} else if (params.get('status') === Status.Disabled) {
return {
badge: '❌',
color: new ThemeColor('GitHubLocalActions.disabled')
};
}
}
}
}

View File

@@ -0,0 +1,7 @@
import { MarkdownString, TreeItem } from "vscode";
export interface GithubLocalActionsTreeItem extends TreeItem {
getChildren: () => GithubLocalActionsTreeItem[] | Promise<GithubLocalActionsTreeItem[]>;
getToolTip?: () => Promise<MarkdownString | string | undefined>;
}