feat: udpate watchlist entity diagram

This commit is contained in:
Maël Gangloff
2024-08-16 13:56:52 +02:00
parent e21df5a137
commit d82aac451c
14 changed files with 223 additions and 203 deletions

View File

@@ -1,6 +1,6 @@
import {Button, Checkbox, Form, FormInstance, Input, Popconfirm, Select, Space, Typography} from "antd";
import React, {useState} from "react";
import {Connector, ConnectorProvider} from "../../utils/api/connectors";
import {Connector, ConnectorProvider} from "../../../utils/api/connectors";
import {t} from "ttag";
import {BankOutlined} from "@ant-design/icons";
import {
@@ -8,8 +8,8 @@ import {
ovhFields as ovhFieldsFunction,
ovhPricingMode as ovhPricingModeFunction,
ovhSubsidiaryList as ovhSubsidiaryListFunction
} from "../../utils/providers/ovh";
import {helpGetTokenLink, tosHyperlink} from "../../utils/providers";
} from "../../../utils/providers/ovh";
import {helpGetTokenLink, tosHyperlink} from "../../../utils/providers";
const formItemLayoutWithOutLabel = {
wrapperCol: {

View File

@@ -2,7 +2,7 @@ import {Card, Divider, Popconfirm, theme, Typography} from "antd";
import {t} from "ttag";
import {DeleteFilled} from "@ant-design/icons";
import React from "react";
import {Connector, deleteConnector} from "../../utils/api/connectors";
import {Connector, deleteConnector} from "../../../utils/api/connectors";
const {useToken} = theme;

View File

@@ -2,50 +2,13 @@ import {Button, Flex, Modal, Space, Typography} from "antd"
import {t} from "ttag"
import React, {useEffect, useState} from "react"
import {ApartmentOutlined} from "@ant-design/icons"
import vCard from "vcf";
import '@xyflow/react/dist/style.css'
import {Background, Controls, MiniMap, ReactFlow, useEdgesState, useNodesState} from "@xyflow/react";
import {getWatchlist, Watchlist} from "../../utils/api";
import dagre from 'dagre'
import vCard from "vcf";
const dagreGraph = new dagre.graphlib.Graph();
dagreGraph.setDefaultEdgeLabel(() => ({}));
const nodeWidth = 172;
const nodeHeight = 200;
const getLayoutedElements = (nodes: any, edges: any, direction = 'TB') => {
const isHorizontal = direction === 'LR';
dagreGraph.setGraph({rankdir: direction});
nodes.forEach((node: any) => {
dagreGraph.setNode(node.id, {width: nodeWidth, height: nodeHeight});
});
edges.forEach((edge: any) => {
dagreGraph.setEdge(edge.source, edge.target);
});
dagre.layout(dagreGraph);
const newNodes = nodes.map((node: any) => {
const nodeWithPosition = dagreGraph.node(node.id)
return {
...node,
targetPosition: isHorizontal ? 'left' : 'top',
sourcePosition: isHorizontal ? 'right' : 'bottom',
position: {
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - nodeHeight / 2
},
};
});
return {nodes: newNodes, edges};
}
import {getWatchlist, Watchlist} from "../../../utils/api";
import {translateRoles} from "../../search/EntitiesList";
import {getLayoutedElements} from "./getLayoutedElements";
function watchlistToNodes(watchlist: Watchlist) {
@@ -79,9 +42,12 @@ function watchlistToNodes(watchlist: Watchlist) {
}
const rolesToColor = (roles: string[]) => roles.includes('registrant') ? 'green' :
roles.includes('technical') ? 'orange' : 'black'
roles.includes('administrative') ? 'blue' :
roles.includes('technical') ? 'orange' : 'violet'
function watchlistToEdges(watchlist: Watchlist) {
const domainRole = translateRoles()
return watchlist.domains
.map(d => d.entities
.filter(e => !e.roles.includes('registrar'))
@@ -90,6 +56,7 @@ function watchlistToEdges(watchlist: Watchlist) {
source: e.roles.includes('technical') ? d.ldhName : e.entity.handle,
target: e.roles.includes('technical') ? e.entity.handle : d.ldhName,
style: {stroke: rolesToColor(e.roles), strokeWidth: 3},
label: e.roles.map(r => Object.keys(domainRole).includes(r) ? domainRole[r as keyof typeof domainRole] : r).join(', '),
animated: e.roles.includes('registrant'),
}))
).flat(2)
@@ -138,6 +105,10 @@ export function ViewDiagramWatchlistButton({token}: { token: string }) {
>
{nodes && edges && <Flex style={{width: '75vw', height: '80vh'}}>
<ReactFlow
fitView
colorMode='system'
nodesConnectable={false}
edgesReconnectable={false}
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}

View File

@@ -0,0 +1,39 @@
import dagre from "dagre";
const dagreGraph = new dagre.graphlib.Graph();
dagreGraph.setDefaultEdgeLabel(() => ({}));
const nodeWidth = 172;
const nodeHeight = 200;
export const getLayoutedElements = (nodes: any, edges: any, direction = 'TB') => {
const isHorizontal = direction === 'LR';
dagreGraph.setGraph({rankdir: direction});
nodes.forEach((node: any) => {
dagreGraph.setNode(node.id, {width: nodeWidth, height: nodeHeight});
});
edges.forEach((edge: any) => {
dagreGraph.setEdge(edge.source, edge.target);
});
dagre.layout(dagreGraph);
const newNodes = nodes.map((node: any) => {
const nodeWithPosition = dagreGraph.node(node.id)
return {
...node,
targetPosition: isHorizontal ? 'left' : 'top',
sourcePosition: isHorizontal ? 'right' : 'bottom',
position: {
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - nodeHeight / 2
},
};
});
return {nodes: newNodes, edges};
}

View File

@@ -1,9 +1,9 @@
import {Popconfirm, theme, Typography} from "antd";
import {t} from "ttag";
import {deleteWatchlist} from "../../utils/api";
import {deleteWatchlist} from "../../../utils/api";
import {DeleteFilled} from "@ant-design/icons";
import React from "react";
import {Watchlist} from "../../pages/tracking/WatchlistPage";
import {Watchlist} from "../../../pages/tracking/WatchlistPage";
export function DeleteWatchlistButton({watchlist, onDelete}: { watchlist: Watchlist, onDelete: () => void }) {
const {token} = theme.useToken()

View File

@@ -2,9 +2,9 @@ import {Button, Drawer, Form, Typography} from "antd";
import {t} from "ttag";
import {WatchlistForm} from "./WatchlistForm";
import React, {useState} from "react";
import {Watchlist} from "../../pages/tracking/WatchlistPage";
import {Watchlist} from "../../../pages/tracking/WatchlistPage";
import {EditOutlined} from "@ant-design/icons";
import {Connector} from "../../utils/api/connectors";
import {Connector} from "../../../utils/api/connectors";
export function UpdateWatchlistButton({watchlist, onUpdateWatchlist, connectors}: {
watchlist: Watchlist,

View File

@@ -2,8 +2,8 @@ import {Button, Form, FormInstance, Input, Select, SelectProps, Space, Tag} from
import {t} from "ttag";
import {ApiOutlined, MinusCircleOutlined, PlusOutlined} from "@ant-design/icons";
import React from "react";
import {Connector} from "../../utils/api/connectors";
import {actionToColor, domainEvent} from "../search/EventTimeline";
import {Connector} from "../../../utils/api/connectors";
import {actionToColor, domainEvent} from "../../search/EventTimeline";
type TagRender = SelectProps['tagRender'];

View File

@@ -2,14 +2,14 @@ import {Card, Divider, Space, Table, Tag, Typography} from "antd";
import {t} from "ttag";
import {CalendarFilled, DisconnectOutlined, LinkOutlined} from "@ant-design/icons";
import React from "react";
import useBreakpoint from "../../hooks/useBreakpoint";
import {actionToColor, domainEvent} from "../search/EventTimeline";
import {Watchlist} from "../../pages/tracking/WatchlistPage";
import useBreakpoint from "../../../hooks/useBreakpoint";
import {actionToColor, domainEvent} from "../../search/EventTimeline";
import {Watchlist} from "../../../pages/tracking/WatchlistPage";
import punycode from "punycode/punycode";
import {Connector} from "../../utils/api/connectors";
import {Connector} from "../../../utils/api/connectors";
import {UpdateWatchlistButton} from "./UpdateWatchlistButton";
import {DeleteWatchlistButton} from "./DeleteWatchlistButton";
import {ViewDiagramWatchlistButton} from "./ViewDiagramWatchlistButton";
import {ViewDiagramWatchlistButton} from "../diagram/ViewDiagramWatchlistButton";
export function WatchlistsList({watchlists, onDelete, onUpdateWatchlist, connectors}: {
watchlists: Watchlist[],