From a546b27bcf0a020e1535edd4462f8a7bdeb65541 Mon Sep 17 00:00:00 2001 From: mapan-nju <2246839805@qq.com> Date: Mon, 24 Mar 2025 14:44:15 +0800 Subject: [PATCH] dependencies page --- .../[name]/[version]/dependencies/page.tsx | 71 +++- .../[nsbehind]/[name]/[version]/page.tsx | 4 +- components/CrateNav.tsx | 10 +- components/DependencyTable.tsx | 356 ++++++++++++++---- components/NewHeader.tsx | 62 ++- public/images/homepage/array-grey.png | Bin 0 -> 692 bytes public/images/homepage/array-up.png | Bin 0 -> 682 bytes public/images/homepage/arry-down.png | Bin 0 -> 677 bytes .../images/homepage/search-Dependencies.png | Bin 0 -> 718 bytes 9 files changed, 372 insertions(+), 131 deletions(-) create mode 100644 public/images/homepage/array-grey.png create mode 100644 public/images/homepage/array-up.png create mode 100644 public/images/homepage/arry-down.png create mode 100644 public/images/homepage/search-Dependencies.png diff --git a/app/[nsfront]/[nsbehind]/[name]/[version]/dependencies/page.tsx b/app/[nsfront]/[nsbehind]/[name]/[version]/dependencies/page.tsx index ea9d4ca..30122a8 100644 --- a/app/[nsfront]/[nsbehind]/[name]/[version]/dependencies/page.tsx +++ b/app/[nsfront]/[nsbehind]/[name]/[version]/dependencies/page.tsx @@ -2,7 +2,7 @@ "use client"; import React, { useEffect, useState } from "react"; import { useParams } from "next/navigation"; - +import Image from "next/image"; import DependencyTable from "@/components/DependencyTable"; // import DependencyGraph from "@/components/DependencyGraph"; // 假设你已经创建了 DependencyGraph 组件 import { dependenciesInfo } from "@/app/lib/all_interface"; @@ -17,7 +17,7 @@ const CratePage = () => { const [error, setError] = useState(null); // 新增状态:控制显示 DependencyTable 或 DependencyGraph - const [showTable, setShowTable] = useState(true); + // const [showTable, setShowTable] = useState(true); useEffect(() => { const fetchCrateData = async () => { @@ -44,22 +44,67 @@ const CratePage = () => { fetchCrateData(); // 调用函数来获取数据 }, [params.name, params.version, params.nsfront, params.nsbehind]); // 依赖项数组,确保在 crateName 或 version 改变时重新获取数据 - if (loading) return
Loading...
; - if (error) return
Error: {error}
; + if (loading) return
Loading...
; + if (error) return
Error: {error}
; return ( -
+
+
+
+ +
+
+ + {/* 页脚 */} +
+
+
+
+
+ CratesPro Logo +
+ +
+

Resources

+
    +
  • Documentation
  • +
  • About
  • +
  • Blog
  • +
  • FAQ
  • +
+
- {/* 切换按钮 */} - setShowTable(!showTable)} // 切换状态 - className="mb-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600" - href={`/${params.nsfront}/${params.nsbehind}/${params.name}/${params.version}/dependencies/graph`} > - {showTable ? "Show Graph" : "Show Table"} - +
+

API

+
    +
  • API
  • +
  • BigQuery Dataset
  • +
  • GitHub
  • +
+
- +
+

Legal

+
    +
  • Legal
  • +
  • Privacy
  • +
  • Terms
  • +
+
+
+
+

Copyright © 2023 jp21.com.cn All Rights Reserved(@ICPBH180237号)

