@carlonicora/nextjs-jsonapi 1.97.2 → 1.99.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/{BlockNoteEditor-LRJUTHTW.mjs → BlockNoteEditor-IBV3KBQM.mjs} +2 -2
  2. package/dist/{BlockNoteEditor-OOZGXU6E.js → BlockNoteEditor-LYJUF5N4.js} +9 -9
  3. package/dist/{BlockNoteEditor-OOZGXU6E.js.map → BlockNoteEditor-LYJUF5N4.js.map} +1 -1
  4. package/dist/billing/index.js +299 -299
  5. package/dist/billing/index.mjs +1 -1
  6. package/dist/{chunk-XYGK26YG.mjs → chunk-CDNVUON3.mjs} +374 -148
  7. package/dist/chunk-CDNVUON3.mjs.map +1 -0
  8. package/dist/{chunk-HCOX3PKM.js → chunk-TRTKIQUB.js} +608 -382
  9. package/dist/chunk-TRTKIQUB.js.map +1 -0
  10. package/dist/client/index.d.mts +32 -3
  11. package/dist/client/index.d.ts +32 -3
  12. package/dist/client/index.js +4 -2
  13. package/dist/client/index.js.map +1 -1
  14. package/dist/client/index.mjs +3 -1
  15. package/dist/components/index.d.mts +5 -2
  16. package/dist/components/index.d.ts +5 -2
  17. package/dist/components/index.js +2 -2
  18. package/dist/components/index.mjs +1 -1
  19. package/dist/{content.fields-hzZvhlBd.d.mts → content.fields-xH3TGvVk.d.mts} +2 -0
  20. package/dist/{content.fields-hzZvhlBd.d.ts → content.fields-xH3TGvVk.d.ts} +2 -0
  21. package/dist/contexts/index.js +2 -2
  22. package/dist/contexts/index.mjs +1 -1
  23. package/dist/core/index.d.mts +1 -1
  24. package/dist/core/index.d.ts +1 -1
  25. package/dist/index.d.mts +1 -1
  26. package/dist/index.d.ts +1 -1
  27. package/package.json +3 -1
  28. package/src/components/forms/FormDate.tsx +27 -3
  29. package/src/components/forms/FormDateTime.tsx +40 -8
  30. package/src/hooks/__tests__/computeLayeredLayout.spec.ts +152 -0
  31. package/src/hooks/computeLayeredLayout.ts +96 -0
  32. package/src/hooks/index.ts +6 -0
  33. package/src/hooks/useCustomD3Graph.tsx +310 -148
  34. package/src/interfaces/d3.node.interface.ts +2 -0
  35. package/dist/chunk-HCOX3PKM.js.map +0 -1
  36. package/dist/chunk-XYGK26YG.mjs.map +0 -1
  37. /package/dist/{BlockNoteEditor-LRJUTHTW.mjs.map → BlockNoteEditor-IBV3KBQM.mjs.map} +0 -0
@@ -6454,8 +6454,73 @@ import * as d3 from "d3";
6454
6454
  import { Loader2 as Loader22 } from "lucide-react";
6455
6455
  import { useCallback as useCallback9, useEffect as useEffect8, useMemo as useMemo8, useRef as useRef8 } from "react";
6456
6456
  import { renderToStaticMarkup } from "react-dom/server";
