Pass kanbn to react via webview message

This commit is contained in:
Gordon 2021-03-28 04:11:46 +01:00
parent 878fcbba39
commit d2234485f4
9 changed files with 9565 additions and 27652 deletions

View File

@ -8,10 +8,9 @@ export default class KanbnBoardPanel {
private readonly _panel: vscode.WebviewPanel; private readonly _panel: vscode.WebviewPanel;
private readonly _extensionPath: string; private readonly _extensionPath: string;
private readonly _workspacePath: string;
private _disposables: vscode.Disposable[] = []; private _disposables: vscode.Disposable[] = [];
public static createOrShow(extensionPath: string, workspacePath: string) { public static createOrShow(extensionPath: string) {
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined; const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
// If we already have a panel, show it. // If we already have a panel, show it.
@ -21,21 +20,40 @@ export default class KanbnBoardPanel {
} else { } else {
KanbnBoardPanel.currentPanel = new KanbnBoardPanel( KanbnBoardPanel.currentPanel = new KanbnBoardPanel(
extensionPath, extensionPath,
workspacePath,
column || vscode.ViewColumn.One column || vscode.ViewColumn.One
); );
} }
} }
private constructor(extensionPath: string, workspacePath: string, column: vscode.ViewColumn) { public static async updateBoard(kanbn: typeof import('@basementuniverse/kanbn/src/main')) {
if (KanbnBoardPanel.currentPanel) {
let index: any;
try {
index = await kanbn.getIndex();
} catch (error) {
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
return;
}
KanbnBoardPanel.currentPanel._panel.webview.postMessage({
index,
tasks: (await kanbn.loadAllTrackedTasks(index)).map(
task => kanbn.hydrateTask(index, task)
)
});
}
}
private constructor(extensionPath: string, column: vscode.ViewColumn) {
this._extensionPath = extensionPath; this._extensionPath = extensionPath;
this._workspacePath = workspacePath;
// Create and show a new webview panel // Create and show a new webview panel
this._panel = vscode.window.createWebviewPanel(KanbnBoardPanel.viewType, "Kanbn Board", column, { this._panel = vscode.window.createWebviewPanel(KanbnBoardPanel.viewType, "Kanbn Board", column, {
// Enable javascript in the webview // Enable javascript in the webview
enableScripts: true, enableScripts: true,
// Retain state even when hidden
retainContextWhenHidden: true,
// Restrict the webview to only loading content from our extension's `media` directory. // Restrict the webview to only loading content from our extension's `media` directory.
localResourceRoots: [ localResourceRoots: [
vscode.Uri.file(path.join(this._extensionPath, 'build')) vscode.Uri.file(path.join(this._extensionPath, 'build'))

View File

@ -42,6 +42,7 @@ export async function activate(context: vscode.ExtensionContext) {
}); });
vscode.window.showInformationMessage(`Initialised kanbn project '${newProjectName}'.`); vscode.window.showInformationMessage(`Initialised kanbn project '${newProjectName}'.`);
kanbnStatusBarItem.update(kanbn); kanbnStatusBarItem.update(kanbn);
KanbnBoardPanel.updateBoard(kanbn);
} }
})); }));
@ -61,7 +62,8 @@ export async function activate(context: vscode.ExtensionContext) {
// If kanbn is initialised, view the kanbn board // If kanbn is initialised, view the kanbn board
if (await kanbn.initialised()) { if (await kanbn.initialised()) {
KanbnBoardPanel.createOrShow(context.extensionPath, kanbn.getMainFolder()); KanbnBoardPanel.createOrShow(context.extensionPath);
KanbnBoardPanel.updateBoard(kanbn);
} else { } else {
vscode.window.showErrorMessage('You need to initialise kanbn before viewing the kanbn board.'); vscode.window.showErrorMessage('You need to initialise kanbn before viewing the kanbn board.');
} }
@ -77,13 +79,14 @@ export async function activate(context: vscode.ExtensionContext) {
// Create status bar item // Create status bar item
kanbnStatusBarItem = new KanbnStatusBarItem(context); kanbnStatusBarItem = new KanbnStatusBarItem(context);
kanbnStatusBarItem.update(kanbn); kanbnStatusBarItem.update(kanbn);
KanbnBoardPanel.updateBoard(kanbn);
// Initialise file watcher // Initialise file watcher
const uri = vscode.workspace.workspaceFolders[0].uri.fsPath; const uri = vscode.workspace.workspaceFolders[0].uri.fsPath;
const fileWatcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(uri, '.kanbn/*')); const fileWatcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(uri, '.kanbn/*'));
fileWatcher.onDidChange(() => { fileWatcher.onDidChange(() => {
kanbnStatusBarItem.update(kanbn); kanbnStatusBarItem.update(kanbn);
// TODO refresh kanbn board KanbnBoardPanel.updateBoard(kanbn);
}); });
} }
} }

37063
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -29,8 +29,7 @@
"react-beautiful-dnd": "12.2.0", "react-beautiful-dnd": "12.2.0",
"react-dom": "^16.3.2", "react-dom": "^16.3.2",
"terser": "3.14.1", "terser": "3.14.1",
"uuid": "3.3.3", "vscode": "^1.1.37"
"vscode": "^1.1.17"
}, },
"scripts": { "scripts": {
"vscode:prepublish": "./scripts/build-non-split.js && tsc -p tsconfig.extension.json", "vscode:prepublish": "./scripts/build-non-split.js && tsc -p tsconfig.extension.json",
@ -41,11 +40,11 @@
"eject": "react-scripts eject" "eject": "react-scripts eject"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^23.3.13", "@types/jest": "^23.3.14",
"@types/node": "^10.1.2", "@types/node": "^10.17.56",
"@types/react": "^16.3.14", "@types/react": "^16.14.5",
"@types/react-dom": "^16.0.5", "@types/react-dom": "^16.9.12",
"react-scripts": "^2.1.3", "react-scripts": "^2.1.8",
"rewire": "^4.0.1", "rewire": "^4.0.1",
"typescript": "^4.0.2" "typescript": "^4.0.2"
}, },