+
+
+
+
); }; diff --git a/app/[nsfront]/[nsbehind]/[name]/[version]/page.tsx b/app/[nsfront]/[nsbehind]/[name]/[version]/page.tsx index b20db55..d0ad492 100644 --- a/app/[nsfront]/[nsbehind]/[name]/[version]/page.tsx +++ b/app/[nsfront]/[nsbehind]/[name]/[version]/page.tsx @@ -272,8 +272,8 @@ const CratePage = () => { No vulnerabilities

No vulnerabilities found

diff --git a/components/CrateNav.tsx b/components/CrateNav.tsx index eae2d72..71e6dde 100644 --- a/components/CrateNav.tsx +++ b/components/CrateNav.tsx @@ -60,9 +60,13 @@ const CrateNav: React.FC = ({ nsfront, nsbehind, name, version }) return (
- -
-
+
+
+ +
+
+
+

{name}

diff --git a/components/DependencyTable.tsx b/components/DependencyTable.tsx index 0da59cd..94efae1 100644 --- a/components/DependencyTable.tsx +++ b/components/DependencyTable.tsx @@ -1,8 +1,8 @@ 'use client'; -import { useMemo } from 'react'; import React, { useState } from 'react'; -import { Table } from 'antd'; -// import { dependenciesInfo } from '@/app/lib/all_interface'; +import Link from 'next/link'; +import { useParams } from 'next/navigation'; +import Image from 'next/image'; interface DependencyItem { crate_name: string; @@ -17,91 +17,285 @@ interface DependencyTableProps { } const DependencyTable: React.FC = ({ data }) => { - const [sortColumn, setSortColumn] = useState(null); - const [sortDirection, setSortDirection] = useState(null); + const params = useParams(); + const [searchQuery, setSearchQuery] = useState(''); + // const [showGraph, setShowGraph] = useState(false); + const [currentPage, setCurrentPage] = useState(1); + const itemsPerPage = 15; // 每页显示条目数 + const [sortField, setSortField] = useState(null); + const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc'); - const x = 1; - if (x <= 0) { - setSortColumn(null); - setSortDirection(null); - console.log(data); - } + // 处理搜索逻辑 + const handleSearch = (e: React.ChangeEvent) => { + setSearchQuery(e.target.value); + setCurrentPage(1); // 搜索时重置到第一页 + }; + // 处理排序 + const handleSort = (field: string) => { + if (sortField === field) { + // 如果已经在按这个字段排序,则切换排序方向 + setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc'); + } else { + // 如果是新的排序字段,设置为升序 + setSortField(field); + setSortDirection('asc'); + } + setCurrentPage(1); // 排序时重置到第一页 + }; + + // 筛选数据 + const filteredData = data?.filter(item => + item.crate_name.toLowerCase().includes(searchQuery.toLowerCase()) || + item.version.toLowerCase().includes(searchQuery.toLowerCase()) || + item.relation.toLowerCase().includes(searchQuery.toLowerCase()) || + (item.license && item.license.toLowerCase().includes(searchQuery.toLowerCase())) + ) || []; + + // 排序数据 + const sortedData = [...filteredData].sort((a, b) => { + if (!sortField) return 0; + let valueA, valueB; - const sortedData = useMemo(() => { - if (data === null) { - return []; + switch (sortField) { + case 'crate_name': + valueA = a.crate_name.toLowerCase(); + valueB = b.crate_name.toLowerCase(); + break; + case 'relation': + valueA = a.relation.toLowerCase(); + valueB = b.relation.toLowerCase(); + break; + case 'dependencies': + valueA = a.dependencies; + valueB = b.dependencies; + break; + default: + return 0; } - if (!data) { - return []; // 如果 data 为 undefined 或 null,返回空数组 + + if (valueA < valueB) return sortDirection === 'asc' ? -1 : 1; + if (valueA > valueB) return sortDirection === 'asc' ? 1 : -1; + return 0; + }); + + // 分页逻辑 + const totalPages = Math.ceil(sortedData.length / itemsPerPage); + const startIndex = (currentPage - 1) * itemsPerPage; + const endIndex = startIndex + itemsPerPage; + const currentItems = sortedData.slice(startIndex, endIndex); + + // 分页控制函数 + const goToPage = (page: number) => { + if (page >= 1 && page <= totalPages) { + setCurrentPage(page); } - return sortColumn - ? data.sort((a: DependencyItem, b: DependencyItem) => { - if (a[sortColumn] < b[sortColumn]) return sortDirection === 'ascend' ? -1 : 1; - if (a[sortColumn] > b[sortColumn]) return sortDirection === 'ascend' ? 1 : -1; - return 0; - }) - : data; - }, [data, sortColumn, sortDirection]); - - const columns = [ - { - title: 'Crate', - dataIndex: 'crate_name', - key: 'Crate', - sorter: true, - sortDirection: sortDirection, - render: (text: string | number | bigint | boolean | React.ReactElement> | Iterable | React.ReactPortal | Promise | null | undefined) => {text}, - }, - { - title: 'Version', - dataIndex: 'version', - key: 'Version', - render: (text: string | number | bigint | boolean | React.ReactElement> | Iterable | React.ReactPortal | Promise | null | undefined) => {text}, - }, - { - title: 'Relation', - dataIndex: 'relation', - key: 'Relation', - sorter: true, - sortDirection: sortDirection, - render: (text: string | number | bigint | boolean | React.ReactElement> | Iterable | React.ReactPortal | Promise | null | undefined) => {text}, - }, - { - title: 'License', - dataIndex: 'license', - key: 'License', - render: (text: string | number | bigint | boolean | React.ReactElement> | Iterable | React.ReactPortal | Promise | null | undefined) => {text}, - }, - { - title: 'Dependencies', - dataIndex: 'dependencies', - key: 'Dependencies', - sorter: true, - sortDirection: sortDirection, - render: (text: string | number | bigint | boolean | React.ReactElement> | Iterable | React.ReactPortal | Promise | null | undefined) => {text}, - }, - ]; - - // const handleSort = (column: SorterResult | SorterResult[], direction: React.SetStateAction) => { - // setSortColumn(column.dataIndex); - // setSortDirection(direction); - // }; - // const x = 1; - // if (x <= 0) { - // setSortColumn(null); - // setSortDirection(null); - // } + }; + + // 生成页码按钮 + const getPageButtons = () => { + const pageButtons = []; + const maxVisiblePages = 5; + + // 计算要显示的页码范围 + let startPage = Math.max(1, currentPage - 2); + const endPage = Math.min(totalPages, startPage + maxVisiblePages - 1); + + // 调整起始页,确保显示足够的页码 + if (endPage - startPage + 1 < maxVisiblePages) { + startPage = Math.max(1, endPage - maxVisiblePages + 1); + } + + for (let i = startPage; i <= endPage; i++) { + pageButtons.push( + + ); + } + + return pageButtons; + }; + return ( -
- handleSort(sorter, sorter.order)} - // rowKey={(record) => record.Crate} - /> +
+ {/* 搜索和显示选项 */} +
+
+
+
+ +
+ +
+
+ + Show Graph + +
+ + {/* 表格 */} +
+
+
+
+ Crate + +
+
+ Version +
+
+ Relation + +
+
+ License +
+
+ Dependencies + +
+
+
+
+ {currentItems.length > 0 ? ( + currentItems.map((item, index) => ( +
+
+ + {item.crate_name} + +
+
{item.version}
+
{item.relation}
+
{item.license || '-'}
+
{item.dependencies}
+
+ )) + ) : ( +
+ {searchQuery ? 'No matching results found' : 'No data available'} +
+ )} +
+
+ + {/* 分页控制 */} + {sortedData.length > 0 && ( +
+ + + + {getPageButtons()} + + + +
+ )}
); }; diff --git a/components/NewHeader.tsx b/components/NewHeader.tsx index e25c650..0e5e889 100644 --- a/components/NewHeader.tsx +++ b/components/NewHeader.tsx @@ -25,41 +25,39 @@ const NewHeader = () => { return ( <> {contextHolder} -
-
-
- -
- -
- -
- -
-
- setSearchQuery(e.target.value)} - onKeyDown={handleKeyPress} +
+
+ +
+
- + +
+ +
+
+ setSearchQuery(e.target.value)} + onKeyDown={handleKeyPress} + />
-
-
+ +
+
); } diff --git a/public/images/homepage/array-grey.png b/public/images/homepage/array-grey.png new file mode 100644 index 0000000000000000000000000000000000000000..20f65927648d2876134048503ab5247314b3a626 GIT binary patch literal 692 zcmV;l0!#ggP)Px%Zb?KzR5(wKlTT<9Q4q$zdEL#{P(ek61P?0WO%yzd7kiKv!P0|5MGdsDdBrxM zfznHry@;R}Nl12I){|X_~`hV`E>}$94pjQda=n24Lu5 zW_}!x$A?m>RILSX0X@%45s?DW3*a|^ZEL{`wOZ{`Hk;LN*Z?Y}h5_6I5C`yynMa7| zDu8pkFo3ygwVHMur``r#*F7nOSOBmK!1qRPr=^t7XJ==(hhg}Dhz0;eM0BT8sZ2FN z-}jG2QM3eLH-I0^e13d6@_m1A6h&_U#E2+k+xA@|(*10)QmJ%^nI8c-*#1>!wrtye)(vW9 z(S?}#XvaNvQ`0{M@ZVs$T<#5mKy=dN<|Om;^F1poD}7Wb6#7ilTw><95aNPu+i$y7 z)CE>oS93%(NUrPd6GFTLU;+3LhT*Bn$;pqKVWpG_Am6wa*_NE=d08U51)vAOi+a62 zG%+#pr3E{VV?1N~T znUAdX|5*qz&>G$r0Vt*PN!a_z7TGO8I2{ ar2hiurtv_mGH~Sp0000Px%WJyFpR5(wilTAoeQ5462=lQ0mVo(vqgo}!37X?8OZE{h553?vRD#2)cnloU5 zw6S=b2x?J`IL;dbg$P0s1kR5!ENgsG8)%&iTRjX1|qV{(d4gloV=)<^Jhm;6{6yCGQHs_iJZ0n-Z>c$%6e z@Z`SC=HYc3xIi)R2Pj#Dhe}E~KX^yHJ1^O?)wgOet2_WofiI#osBjrL4X7&p zbAFniJCa!f>ss`a6vcEZ(@{~g*!)r?YbqMoC0_-Kp#pCfSB615TTF}E}CX)%YwY7cE!;a&ae!stS zVfoiRnX2lG+;CJ?dV70ss%i&dcn-_50!>X#GoCMzNL&SOcs}4wHk++lnyTYChTrdx z0+$xWKWv(2V>+EaB_eT8Ai&2|Dpe7QM82(BM>HC>EX(Q#8glOtnNZb(i|_wx7)E7& zc0%2J{oCux#&Y~`f?0mJ;^SIaje QiU0rr07*qoM6N<$f>bj+%>V!Z literal 0 HcmV?d00001 diff --git a/public/images/homepage/arry-down.png b/public/images/homepage/arry-down.png new file mode 100644 index 0000000000000000000000000000000000000000..b4181ffdf5896e80341fdf23612e07e6f82bcceb GIT binary patch literal 677 zcmV;W0$TlvP)Px%Ur9tkR5(wKlTApJQ51%sbI18-~kW>KC5bvh+GB2 zZed`&P$j$5F=hhT4SZket;4dc=cA*e4drtAk%+Vcj))B9^Z9{QFqg|U zIgT?6>;V>4^;|q2ch{?tN~QK1VnnU9mjbK_(Y^X8jao;5x1YJ$Y!%gRCO9SynaBpg=Hk4EYx+^6+R4zmJ5HJqOwk$1H!x&?Ly z7*=SLwzwYfz8Ei+kpQ}ZLc2d6JPx%h)G02R7gwhmQ6@hVHAd+b9FQ*TE+wgMO5T0ODR|F%5f$a5n+GeBIlOXHr-9D zY-^EMTLk^N6VjQncCIAGY*#@M1qlu0#9nw{IeeQX_^M2>N=My&g zlMUwaAGo4;I<3}Bfw)4aLMyPNbQQA#Qwk5Vjyw-?J!?vuyr{8a9rp#At0h#Jt}D_t zeotOki>nGu*m_jqDXrAptLrcy}e9LZG1cmfl)J}#ZKFXu>qknStT zv|rNeDE;OdGLD=L1Z=nUBe2U=ViQC1CJeA6rA^C%>C{hIM|KAVE&=s!giRB-Wibr! zV7Er1rhj2M>qsONu;9`#Gb{!k_-nhWjn)!B!UAiSv@NAgR#-{PO@q*z9h6&v%LC%J z_6pn#)iiNi69VJLT^1}3gdB@^CD%Fb<*%M&VTL$g;Ds4{bJ9am&IcL%=>m_8+nB-6 zInv^#jK8(@Xv{6HS{pF3V9{O8+P=FCnb|eg<|;@0#wm<>&nXP3GDZU*b}r(67WP^e zNt7$USC%lE9h8%y&Aa?VvPWaZ;@ay8c!jVZWwStk#*w~Il2!&Ae-*gkwSZk1X^E1{ z7l;dt0ug~58AsBA20zRgRK~WY^t2@_%~P-Nmlvjtd3OKXv|=10`OhM9c70E=}AEO1z{X8-^I07*qoM6N<$g5S|Z As{jB1 literal 0 HcmV?d00001