6457
+
6458
+ // src/hooks/computeLayeredLayout.ts
6459
+ import * as dagre from "dagre";
6460
+ var DEFAULT_RANKDIR = "LR";
6461
+ var DEFAULT_NODESEP = 50;
6462
+ var DEFAULT_RANKSEP = 120;
6463
+ var TITLE_PX_PER_CHAR_16 = 8;
6464
+ var NAME_PX_PER_CHAR_12 = 6.5;
6465
+ var NAME_PX_PER_CHAR_16_BOLD = 8;
6466
+ var SUBTITLE_PX_PER_CHAR_11 = 6;
6467
+ var LABEL_PADDING_PX = 16;
6468
+ function estimateLabelWidth(node) {
6469
+ if (node.subtitle) {
6470
+ const titleWidth = (node.name?.length ?? 0) * TITLE_PX_PER_CHAR_16;
6471
+ const subtitleWidth = node.subtitle.length * SUBTITLE_PX_PER_CHAR_11;
6472
+ return Math.max(titleWidth, subtitleWidth) + LABEL_PADDING_PX;
6473
+ }
6474
+ const perChar = node.bold ? NAME_PX_PER_CHAR_16_BOLD : NAME_PX_PER_CHAR_12;
6475
+ return (node.name?.length ?? 0) * perChar + LABEL_PADDING_PX;
6476
+ }
6477
+ __name(estimateLabelWidth, "estimateLabelWidth");
6478
+ function linkEndpointId(end) {
6479
+ return typeof end === "string" ? end : end.id;
6480
+ }
6481
+ __name(linkEndpointId, "linkEndpointId");
6482
+ function computeLayeredLayout(nodes, links, opts) {
6483
+ if (nodes.length === 0) return /* @__PURE__ */ new Map();
6484
+ const rankdir = opts.rankdir ?? DEFAULT_RANKDIR;
6485
+ const nodesep = opts.nodesep ?? DEFAULT_NODESEP;
6486
+ const ranksep = opts.ranksep ?? DEFAULT_RANKSEP;
6487
+ const g = new dagre.graphlib.Graph({ directed: true });
6488
+ g.setGraph({ rankdir, nodesep, ranksep, marginx: 20, marginy: 20 });
6489
+ g.setDefaultEdgeLabel(() => ({}));
6490
+ for (const node of nodes) {
6491
+ const width = Math.max(opts.minNodeWidth, estimateLabelWidth(node));
6492
+ const height = opts.minNodeHeight;
6493
+ g.setNode(node.id, { width, height });
6494
+ }
6495
+ const seen = /* @__PURE__ */ new Set();
6496
+ for (const link of links) {
6497
+ const sourceId = linkEndpointId(link.source);
6498
+ const targetId = linkEndpointId(link.target);
6499
+ if (!g.hasNode(sourceId) || !g.hasNode(targetId)) continue;
6500
+ const key = `${sourceId}->${targetId}`;
6501
+ if (seen.has(key)) continue;
6502
+ seen.add(key);
6503
+ g.setEdge(sourceId, targetId);
6504
+ }
6505
+ try {
6506
+ dagre.layout(g);
6507
+ } catch {
6508
+ return null;
6509
+ }
6510
+ const positions = /* @__PURE__ */ new Map();
6511
+ for (const node of nodes) {
6512
+ const laid = g.node(node.id);
6513
+ if (laid && Number.isFinite(laid.x) && Number.isFinite(laid.y)) {
6514
+ positions.set(node.id, { x: laid.x, y: laid.y });
6515
+ }
6516
+ }
6517
+ return positions;
6518
+ }
6519
+ __name(computeLayeredLayout, "computeLayeredLayout");
6520
+
6521
+ // src/hooks/useCustomD3Graph.tsx
6457
6522
  import { jsx as jsx49 } from "react/jsx-runtime";
6458
- function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, loadingNodeIds, containerKey) {
6523
+ function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, options, loadingNodeIds, containerKey) {
6459
6524
  const svgRef = useRef8(null);
6460
6525
  const zoomRef = useRef8(null);
6461
6526
  const zoomBehaviorRef = useRef8(null);
@@ -6543,6 +6608,9 @@ function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, loadingNode
6543
6608
  }, []);
