mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-18 15:04:59 +00:00
General improvements to Access Tree view
This commit is contained in:
@@ -1,17 +1,31 @@
|
||||
import { Dispatch, SetStateAction } from "react";
|
||||
|
||||
import { ProjectPermissionSub } from "@app/context";
|
||||
import { TProjectEnvironmentsFolders } from "@app/hooks/api/secretFolders/types";
|
||||
|
||||
import { PermissionNode } from "../types";
|
||||
|
||||
export const createRoleNode = ({
|
||||
subject,
|
||||
environment
|
||||
environment,
|
||||
environments,
|
||||
onSubjectChange,
|
||||
onEnvironmentChange
|
||||
}: {
|
||||
subject: string;
|
||||
environment: string;
|
||||
environments: TProjectEnvironmentsFolders;
|
||||
onSubjectChange: Dispatch<SetStateAction<ProjectPermissionSub>>;
|
||||
onEnvironmentChange: (value: string) => void;
|
||||
}) => ({
|
||||
id: `role-${subject}-${environment}`,
|
||||
position: { x: 0, y: 0 },
|
||||
data: {
|
||||
subject,
|
||||
environment
|
||||
environment,
|
||||
environments,
|
||||
onSubjectChange,
|
||||
onEnvironmentChange
|
||||
},
|
||||
type: PermissionNode.Role,
|
||||
height: 48,
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
import { ProjectPermissionSub } from "@app/context";
|
||||
|
||||
import { PermissionNode } from "../types";
|
||||
|
||||
export const createShowMoreNode = ({
|
||||
parentId,
|
||||
onClick,
|
||||
remaining
|
||||
remaining,
|
||||
subject
|
||||
}: {
|
||||
parentId: string | null;
|
||||
onClick: () => void;
|
||||
remaining: number;
|
||||
subject: ProjectPermissionSub;
|
||||
}) => {
|
||||
let height: number;
|
||||
|
||||
switch (subject) {
|
||||
case ProjectPermissionSub.DynamicSecrets:
|
||||
height = 130;
|
||||
break;
|
||||
case ProjectPermissionSub.Secrets:
|
||||
height = 85;
|
||||
break;
|
||||
default:
|
||||
height = 64;
|
||||
}
|
||||
const id = `show-more-${parentId || "root"}`;
|
||||
return {
|
||||
id,
|
||||
@@ -19,7 +35,11 @@ export const createShowMoreNode = ({
|
||||
onClick,
|
||||
remaining
|
||||
},
|
||||
width: 100,
|
||||
height: 40
|
||||
width: 150,
|
||||
height,
|
||||
style: {
|
||||
background: "transparent",
|
||||
border: "none"
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2,8 +2,10 @@ import Dagre from "@dagrejs/dagre";
|
||||
import { Edge, Node } from "@xyflow/react";
|
||||
|
||||
export const positionElements = (nodes: Node[], edges: Edge[]) => {
|
||||
const regularNodes = nodes.filter((node) => node.type !== "showMoreButton");
|
||||
const showMoreNodes = nodes.filter((node) => node.type === "showMoreButton");
|
||||
const showMoreParentIds = new Set(
|
||||
showMoreNodes.map((node) => node.data.parentId).filter(Boolean)
|
||||
);
|
||||
|
||||
const nodeMap: Record<string, Node> = {};
|
||||
const childrenMap: Record<string, string[]> = {};
|
||||
@@ -17,75 +19,79 @@ export const positionElements = (nodes: Node[], edges: Edge[]) => {
|
||||
|
||||
const dagre = new Dagre.graphlib.Graph({ directed: true })
|
||||
.setDefaultEdgeLabel(() => ({}))
|
||||
.setGraph({ rankdir: "TB" });
|
||||
.setGraph({
|
||||
rankdir: "TB",
|
||||
nodesep: 50,
|
||||
ranksep: 70
|
||||
});
|
||||
|
||||
nodes.forEach((node) => {
|
||||
dagre.setNode(node.id, {
|
||||
width: node.width || 150,
|
||||
height: node.height || 40
|
||||
});
|
||||
});
|
||||
|
||||
edges.forEach((edge) => dagre.setEdge(edge.source, edge.target));
|
||||
|
||||
regularNodes.forEach((node) => dagre.setNode(node.id, node));
|
||||
|
||||
Dagre.layout(dagre, {});
|
||||
|
||||
const positionedNodes = regularNodes.map((node) => {
|
||||
const positionedNodes = nodes.map((node) => {
|
||||
const { x, y } = dagre.node(node.id);
|
||||
|
||||
const positionedNode = {
|
||||
...node,
|
||||
position: {
|
||||
x: x - (node.width ? node.width / 2 : 0),
|
||||
y: y - (node.height ? node.height / 2 : 0)
|
||||
}
|
||||
};
|
||||
|
||||
nodeMap[node.id] = positionedNode;
|
||||
|
||||
return positionedNode;
|
||||
});
|
||||
|
||||
const findLastChildNode = (parentId: string): Node | undefined => {
|
||||
const childrenIds = childrenMap[parentId] || [];
|
||||
if (childrenIds.length === 0) return undefined;
|
||||
|
||||
const childNodes = childrenIds.map((id) => nodeMap[id]).filter(Boolean);
|
||||
|
||||
if (childNodes.length === 0) return undefined;
|
||||
|
||||
childNodes.sort((a, b) => {
|
||||
if (a.position.y === b.position.y) {
|
||||
return b.position.x - a.position.x;
|
||||
}
|
||||
return b.position.y - a.position.y;
|
||||
});
|
||||
|
||||
return childNodes[0];
|
||||
};
|
||||
|
||||
const positionedShowMoreNodes = showMoreNodes.map((node) => {
|
||||
const parentId = node.data.parentId as string;
|
||||
|
||||
const parentNode = nodeMap[parentId] || positionedNodes[0];
|
||||
const lastChildNode = findLastChildNode(parentId);
|
||||
|
||||
const referenceNode = lastChildNode || parentNode;
|
||||
|
||||
const referenceX = referenceNode.position.x;
|
||||
const referenceY = referenceNode.position.y;
|
||||
|
||||
const referenceWidth = referenceNode.width || 150;
|
||||
|
||||
const buttonX = referenceX + referenceWidth - 85;
|
||||
const buttonY = referenceY - 25;
|
||||
if (node.type === "role") {
|
||||
return {
|
||||
...node,
|
||||
position: {
|
||||
x: x - (node.width ? node.width / 2 : 0),
|
||||
y: y - 150
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...node,
|
||||
position: {
|
||||
x: buttonX,
|
||||
y: buttonY
|
||||
}
|
||||
x: x - (node.width ? node.width / 2 : 0),
|
||||
y: y - (node.height ? node.height / 2 : 0)
|
||||
},
|
||||
style: node.type === "showMoreButton" ? { ...node.style, zIndex: 10 } : node.style
|
||||
};
|
||||
});
|
||||
|
||||
positionedNodes.forEach((node) => {
|
||||
nodeMap[node.id] = node;
|
||||
});
|
||||
|
||||
Array.from(showMoreParentIds).forEach((parentId) => {
|
||||
const showMoreNodeIndex = positionedNodes.findIndex(
|
||||
(node) => node.type === "showMoreButton" && node.data.parentId === parentId
|
||||
);
|
||||
|
||||
if (showMoreNodeIndex !== -1) {
|
||||
const siblings = positionedNodes.filter(
|
||||
(node) => node.data?.parentId === parentId && node.type !== "showMoreButton"
|
||||
);
|
||||
|
||||
if (siblings.length > 0) {
|
||||
const rightmostSibling = siblings.reduce(
|
||||
(rightmost, current) => (current.position.x > rightmost.position.x ? current : rightmost),
|
||||
siblings[0]
|
||||
);
|
||||
|
||||
positionedNodes[showMoreNodeIndex] = {
|
||||
...positionedNodes[showMoreNodeIndex],
|
||||
position: {
|
||||
x: rightmostSibling.position.x + (rightmostSibling.width || 150) + 30,
|
||||
y: rightmostSibling.position.y
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
nodes: [...positionedNodes, ...positionedShowMoreNodes],
|
||||
nodes: positionedNodes,
|
||||
edges
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user