View File

@ -1,37 +1,30 @@
// import * as vscode from 'vscode';
import Board from './Board'; import Board from './Board';
import Header from './Header'; import Header from './Header';
import React, { useEffect, useState } from "react"; import React, { useState } from "react";
function App(props) { const zip = (a: Array<any>, b: Array<any>): Array<[any, any]> => a.map((v: any, i: number): [any, any] => [v, b[i]]);
// const [cwd, setCwd] = useState('initialcwd');
// const [index, setIndex] = useState({});
// const [tasks, setTasks] = useState([]);
// useEffect(() => { function App() {
// // process.chdir(vscode!.workspace.workspaceFolders[0].uri.fsPath); const [name, setName] = useState('');
// import('@basementuniverse/kanbn/src/main').then(kanbn => { const [description, setDescription] = useState('');
// vscode.postMessage({ const [columns, setColumns] = useState({});
// command: 'error',
// text: 'hello!'
// });
// });
// });
// console.log(vscode!.workspace.workspaceFolders[0].uri.fsPath);
// window.addEventListener('message', event => { window.addEventListener('message', event => {
// const message = event.data; // The JSON data our extension sent const tasks = Object.fromEntries(event.data.tasks.map(task => [task.id, task]));
// switch (message.command) { setName(event.data.index.name);
// case 'test': setDescription(event.data.index.description);
// setCwd(message.cwd); setColumns(Object.fromEntries(
// break; zip(
// } Object.keys(event.data.index.columns),
// }); Object.values(event.data.index.columns).map(column => (column as string[]).map(taskId => tasks[taskId]))
)
));
});
return ( return (
<div> <div>
<Header /> <Header name={name} description={description} />
<Board /> <Board columns={columns} />
</div> </div>
); );
} }

View File

@ -1,33 +1,10 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd"; import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
import uuid from "uuid/v4";
const itemsFromBackend = [ export type task = {
{ id: uuid(), content: "First task" }, id: string,
{ id: uuid(), content: "Second task" }, name: string
{ id: uuid(), content: "Third task" }, }
{ id: uuid(), content: "Fourth task" },
{ id: uuid(), content: "Fifth task" }
];
const columnsFromBackend = {
[uuid()]: {
name: "Requested",
items: itemsFromBackend
},
[uuid()]: {
name: "To do",
items: []
},
[uuid()]: {
name: "In Progress",
items: []
},
[uuid()]: {
name: "Done",
items: []
}
};
const onDragEnd = (result, columns, setColumns) => { const onDragEnd = (result, columns, setColumns) => {
if (!result.destination) return; if (!result.destination) return;
@ -66,14 +43,15 @@ const onDragEnd = (result, columns, setColumns) => {
} }
}; };
function Board() { const Board = ({ columns }) => {
const [columns, setColumns] = useState(columnsFromBackend); // const [columns, setColumns] = useState(props.columns);
return ( return (
<div style={{ display: "flex", justifyContent: "center", height: "100%" }}> <div style={{ display: "flex", justifyContent: "center", height: "100%" }}>
<DragDropContext {/* <DragDropContext
onDragEnd={result => onDragEnd(result, columns, setColumns)} onDragEnd={result => onDragEnd(result, columns, setColumns)}
> > */}
{Object.entries(columns).map(([columnId, column], index) => { <DragDropContext>
{Object.entries(columns).map(([columnId, column]) => {
return ( return (
<div <div
style={{ style={{
@ -83,7 +61,7 @@ function Board() {
}} }}
key={columnId} key={columnId}
> >
<h2>{column.name}</h2> <h2>{columnId}</h2>
<div style={{ margin: 8 }}> <div style={{ margin: 8 }}>
<Droppable droppableId={columnId} key={columnId}> <Droppable droppableId={columnId} key={columnId}>
{(provided, snapshot) => { {(provided, snapshot) => {
@ -100,7 +78,7 @@ function Board() {
minHeight: 500 minHeight: 500
}} }}
> >
{column.items.map((item, index) => { {(column as task[]).map((item, index) => {
return ( return (
<Draggable <Draggable
key={item.id} key={item.id}
@ -125,7 +103,7 @@ function Board() {
...provided.draggableProps.style ...provided.draggableProps.style
}} }}
> >
{item.content} {item.name}
</div> </div>
); );
}} }}

View File

@ -1,9 +1,13 @@
import React, { useState } from "react"; import React from "react";
function Header() { const Header = ({ name, description }) => {
return ( return (
<div> <div>
Header <h1>{name}</h1>
<p>
{description}
</p>
<hr />
</div> </div>
); );
} }

View File

@ -1,5 +1,5 @@
body { body {
margin: 0; margin: 0;
padding: 0; padding: 1em;
font-family: sans-serif; font-family: sans-serif;
} }

1
src/uuid.v4.d.ts vendored
View File

@ -1 +0,0 @@
declare module 'uuid/v4';