update
This commit is contained in:
30
package-lock.json
generated
30
package-lock.json
generated
@@ -10,8 +10,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/cytoscape": "^3.21.9",
|
"@types/cytoscape": "^3.21.9",
|
||||||
"cytoscape": "^3.33.4",
|
"cytoscape": "^3.33.4"
|
||||||
"cytoscape-fcose": "^2.2.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.11.0",
|
"@types/node": "^20.11.0",
|
||||||
@@ -502,15 +501,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cose-base": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"layout-base": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/crelt": {
|
"node_modules/crelt": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
||||||
@@ -528,18 +518,6 @@
|
|||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cytoscape-fcose": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"cose-base": "^2.2.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"cytoscape": "^3.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/esbuild": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.20.2",
|
"version": "0.20.2",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
|
||||||
@@ -579,12 +557,6 @@
|
|||||||
"@esbuild/win32-x64": "0.20.2"
|
"@esbuild/win32-x64": "0.20.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/layout-base": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/moment": {
|
"node_modules/moment": {
|
||||||
"version": "2.29.4",
|
"version": "2.29.4",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/cytoscape": "^3.21.9",
|
"@types/cytoscape": "^3.21.9",
|
||||||
"cytoscape": "^3.33.4",
|
"cytoscape": "^3.33.4"
|
||||||
"cytoscape-fcose": "^2.2.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import {
|
|||||||
normalizePath,
|
normalizePath,
|
||||||
} from "obsidian";
|
} from "obsidian";
|
||||||
import cytoscape, { Core, NodeSingular } from "cytoscape";
|
import cytoscape, { Core, NodeSingular } from "cytoscape";
|
||||||
// @ts-ignore — no types for cytoscape-fcose
|
|
||||||
import fcose from "cytoscape-fcose";
|
|
||||||
import {
|
import {
|
||||||
VIEW_TYPE_PROJECT_DETAILS_VIEW,
|
VIEW_TYPE_PROJECT_DETAILS_VIEW,
|
||||||
VIEW_TYPE_PROJECT_VIEW,
|
VIEW_TYPE_PROJECT_VIEW,
|
||||||
@@ -30,14 +28,12 @@ import {
|
|||||||
import { menu, breadcrumb, emptyState, openMarkdown } from "../ui";
|
import { menu, breadcrumb, emptyState, openMarkdown } from "../ui";
|
||||||
import { NameModal } from "../modals/NameModal";
|
import { NameModal } from "../modals/NameModal";
|
||||||
|
|
||||||
cytoscape.use(fcose);
|
|
||||||
|
|
||||||
export interface ProjectDetailsState extends Record<string, unknown> {
|
export interface ProjectDetailsState extends Record<string, unknown> {
|
||||||
project: string;
|
project: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NAME_RX = /^[^\\/:*?"<>|]+$/;
|
const NAME_RX = /^[^\\/:*?"<>|]+$/;
|
||||||
const ROOT_ID = ":root:";
|
const ROOT_ID = "__pk_root__";
|
||||||
|
|
||||||
function validateName(name: string, taken: string[], current?: string): string | null {
|
function validateName(name: string, taken: string[], current?: string): string | null {
|
||||||
if (!name) return "Name darf nicht leer sein.";
|
if (!name) return "Name darf nicht leer sein.";
|
||||||
@@ -155,6 +151,7 @@ export class ProjectDetailsView extends ItemView {
|
|||||||
const styles = getComputedStyle(this.containerEl);
|
const styles = getComputedStyle(this.containerEl);
|
||||||
const textColor = styles.getPropertyValue("--text-normal").trim() || "#222";
|
const textColor = styles.getPropertyValue("--text-normal").trim() || "#222";
|
||||||
const borderColor = styles.getPropertyValue("--background-modifier-border").trim() || "#ccc";
|
const borderColor = styles.getPropertyValue("--background-modifier-border").trim() || "#ccc";
|
||||||
|
const edgeColor = styles.getPropertyValue("--text-muted").trim() || "#888";
|
||||||
const accent = styles.getPropertyValue("--interactive-accent").trim() || "#7b6cd9";
|
const accent = styles.getPropertyValue("--interactive-accent").trim() || "#7b6cd9";
|
||||||
const bgNode = styles.getPropertyValue("--background-primary").trim() || "#fff";
|
const bgNode = styles.getPropertyValue("--background-primary").trim() || "#fff";
|
||||||
|
|
||||||
@@ -201,28 +198,25 @@ export class ProjectDetailsView extends ItemView {
|
|||||||
{
|
{
|
||||||
selector: "edge",
|
selector: "edge",
|
||||||
style: {
|
style: {
|
||||||
width: 1.5,
|
width: 2,
|
||||||
"line-color": borderColor,
|
"line-color": edgeColor,
|
||||||
"target-arrow-color": borderColor,
|
"target-arrow-color": edgeColor,
|
||||||
"target-arrow-shape": "triangle",
|
"target-arrow-shape": "triangle",
|
||||||
"curve-style": "bezier",
|
"curve-style": "bezier",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
layout: {
|
layout: {
|
||||||
name: "fcose",
|
name: "concentric",
|
||||||
// @ts-ignore — fcose options not in cytoscape types
|
concentric: (node) => -((node.data("depth") as number) ?? 0),
|
||||||
quality: "default",
|
levelWidth: () => 1,
|
||||||
randomize: true,
|
minNodeSpacing: 60,
|
||||||
animate: false,
|
// @ts-ignore — spacingFactor exists in concentric layout
|
||||||
|
spacingFactor: 1.4,
|
||||||
fit: true,
|
fit: true,
|
||||||
padding: 30,
|
padding: 30,
|
||||||
nodeRepulsion: 8000,
|
startAngle: -Math.PI / 2,
|
||||||
idealEdgeLength: 100,
|
clockwise: true,
|
||||||
gravity: 0.25,
|
|
||||||
fixedNodeConstraint: [
|
|
||||||
{ nodeId: ROOT_ID, position: { x: 0, y: 0 } },
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -231,15 +225,17 @@ export class ProjectDetailsView extends ItemView {
|
|||||||
|
|
||||||
private treeToElements(tree: NodeTree): cytoscape.ElementDefinition[] {
|
private treeToElements(tree: NodeTree): cytoscape.ElementDefinition[] {
|
||||||
const els: cytoscape.ElementDefinition[] = [];
|
const els: cytoscape.ElementDefinition[] = [];
|
||||||
els.push({ data: { id: ROOT_ID, label: tree.name } });
|
els.push({ data: { id: ROOT_ID, label: tree.name, path: tree.path, depth: 0 } });
|
||||||
const walk = (node: NodeTree, parentId: string) => {
|
let counter = 0;
|
||||||
for (const child of node.children) {
|
const walk = (children: NodeTree[], parentId: string, depth: number) => {
|
||||||
els.push({ data: { id: child.path, label: child.name } });
|
for (const child of children) {
|
||||||
els.push({ data: { id: `${parentId}>${child.path}`, source: parentId, target: child.path } });
|
const id = `n${counter++}`;
|
||||||
walk(child, child.path);
|
els.push({ data: { id, label: child.name, path: child.path, depth } });
|
||||||
|
els.push({ data: { source: parentId, target: id } });
|
||||||
|
walk(child.children, id, depth + 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
walk(tree, ROOT_ID);
|
walk(tree.children, ROOT_ID, 1);
|
||||||
return els;
|
return els;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,28 +245,27 @@ export class ProjectDetailsView extends ItemView {
|
|||||||
|
|
||||||
cy.on("tap", "node", (ev) => {
|
cy.on("tap", "node", (ev) => {
|
||||||
const node = ev.target as NodeSingular;
|
const node = ev.target as NodeSingular;
|
||||||
const id = node.id();
|
if (node.id() === ROOT_ID) {
|
||||||
if (id === ROOT_ID) {
|
|
||||||
const corePath = normalizePath(`${projectPath(this.project)}/${CORE_FILE}`);
|
const corePath = normalizePath(`${projectPath(this.project)}/${CORE_FILE}`);
|
||||||
void openMarkdown(this.app, corePath, this.leaf);
|
void openMarkdown(this.app, corePath, this.leaf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void openMarkdown(this.app, nodeMdPath(id), this.leaf);
|
const path = node.data("path") as string;
|
||||||
|
void openMarkdown(this.app, nodeMdPath(path), this.leaf);
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.on("cxttap", "node", (ev) => {
|
cy.on("cxttap", "node", (ev) => {
|
||||||
const node = ev.target as NodeSingular;
|
const node = ev.target as NodeSingular;
|
||||||
const id = node.id();
|
|
||||||
const originalEvent = ev.originalEvent as MouseEvent;
|
const originalEvent = ev.originalEvent as MouseEvent;
|
||||||
originalEvent.preventDefault();
|
originalEvent.preventDefault();
|
||||||
if (id === ROOT_ID) {
|
if (node.id() === ROOT_ID) {
|
||||||
const parent = projectPath(this.project);
|
const parent = projectPath(this.project);
|
||||||
menu(originalEvent, [
|
menu(originalEvent, [
|
||||||
{ title: "Neuer Child-Node", icon: "plus", onClick: () => this.openCreateChild(parent) },
|
{ title: "Neuer Child-Node", icon: "plus", onClick: () => this.openCreateChild(parent) },
|
||||||
]);
|
]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const folder = id;
|
const folder = node.data("path") as string;
|
||||||
const parentPath = folder.substring(0, folder.lastIndexOf("/"));
|
const parentPath = folder.substring(0, folder.lastIndexOf("/"));
|
||||||
const currentName = folder.split("/").pop() ?? "";
|
const currentName = folder.split("/").pop() ?? "";
|
||||||
menu(originalEvent, [
|
menu(originalEvent, [
|
||||||
@@ -320,8 +315,10 @@ export class ProjectDetailsView extends ItemView {
|
|||||||
if (start) node.position(start);
|
if (start) node.position(start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const sourcePath = node.id();
|
const sourcePath = node.data("path") as string;
|
||||||
const targetPath = target.id() === ROOT_ID ? projectPath(this.project) : target.id();
|
const targetPath = target.id() === ROOT_ID
|
||||||
|
? projectPath(this.project)
|
||||||
|
: (target.data("path") as string);
|
||||||
const currentParent = sourcePath.substring(0, sourcePath.lastIndexOf("/"));
|
const currentParent = sourcePath.substring(0, sourcePath.lastIndexOf("/"));
|
||||||
if (currentParent === targetPath) {
|
if (currentParent === targetPath) {
|
||||||
if (start) node.position(start);
|
if (start) node.position(start);
|
||||||
|
|||||||
Reference in New Issue
Block a user