diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 75d4c3e..7d1fa22 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,3 +19,9 @@ jobs: uses: codecov/codecov-action@v3 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + - uses: paambaati/codeclimate-action@v5.0.0 + continue-on-error: true + env: + CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} + with: + coverageLocations: ./coverage/*.xml:clover diff --git a/README.md b/README.md index e3e35ba..d91f97c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# Trello Kanban Board [![test](https://github.com/mayank1513/vscode-extension-trello-kanban-board/actions/workflows/test.yml/badge.svg)](https://github.com/mayank1513/vscode-extension-trello-kanban-board/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/mayank1513/vscode-extension-trello-kanban-board/graph/badge.svg)](https://codecov.io/gh/mayank1513/vscode-extension-trello-kanban-board) +# Trello Kanban Board + +[![test](https://github.com/mayank1513/vscode-extension-trello-kanban-board/actions/workflows/test.yml/badge.svg)](https://github.com/mayank1513/vscode-extension-trello-kanban-board/actions/workflows/test.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/ac44e4371dd3a274285e/maintainability)](https://codeclimate.com/github/mayank1513/vscode-extension-trello-kanban-board/maintainability) [![codecov](https://codecov.io/gh/mayank1513/vscode-extension-trello-kanban-board/graph/badge.svg)](https://codecov.io/gh/mayank1513/vscode-extension-trello-kanban-board) > Organize your work/ideas with Trello like Kanban board! @@ -14,11 +16,9 @@ ✅ Intuitive drag and drop UI -## Installation - -Click here to install this extension. +✅ Awailable for web as well - https://vscode-extension-trello-kanban-board.vercel.app/ -OR +## Installation Visit [MarketPlace](https://marketplace.visualstudio.com/items?itemName=mayank1513.trello-kanban-task-board) diff --git a/extension/panel.ts b/extension/panel.ts index df2db20..92a7ef7 100644 --- a/extension/panel.ts +++ b/extension/panel.ts @@ -1,4 +1,4 @@ -import { Disposable, ExtensionContext, Uri, ViewColumn, WebviewPanel, window } from "vscode"; +import { Disposable, ExtensionContext, Memento, Uri, ViewColumn, Webview, WebviewPanel, window } from "vscode"; import { ScopeType, prefix } from "./constants"; import { MessageType } from "./interface"; @@ -32,11 +32,26 @@ export class Panel { private _setupWebView() { const { extensionUri, globalState, workspaceState } = this._context; const { webview } = this._panel; + + webview.html = this._getHTML(webview, extensionUri); + + this._panel.onDidDispose(this._dispose, null, this._disposables); + + // message listeners + const scope = this._scope; + const memento = scope === "Global" ? globalState : workspaceState; + webview.onDidReceiveMessage( + (message: MessageType) => this._messageHandler(message, memento, prefix, scope, webview), + undefined, + this._disposables + ); + } + + private _getHTML(webview: Webview, extensionUri: Uri) { const cssUri = webview.asWebviewUri(Uri.joinPath(extensionUri, "assets", "index.css")); const jsUri = webview.asWebviewUri(Uri.joinPath(extensionUri, "assets", "index.js")); const iconUri = webview.asWebviewUri(Uri.joinPath(extensionUri, "logo.png")); - - webview.html = ` + return `
@@ -51,54 +66,42 @@ export class Panel { `; + } - this._panel.onDidDispose( - () => { - this._panel.dispose(); - // Dispose of all disposables (i.e. commands) for the current webview panel - // using while loop as disposables might be added while disposing other disposables in the array - while (this._disposables.length) { - const disposable = this._disposables.pop(); - if (disposable) { - disposable.dispose(); - } - } - }, - null, - this._disposables - ); + private _dispose() { + this._panel.dispose(); + // Dispose of all disposables (i.e. commands) for the current webview panel + // using while loop as disposables might be added while disposing other disposables in the array + while (this._disposables.length) { + const disposable = this._disposables.pop(); + if (disposable) { + disposable.dispose(); + } + } + } - // message listeners - const scope = this._scope; - const momento = scope === "Global" ? globalState : workspaceState; - const key = prefix; - webview.onDidReceiveMessage( - (message: MessageType) => { - const { action, data, text } = message; - switch (action) { - case "load": - { - const data = momento.get(key) || { scope }; - webview.postMessage({ action: "load", data: { ...data, scope } } as MessageType); - } - break; - case "save": - momento.update(key, data); - break; - case "success": - case "info": - window.showInformationMessage(text || ""); - break; - case "warn": - window.showWarningMessage(text || ""); - break; - case "error": - window.showErrorMessage(text || ""); - break; + private _messageHandler(message: MessageType, memento: Memento, key: string, scope: string, webview: Webview) { + const { action, data, text } = message; + switch (action) { + case "load": + { + const data = memento.get(key) || { scope }; + webview.postMessage({ action: "load", data: { ...data, scope } } as MessageType); } - }, - undefined, - this._disposables - ); + break; + case "save": + memento.update(key, data); + break; + case "success": + case "info": + window.showInformationMessage(text || ""); + break; + case "warn": + window.showWarningMessage(text || ""); + break; + case "error": + window.showErrorMessage(text || ""); + break; + } } } diff --git a/package.json b/package.json index 91ada7d..5ff9a50 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "trello-kanban-task-board", "private": true, - "version": "0.0.0", + "version": "0.0.1", "type": "module", "scripts": { "dev": "vite", @@ -13,37 +13,37 @@ "deploy": "npm run build && npm run build:extension && cd dist && vsce publish --yarn" }, "dependencies": { - "@mayank1513/fork-me": "^1.1.2", - "@paralleldrive/cuid2": "^2.2.2", + "@mayank1513/fork-me": "^2.0.0", + "nanoid": "^5.0.4", "react": "^18.2.0", "react-beautiful-dnd": "^13.1.1", "react-dom": "^18.2.0", - "react-markdown": "^9.0.0", + "react-markdown": "^9.0.1", "react-toastify": "^9.1.3" }, "devDependencies": { - "@testing-library/jest-dom": "^6.1.3", - "@testing-library/react": "^14.0.0", - "@types/node": "^20.8.3", - "@types/react": "^18.2.25", - "@types/react-beautiful-dnd": "^13.1.5", - "@types/react-dom": "^18.2.11", - "@types/vscode": "^1.83.0", - "@types/vscode-webview": "^1.57.2", - "@typescript-eslint/eslint-plugin": "^6.7.4", - "@typescript-eslint/parser": "^6.7.4", - "@vitejs/plugin-react": "^4.1.0", - "@vitest/coverage-v8": "^0.34.6", - "@vscode/vsce": "^2.21.1", - "eslint": "^8.51.0", + "@testing-library/jest-dom": "^6.1.5", + "@testing-library/react": "^14.1.2", + "@types/node": "^20.10.4", + "@types/react": "^18.2.45", + "@types/react-beautiful-dnd": "^13.1.7", + "@types/react-dom": "^18.2.17", + "@types/vscode": "^1.85.0", + "@types/vscode-webview": "^1.57.4", + "@typescript-eslint/eslint-plugin": "^6.14.0", + "@typescript-eslint/parser": "^6.14.0", + "@vitejs/plugin-react": "^4.2.1", + "@vitest/coverage-v8": "^1.0.4", + "@vscode/vsce": "^2.22.0", + "eslint": "^8.55.0", "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.3", - "jsdom": "^22.1.0", - "sass": "^1.69.0", - "ts-node": "^10.9.1", - "typescript": "^5.2.2", - "vite": "^4.4.11", - "vite-tsconfig-paths": "^4.2.1", - "vitest": "^0.34.6" + "eslint-plugin-react-refresh": "^0.4.5", + "jsdom": "^23.0.1", + "sass": "^1.69.5", + "ts-node": "^10.9.2", + "typescript": "^5.3.3", + "vite": "^5.0.8", + "vite-tsconfig-paths": "^4.2.2", + "vitest": "^1.0.4" } } diff --git a/src/components/board.module.scss b/src/components/board.module.scss index 5d273d3..8853faf 100644 --- a/src/components/board.module.scss +++ b/src/components/board.module.scss @@ -17,6 +17,10 @@ } } +.main { + display: flex; +} + .theme1 { background: linear-gradient(-45deg, blue, red); } diff --git a/src/components/board.tsx b/src/components/board.tsx index 493e0bf..cef9488 100644 --- a/src/components/board.tsx +++ b/src/components/board.tsx @@ -4,61 +4,76 @@ import ColumnList from "./column-list"; import { DragDropContext, DropResult } from "react-beautiful-dnd"; import { ForkMe } from "@mayank1513/fork-me/server"; import "@mayank1513/fork-me/server/index.css"; +import { BoardType } from "@/interface"; +import DrawerToggle from "./drawer-toggle"; +import { useState } from "react"; +import Drawer from "./drawer"; export default function Board() { - const { setState, state } = useGlobalState(); + const { state, setState } = useGlobalState(); + const [open, setOpen] = useState(false); - const onDragEnd = (result: DropResult) => { - const { source, destination, draggableId } = result; - if (!destination) return; - - if (destination.droppableId === source.droppableId && destination.index === source.index) return; - - /** column id always starts with "column-" */ - const columns = [...state.columns]; - if (draggableId.startsWith("column-")) { - const column = columns.splice(source.index, 1)[0]; - columns.splice(destination.index, 0, column); - setState({ ...state, columns: columns }); - } else { - const sourceCol = columns.find((c) => c.id === source.droppableId); - let destinationCol; - if (destination.droppableId === "columns") { - destinationCol = columns[Math.min(destination.index, columns.length - 1)]; - } else { - destinationCol = columns.find((c) => c.id === destination.droppableId); - } - const taskId = sourceCol?.tasksIds.splice(source.index, 1)[0]; - const tasks = { ...state.tasks }; - if (taskId) { - tasks[taskId].columnId = destination.droppableId; - destinationCol?.tasksIds.splice(destination.index, 0, taskId); - setState({ ...state, columns }); - } - } - }; + const onDragEnd = (result: DropResult) => handleDragEnd(result, state, setState); return (