Allow repository admins to hide specific folders from the code browser for non-admin users. Hidden folders are shown dimmed to admins but completely hidden from regular users. Includes database migration, settings UI, tree filtering logic, and frontend support for toggling visibility.
84 lines
2.5 KiB
Go
84 lines
2.5 KiB
Go
// Copyright 2026 MarketAlly. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package repo
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"code.gitcaddy.com/server/v3/models/db"
|
|
"code.gitcaddy.com/server/v3/modules/timeutil"
|
|
)
|
|
|
|
// RepoHiddenFolder represents a folder that is hidden from the code browser
|
|
// for non-admin users.
|
|
type RepoHiddenFolder struct {
|
|
ID int64 `xorm:"pk autoincr"`
|
|
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
|
FolderPath string `xorm:"UNIQUE(s) NOT NULL"`
|
|
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
|
}
|
|
|
|
func init() {
|
|
db.RegisterModel(new(RepoHiddenFolder))
|
|
}
|
|
|
|
// GetHiddenFolders returns all hidden folders for a repository.
|
|
func GetHiddenFolders(ctx context.Context, repoID int64) ([]*RepoHiddenFolder, error) {
|
|
folders := make([]*RepoHiddenFolder, 0)
|
|
return folders, db.GetEngine(ctx).Where("repo_id = ?", repoID).OrderBy("folder_path").Find(&folders)
|
|
}
|
|
|
|
// GetHiddenFolderPaths returns a set of hidden folder paths for fast lookup.
|
|
func GetHiddenFolderPaths(ctx context.Context, repoID int64) (map[string]bool, error) {
|
|
folders, err := GetHiddenFolders(ctx, repoID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
paths := make(map[string]bool, len(folders))
|
|
for _, f := range folders {
|
|
paths[f.FolderPath] = true
|
|
}
|
|
return paths, nil
|
|
}
|
|
|
|
// IsHiddenFolder checks if a specific folder path is hidden.
|
|
func IsHiddenFolder(ctx context.Context, repoID int64, folderPath string) (bool, error) {
|
|
return db.GetEngine(ctx).Where("repo_id = ? AND folder_path = ?", repoID, folderPath).Exist(&RepoHiddenFolder{})
|
|
}
|
|
|
|
// AddHiddenFolder adds a folder to the hidden list.
|
|
func AddHiddenFolder(ctx context.Context, repoID int64, folderPath string) error {
|
|
_, err := db.GetEngine(ctx).Insert(&RepoHiddenFolder{
|
|
RepoID: repoID,
|
|
FolderPath: folderPath,
|
|
})
|
|
return err
|
|
}
|
|
|
|
// RemoveHiddenFolder removes a folder from the hidden list.
|
|
func RemoveHiddenFolder(ctx context.Context, repoID int64, folderPath string) error {
|
|
_, err := db.GetEngine(ctx).Where("repo_id = ? AND folder_path = ?", repoID, folderPath).Delete(&RepoHiddenFolder{})
|
|
return err
|
|
}
|
|
|
|
// IsPathUnderHiddenFolder checks if a path or any of its parent paths is hidden.
|
|
func IsPathUnderHiddenFolder(hiddenPaths map[string]bool, targetPath string) bool {
|
|
if hiddenPaths[targetPath] {
|
|
return true
|
|
}
|
|
// Check parent paths
|
|
for {
|
|
idx := strings.LastIndex(targetPath, "/")
|
|
if idx < 0 {
|
|
break
|
|
}
|
|
targetPath = targetPath[:idx]
|
|
if hiddenPaths[targetPath] {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|