mirror of
https://github.com/poanse/obsidian-taskmap.git
synced 2026-07-22 06:05:58 +00:00
Fixed task priorities after reparent (#3)
* fixed priorities bug when parent is changed. also added a fixing migration to existing projects * added auto test for priorities after reparent
This commit is contained in:
parent
ede78786f7
commit
aea63cfc0d
8 changed files with 35 additions and 8 deletions
|
|
@ -65,7 +65,7 @@ export default defineConfig([
|
|||
},
|
||||
},
|
||||
{
|
||||
files: ["scripts/**/*.ts", "*.mjs"],
|
||||
files: ["scripts/**/*.ts", "tests/**/*.ts", "*.mjs"],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "taskmap",
|
||||
"name": "Taskmap",
|
||||
"version": "0.1.6",
|
||||
"version": "0.1.7",
|
||||
"minAppVersion": "1.12.4",
|
||||
"description": "Plan projects via interactive GUI task trees with automatic layout.",
|
||||
"author": "poanse",
|
||||
|
|
|
|||
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "obsidian-taskmap",
|
||||
"version": "0.1.6",
|
||||
"version": "0.1.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "obsidian-taskmap",
|
||||
"version": "0.1.6",
|
||||
"version": "0.1.7",
|
||||
"description": "Taskmap plugin for Obsidian (https://obsidian.md)",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
"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",
|
||||
"test": "tsx --test tests/reparent-priorities.test.ts",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ function randomTaskIds(count: number, picks: number): TaskId[] {
|
|||
|
||||
function createProjectData(tasks: TaskData[]): ProjectData {
|
||||
return new ProjectData({
|
||||
schemaVersion: undefined,
|
||||
tasks: tasks.map((t) => ({ ...t })),
|
||||
blockerPairs: [],
|
||||
folderPath: undefined,
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ export class ChangeParentAction implements Action {
|
|||
private taskId: TaskId;
|
||||
private newParentId: TaskId;
|
||||
private oldParentId?: TaskId;
|
||||
private oldPriority?: number;
|
||||
|
||||
constructor(taskId: TaskId, newParentId: number) {
|
||||
this.taskId = taskId;
|
||||
|
|
@ -232,15 +233,25 @@ export class ChangeParentAction implements Action {
|
|||
|
||||
do(data: ProjectData) {
|
||||
this.oldParentId = data.getTask(this.taskId).parentId;
|
||||
this.oldPriority = data.getTask(this.taskId).priority;
|
||||
data.getTask(this.taskId).priority = data.getChildren(this.newParentId).length;
|
||||
data.changeParent(this.taskId, this.newParentId);
|
||||
data.recalcPriorities(this.newParentId);
|
||||
data.recalcPriorities(this.oldParentId);
|
||||
}
|
||||
|
||||
undo(data: ProjectData) {
|
||||
if (this.oldParentId === undefined) {
|
||||
if (this.oldParentId === undefined || this.oldPriority === undefined) {
|
||||
throw new Error();
|
||||
}
|
||||
// Use oldPriority - 0.5 so recalcPriorities places task exactly at oldPriority
|
||||
// (sibling priorities are always whole numbers, so this slots in unambiguously)
|
||||
data.getTask(this.taskId).priority = this.oldPriority - 0.5;
|
||||
data.changeParent(this.taskId, this.oldParentId);
|
||||
data.recalcPriorities(this.oldParentId);
|
||||
data.recalcPriorities(this.newParentId);
|
||||
this.oldParentId = undefined;
|
||||
this.oldPriority = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@
|
|||
} from "../types";
|
||||
import { SvelteMap } from "svelte/reactivity";
|
||||
import { NoTaskId, RootTaskId } from "../NodePositionsCalculator";
|
||||
import type { ProjectFileParsed } from "./ProjectDataSchema";
|
||||
import {
|
||||
TASKMAP_FILE_SCHEMA_VERSION,
|
||||
type ProjectFileParsed,
|
||||
} from "./ProjectDataSchema";
|
||||
|
||||
export class ProjectData {
|
||||
// cannot use just SvelteMap<TaskId, Task> because it breaks reactivity
|
||||
|
|
@ -22,6 +25,7 @@ export class ProjectData {
|
|||
|
||||
public static getDefault(): ProjectData {
|
||||
return new ProjectData({
|
||||
schemaVersion: TASKMAP_FILE_SCHEMA_VERSION,
|
||||
tasks: new Array<TaskData>(),
|
||||
blockerPairs: new Array<BlockerPair>(),
|
||||
folderPath: undefined,
|
||||
|
|
@ -39,6 +43,11 @@ export class ProjectData {
|
|||
this.addRootTask();
|
||||
}
|
||||
this.rebuildCaches();
|
||||
if ((obj.schemaVersion ?? 0) < TASKMAP_FILE_SCHEMA_VERSION) {
|
||||
for (const parentId of this.childrenCache.keys()) {
|
||||
this.recalcPriorities(parentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public markTasksUpdated() {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@ import * as v from "valibot";
|
|||
import type { FlatErrors } from "valibot";
|
||||
import { StatusCode, type BlockerPair, type TaskData } from "../types";
|
||||
|
||||
/** Bump when the on-disk JSON shape changes (migrations can branch on this). */
|
||||
export const TASKMAP_FILE_SCHEMA_VERSION = 1 as const;
|
||||
/**
|
||||
* Bump when the on-disk JSON shape changes (migrations can branch on this).
|
||||
* v2: normalize sibling priorities after reparent
|
||||
*/
|
||||
export const TASKMAP_FILE_SCHEMA_VERSION = 2 as const;
|
||||
|
||||
const statusCodeSchema = v.picklist([
|
||||
StatusCode.DRAFT,
|
||||
|
|
@ -45,6 +48,7 @@ export const projectFileSchema = v.object({
|
|||
});
|
||||
|
||||
export type ProjectFileParsed = {
|
||||
schemaVersion: number | undefined;
|
||||
tasks: TaskData[];
|
||||
blockerPairs: BlockerPair[];
|
||||
folderPath: string | undefined;
|
||||
|
|
@ -89,6 +93,7 @@ export function parseProjectFileJson(parsed: unknown): ProjectFileParsed {
|
|||
}
|
||||
const o = result.output;
|
||||
return {
|
||||
schemaVersion: o.schemaVersion,
|
||||
tasks: o.tasks,
|
||||
blockerPairs: o.blockerPairs ?? [],
|
||||
folderPath: o.folderPath,
|
||||
|
|
|
|||
Loading…
Reference in a new issue