From ede78786f730d0deb1e57aa4e2c974a1c0af8d8f Mon Sep 17 00:00:00 2001 From: Poluboiarinov Anton <50020771+poanse@users.noreply.github.com> Date: Sat, 16 May 2026 07:54:55 +0300 Subject: [PATCH] Obsidian review and eslint fixes, readme update (#2) * updated installation instruction * fixed warnings from automatic review * removed unused dependencies * updated eslint settings and fixed warnings * fixed esling warnings, moved screenshot to .github * bumped version --- .eslintignore | 3 - screenshot.png => .github/screenshot.png | Bin README.md | 7 +- esbuild.config.mjs | 2 - eslint.config.mjs | 84 ++++++++++++++---- manifest.json | 2 +- package-lock.json | 104 +++++++++-------------- package.json | 11 ++- src/Context.svelte.ts | 11 ++- src/DraggingManager.svelte.ts | 2 +- src/NodePositionsCalculator.ts | 2 +- src/components/SettingsButton.svelte | 5 +- src/components/TaskmapContainer.svelte | 4 +- src/components/Toolbar.svelte | 4 +- src/helpers/FolderSuggest.ts | 2 +- src/helpers/LinkSuggest.ts | 2 +- src/helpers/svelte.js | 76 ----------------- src/helpers/svelte.ts | 79 +++++++++++++++++ 18 files changed, 209 insertions(+), 191 deletions(-) delete mode 100644 .eslintignore rename screenshot.png => .github/screenshot.png (100%) delete mode 100644 src/helpers/svelte.js create mode 100644 src/helpers/svelte.ts diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index e019f3c..0000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules/ - -main.js diff --git a/screenshot.png b/.github/screenshot.png similarity index 100% rename from screenshot.png rename to .github/screenshot.png diff --git a/README.md b/README.md index 5ae06d2..ef3c2bb 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,7 @@ No need to move tasks around manually — the automatic layout keeps your struct ## How to install -*Taskmap is in beta. Installation from Obsidian community plugins is currently unavailable.* - -Install [BRAT](https://github.com/TfTHacker/obsidian42-brat) community plugin from obsidian app. -Go to settings, press `Add beta plugin` and paste link to this repo https://github.com/poanse/obsidian-taskmap +Taskmap is available via obsidian community portal https://community.obsidian.md/plugins/taskmap and "Community plugins" option in the obsidian app. ## Why Taskmap? @@ -29,4 +26,4 @@ Canvas-style visualization, zero manual positioning. - Automatic parent status from children - Link tasks outside of tree structure using blocker system -![screenshot.png](screenshot.png) +![screenshot.png](.github/screenshot.png) diff --git a/esbuild.config.mjs b/esbuild.config.mjs index bab5723..8b9e917 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -1,6 +1,5 @@ import esbuild from "esbuild"; import process from "process"; -import builtins from "builtin-modules"; import esbuildSvelte from "esbuild-svelte"; import { sveltePreprocess } from "svelte-preprocess"; import fs from "fs"; @@ -54,7 +53,6 @@ const context = await esbuild.context({ "@lezer/common", "@lezer/highlight", "@lezer/lr", - ...builtins, ], format: "cjs", target: "es2022", diff --git a/eslint.config.mjs b/eslint.config.mjs index a2098f0..481bc26 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,31 +1,79 @@ -// eslint.config.mjs -import ts from "typescript-eslint"; +import js from "@eslint/js"; +import tsparser from "@typescript-eslint/parser"; import { defineConfig } from "eslint/config"; import obsidianmd from "eslint-plugin-obsidianmd"; import svelte from "eslint-plugin-svelte"; +import svelteParser from "svelte-eslint-parser"; import prettier from "eslint-config-prettier"; -import js from "@eslint/js"; +import ts from "typescript-eslint"; +import globals from "globals"; export default defineConfig([ - ...obsidianmd.configs.recommended, + { + ignores: [ + "node_modules/**", + "dist/**", + "main.js", + "package.json", + "package-lock.json", + "versions.json", + "eslint.config.*", + "esbuild.config.mjs", + ], + }, + js.configs.recommended, - ...ts.configs.recommended, + + ...obsidianmd.configs.recommended, + ...svelte.configs["flat/recommended"], ...svelte.configs["flat/prettier"], - prettier, - { - files: ["**/*.ts", "**/*.svelte"], - languageOptions: { - parser: ts.parser, - parserOptions: { project: "./tsconfig.json" }, - }, - // You can add your own configuration to override or add rules - rules: { - // example: turn off a rule from the recommended set - // "obsidianmd/sample-names": "off", - // example: add a rule not in the recommended set and set its severity - // "obsidianmd/prefer-file-manager-trash": "error", + { + files: ["**/*.ts"], + extends: [...ts.configs.recommendedTypeChecked], + languageOptions: { + parser: tsparser, + parserOptions: { + project: "./tsconfig.json", + tsconfigRootDir: import.meta.dirname, + }, }, }, + + { + files: ["src/**/*.svelte"], + languageOptions: { + parser: svelteParser, + parserOptions: { + parser: tsparser, + extraFileExtensions: [".svelte"], + }, + globals: { + ...globals.browser, + }, + }, + rules: { + "@typescript-eslint/no-deprecated": "off", + }, + }, + + { + files: ["scripts/**/*.ts"], + rules: { + "import/no-nodejs-modules": "off", + }, + }, + { + files: ["scripts/**/*.ts", "*.mjs"], + languageOptions: { + globals: { + ...globals.node, + }, + }, + rules: { + "import/no-nodejs-modules": "off", + }, + }, + prettier, ]); diff --git a/manifest.json b/manifest.json index 7d0a8f2..48e979d 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "taskmap", "name": "Taskmap", - "version": "0.1.5", + "version": "0.1.6", "minAppVersion": "1.12.4", "description": "Plan projects via interactive GUI task trees with automatic layout.", "author": "poanse", diff --git a/package-lock.json b/package-lock.json index c0b9220..fc1e8d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,16 @@ { "name": "obsidian-taskmap", - "version": "0.1.5", + "version": "0.1.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "obsidian-taskmap", - "version": "0.1.3", + "version": "0.1.5", "license": "MIT", "dependencies": { "@napolab/alpha-blend": "^2.0.0", "@panzoom/panzoom": "^4.6.1", - "autobind-decorator": "^2.4.0", - "esm-env": "^1.2.2", "lucide-svelte": "^0.562.0", "rollup-plugin-css-only": "^4.5.5", "ts-pattern": "^5.9.0", @@ -24,10 +22,9 @@ "@types/node": "latest", "@typescript-eslint/eslint-plugin": "latest", "@typescript-eslint/parser": "latest", - "builtin-modules": "latest", "esbuild": "latest", "esbuild-svelte": "^0.9.3", - "eslint": "^9.39.2", + "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", "eslint-plugin-obsidianmd": "^0.1.9", "eslint-plugin-svelte": "^3.14.0", @@ -541,15 +538,15 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^3.1.5" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -635,20 +632,20 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, "engines": { @@ -737,9 +734,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", "dev": true, "license": "MIT", "peer": true, @@ -1628,9 +1625,9 @@ } }, "node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -1846,16 +1843,6 @@ "node": ">= 0.4" } }, - "node_modules/autobind-decorator": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/autobind-decorator/-/autobind-decorator-2.4.0.tgz", - "integrity": "sha512-OGYhWUO72V6DafbF8PM8rm3EPbfuyMZcJhtm5/n26IDwO18pohE4eNazLoCGhPiXOCD0gEGmrbU3849QvM8bbw==", - "license": "MIT", - "engines": { - "node": ">=8.10", - "npm": ">=6.4.1" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -1898,19 +1885,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/builtin-modules": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz", - "integrity": "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -2215,9 +2189,9 @@ } }, "node_modules/devalue": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.7.1.tgz", - "integrity": "sha512-MUbZ586EgQqdRnC4yDrlod3BEdyvE4TapGYHMW2CiaW+KkkFmWEFqBUaLltEZCGi0iFXCEjRF0OjF0DV2QHjOA==", + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.8.1.tgz", + "integrity": "sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==", "license": "MIT" }, "node_modules/dunder-proto": { @@ -2510,26 +2484,26 @@ } }, "node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", + "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "ajv": "^6.12.4", + "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", @@ -2548,7 +2522,7 @@ "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -3377,9 +3351,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", "dev": true, "funding": [ { @@ -4848,9 +4822,9 @@ } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", "dev": true, "funding": [ { @@ -5720,9 +5694,9 @@ } }, "node_modules/svelte": { - "version": "5.55.3", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.55.3.tgz", - "integrity": "sha512-dS1N+i3bA1v+c4UDb750MlN5vCO82G6vxh8HeTsPsTdJ1BLsN1zxSyDlIdBBqUjqZ/BxEwM8UrFf98aaoVnZFQ==", + "version": "5.55.7", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.55.7.tgz", + "integrity": "sha512-ymI5ykLPwIHW839E053FQbI1G+jnRFJEw3Kv5Y4njixVWywQBx+NUFpkkKyk5LIb36Fg9DVXSYpqiGekLD0hyw==", "license": "MIT", "peer": true, "dependencies": { @@ -5735,7 +5709,7 @@ "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", - "devalue": "^5.6.4", + "devalue": "^5.8.1", "esm-env": "^1.2.1", "esrap": "^2.2.4", "is-reference": "^3.0.3", diff --git a/package.json b/package.json index 3e08de5..e871f8f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-taskmap", - "version": "0.1.5", + "version": "0.1.6", "description": "Taskmap plugin for Obsidian (https://obsidian.md)", "main": "main.js", "scripts": { @@ -8,7 +8,9 @@ "build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production", "version": "node version-bump.mjs && git add manifest.json versions.json", "svelte-check": "svelte-check --tsconfig tsconfig.json", - "perf:tasks": "tsx scripts/perf-tasks.ts" + "perf:tasks": "tsx scripts/perf-tasks.ts", + "lint": "eslint .", + "lint:fix": "eslint . --fix" }, "keywords": [], "author": "", @@ -19,10 +21,9 @@ "@types/node": "latest", "@typescript-eslint/eslint-plugin": "latest", "@typescript-eslint/parser": "latest", - "builtin-modules": "latest", "esbuild": "latest", "esbuild-svelte": "^0.9.3", - "eslint": "^9.39.2", + "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", "eslint-plugin-obsidianmd": "^0.1.9", "eslint-plugin-svelte": "^3.14.0", @@ -41,8 +42,6 @@ "dependencies": { "@napolab/alpha-blend": "^2.0.0", "@panzoom/panzoom": "^4.6.1", - "autobind-decorator": "^2.4.0", - "esm-env": "^1.2.2", "lucide-svelte": "^0.562.0", "rollup-plugin-css-only": "^4.5.5", "ts-pattern": "^5.9.0", diff --git a/src/Context.svelte.ts b/src/Context.svelte.ts index 55c579e..55aa69e 100644 --- a/src/Context.svelte.ts +++ b/src/Context.svelte.ts @@ -180,7 +180,7 @@ export class Context { public finishTaskDragging = (e: PointerEvent, updatePositions = false) => { this.draggedTaskId = NoTaskId; - this.taskDraggingManager.onPointerUp(e); + this.taskDraggingManager.onPointerUp(); if (updatePositions) { this.updateTaskPositions(); } @@ -315,7 +315,7 @@ export class Context { const taskIdSet: ReadonlySet = new SvelteSet( this.taskPositions.map((t) => t.taskId), ); - this.positions.forEach((v, k) => { + this.positions.forEach((_v, k) => { if (k != NoTaskId && !taskIdSet.has(k)) { this.taskPositions.push({ taskId: k, @@ -426,8 +426,11 @@ export class Context { this.app.workspace .getLeavesOfType(TASKMAP_VIEW_TYPE) .map((leaf) => leaf.view) - .filter((view) => view instanceof TaskmapView) - .forEach((view) => view.debouncedSave()); + .forEach((view) => { + if (view instanceof TaskmapView) { + view.debouncedSave(); + } + }); } public addTask(parentId: TaskId): void { diff --git a/src/DraggingManager.svelte.ts b/src/DraggingManager.svelte.ts index 7fe314c..b58ef7d 100644 --- a/src/DraggingManager.svelte.ts +++ b/src/DraggingManager.svelte.ts @@ -27,7 +27,7 @@ export class DraggingManager { } }; - public onPointerUp = (e: PointerEvent) => { + public onPointerUp = () => { console.debug(`DraggingManager pointerUp: ${this.deltaX}`); this.reset(); }; diff --git a/src/NodePositionsCalculator.ts b/src/NodePositionsCalculator.ts index 64d0f64..428212b 100644 --- a/src/NodePositionsCalculator.ts +++ b/src/NodePositionsCalculator.ts @@ -321,7 +321,7 @@ export class NodePositionsCalculator { rootChildrenByPriority.set(idx, id); }); - rootChildrenByPriority.forEach((priority, chId) => { + rootChildrenByPriority.forEach((_priority, chId) => { const x = taskById.get(chId)!; if (this.RowIndex(x) === 0) { const neighbourId = diff --git a/src/components/SettingsButton.svelte b/src/components/SettingsButton.svelte index 63cf719..73fa8a6 100644 --- a/src/components/SettingsButton.svelte +++ b/src/components/SettingsButton.svelte @@ -8,7 +8,6 @@ let { iconCode, context }: { iconCode: SettingsIconCode, context: Context } = $props(); let isPressedDown = $state(false); - let modal: ProjectSettingsModal | null = null; function onpointerdown(event: MouseEvent) { isPressedDown = true; @@ -84,8 +83,8 @@ display: inline-flex; align-items: center; justify-content: center; - gap: 0px; - padding: 0px; + gap: 0; + padding: 0; /*background-color: #e0e0e0;*/ cursor: pointer; border-radius: 4px; diff --git a/src/components/TaskmapContainer.svelte b/src/components/TaskmapContainer.svelte index 334c1f2..1fe2791 100644 --- a/src/components/TaskmapContainer.svelte +++ b/src/components/TaskmapContainer.svelte @@ -132,7 +132,7 @@ viewportEl!.focus(); e.stopPropagation(); } - draggingManager.onPointerUp(e); + draggingManager.onPointerUp(); context.finishTaskDragging(e, true); } @@ -220,7 +220,7 @@ const blockerT = context.versionedData.getTask(p.blocker); return blockedT.status !== StatusCode.DONE && blockerT.status !== StatusCode.DONE && !blockerT.deleted && !blockedT.deleted; } - )) as pair} + )) as pair (pair.blocker + '-' + pair.blocked)} {#key context.updateOnZoomCounter} - {#each toolbarButtons as button} + {#each toolbarButtons as button (button)}