Pass kanbn to react via webview message
This commit is contained in:
parent
878fcbba39
commit
d2234485f4
@ -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'))
|
||||||
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36949
package-lock.json
generated
36949
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@ -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"
|
||||||
},
|
},
|
||||||
|
45
src/App.tsx
45
src/App.tsx
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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
1
src/uuid.v4.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
declare module 'uuid/v4';
|
|
Loading…
x
Reference in New Issue
Block a user