6544
6609
  const getNodeColor = useCallback9(
6545
6610
  (node) => {
6611
+ if (node.color) {
6612
+ return node.washedOut ? washOutColor(node.color) : node.color;
6613
+ }
6546
6614
  const baseColor = colorScale.get(node.instanceType) || "gray";
6547
6615
  if (node.washedOut) {
6548
6616
  return washOutColor(baseColor);
@@ -6568,6 +6636,12 @@ function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, loadingNode
6568
6636
  const height = container.clientHeight;
6569
6637
  svg.attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`);
6570
6638
  const graphGroup = svg.append("g").attr("class", "graph-content");
6639
+ const nodeRadius = 40;
6640
+ const directed = options?.directed === true;
6641
+ if (directed) {
6642
+ const defs = svg.append("defs");
6643
+ defs.append("marker").attr("id", "narr8-arrow").attr("viewBox", "-10 -10 20 20").attr("markerWidth", 14).attr("markerHeight", 14).attr("markerUnits", "userSpaceOnUse").attr("orient", "auto").attr("refX", 0).attr("refY", 0).append("path").attr("d", "M-10,-10 L0,0 L-10,10 z").attr("fill", "#999");
6644
+ }
6571
6645
  const zoom2 = d3.zoom().scaleExtent([0.1, 4]).on("zoom", (event) => {
6572
6646
  const transform = event.transform;
6573
6647
  graphGroup.attr("transform", transform.toString());
@@ -6575,119 +6649,190 @@ function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, loadingNode
6575
6649
  });
6576
6650
  zoomBehaviorRef.current = zoom2;
6577
6651
  svg.call(zoom2).on("wheel.zoom", null).on("dblclick.zoom", null);
6578
- const nodeRadius = 40;
6579
- const childDistanceFromRoot = Math.min(width, height) * 0.4;
6580
- const grandchildDistanceFromChild = nodeRadius * 10;
6581
- const centralNodeId = nodes[0].id;
6582
- const nodeHierarchy = /* @__PURE__ */ new Map();
6583
- nodeHierarchy.set(centralNodeId, {
6584
- depth: 0,
6585
- parent: null,
6586
- children: []
6587
- });
6588
- visibleLinks.forEach((link2) => {
6589
- const sourceId = typeof link2.source === "string" ? link2.source : link2.source.id;
6590
- const targetId = typeof link2.target === "string" ? link2.target : link2.target.id;
6591
- if (sourceId === centralNodeId) {
6592
- nodeHierarchy.set(targetId, { depth: 1, parent: centralNodeId, children: [] });
6593
- const rootNode = nodeHierarchy.get(centralNodeId);
6594
- if (rootNode) {
6595
- rootNode.children.push(targetId);
6596
- }
6597
- }
6598
- });
6599
- visibleLinks.forEach((link2) => {
6600
- const sourceId = typeof link2.source === "string" ? link2.source : link2.source.id;
6601
- const targetId = typeof link2.target === "string" ? link2.target : link2.target.id;
6602
- const sourceNode = nodeHierarchy.get(sourceId);
6603
- if (sourceNode && sourceNode.depth === 1 && !nodeHierarchy.has(targetId)) {
6604
- nodeHierarchy.set(targetId, { depth: 2, parent: sourceId, children: [] });
6605
- sourceNode.children.push(targetId);
6606
- }
6607
- });
6608
- const rootChildren = nodeHierarchy.get(centralNodeId)?.children || [];
6609
- const childAngleStep = 2 * Math.PI / Math.max(rootChildren.length, 1);
6610
- rootChildren.forEach((childId, index) => {
6611
- const childNode = nodeHierarchy.get(childId);
6612
- if (childNode) {
6613
- const angle = index * childAngleStep;
6614
- childNode.angle = angle;
6615
- childNode.x = width / 2 + childDistanceFromRoot * Math.cos(angle);
6616
- childNode.y = height / 2 + childDistanceFromRoot * Math.sin(angle);
6652
+ const layoutMode = options?.layout ?? "radial";
6653
+ let layeredPositionsApplied = false;
6654
+ if (layoutMode === "layered") {
6655
+ const layeredOpts = options?.layered ?? {};
6656
+ const positions = computeLayeredLayout(visibleNodes, visibleLinks, {
6657
+ rankdir: layeredOpts.rankdir ?? "LR",
6658
+ nodesep: layeredOpts.nodesep,
6659
+ ranksep: layeredOpts.ranksep,
6660
+ minNodeWidth: nodeRadius * 2,
6661
+ minNodeHeight: nodeRadius * 2
6662
+ });
6663
+ if (positions) {
6664
+ visibleNodes.forEach((node2) => {
6665
+ const saved = nodePositionsRef.current.get(node2.id);
6666
+ if (saved) {
6667
+ node2.fx = saved.x;
6668
+ node2.fy = saved.y;
6669
+ node2.x = saved.x;
6670
+ node2.y = saved.y;
6671
+ return;
6672
+ }
6673
+ const pos = positions.get(node2.id);
6674
+ if (pos) {
6675
+ node2.fx = pos.x;
6676
+ node2.fy = pos.y;
6677
+ node2.x = pos.x;
6678
+ node2.y = pos.y;
6679
+ nodePositionsRef.current.set(node2.id, { x: pos.x, y: pos.y });
6680
+ }
6681
+ });
6682
+ const nodeById = /* @__PURE__ */ new Map();
6683
+ visibleNodes.forEach((n) => nodeById.set(n.id, n));
6684
+ visibleLinks.forEach((link2) => {
6685
+ if (typeof link2.source === "string") {
6686
+ const src = nodeById.get(link2.source);
6687
+ if (src) link2.source = src;
6688
+ }
6689
+ if (typeof link2.target === "string") {
6690
+ const tgt = nodeById.get(link2.target);
6691
+ if (tgt) link2.target = tgt;
6692
+ }
6693
+ });
6694
+ layeredPositionsApplied = true;
6695
+ } else {
6696
+ console.warn("[useCustomD3Graph] Layered layout failed; falling back to radial.");
6617
6697
  }
6618
- });
6619
- for (const [_nodeId, node2] of nodeHierarchy.entries()) {
6620
- if (node2.depth === 1 && node2.angle !== void 0 && node2.x !== void 0 && node2.y !== void 0) {
6621
- const childAngle = node2.angle;
6622
- const childX = node2.x;
6623
- const childY = node2.y;
6624
- const grandchildren = node2.children;
6625
- if (grandchildren.length === 0) continue;
6626
- const dirX = childX - width / 2;
6627
- const dirY = childY - height / 2;
6628
- const dirLength = Math.sqrt(dirX * dirX + dirY * dirY);
6629
- const normDirX = dirX / dirLength;
6630
- const normDirY = dirY / dirLength;
6631
- if (grandchildren.length === 1) {
6632
- const grandchildId = grandchildren[0];
6633
- const grandchildNode = nodeHierarchy.get(grandchildId);
6634
- if (grandchildNode) {
6635
- grandchildNode.x = childX + normDirX * grandchildDistanceFromChild;
6636
- grandchildNode.y = childY + normDirY * grandchildDistanceFromChild;
6637
- grandchildNode.angle = childAngle;
6698
+ }
6699
+ let simulation = null;
6700
+ if (!layeredPositionsApplied) {
6701
+ const childDistanceFromRoot = Math.min(width, height) * 0.4;
6702
+ const grandchildDistanceFromChild = nodeRadius * 10;
6703
+ const centralNodeId = nodes[0].id;
6704
+ const nodeHierarchy = /* @__PURE__ */ new Map();
6705
+ nodeHierarchy.set(centralNodeId, {
6706
+ depth: 0,
6707
+ parent: null,
6708
+ children: []
6709
+ });
6710
+ visibleLinks.forEach((link2) => {
6711
+ const sourceId = typeof link2.source === "string" ? link2.source : link2.source.id;
6712
+ const targetId = typeof link2.target === "string" ? link2.target : link2.target.id;
6713
+ if (sourceId === centralNodeId) {
6714
+ nodeHierarchy.set(targetId, { depth: 1, parent: centralNodeId, children: [] });
6715
+ const rootNode = nodeHierarchy.get(centralNodeId);
6716
+ if (rootNode) {
6717
+ rootNode.children.push(targetId);
6638
6718
  }
6639
- } else {
6640
- const numChildren = grandchildren.length;
6641
- const minArc = Math.PI / 3;
6642
- const maxArc = Math.PI;
6643
- const arcProgress = Math.min(1, (numChildren - 2) / 5);
6644
- const arcSpan = minArc + arcProgress * (maxArc - minArc);
6645
- const startAngle = childAngle - arcSpan / 2;
6646
- grandchildren.forEach((grandchildId, index) => {
6719
+ }
6720
+ });
6721
+ visibleLinks.forEach((link2) => {
6722
+ const sourceId = typeof link2.source === "string" ? link2.source : link2.source.id;
6723
+ const targetId = typeof link2.target === "string" ? link2.target : link2.target.id;
6724
+ const sourceNode = nodeHierarchy.get(sourceId);
6725
+ if (sourceNode && sourceNode.depth === 1 && !nodeHierarchy.has(targetId)) {
6726
+ nodeHierarchy.set(targetId, { depth: 2, parent: sourceId, children: [] });
6727
+ sourceNode.children.push(targetId);
6728
+ }
6729
+ });
6730
+ const rootChildren = nodeHierarchy.get(centralNodeId)?.children || [];
6731
+ const childAngleStep = 2 * Math.PI / Math.max(rootChildren.length, 1);
6732
+ rootChildren.forEach((childId, index) => {
6733
+ const childNode = nodeHierarchy.get(childId);
6734
+ if (childNode) {
6735
+ const angle = index * childAngleStep;
6736
+ childNode.angle = angle;
6737
+ childNode.x = width / 2 + childDistanceFromRoot * Math.cos(angle);
6738
+ childNode.y = height / 2 + childDistanceFromRoot * Math.sin(angle);
6739
+ }
6740
+ });
6741
+ for (const [_nodeId, node2] of nodeHierarchy.entries()) {
6742
+ if (node2.depth === 1 && node2.angle !== void 0 && node2.x !== void 0 && node2.y !== void 0) {
6743
+ const childAngle = node2.angle;
6744
+ const childX = node2.x;
6745
+ const childY = node2.y;
6746
+ const grandchildren = node2.children;
6747
+ if (grandchildren.length === 0) continue;
6748
+ const dirX = childX - width / 2;
6749
+ const dirY = childY - height / 2;
6750
+ const dirLength = Math.sqrt(dirX * dirX + dirY * dirY);
6751
+ const normDirX = dirX / dirLength;
6752
+ const normDirY = dirY / dirLength;
6753
+ if (grandchildren.length === 1) {
6754
+ const grandchildId = grandchildren[0];
6647
6755
  const grandchildNode = nodeHierarchy.get(grandchildId);
6648
- if (!grandchildNode) return;
6649
- const angleOffset = numChildren > 1 ? index / (numChildren - 1) * arcSpan : 0;
6650
- const angle = startAngle + angleOffset;
6651
- grandchildNode.x = childX + grandchildDistanceFromChild * Math.cos(angle);
6652
- grandchildNode.y = childY + grandchildDistanceFromChild * Math.sin(angle);
6653
- grandchildNode.angle = angle;
6654
- });
6756
+ if (grandchildNode) {
6757
+ grandchildNode.x = childX + normDirX * grandchildDistanceFromChild;
6758
+ grandchildNode.y = childY + normDirY * grandchildDistanceFromChild;
6759
+ grandchildNode.angle = childAngle;
6760
+ }
6761
+ } else {
6762
+ const numChildren = grandchildren.length;
6763
+ const minArc = Math.PI / 3;
6764
+ const maxArc = Math.PI;
6765
+ const arcProgress = Math.min(1, (numChildren - 2) / 5);
6766
+ const arcSpan = minArc + arcProgress * (maxArc - minArc);
6767
+ const startAngle = childAngle - arcSpan / 2;
6768
+ grandchildren.forEach((grandchildId, index) => {
6769
+ const grandchildNode = nodeHierarchy.get(grandchildId);
6770
+ if (!grandchildNode) return;
6771
+ const angleOffset = numChildren > 1 ? index / (numChildren - 1) * arcSpan : 0;
6772
+ const angle = startAngle + angleOffset;
6773
+ grandchildNode.x = childX + grandchildDistanceFromChild * Math.cos(angle);
6774
+ grandchildNode.y = childY + grandchildDistanceFromChild * Math.sin(angle);
6775
+ grandchildNode.angle = angle;
6776
+ });
6777
+ }
6655
6778
  }
6656
6779
  }
6657
- }
6658
- visibleNodes.forEach((node2) => {
6659
- const savedPosition = nodePositionsRef.current.get(node2.id);
6660
- if (savedPosition) {
6661
- node2.fx = savedPosition.x;
6662
- node2.fy = savedPosition.y;
6663
- } else {
6664
- const hierarchyNode = nodeHierarchy.get(node2.id);
6665
- if (hierarchyNode && hierarchyNode.x !== void 0 && hierarchyNode.y !== void 0) {
6666
- node2.fx = hierarchyNode.x;
6667
- node2.fy = hierarchyNode.y;
6668
- nodePositionsRef.current.set(node2.id, { x: hierarchyNode.x, y: hierarchyNode.y });
6669
- } else if (node2.id === centralNodeId) {
6670
- node2.fx = width / 2;
6671
- node2.fy = height / 2;
6672
- nodePositionsRef.current.set(node2.id, { x: width / 2, y: height / 2 });
6780
+ visibleNodes.forEach((node2) => {
6781
+ const savedPosition = nodePositionsRef.current.get(node2.id);
6782
+ if (savedPosition) {
6783
+ node2.fx = savedPosition.x;
6784
+ node2.fy = savedPosition.y;
6785
+ } else {
6786
+ const hierarchyNode = nodeHierarchy.get(node2.id);
6787
+ if (hierarchyNode && hierarchyNode.x !== void 0 && hierarchyNode.y !== void 0) {
6788
+ node2.fx = hierarchyNode.x;
6789
+ node2.fy = hierarchyNode.y;
6790
+ nodePositionsRef.current.set(node2.id, { x: hierarchyNode.x, y: hierarchyNode.y });
6791
+ } else if (node2.id === centralNodeId) {
6792
+ node2.fx = width / 2;
6793
+ node2.fy = height / 2;
6794
+ nodePositionsRef.current.set(node2.id, { x: width / 2, y: height / 2 });
6795
+ }
6673
6796
  }
6797
+ });
6798
+ simulation = d3.forceSimulation(visibleNodes).force(
6799
+ "link",
6800
+ d3.forceLink(visibleLinks).id((d) => d.id).distance(nodeRadius * 3).strength(0.1)
6801
+ ).force("charge", d3.forceManyBody().strength(-500).distanceMax(300)).force("collision", d3.forceCollide().radius(nodeRadius * 1.2)).force("center", d3.forceCenter(width / 2, height / 2).strength(0.1));
6802
+ simulation.stop();
6803
+ for (let i = 0; i < 100; i++) {
6804
+ simulation.tick();
6674
6805
  }
6675
- });
6676
- const simulation = d3.forceSimulation(visibleNodes).force(
6677
- "link",
6678
- d3.forceLink(visibleLinks).id((d) => d.id).distance(nodeRadius * 3).strength(0.1)
6679
- ).force("charge", d3.forceManyBody().strength(-500).distanceMax(300)).force("collision", d3.forceCollide().radius(nodeRadius * 1.2)).force("center", d3.forceCenter(width / 2, height / 2).strength(0.1));
6680
- simulation.stop();
6681
- for (let i = 0; i < 100; i++) {
6682
- simulation.tick();
6683
- }
6684
- visibleNodes.forEach((node2) => {
6685
- if (node2.fx === void 0) {
6686
- node2.fx = node2.x;
6687
- node2.fy = node2.y;
6688
- }
6689
- });
6690
- const link = graphGroup.append("g").attr("stroke", "#999").attr("stroke-opacity", 0.6).selectAll("line").data(visibleLinks).join("line").attr("x1", (d) => d.source.x || 0).attr("y1", (d) => d.source.y || 0).attr("x2", (d) => d.target.x || 0).attr("y2", (d) => d.target.y || 0).attr("stroke-width", 1.5);
6806
+ visibleNodes.forEach((node2) => {
6807
+ if (node2.fx === void 0) {
6808
+ node2.fx = node2.x;
6809
+ node2.fy = node2.y;
6810
+ }
6811
+ });
6812
+ }
6813
+ const linkX2 = /* @__PURE__ */ __name((sx, sy, tx, ty) => {
6814
+ if (!directed) return tx;
6815
+ const dx = tx - sx;
6816
+ const dy = ty - sy;
6817
+ const dist = Math.sqrt(dx * dx + dy * dy) || 1;
6818
+ return tx - dx / dist * nodeRadius;
6819
+ }, "linkX2");
6820
+ const linkY2 = /* @__PURE__ */ __name((sx, sy, tx, ty) => {
6821
+ if (!directed) return ty;
6822
+ const dx = tx - sx;
6823
+ const dy = ty - sy;
6824
+ const dist = Math.sqrt(dx * dx + dy * dy) || 1;
6825
+ return ty - dy / dist * nodeRadius;
6826
+ }, "linkY2");
6827
+ const link = graphGroup.append("g").attr("stroke", "#999").attr("stroke-opacity", 0.6).selectAll("line").data(visibleLinks).join("line").attr("x1", (d) => d.source.x || 0).attr("y1", (d) => d.source.y || 0).attr("x2", (d) => {
6828
+ const s = d.source;
6829
+ const t = d.target;
6830
+ return linkX2(s.x || 0, s.y || 0, t.x || 0, t.y || 0);
6831
+ }).attr("y2", (d) => {
6832
+ const s = d.source;
6833
+ const t = d.target;
6834
+ return linkY2(s.x || 0, s.y || 0, t.x || 0, t.y || 0);
6835
+ }).attr("stroke-width", 1.5).attr("marker-end", directed ? "url(#narr8-arrow)" : null);
6691
6836
  const node = graphGroup.append("g").selectAll("g").data(visibleNodes).join("g").attr("class", "node-group").attr("data-id", (d) => d.id).attr("cursor", "pointer").attr("transform", (d) => `translate(${d.x || 0}, ${d.y || 0})`).call(
6692
6837
  d3.drag().subject(function(d) {
6693
6838
  return d;
@@ -6707,11 +6852,21 @@ function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, loadingNode
6707
6852
  const source = l.source;
6708
6853
  return source.fy || source.y || 0;
6709
6854
  }).attr("x2", (l) => {
6855
+ const source = l.source;
6710
6856
  const target = l.target;
6711
- return target.fx || target.x || 0;
6857
+ const sx = source.fx || source.x || 0;
6858
+ const sy = source.fy || source.y || 0;
6859
+ const tx = target.fx || target.x || 0;
6860
+ const ty = target.fy || target.y || 0;
6861
+ return linkX2(sx, sy, tx, ty);
6712
6862
  }).attr("y2", (l) => {
6863
+ const source = l.source;
6713
6864
  const target = l.target;
6714
- return target.fy || target.y || 0;
6865
+ const sx = source.fx || source.x || 0;
6866
+ const sy = source.fy || source.y || 0;
6867
+ const tx = target.fx || target.x || 0;
6868
+ const ty = target.fy || target.y || 0;
6869
+ return linkY2(sx, sy, tx, ty);
6715
6870
  });
6716
6871
  }).on("end", function(event, d) {
6717
6872
  d.fx = event.x;
@@ -6732,7 +6887,7 @@ function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, loadingNode
6732
6887
  if (d.instanceType === "root") return;
6733
6888
  const currentNode = d3.select(this);
6734
6889
  currentNode.select("circle").transition().duration(250).ease(d3.easeExpOut).attr("r", nodeRadius).attr("filter", null);
6735
- const normalOffset = nodeRadius + 5;
6890
+ const normalOffset = nodeRadius + 5 + (d.subtitle ? 16 : 0);
6736
6891
  currentNode.select("text").transition().duration(250).ease(d3.easeExpOut).attr("dy", -normalOffset).attr("transform", `translate(0, ${-normalOffset}) scale(1) translate(0, ${normalOffset})`);
6737
6892
  });
6738
6893
  node.append("circle").attr("r", nodeRadius).attr("fill", (d) => getNodeColor(d)).attr("stroke", "#fff").attr("stroke-width", 1.5).on("click", (event, d) => {
@@ -6784,14 +6939,33 @@ function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, loadingNode
6784
6939
  words.forEach((word, index) => {
6785
6940
  textElement.append("tspan").attr("x", 0).attr("dy", index === 0 ? `${startY}em` : `${lineHeight}em`).text(word);
6786
6941
  });
6942
+ } else if (d.subtitle) {
6943
+ const titleSize = 16;
6944
+ const subtitleSize = 11;
6945
+ const lineGap = titleSize;
6946
+ textElement.attr("dy", -nodeRadius - 5 - lineGap).attr("fill", "currentColor");
6947
+ textElement.append("tspan").attr("x", 0).attr("font-size", titleSize).attr("font-weight", 700).text(d.name);
6948
+ textElement.append("tspan").attr("x", 0).attr("dy", lineGap).attr("font-size", subtitleSize).attr("fill-opacity", 0.7).text(d.subtitle);
6787
6949
  } else {
6788
6950
  textElement.attr("dy", -nodeRadius - 5).attr("fill", "currentColor").attr("font-size", d.bold ? 16 : 12).attr("font-weight", d.bold ? 700 : null).text(d.name);
6789
6951
  }
6790
6952
  });
6791
6953
  return () => {
6792
- simulation.stop();
6954
+ simulation?.stop();
6793
6955
  };
6794
- }, [nodes, links, colorScale, visibleNodeIds, loadingNodeIds, onNodeClick]);
6956
+ }, [
6957
+ nodes,
6958
+ links,
6959
+ colorScale,
6960
+ visibleNodeIds,
6961
+ options?.directed,
6962
+ options?.layout,
6963
+ options?.layered?.rankdir,
6964
+ options?.layered?.nodesep,
6965
+ options?.layered?.ranksep,
6966
+ loadingNodeIds,
6967
+ onNodeClick
6968
+ ]);
6795
6969
  const zoomIn = useCallback9(() => {
6796
6970
  if (!svgRef.current || !zoomBehaviorRef.current) return;
6797
6971
  const svg = d3.select(svgRef.current);
@@ -9226,7 +9400,7 @@ import { useRef as useRef15 } from "react";
9226
9400
  import dynamic from "next/dynamic";
9227
9401
  import React14 from "react";
9228
9402
  import { jsx as jsx73 } from "react/jsx-runtime";
9229
- var BlockNoteEditor = dynamic(() => import("./BlockNoteEditor-LRJUTHTW.mjs"), {
9403
+ var BlockNoteEditor = dynamic(() => import("./BlockNoteEditor-IBV3KBQM.mjs"), {
9230
9404
  ssr: false
9231
9405
  });
9232
9406
  var BlockNoteEditorContainer = React14.memo(/* @__PURE__ */ __name(function EditorContainer(props) {
@@ -9325,14 +9499,17 @@ function FormDate({
9325
9499
  name,
9326
9500
  minDate,
9327
9501
  onChange,
9328
- isRequired = false
9502
+ isRequired = false,
9503
+ defaultMonth,
9504
+ allowEmpty
9329
9505
  }) {
9506
+ const t = useI18nTranslations();
9330
9507
  const locale = useI18nLocale();
9331
9508
  const dateFnsLocale = useI18nDateFnsLocale();
9332
9509
  const [open, setOpen] = useState21(false);
9333
9510
  const [displayMonth, setDisplayMonth] = useState21(() => {
9334
9511
  const currentValue = form.getValues(id);
9335
- return currentValue || /* @__PURE__ */ new Date();
9512
+ return currentValue || defaultMonth || /* @__PURE__ */ new Date();
9336
9513
  });
9337
9514
  const dateFormatter = useMemo12(
9338
9515
  () => new Intl.DateTimeFormat(locale, { day: "2-digit", month: "2-digit", year: "numeric" }),
@@ -9395,7 +9572,7 @@ function FormDate({
9395
9572
  ),
9396
9573
  /* @__PURE__ */ jsxs44(InputGroupAddon, { align: "inline-end", children: [
9397
9574
  /* @__PURE__ */ jsx75(PopoverTrigger, { render: /* @__PURE__ */ jsx75("div", {}), nativeButton: false, children: /* @__PURE__ */ jsx75(InputGroupButton, { variant: "ghost", size: "icon-xs", children: /* @__PURE__ */ jsx75(CalendarIcon3, { className: "h-4 w-4 opacity-50" }) }) }),
9398
- field.value && /* @__PURE__ */ jsx75(
9575
+ field.value && allowEmpty !== false && /* @__PURE__ */ jsx75(
9399
9576
  InputGroupButton,
9400
9577
  {
9401
9578
  variant: "ghost",
@@ -9410,25 +9587,43 @@ function FormDate({
9410
9587
  )
9411
9588
  ] })
9412
9589
  ] }),
9413
- /* @__PURE__ */ jsx75(PopoverContent, { className: "w-auto p-0", align: "end", children: /* @__PURE__ */ jsx75(
9414
- Calendar,
9415
- {
9416
- mode: "single",
9417
- captionLayout: "dropdown",
9418
- selected: field.value,
9419
- onSelect: (e) => {
9420
- handleCalendarSelect(e, field);
9421
- setOpen(false);
9422
- },
9423
- disabled: (date) => minDate && date < minDate ? true : false,
9424
- locale: dateFnsLocale,
9425
- weekStartsOn: 1,
9426
- month: displayMonth,
9427
- onMonthChange: setDisplayMonth,
9428
- startMonth: new Date(1900, 0),
9429
- endMonth: new Date((/* @__PURE__ */ new Date()).getFullYear() + 10, 11)
9430
- }
9431
- ) })
9590
+ /* @__PURE__ */ jsxs44(PopoverContent, { className: "w-auto p-0", align: "end", children: [
9591
+ /* @__PURE__ */ jsx75(
9592
+ Calendar,
9593
+ {
9594
+ mode: "single",
9595
+ captionLayout: "dropdown",
9596
+ selected: field.value,
9597
+ onSelect: (e) => {
9598
+ handleCalendarSelect(e, field);
9599
+ setOpen(false);
9600
+ },
9601
+ disabled: (date) => minDate && date < minDate ? true : false,
9602
+ locale: dateFnsLocale,
9603
+ weekStartsOn: 1,
9604
+ month: displayMonth,
9605
+ onMonthChange: setDisplayMonth,
9606
+ startMonth: new Date(1900, 0),
9607
+ endMonth: new Date((/* @__PURE__ */ new Date()).getFullYear() + 10, 11)
9608
+ }
9609
+ ),
9610
+ allowEmpty !== false && /* @__PURE__ */ jsx75("div", { className: "border-t p-2", children: /* @__PURE__ */ jsx75(
9611
+ Button,
9612
+ {
9613
+ type: "button",
9614
+ variant: "outline",
9615
+ className: "w-full",
9616
+ disabled: !field.value,
9617
+ onClick: () => {
9618
+ field.onChange(void 0);
9619
+ setInputValue("");
9620
+ if (onChange) onChange(void 0);
9621
+ setOpen(false);
9622
+ },
9623
+ children: t(`ui.buttons.clear`)
9624
+ }
9625
+ ) })
9626
+ ] })
9432
9627
  ] }) }) });
9433
9628
  }
9434
9629
  __name(FormDate, "FormDate");
@@ -9443,12 +9638,17 @@ function FormDateTime({
9443
9638
  name,
9444
9639
  minDate,
9445
9640
  onChange,
9446
- allowEmpty
9641
+ allowEmpty,
9642
+ defaultMonth
9447
9643
  }) {
9448
9644
  const [open, setOpen] = useState22(false);
9449
9645
  const t = useI18nTranslations();
9450
9646
  const locale = useI18nLocale();
9451
9647
  const dateFnsLocale = useI18nDateFnsLocale();
9648
+ const [displayMonth, setDisplayMonth] = useState22(() => {
9649
+ const currentValue = form.getValues(id);
9650
+ return currentValue || defaultMonth || /* @__PURE__ */ new Date();
9651
+ });
9452
9652
  const dateTimeFormatter = useMemo13(
9453
9653
  () => new Intl.DateTimeFormat(locale, {
9454
9654
  year: "numeric",
@@ -9525,7 +9725,10 @@ function FormDateTime({
9525
9725
  Calendar,
9526
9726
  {
9527
9727
  mode: "single",
9728
+ captionLayout: "dropdown",
9528
9729
  selected: field.value,
9730
+ month: displayMonth,
9731
+ onMonthChange: setDisplayMonth,
9529
9732
  onSelect: (date) => {
9530
9733
  if (date) {
9531
9734
  const newDate = new Date(date);
@@ -9536,13 +9739,17 @@ function FormDateTime({
9536
9739
  newDate.setHours(selectedHours, selectedMinutes);
9537
9740
  }
9538
9741
  form.setValue(id, newDate);
9742
+ setDisplayMonth(newDate);
9539
9743
  if (onChange) onChange(newDate);
9540
9744
  setSelectedHours(newDate.getHours());
9541
9745
  setSelectedMinutes(roundToNearestFiveMinutes(newDate.getMinutes()));
9542
9746
  }
9543
9747
  },
9544
9748
  disabled: (date) => minDate && date < minDate ? true : false,
9545
- locale: dateFnsLocale
9749
+ locale: dateFnsLocale,
9750
+ weekStartsOn: 1,
9751
+ startMonth: new Date(1900, 0),
9752
+ endMonth: new Date((/* @__PURE__ */ new Date()).getFullYear() + 10, 11)
9546
9753
  }
9547
9754
  ),
9548
9755
  /* @__PURE__ */ jsxs45("div", { className: "flex flex-row items-end justify-center space-x-4", children: [
@@ -9591,16 +9798,34 @@ function FormDateTime({
9591
9798
  )
9592
9799
  ] })
9593
9800
  ] }),
9594
- /* @__PURE__ */ jsx76(
9595
- Button,
9596
- {
9597
- className: "mt-2",
9598
- onClick: () => {
9599
- setOpen(false);
9600
- },
9601
- children: t(`ui.buttons.select_date`)
9602
- }
9603
- )
9801
+ /* @__PURE__ */ jsxs45("div", { className: "mt-2 flex flex-row gap-x-2", children: [
9802
+ allowEmpty !== false && /* @__PURE__ */ jsx76(
9803
+ Button,
9804
+ {
9805
+ type: "button",
9806
+ variant: "outline",
9807
+ className: "flex-1",
9808
+ disabled: !field.value,
9809
+ onClick: () => {
9810
+ if (onChange) onChange(void 0);
9811
+ form.setValue(id, "");
9812
+ setOpen(false);
9813
+ },
9814
+ children: t(`ui.buttons.clear`)
9815
+ }
9816
+ ),
9817
+ /* @__PURE__ */ jsx76(
9818
+ Button,
9819
+ {
9820
+ type: "button",
9821
+ className: "flex-1",
9822
+ onClick: () => {
9823
+ setOpen(false);
9824
+ },
9825
+ children: t(`ui.buttons.select_date`)
9826
+ }
9827
+ )
9828
+ ] })
9604
9829
  ] }) })
9605
9830
  ] }) }) }) });
9606
9831
  }
@@ -21589,6 +21814,7 @@ export {
21589
21814
  useDebounce2 as useDebounce,
21590
21815
  registerTableGenerator,
21591
21816
  useTableGenerator,
21817
+ computeLayeredLayout,
21592
21818
  useCustomD3Graph,
21593
21819
  SocketContext,
21594
21820
  SocketProvider,
@@ -22088,4 +22314,4 @@ export {
22088
22314
  useOAuthClients,
22089
22315
  useOAuthClient
22090
22316
  };
22091
- //# sourceMappingURL=chunk-XYGK26YG.mjs.map
22317
+ //# sourceMappingURL=chunk-CDNVUON3.mjs.map