feat: 添加仅显示内部包的过滤选项

This commit is contained in:
hailaz
2026-01-08 15:27:26 +08:00
parent a7b2c21974
commit 3e79cdefcb
4 changed files with 35 additions and 13 deletions

View File

@ -125,7 +125,7 @@ func (a *analyzer) startServer(in Input) error {
state.currentAnalyzer.handleGraphAPI(w, r, in)
})
http.HandleFunc("/api/packages", func(w http.ResponseWriter, r *http.Request) {
state.currentAnalyzer.handlePackagesAPI(w, in)
state.currentAnalyzer.handlePackagesAPI(w, r, in)
})
http.HandleFunc("/api/package", func(w http.ResponseWriter, r *http.Request) {
state.currentAnalyzer.handlePackageAPI(w, r, in)
@ -173,6 +173,9 @@ func (a *analyzer) handleGraphAPI(w http.ResponseWriter, r *http.Request, in Inp
if rev := query.Get("reverse"); rev != "" {
in.Reverse = rev == "true"
}
if i := query.Get("internal"); i != "" {
in.Internal = i == "true"
}
pkg := query.Get("package")
var data *graphData
@ -186,7 +189,12 @@ func (a *analyzer) handleGraphAPI(w http.ResponseWriter, r *http.Request, in Inp
}
// handlePackagesAPI returns all packages list with dependency stats.
func (a *analyzer) handlePackagesAPI(w http.ResponseWriter, in Input) {
func (a *analyzer) handlePackagesAPI(w http.ResponseWriter, r *http.Request, in Input) {
query := r.URL.Query()
if i := query.Get("internal"); i != "" {
in.Internal = i == "true"
}
// Build reverse dependency map (who uses each package)
usedByMap := make(map[string]int)
for fullPath, pkg := range a.packages {
@ -294,6 +302,9 @@ func (a *analyzer) handleTreeAPI(w http.ResponseWriter, r *http.Request, in Inpu
if d := query.Get("depth"); d != "" {
fmt.Sscanf(d, "%d", &in.Depth)
}
if i := query.Get("internal"); i != "" {
in.Internal = i == "true"
}
pkg := query.Get("package")
var output string
@ -310,6 +321,9 @@ func (a *analyzer) handleTreeAPI(w http.ResponseWriter, r *http.Request, in Inpu
// handleListAPI returns list format output.
func (a *analyzer) handleListAPI(w http.ResponseWriter, r *http.Request, in Input) {
query := r.URL.Query()
if i := query.Get("internal"); i != "" {
in.Internal = i == "true"
}
pkg := query.Get("package")
var output string

View File

@ -406,7 +406,8 @@ async function loadModuleName() {
// Load packages list
async function loadPackages() {
try {
const response = await fetch('/api/packages');
const internal = document.getElementById('internal').checked;
const response = await fetch(`/api/packages?internal=${internal}`);
allPackages = await response.json();
document.getElementById('packageCount').textContent = allPackages.length;
renderPackageList(allPackages);
@ -642,6 +643,7 @@ async function refresh() {
const depth = document.getElementById('depth').value;
const group = document.getElementById('group').checked;
const reverse = document.getElementById('reverse').checked;
const internal = document.getElementById('internal').checked;
if (selectedPackage) {
await showPackageInfo(selectedPackage);
@ -650,11 +652,11 @@ async function refresh() {
}
if (currentView === 'graph') {
await refreshGraph(depth, group, reverse);
await refreshGraph(depth, group, reverse, internal);
} else if (currentView === 'tree') {
await refreshTree(depth);
await refreshTree(depth, internal);
} else {
await refreshList();
await refreshList(internal);
}
}
@ -687,7 +689,7 @@ async function showPackageInfo(pkg) {
}
// Refresh graph view
async function refreshGraph(depth, group, reverse) {
async function refreshGraph(depth, group, reverse, internal) {
document.getElementById('graphView').classList.remove('hidden');
document.getElementById('textView').classList.add('hidden');
@ -697,7 +699,7 @@ async function refreshGraph(depth, group, reverse) {
panY = 0;
applyTransform();
let url = `/api/graph?depth=${depth}&group=${group}&reverse=${reverse}`;
let url = `/api/graph?depth=${depth}&group=${group}&reverse=${reverse}&internal=${internal}`;
if (selectedPackage) {
url += '&package=' + encodeURIComponent(selectedPackage);
}
@ -772,11 +774,11 @@ function autoFitGraph() {
}
// Refresh tree view
async function refreshTree(depth) {
async function refreshTree(depth, internal) {
document.getElementById('graphView').classList.add('hidden');
document.getElementById('textView').classList.remove('hidden');
let url = `/api/tree?depth=${depth}`;
let url = `/api/tree?depth=${depth}&internal=${internal}`;
if (selectedPackage) {
url += '&package=' + encodeURIComponent(selectedPackage);
}
@ -795,13 +797,13 @@ async function refreshTree(depth) {
}
// Refresh list view
async function refreshList() {
async function refreshList(internal) {
document.getElementById('graphView').classList.add('hidden');
document.getElementById('textView').classList.remove('hidden');
let url = '/api/list';
let url = `/api/list?internal=${internal}`;
if (selectedPackage) {
url += '?package=' + encodeURIComponent(selectedPackage);
url += '&package=' + encodeURIComponent(selectedPackage);
}
try {

View File

@ -22,6 +22,7 @@ const i18n = {
depthUnlimited: 'Unlimited',
reverseLabel: 'Reverse (show who uses)',
groupLabel: 'Group by directory',
internalLabel: 'Internal only',
layoutLabel: 'Layout:',
layoutTD: 'Top-Down',
layoutLR: 'Left-Right',
@ -67,6 +68,7 @@ const i18n = {
depthUnlimited: '无限制',
reverseLabel: '反向依赖 (谁引用了它)',
groupLabel: '按目录分组',
internalLabel: '仅内部包',
layoutLabel: '布局:',
layoutTD: '从上到下',
layoutLR: '从左到右',

View File

@ -70,6 +70,10 @@
<input type="checkbox" id="group" onchange="refresh()">
<label for="group" data-i18n="groupLabel">Group by directory</label>
</div>
<div class="control-group">
<input type="checkbox" id="internal" checked onchange="refresh()">
<label for="internal" data-i18n="internalLabel">Internal only</label>
</div>
<div class="control-group graph-only" id="layoutGroup">
<label data-i18n="layoutLabel">Layout:</label>
<div class="btn-group">