From 447cd7a4d265ff28886e6faa6dcef60e2c263091 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sat, 16 May 2026 16:17:45 +0300 Subject: [PATCH] repo settings: add Features toggles for discussions, projects, milestones, wiki Owners can disable per-repo features in Settings; menu items hide when off. --- gitly.v | 4 +++ repo/repo.v | 59 ++++++++++++++++++++++++--------- repo/repo_routes.v | 22 ++++++++++++ static/css/gitly.scss | 19 +++++++++++ templates/layout/repo_menu.html | 30 ++++++++++------- templates/repo/settings.html | 40 ++++++++++++++++++++++ translations/en.tr | 12 +++++++ translations/ru.tr | 12 +++++++ 8 files changed, 170 insertions(+), 28 deletions(-) diff --git a/gitly.v b/gitly.v index 7cf5fdc..2fb81c3 100644 --- a/gitly.v +++ b/gitly.v @@ -329,6 +329,10 @@ fn (mut app App) migrate_tables() ! { app.add_missing_column('File', 'is_size_calculated', db_bool_column_type())! app.add_missing_column('Settings', 'disable_tree_folder_size', db_bool_column_type())! app.add_missing_column('Repo', 'is_deleted', db_bool_column_type())! + app.add_missing_column('Repo', 'disable_discussions', db_bool_column_type())! + app.add_missing_column('Repo', 'disable_projects', db_bool_column_type())! + app.add_missing_column('Repo', 'disable_milestones', db_bool_column_type())! + app.add_missing_column('Repo', 'disable_wiki', db_bool_column_type())! } fn (mut app App) add_missing_column(table_name string, column_name string, column_type string) ! { diff --git a/repo/repo.v b/repo/repo.v index ca0dbde..10a69d3 100644 --- a/repo/repo.v +++ b/repo/repo.v @@ -26,22 +26,42 @@ struct Repo { latest_update_hash string @[skip] latest_activity time.Time @[skip] mut: - webhook_secret string - tags_count int - nr_open_issues int @[orm: 'open_issues_count'] - nr_open_prs int @[orm: 'open_prs_count'] - nr_releases int @[orm: 'releases_count'] - nr_branches int @[orm: 'branches_count'] - nr_tags int - nr_stars int @[orm: 'stars_count'] - lang_stats []LangStat @[skip] - created_at int - nr_contributors int - labels []Label @[skip] - status RepoStatus - msg_cache map[string]string @[skip] - latest_commit_at int @[skip] - activity_buckets []int @[skip] + webhook_secret string + tags_count int + nr_open_issues int @[orm: 'open_issues_count'] + nr_open_prs int @[orm: 'open_prs_count'] + nr_releases int @[orm: 'releases_count'] + nr_branches int @[orm: 'branches_count'] + nr_tags int + nr_stars int @[orm: 'stars_count'] + lang_stats []LangStat @[skip] + created_at int + nr_contributors int + labels []Label @[skip] + status RepoStatus + msg_cache map[string]string @[skip] + latest_commit_at int @[skip] + activity_buckets []int @[skip] + disable_discussions bool + disable_projects bool + disable_milestones bool + disable_wiki bool +} + +fn (r &Repo) discussions_enabled() bool { + return !r.disable_discussions +} + +fn (r &Repo) projects_enabled() bool { + return !r.disable_projects +} + +fn (r &Repo) milestones_enabled() bool { + return !r.disable_milestones +} + +fn (r &Repo) wiki_enabled() bool { + return !r.disable_wiki } // log_field_separator is declared as constant in case we need to change it later @@ -202,6 +222,13 @@ fn (mut app App) set_repo_webhook_secret(repo_id int, secret string) ! { }! } +fn (mut app App) update_repo_features(repo_id int, disable_discussions bool, disable_projects bool, disable_milestones bool, disable_wiki bool) ! { + sql app.db { + update Repo set disable_discussions = disable_discussions, disable_projects = disable_projects, + disable_milestones = disable_milestones, disable_wiki = disable_wiki where id == repo_id + }! +} + fn (mut app App) set_repo_status(repo_id int, status RepoStatus) ! { sql app.db { update Repo set status = status where id == repo_id diff --git a/repo/repo_routes.v b/repo/repo_routes.v index 2905d3a..2c2a643 100644 --- a/repo/repo_routes.v +++ b/repo/repo_routes.v @@ -80,6 +80,28 @@ pub fn (mut app App) handle_update_repo_settings(username string, repo_name stri return ctx.redirect_to_repository(username, repo_name) } +@['/:username/:repo_name/settings/features'; post] +pub fn (mut app App) handle_update_repo_features(username string, repo_name string) veb.Result { + repo := app.find_repo_by_name_and_username(repo_name, username) or { + return ctx.redirect_to_repository(username, repo_name) + } + is_owner := app.check_repo_owner(ctx.user.username, repo_name) + + if !is_owner { + return ctx.redirect_to_repository(username, repo_name) + } + + disable_discussions := 'discussions_enabled' !in ctx.form + disable_projects := 'projects_enabled' !in ctx.form + disable_milestones := 'milestones_enabled' !in ctx.form + disable_wiki := 'wiki_enabled' !in ctx.form + + app.update_repo_features(repo.id, disable_discussions, disable_projects, disable_milestones, + disable_wiki) or { app.info(err.str()) } + + return ctx.redirect('/${username}/${repo_name}/settings') +} + @['/:user/:repo_name/delete'; post] pub fn (mut app App) handle_repo_delete(username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { diff --git a/static/css/gitly.scss b/static/css/gitly.scss index 35882bd..b11ed51 100644 --- a/static/css/gitly.scss +++ b/static/css/gitly.scss @@ -621,6 +621,25 @@ form { } } +.features-form { + flex-direction: column; + align-items: flex-start; + gap: 10px; +} + +.features-form__option { + display: flex; + align-items: center; + gap: 8px; + font-size: 14px; + cursor: pointer; + + input[type="checkbox"] { + margin: 0; + cursor: pointer; + } +} + .settings-form__submit--danger { color: #cf222e !important; border-color: rgba(207, 34, 46, 0.4) !important; diff --git a/templates/layout/repo_menu.html b/templates/layout/repo_menu.html index 98bfe67..3350ac5 100644 --- a/templates/layout/repo_menu.html +++ b/templates/layout/repo_menu.html @@ -43,18 +43,24 @@ @repo.format_nr_releases(ctx.lang) - - - %discussions - - - - %projects - - - - %milestones - + @if repo.discussions_enabled() + + + %discussions + + @end + @if repo.projects_enabled() + + + %projects + + @end + @if repo.milestones_enabled() + + + %milestones + + @end %ci_label diff --git a/templates/repo/settings.html b/templates/repo/settings.html index a611149..af4b82e 100644 --- a/templates/repo/settings.html +++ b/templates/repo/settings.html @@ -15,6 +15,46 @@
@ctx.form_error
@end +
+

%features_section_title

+

%features_section_desc

+
+ + + + + +
+
+

%webhooks

%webhook_secret_hint

diff --git a/translations/en.tr b/translations/en.tr index 42cab1d..4860ce0 100644 --- a/translations/en.tr +++ b/translations/en.tr @@ -731,6 +731,18 @@ Once deleted, the repository is gone. Type the full path to confirm. delete_repo Delete repo ----- +features_section_title +Features +----- +features_section_desc +Enable or disable features for this repository. +----- +save_features +Save features +----- +wiki +Wiki +----- header_search_placeholder Search... ----- diff --git a/translations/ru.tr b/translations/ru.tr index 4d78765..16b5fbd 100644 --- a/translations/ru.tr +++ b/translations/ru.tr @@ -731,6 +731,18 @@ delete_repo_desc delete_repo Удалить репозиторий ----- +features_section_title +Возможности +----- +features_section_desc +Включите или отключите возможности этого репозитория. +----- +save_features +Сохранить настройки +----- +wiki +Вики +----- header_search_placeholder Поиск... ----- -- 2.39.5