mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-22 12:54:53 -05:00
Merge pull request 'Repository settings refactor' (#2221) from algernon/forgejo:repo-units/ui-refactor into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/2221 Reviewed-by: oliverpool <oliverpool@noreply.codeberg.org>
This commit is contained in:
commit
05eaf1cf3e
15 changed files with 791 additions and 510 deletions
|
@ -108,6 +108,10 @@ var (
|
|||
|
||||
// DisabledRepoUnits contains the units that have been globally disabled
|
||||
DisabledRepoUnits = []Type{}
|
||||
|
||||
// AllowedRepoUnitGroups contains the units that have been globally enabled,
|
||||
// with mutually exclusive units grouped together.
|
||||
AllowedRepoUnitGroups = [][]Type{}
|
||||
)
|
||||
|
||||
// Get valid set of default repository units from settings
|
||||
|
@ -162,6 +166,45 @@ func LoadUnitConfig() error {
|
|||
if len(DefaultForkRepoUnits) == 0 {
|
||||
return errors.New("no default fork repository units found")
|
||||
}
|
||||
|
||||
// Collect the allowed repo unit groups. Mutually exclusive units are
|
||||
// grouped together.
|
||||
AllowedRepoUnitGroups = [][]Type{}
|
||||
for _, unit := range []Type{
|
||||
TypeCode,
|
||||
TypePullRequests,
|
||||
TypeProjects,
|
||||
TypePackages,
|
||||
TypeActions,
|
||||
} {
|
||||
// If unit is globally disabled, ignore it.
|
||||
if unit.UnitGlobalDisabled() {
|
||||
continue
|
||||
}
|
||||
|
||||
// If it is allowed, add it to the group list.
|
||||
AllowedRepoUnitGroups = append(AllowedRepoUnitGroups, []Type{unit})
|
||||
}
|
||||
|
||||
addMutuallyExclusiveGroup := func(unit1, unit2 Type) {
|
||||
var list []Type
|
||||
|
||||
if !unit1.UnitGlobalDisabled() {
|
||||
list = append(list, unit1)
|
||||
}
|
||||
|
||||
if !unit2.UnitGlobalDisabled() {
|
||||
list = append(list, unit2)
|
||||
}
|
||||
|
||||
if len(list) > 0 {
|
||||
AllowedRepoUnitGroups = append(AllowedRepoUnitGroups, list)
|
||||
}
|
||||
}
|
||||
|
||||
addMutuallyExclusiveGroup(TypeIssues, TypeExternalTracker)
|
||||
addMutuallyExclusiveGroup(TypeWiki, TypeExternalWiki)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,31 @@ func (r *Repository) CanCreateBranch() bool {
|
|||
return r.Permission.CanWrite(unit_model.TypeCode) && r.Repository.CanCreateBranch()
|
||||
}
|
||||
|
||||
// AllUnitsEnabled returns true if all units are enabled for the repo.
|
||||
func (r *Repository) AllUnitsEnabled(ctx context.Context) bool {
|
||||
hasAnyUnitEnabled := func(unitGroup []unit_model.Type) bool {
|
||||
// Loop over the group of units
|
||||
for _, unit := range unitGroup {
|
||||
// If *any* of them is enabled, return true.
|
||||
if r.Repository.UnitEnabled(ctx, unit) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// If none are enabled, return false.
|
||||
return false
|
||||
}
|
||||
|
||||
for _, unitGroup := range unit_model.AllowedRepoUnitGroups {
|
||||
// If any disabled unit is found, return false immediately.
|
||||
if !hasAnyUnitEnabled(unitGroup) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// RepoMustNotBeArchived checks if a repo is archived
|
||||
func RepoMustNotBeArchived() func(ctx *Context) {
|
||||
return func(ctx *Context) {
|
||||
|
@ -1053,6 +1078,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
|
|||
ctx.Data["IsViewTag"] = ctx.Repo.IsViewTag
|
||||
ctx.Data["IsViewCommit"] = ctx.Repo.IsViewCommit
|
||||
ctx.Data["CanCreateBranch"] = ctx.Repo.CanCreateBranch()
|
||||
ctx.Data["AllUnitsEnabled"] = ctx.Repo.AllUnitsEnabled(ctx)
|
||||
|
||||
ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount()
|
||||
if err != nil {
|
||||
|
|
|
@ -2066,6 +2066,10 @@ settings.mirror_settings.push_mirror.remote_url = Git Remote Repository URL
|
|||
settings.mirror_settings.push_mirror.add = Add Push Mirror
|
||||
settings.mirror_settings.push_mirror.edit_sync_time = Edit mirror sync interval
|
||||
|
||||
settings.units.units = Repository Units
|
||||
settings.units.overview = Overview
|
||||
settings.units.add_more = Add more...
|
||||
|
||||
settings.sync_mirror = Synchronize Now
|
||||
settings.pull_mirror_sync_in_progress = Pulling changes from the remote %s at the moment.
|
||||
settings.push_mirror_sync_in_progress = Pushing changes to the remote %s at the moment.
|
||||
|
|
|
@ -41,6 +41,7 @@ import (
|
|||
|
||||
const (
|
||||
tplSettingsOptions base.TplName = "repo/settings/options"
|
||||
tplSettingsUnits base.TplName = "repo/settings/units"
|
||||
tplCollaboration base.TplName = "repo/settings/collaboration"
|
||||
tplBranches base.TplName = "repo/settings/branches"
|
||||
tplGithooks base.TplName = "repo/settings/githooks"
|
||||
|
@ -89,6 +90,201 @@ func SettingsCtxData(ctx *context.Context) {
|
|||
ctx.Data["PushMirrors"] = pushMirrors
|
||||
}
|
||||
|
||||
// Units show a repositorys unit settings page
|
||||
func Units(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.settings.units.units")
|
||||
ctx.Data["PageIsRepoSettingsUnits"] = true
|
||||
|
||||
ctx.HTML(http.StatusOK, tplSettingsUnits)
|
||||
}
|
||||
|
||||
func UnitsPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.RepoUnitSettingForm)
|
||||
|
||||
repo := ctx.Repo.Repository
|
||||
|
||||
var repoChanged bool
|
||||
var units []repo_model.RepoUnit
|
||||
var deleteUnitTypes []unit_model.Type
|
||||
|
||||
// This section doesn't require repo_name/RepoName to be set in the form, don't show it
|
||||
// as an error on the UI for this action
|
||||
ctx.Data["Err_RepoName"] = nil
|
||||
|
||||
if repo.CloseIssuesViaCommitInAnyBranch != form.EnableCloseIssuesViaCommitInAnyBranch {
|
||||
repo.CloseIssuesViaCommitInAnyBranch = form.EnableCloseIssuesViaCommitInAnyBranch
|
||||
repoChanged = true
|
||||
}
|
||||
|
||||
if form.EnableCode && !unit_model.TypeCode.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeCode,
|
||||
})
|
||||
} else if !unit_model.TypeCode.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeCode)
|
||||
}
|
||||
|
||||
if form.EnableWiki && form.EnableExternalWiki && !unit_model.TypeExternalWiki.UnitGlobalDisabled() {
|
||||
if !validation.IsValidExternalURL(form.ExternalWikiURL) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.external_wiki_url_error"))
|
||||
ctx.Redirect(repo.Link() + "/settings/units")
|
||||
return
|
||||
}
|
||||
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeExternalWiki,
|
||||
Config: &repo_model.ExternalWikiConfig{
|
||||
ExternalWikiURL: form.ExternalWikiURL,
|
||||
},
|
||||
})
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeWiki)
|
||||
} else if form.EnableWiki && !form.EnableExternalWiki && !unit_model.TypeWiki.UnitGlobalDisabled() {
|
||||
var wikiPermissions repo_model.UnitAccessMode
|
||||
if form.GloballyWriteableWiki {
|
||||
wikiPermissions = repo_model.UnitAccessModeWrite
|
||||
} else {
|
||||
wikiPermissions = repo_model.UnitAccessModeRead
|
||||
}
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeWiki,
|
||||
Config: new(repo_model.UnitConfig),
|
||||
DefaultPermissions: wikiPermissions,
|
||||
})
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalWiki)
|
||||
} else {
|
||||
if !unit_model.TypeExternalWiki.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalWiki)
|
||||
}
|
||||
if !unit_model.TypeWiki.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeWiki)
|
||||
}
|
||||
}
|
||||
|
||||
if form.EnableIssues && form.EnableExternalTracker && !unit_model.TypeExternalTracker.UnitGlobalDisabled() {
|
||||
if !validation.IsValidExternalURL(form.ExternalTrackerURL) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.external_tracker_url_error"))
|
||||
ctx.Redirect(repo.Link() + "/settings/units")
|
||||
return
|
||||
}
|
||||
if len(form.TrackerURLFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(form.TrackerURLFormat) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.tracker_url_format_error"))
|
||||
ctx.Redirect(repo.Link() + "/settings/units")
|
||||
return
|
||||
}
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeExternalTracker,
|
||||
Config: &repo_model.ExternalTrackerConfig{
|
||||
ExternalTrackerURL: form.ExternalTrackerURL,
|
||||
ExternalTrackerFormat: form.TrackerURLFormat,
|
||||
ExternalTrackerStyle: form.TrackerIssueStyle,
|
||||
ExternalTrackerRegexpPattern: form.ExternalTrackerRegexpPattern,
|
||||
},
|
||||
})
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeIssues)
|
||||
} else if form.EnableIssues && !form.EnableExternalTracker && !unit_model.TypeIssues.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeIssues,
|
||||
Config: &repo_model.IssuesConfig{
|
||||
EnableTimetracker: form.EnableTimetracker,
|
||||
AllowOnlyContributorsToTrackTime: form.AllowOnlyContributorsToTrackTime,
|
||||
EnableDependencies: form.EnableIssueDependencies,
|
||||
},
|
||||
})
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalTracker)
|
||||
} else {
|
||||
if !unit_model.TypeExternalTracker.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalTracker)
|
||||
}
|
||||
if !unit_model.TypeIssues.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeIssues)
|
||||
}
|
||||
}
|
||||
|
||||
if form.EnableProjects && !unit_model.TypeProjects.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeProjects,
|
||||
})
|
||||
} else if !unit_model.TypeProjects.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeProjects)
|
||||
}
|
||||
|
||||
if form.EnableReleases && !unit_model.TypeReleases.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeReleases,
|
||||
})
|
||||
} else if !unit_model.TypeReleases.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeReleases)
|
||||
}
|
||||
|
||||
if form.EnablePackages && !unit_model.TypePackages.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypePackages,
|
||||
})
|
||||
} else if !unit_model.TypePackages.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages)
|
||||
}
|
||||
|
||||
if form.EnableActions && !unit_model.TypeActions.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeActions,
|
||||
})
|
||||
} else if !unit_model.TypeActions.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeActions)
|
||||
}
|
||||
|
||||
if form.EnablePulls && !unit_model.TypePullRequests.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypePullRequests,
|
||||
Config: &repo_model.PullRequestsConfig{
|
||||
IgnoreWhitespaceConflicts: form.PullsIgnoreWhitespace,
|
||||
AllowMerge: form.PullsAllowMerge,
|
||||
AllowRebase: form.PullsAllowRebase,
|
||||
AllowRebaseMerge: form.PullsAllowRebaseMerge,
|
||||
AllowSquash: form.PullsAllowSquash,
|
||||
AllowManualMerge: form.PullsAllowManualMerge,
|
||||
AutodetectManualMerge: form.EnableAutodetectManualMerge,
|
||||
AllowRebaseUpdate: form.PullsAllowRebaseUpdate,
|
||||
DefaultDeleteBranchAfterMerge: form.DefaultDeleteBranchAfterMerge,
|
||||
DefaultMergeStyle: repo_model.MergeStyle(form.PullsDefaultMergeStyle),
|
||||
DefaultAllowMaintainerEdit: form.DefaultAllowMaintainerEdit,
|
||||
},
|
||||
})
|
||||
} else if !unit_model.TypePullRequests.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePullRequests)
|
||||
}
|
||||
|
||||
if len(units) == 0 {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.update_settings_no_unit"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/units")
|
||||
return
|
||||
}
|
||||
|
||||
if err := repo_model.UpdateRepositoryUnits(ctx, repo, units, deleteUnitTypes); err != nil {
|
||||
ctx.ServerError("UpdateRepositoryUnits", err)
|
||||
return
|
||||
}
|
||||
if repoChanged {
|
||||
if err := repo_service.UpdateRepository(ctx, repo, false); err != nil {
|
||||
ctx.ServerError("UpdateRepository", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
log.Trace("Repository advanced settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/units")
|
||||
}
|
||||
|
||||
// Settings show a repository's settings page
|
||||
func Settings(ctx *context.Context) {
|
||||
ctx.HTML(http.StatusOK, tplSettingsOptions)
|
||||
|
@ -435,188 +631,6 @@ func SettingsPost(ctx *context.Context) {
|
|||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||
ctx.Redirect(repo.Link() + "/settings")
|
||||
|
||||
case "advanced":
|
||||
var repoChanged bool
|
||||
var units []repo_model.RepoUnit
|
||||
var deleteUnitTypes []unit_model.Type
|
||||
|
||||
// This section doesn't require repo_name/RepoName to be set in the form, don't show it
|
||||
// as an error on the UI for this action
|
||||
ctx.Data["Err_RepoName"] = nil
|
||||
|
||||
if repo.CloseIssuesViaCommitInAnyBranch != form.EnableCloseIssuesViaCommitInAnyBranch {
|
||||
repo.CloseIssuesViaCommitInAnyBranch = form.EnableCloseIssuesViaCommitInAnyBranch
|
||||
repoChanged = true
|
||||
}
|
||||
|
||||
if form.EnableCode && !unit_model.TypeCode.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeCode,
|
||||
})
|
||||
} else if !unit_model.TypeCode.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeCode)
|
||||
}
|
||||
|
||||
if form.EnableWiki && form.EnableExternalWiki && !unit_model.TypeExternalWiki.UnitGlobalDisabled() {
|
||||
if !validation.IsValidExternalURL(form.ExternalWikiURL) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.external_wiki_url_error"))
|
||||
ctx.Redirect(repo.Link() + "/settings")
|
||||
return
|
||||
}
|
||||
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeExternalWiki,
|
||||
Config: &repo_model.ExternalWikiConfig{
|
||||
ExternalWikiURL: form.ExternalWikiURL,
|
||||
},
|
||||
})
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeWiki)
|
||||
} else if form.EnableWiki && !form.EnableExternalWiki && !unit_model.TypeWiki.UnitGlobalDisabled() {
|
||||
var wikiPermissions repo_model.UnitAccessMode
|
||||
if form.GloballyWriteableWiki {
|
||||
wikiPermissions = repo_model.UnitAccessModeWrite
|
||||
} else {
|
||||
wikiPermissions = repo_model.UnitAccessModeRead
|
||||
}
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeWiki,
|
||||
Config: new(repo_model.UnitConfig),
|
||||
DefaultPermissions: wikiPermissions,
|
||||
})
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalWiki)
|
||||
} else {
|
||||
if !unit_model.TypeExternalWiki.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalWiki)
|
||||
}
|
||||
if !unit_model.TypeWiki.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeWiki)
|
||||
}
|
||||
}
|
||||
|
||||
if form.EnableIssues && form.EnableExternalTracker && !unit_model.TypeExternalTracker.UnitGlobalDisabled() {
|
||||
if !validation.IsValidExternalURL(form.ExternalTrackerURL) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.external_tracker_url_error"))
|
||||
ctx.Redirect(repo.Link() + "/settings")
|
||||
return
|
||||
}
|
||||
if len(form.TrackerURLFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(form.TrackerURLFormat) {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.tracker_url_format_error"))
|
||||
ctx.Redirect(repo.Link() + "/settings")
|
||||
return
|
||||
}
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeExternalTracker,
|
||||
Config: &repo_model.ExternalTrackerConfig{
|
||||
ExternalTrackerURL: form.ExternalTrackerURL,
|
||||
ExternalTrackerFormat: form.TrackerURLFormat,
|
||||
ExternalTrackerStyle: form.TrackerIssueStyle,
|
||||
ExternalTrackerRegexpPattern: form.ExternalTrackerRegexpPattern,
|
||||
},
|
||||
})
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeIssues)
|
||||
} else if form.EnableIssues && !form.EnableExternalTracker && !unit_model.TypeIssues.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeIssues,
|
||||
Config: &repo_model.IssuesConfig{
|
||||
EnableTimetracker: form.EnableTimetracker,
|
||||
AllowOnlyContributorsToTrackTime: form.AllowOnlyContributorsToTrackTime,
|
||||
EnableDependencies: form.EnableIssueDependencies,
|
||||
},
|
||||
})
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalTracker)
|
||||
} else {
|
||||
if !unit_model.TypeExternalTracker.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalTracker)
|
||||
}
|
||||
if !unit_model.TypeIssues.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeIssues)
|
||||
}
|
||||
}
|
||||
|
||||
if form.EnableProjects && !unit_model.TypeProjects.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeProjects,
|
||||
})
|
||||
} else if !unit_model.TypeProjects.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeProjects)
|
||||
}
|
||||
|
||||
if form.EnableReleases && !unit_model.TypeReleases.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeReleases,
|
||||
})
|
||||
} else if !unit_model.TypeReleases.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeReleases)
|
||||
}
|
||||
|
||||
if form.EnablePackages && !unit_model.TypePackages.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypePackages,
|
||||
})
|
||||
} else if !unit_model.TypePackages.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages)
|
||||
}
|
||||
|
||||
if form.EnableActions && !unit_model.TypeActions.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeActions,
|
||||
})
|
||||
} else if !unit_model.TypeActions.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeActions)
|
||||
}
|
||||
|
||||
if form.EnablePulls && !unit_model.TypePullRequests.UnitGlobalDisabled() {
|
||||
units = append(units, repo_model.RepoUnit{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypePullRequests,
|
||||
Config: &repo_model.PullRequestsConfig{
|
||||
IgnoreWhitespaceConflicts: form.PullsIgnoreWhitespace,
|
||||
AllowMerge: form.PullsAllowMerge,
|
||||
AllowRebase: form.PullsAllowRebase,
|
||||
AllowRebaseMerge: form.PullsAllowRebaseMerge,
|
||||
AllowSquash: form.PullsAllowSquash,
|
||||
AllowManualMerge: form.PullsAllowManualMerge,
|
||||
AutodetectManualMerge: form.EnableAutodetectManualMerge,
|
||||
AllowRebaseUpdate: form.PullsAllowRebaseUpdate,
|
||||
DefaultDeleteBranchAfterMerge: form.DefaultDeleteBranchAfterMerge,
|
||||
DefaultMergeStyle: repo_model.MergeStyle(form.PullsDefaultMergeStyle),
|
||||
DefaultAllowMaintainerEdit: form.DefaultAllowMaintainerEdit,
|
||||
},
|
||||
})
|
||||
} else if !unit_model.TypePullRequests.UnitGlobalDisabled() {
|
||||
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePullRequests)
|
||||
}
|
||||
|
||||
if len(units) == 0 {
|
||||
ctx.Flash.Error(ctx.Tr("repo.settings.update_settings_no_unit"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
return
|
||||
}
|
||||
|
||||
if err := repo_model.UpdateRepositoryUnits(ctx, repo, units, deleteUnitTypes); err != nil {
|
||||
ctx.ServerError("UpdateRepositoryUnits", err)
|
||||
return
|
||||
}
|
||||
if repoChanged {
|
||||
if err := repo_service.UpdateRepository(ctx, repo, false); err != nil {
|
||||
ctx.ServerError("UpdateRepository", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
log.Trace("Repository advanced settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
|
||||
case "signing":
|
||||
changed := false
|
||||
trustModel := repo_model.ToTrustModel(form.TrustModel)
|
||||
|
|
|
@ -1034,6 +1034,8 @@ func registerRoutes(m *web.Route) {
|
|||
m.Combo("").Get(repo_setting.Settings).
|
||||
Post(web.Bind(forms.RepoSettingForm{}), repo_setting.SettingsPost)
|
||||
}, repo_setting.SettingsCtxData)
|
||||
m.Combo("/units").Get(repo_setting.Units).
|
||||
Post(web.Bind(forms.RepoUnitSettingForm{}), repo_setting.UnitsPost)
|
||||
m.Post("/avatar", web.Bind(forms.AvatarForm{}), repo_setting.SettingsAvatar)
|
||||
m.Post("/avatar/delete", repo_setting.SettingsDeleteAvatar)
|
||||
|
||||
|
|
|
@ -130,6 +130,24 @@ type RepoSettingForm struct {
|
|||
EnablePrune bool
|
||||
|
||||
// Advanced settings
|
||||
IsArchived bool
|
||||
|
||||
// Signing Settings
|
||||
TrustModel string
|
||||
|
||||
// Admin settings
|
||||
EnableHealthCheck bool
|
||||
RequestReindexType string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *RepoSettingForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// RepoUnitSettingForm form for changing repository unit settings
|
||||
type RepoUnitSettingForm struct {
|
||||
EnableCode bool
|
||||
EnableWiki bool
|
||||
GloballyWriteableWiki bool
|
||||
|
@ -161,18 +179,10 @@ type RepoSettingForm struct {
|
|||
EnableTimetracker bool
|
||||
AllowOnlyContributorsToTrackTime bool
|
||||
EnableIssueDependencies bool
|
||||
IsArchived bool
|
||||
|
||||
// Signing Settings
|
||||
TrustModel string
|
||||
|
||||
// Admin settings
|
||||
EnableHealthCheck bool
|
||||
RequestReindexType string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *RepoSettingForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
func (f *RepoUnitSettingForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
|
|
@ -219,6 +219,11 @@
|
|||
{{end}}
|
||||
|
||||
{{if .Permission.IsAdmin}}
|
||||
{{if not .AllUnitsEnabled}}
|
||||
<a class="{{if .PageIsRepoSettingsUnits}}active {{end}}item" href="{{.RepoLink}}/settings/units">
|
||||
{{svg "octicon-diff-added"}} {{ctx.Locale.Tr "repo.settings.units.add_more"}}
|
||||
</a>
|
||||
{{end}}
|
||||
<a class="{{if .PageIsRepoSettings}}active {{end}} item" href="{{.RepoLink}}/settings">
|
||||
{{svg "octicon-tools"}} {{ctx.Locale.Tr "repo.settings"}}
|
||||
</a>
|
||||
|
|
|
@ -4,6 +4,23 @@
|
|||
<a class="{{if .PageIsSettingsOptions}}active {{end}}item" href="{{.RepoLink}}/settings">
|
||||
{{ctx.Locale.Tr "repo.settings.options"}}
|
||||
</a>
|
||||
<details class="item toggleable-item" {{if .PageIsRepoSettingsUnits}}open{{end}}>
|
||||
<summary class="item{{if .PageIsRepoSettingsUnits}} active{{end}}">{{ctx.Locale.Tr "repo.settings.units.units"}}</summary>
|
||||
<div class="menu">
|
||||
<a class="item" href="{{.RepoLink}}/settings/units#overview">
|
||||
{{ctx.Locale.Tr "repo.settings.units.overview"}}
|
||||
</a>
|
||||
<a class="item" href="{{.RepoLink}}/settings/units#issues">
|
||||
{{ctx.Locale.Tr "repo.issues"}}
|
||||
</a>
|
||||
<a class="item" href="{{.RepoLink}}/settings/units#pulls">
|
||||
{{ctx.Locale.Tr "repo.pulls"}}
|
||||
</a>
|
||||
<a class="item" href="{{.RepoLink}}/settings/units#wiki">
|
||||
{{ctx.Locale.Tr "repo.wiki"}}
|
||||
</a>
|
||||
</div>
|
||||
</details>
|
||||
<a class="{{if .PageIsSettingsCollaboration}}active {{end}}item" href="{{.RepoLink}}/settings/collaboration">
|
||||
{{ctx.Locale.Tr "repo.settings.collaboration"}}
|
||||
</a>
|
||||
|
|
|
@ -299,325 +299,6 @@
|
|||
</div>
|
||||
{{end}}
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{ctx.Locale.Tr "repo.settings.advanced_settings"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<form class="ui form" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="advanced">
|
||||
|
||||
{{$isCodeEnabled := .Repository.UnitEnabled $.Context $.UnitTypeCode}}
|
||||
{{$isCodeGlobalDisabled := .UnitTypeCode.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.code"}}</label>
|
||||
<div class="ui checkbox{{if $isCodeGlobalDisabled}} disabled{{end}}"{{if $isCodeGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_code" type="checkbox"{{if $isCodeEnabled}} checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.code.desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{$isWikiEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeWiki) (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}
|
||||
{{$isWikiGlobalDisabled := .UnitTypeWiki.UnitGlobalDisabled}}
|
||||
{{$isExternalWikiGlobalDisabled := .UnitTypeExternalWiki.UnitGlobalDisabled}}
|
||||
{{$isBothWikiGlobalDisabled := and $isWikiGlobalDisabled $isExternalWikiGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.wiki"}}</label>
|
||||
<div class="ui checkbox{{if $isBothWikiGlobalDisabled}} disabled{{end}}"{{if $isBothWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_wiki" type="checkbox" data-target="#wiki_box" {{if $isWikiEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.wiki_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field{{if not $isWikiEnabled}} disabled{{end}}" id="wiki_box">
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isWikiGlobalDisabled}} disabled{{end}}"{{if $isWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="false" data-target="#external_wiki_box" {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_internal_wiki"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
{{if (not .Repository.IsPrivate)}}
|
||||
<div class="field {{if (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}disabled{{end}}">
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="globally_writeable_wiki" type="checkbox" {{if .Permission.IsGloballyWriteable $.UnitTypeWiki}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.wiki_globally_editable"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isExternalWikiGlobalDisabled}} disabled{{end}}"{{if $isExternalWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="true" data-target="#external_wiki_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalWiki}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_external_wiki"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field gt-pl-4 {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}disabled{{end}}" id="external_wiki_box">
|
||||
<label for="external_wiki_url">{{ctx.Locale.Tr "repo.settings.external_wiki_url"}}</label>
|
||||
<input id="external_wiki_url" name="external_wiki_url" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalWiki).ExternalWikiConfig.ExternalWikiURL}}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.external_wiki_url_desc"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
{{$isIssuesEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeIssues) (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}
|
||||
{{$isIssuesGlobalDisabled := .UnitTypeIssues.UnitGlobalDisabled}}
|
||||
{{$isExternalTrackerGlobalDisabled := .UnitTypeExternalTracker.UnitGlobalDisabled}}
|
||||
{{$isIssuesAndExternalGlobalDisabled := and $isIssuesGlobalDisabled $isExternalTrackerGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.issues"}}</label>
|
||||
<div class="ui checkbox{{if $isIssuesAndExternalGlobalDisabled}} disabled{{end}}"{{if $isIssuesAndExternalGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_issues" type="checkbox" data-target="#issue_box" {{if $isIssuesEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.issues_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field {{if not $isIssuesEnabled}}disabled{{end}}" id="issue_box">
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isIssuesGlobalDisabled}} disabled{{end}}"{{if $isIssuesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="false" data-context="#internal_issue_box" data-target="#external_issue_box" {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_internal_issue_tracker"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field gt-pl-4 {{if (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}disabled{{end}}" id="internal_issue_box">
|
||||
{{if .Repository.CanEnableTimetracker}}
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_timetracker" class="enable-system" data-target="#only_contributors" type="checkbox" {{if .Repository.IsTimetrackerEnabled $.Context}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.enable_timetracker"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field {{if not (.Repository.IsTimetrackerEnabled $.Context)}}disabled{{end}}" id="only_contributors">
|
||||
<div class="ui checkbox">
|
||||
<input name="allow_only_contributors_to_track_time" type="checkbox" {{if .Repository.AllowOnlyContributorsToTrackTime $.Context}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.allow_only_contributors_to_track_time"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_issue_dependencies" type="checkbox" {{if (.Repository.IsDependenciesEnabled $.Context)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.issues.dependency.setting"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_close_issues_via_commit_in_any_branch" type="checkbox" {{if .Repository.CloseIssuesViaCommitInAnyBranch}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.admin_enable_close_issues_via_commit_in_any_branch"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isExternalTrackerGlobalDisabled}} disabled{{end}}"{{if $isExternalTrackerGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="true" data-context="#internal_issue_box" data-target="#external_issue_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalTracker}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_external_issue_tracker"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field gt-pl-4 {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}disabled{{end}}" id="external_issue_box">
|
||||
<div class="field">
|
||||
<label for="external_tracker_url">{{ctx.Locale.Tr "repo.settings.external_tracker_url"}}</label>
|
||||
<input id="external_tracker_url" name="external_tracker_url" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerURL}}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.external_tracker_url_desc"}}</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="tracker_url_format">{{ctx.Locale.Tr "repo.settings.tracker_url_format"}}</label>
|
||||
<input id="tracker_url_format" name="tracker_url_format" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerFormat}}" placeholder="https://github.com/{user}/{repo}/issues/{index}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.tracker_url_format_desc" | Str2html}}</p>
|
||||
</div>
|
||||
<div class="inline fields">
|
||||
<label for="issue_style">{{ctx.Locale.Tr "repo.settings.tracker_issue_style"}}</label>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
{{$externalTracker := (.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker)}}
|
||||
{{$externalTrackerStyle := $externalTracker.ExternalTrackerConfig.ExternalTrackerStyle}}
|
||||
<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="numeric" {{if eq $externalTrackerStyle "numeric"}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.numeric"}} <span class="ui light grey text">#1234</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="alphanumeric" {{if eq $externalTrackerStyle "alphanumeric"}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.alphanumeric"}} <span class="ui light grey text">ABC-123 , DEFG-234</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="regexp" {{if eq $externalTrackerStyle "regexp"}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp"}} <span class="ui light grey text">(ISSUE-\d+) , ISSUE-(\d+)</span></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field {{if ne $externalTrackerStyle "regexp"}}disabled{{end}}" id="tracker-issue-style-regex-box">
|
||||
<label for="external_tracker_regexp_pattern">{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp_pattern"}}</label>
|
||||
<input id="external_tracker_regexp_pattern" name="external_tracker_regexp_pattern" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerRegexpPattern}}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp_pattern_desc" | Str2html}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
{{$isProjectsEnabled := .Repository.UnitEnabled $.Context $.UnitTypeProjects}}
|
||||
{{$isProjectsGlobalDisabled := .UnitTypeProjects.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.project_board"}}</label>
|
||||
<div class="ui checkbox{{if $isProjectsGlobalDisabled}} disabled{{end}}"{{if $isProjectsGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_projects" type="checkbox" {{if $isProjectsEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.projects_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{$isReleasesEnabled := .Repository.UnitEnabled $.Context $.UnitTypeReleases}}
|
||||
{{$isReleasesGlobalDisabled := .UnitTypeReleases.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.releases"}}</label>
|
||||
<div class="ui checkbox{{if $isReleasesGlobalDisabled}} disabled{{end}}"{{if $isReleasesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_releases" type="checkbox" {{if $isReleasesEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.releases_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{$isPackagesEnabled := .Repository.UnitEnabled $.Context $.UnitTypePackages}}
|
||||
{{$isPackagesGlobalDisabled := .UnitTypePackages.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.packages"}}</label>
|
||||
<div class="ui checkbox{{if $isPackagesGlobalDisabled}} disabled{{end}}"{{if $isPackagesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_packages" type="checkbox" {{if $isPackagesEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.packages_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .EnableActions}}
|
||||
{{$isActionsEnabled := .Repository.UnitEnabled $.Context $.UnitTypeActions}}
|
||||
{{$isActionsGlobalDisabled := .UnitTypeActions.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "actions.actions"}}</label>
|
||||
<div class="ui checkbox{{if $isActionsGlobalDisabled}} disabled{{end}}"{{if $isActionsGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_actions" type="checkbox" {{if $isActionsEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.actions_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{if not .IsMirror}}
|
||||
<div class="divider"></div>
|
||||
{{$pullRequestEnabled := .Repository.UnitEnabled $.Context $.UnitTypePullRequests}}
|
||||
{{$pullRequestGlobalDisabled := .UnitTypePullRequests.UnitGlobalDisabled}}
|
||||
{{$prUnit := .Repository.MustGetUnit $.Context $.UnitTypePullRequests}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.pulls"}}</label>
|
||||
<div class="ui checkbox{{if $pullRequestGlobalDisabled}} disabled{{end}}"{{if $pullRequestGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_pulls" type="checkbox" data-target="#pull_box" {{if $pullRequestEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field{{if not $pullRequestEnabled}} disabled{{end}}" id="pull_box">
|
||||
<div class="field">
|
||||
<p>
|
||||
{{ctx.Locale.Tr "repo.settings.merge_style_desc"}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowMerge)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_rebase" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebase)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_rebase_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebaseMerge)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_squash" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowSquash)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_manual_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowManualMerge)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.pulls.merge_manually"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p>
|
||||
{{ctx.Locale.Tr "repo.settings.default_merge_style_desc"}}
|
||||
</p>
|
||||
<div class="ui dropdown selection">
|
||||
<select name="pulls_default_merge_style">
|
||||
<option value="merge" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "merge")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</option>
|
||||
<option value="rebase" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</option>
|
||||
<option value="rebase-merge" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase-merge")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</option>
|
||||
<option value="squash" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "squash")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</option>
|
||||
</select>{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<div class="default text">
|
||||
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "merge")}}
|
||||
{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}
|
||||
{{end}}
|
||||
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase")}}
|
||||
{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}
|
||||
{{end}}
|
||||
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase-merge")}}
|
||||
{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}
|
||||
{{end}}
|
||||
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "squash")}}
|
||||
{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="menu">
|
||||
<div class="item" data-value="merge">{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</div>
|
||||
<div class="item" data-value="rebase">{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</div>
|
||||
<div class="item" data-value="rebase-merge">{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</div>
|
||||
<div class="item" data-value="squash">{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="default_allow_maintainer_edit" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.DefaultAllowMaintainerEdit)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls.default_allow_edits_from_maintainers"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_rebase_update" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebaseUpdate)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls.allow_rebase_update"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="default_delete_branch_after_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls.default_delete_branch_after_merge"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_autodetect_manual_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AutodetectManualMerge)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls.enable_autodetect_manual_merge"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_ignore_whitespace" type="checkbox" {{if and $pullRequestEnabled ($prUnit.PullRequestsConfig.IgnoreWhitespaceConflicts)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls.ignore_whitespace"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="divider"></div>
|
||||
<div class="field">
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_settings"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{ctx.Locale.Tr "repo.settings.signing_settings"}}
|
||||
</h4>
|
||||
|
|
13
templates/repo/settings/units.tmpl
Normal file
13
templates/repo/settings/units.tmpl
Normal file
|
@ -0,0 +1,13 @@
|
|||
{{template "repo/settings/layout_head" (dict "ctxData" . "pageClass" "repository settings options")}}
|
||||
<div class="user-main-content twelve wide column">
|
||||
<form class="ui form" method="post" action="{{.RepoLink}}/settings/units">
|
||||
{{.CsrfTokenHtml}}
|
||||
{{template "repo/settings/units/overview" .}}
|
||||
{{template "repo/settings/units/issues" .}}
|
||||
{{if not .IsMirror}}
|
||||
{{template "repo/settings/units/pulls" .}}
|
||||
{{end}}
|
||||
{{template "repo/settings/units/wiki" .}}
|
||||
</form>
|
||||
</div>
|
||||
{{template "repo/settings/layout_footer" .}}
|
102
templates/repo/settings/units/issues.tmpl
Normal file
102
templates/repo/settings/units/issues.tmpl
Normal file
|
@ -0,0 +1,102 @@
|
|||
<h4 class="ui top attached header" id="issues">
|
||||
{{ctx.Locale.Tr "repo.issues"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
{{$isIssuesEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeIssues) (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}
|
||||
{{$isIssuesGlobalDisabled := .UnitTypeIssues.UnitGlobalDisabled}}
|
||||
{{$isExternalTrackerGlobalDisabled := .UnitTypeExternalTracker.UnitGlobalDisabled}}
|
||||
{{$isIssuesAndExternalGlobalDisabled := and $isIssuesGlobalDisabled $isExternalTrackerGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.issues"}}</label>
|
||||
<div class="ui checkbox{{if $isIssuesAndExternalGlobalDisabled}} disabled{{end}}"{{if $isIssuesAndExternalGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_issues" type="checkbox" data-target="#issue_box" {{if $isIssuesEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.issues_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field {{if not $isIssuesEnabled}}disabled{{end}}" id="issue_box">
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isIssuesGlobalDisabled}} disabled{{end}}"{{if $isIssuesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="false" data-context="#internal_issue_box" data-target="#external_issue_box" {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_internal_issue_tracker"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field gt-pl-4 {{if (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}disabled{{end}}" id="internal_issue_box">
|
||||
{{if .Repository.CanEnableTimetracker}}
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_timetracker" class="enable-system" data-target="#only_contributors" type="checkbox" {{if .Repository.IsTimetrackerEnabled $.Context}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.enable_timetracker"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field {{if not (.Repository.IsTimetrackerEnabled $.Context)}}disabled{{end}}" id="only_contributors">
|
||||
<div class="ui checkbox">
|
||||
<input name="allow_only_contributors_to_track_time" type="checkbox" {{if .Repository.AllowOnlyContributorsToTrackTime $.Context}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.allow_only_contributors_to_track_time"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_issue_dependencies" type="checkbox" {{if (.Repository.IsDependenciesEnabled $.Context)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.issues.dependency.setting"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_close_issues_via_commit_in_any_branch" type="checkbox" {{if .Repository.CloseIssuesViaCommitInAnyBranch}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.admin_enable_close_issues_via_commit_in_any_branch"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isExternalTrackerGlobalDisabled}} disabled{{end}}"{{if $isExternalTrackerGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="true" data-context="#internal_issue_box" data-target="#external_issue_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalTracker}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_external_issue_tracker"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field gt-pl-4 {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}disabled{{end}}" id="external_issue_box">
|
||||
<div class="field">
|
||||
<label for="external_tracker_url">{{ctx.Locale.Tr "repo.settings.external_tracker_url"}}</label>
|
||||
<input id="external_tracker_url" name="external_tracker_url" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerURL}}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.external_tracker_url_desc"}}</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="tracker_url_format">{{ctx.Locale.Tr "repo.settings.tracker_url_format"}}</label>
|
||||
<input id="tracker_url_format" name="tracker_url_format" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerFormat}}" placeholder="https://github.com/{user}/{repo}/issues/{index}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.tracker_url_format_desc" | Str2html}}</p>
|
||||
</div>
|
||||
<div class="inline fields">
|
||||
<label for="issue_style">{{ctx.Locale.Tr "repo.settings.tracker_issue_style"}}</label>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
{{$externalTracker := (.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker)}}
|
||||
{{$externalTrackerStyle := $externalTracker.ExternalTrackerConfig.ExternalTrackerStyle}}
|
||||
<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="numeric" {{if eq $externalTrackerStyle "numeric"}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.numeric"}} <span class="ui light grey text">#1234</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="alphanumeric" {{if eq $externalTrackerStyle "alphanumeric"}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.alphanumeric"}} <span class="ui light grey text">ABC-123 , DEFG-234</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="regexp" {{if eq $externalTrackerStyle "regexp"}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp"}} <span class="ui light grey text">(ISSUE-\d+) , ISSUE-(\d+)</span></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field {{if ne $externalTrackerStyle "regexp"}}disabled{{end}}" id="tracker-issue-style-regex-box">
|
||||
<label for="external_tracker_regexp_pattern">{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp_pattern"}}</label>
|
||||
<input id="external_tracker_regexp_pattern" name="external_tracker_regexp_pattern" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerRegexpPattern}}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp_pattern_desc" | Str2html}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="field">
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_settings"}}</button>
|
||||
</div>
|
||||
</div>
|
62
templates/repo/settings/units/overview.tmpl
Normal file
62
templates/repo/settings/units/overview.tmpl
Normal file
|
@ -0,0 +1,62 @@
|
|||
<h4 class="ui top attached header" id="overview">
|
||||
{{ctx.Locale.Tr "repo.settings.units.overview"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
{{$isCodeEnabled := .Repository.UnitEnabled $.Context $.UnitTypeCode}}
|
||||
{{$isCodeGlobalDisabled := .UnitTypeCode.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.code"}}</label>
|
||||
<div class="ui checkbox{{if $isCodeGlobalDisabled}} disabled{{end}}"{{if $isCodeGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_code" type="checkbox"{{if $isCodeEnabled}} checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.code.desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{$isProjectsEnabled := .Repository.UnitEnabled $.Context $.UnitTypeProjects}}
|
||||
{{$isProjectsGlobalDisabled := .UnitTypeProjects.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.project_board"}}</label>
|
||||
<div class="ui checkbox{{if $isProjectsGlobalDisabled}} disabled{{end}}"{{if $isProjectsGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_projects" type="checkbox" {{if $isProjectsEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.projects_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{$isReleasesEnabled := .Repository.UnitEnabled $.Context $.UnitTypeReleases}}
|
||||
{{$isReleasesGlobalDisabled := .UnitTypeReleases.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.releases"}}</label>
|
||||
<div class="ui checkbox{{if $isReleasesGlobalDisabled}} disabled{{end}}"{{if $isReleasesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_releases" type="checkbox" {{if $isReleasesEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.releases_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{$isPackagesEnabled := .Repository.UnitEnabled $.Context $.UnitTypePackages}}
|
||||
{{$isPackagesGlobalDisabled := .UnitTypePackages.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.packages"}}</label>
|
||||
<div class="ui checkbox{{if $isPackagesGlobalDisabled}} disabled{{end}}"{{if $isPackagesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_packages" type="checkbox" {{if $isPackagesEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.packages_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .EnableActions}}
|
||||
{{$isActionsEnabled := .Repository.UnitEnabled $.Context $.UnitTypeActions}}
|
||||
{{$isActionsGlobalDisabled := .UnitTypeActions.UnitGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "actions.actions"}}</label>
|
||||
<div class="ui checkbox{{if $isActionsGlobalDisabled}} disabled{{end}}"{{if $isActionsGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_actions" type="checkbox" {{if $isActionsEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.actions_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="field">
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_settings"}}</button>
|
||||
</div>
|
||||
</div>
|
121
templates/repo/settings/units/pulls.tmpl
Normal file
121
templates/repo/settings/units/pulls.tmpl
Normal file
|
@ -0,0 +1,121 @@
|
|||
<h4 class="ui top attached header" id="pulls">
|
||||
{{ctx.Locale.Tr "repo.pulls"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
{{$pullRequestEnabled := .Repository.UnitEnabled $.Context $.UnitTypePullRequests}}
|
||||
{{$pullRequestGlobalDisabled := .UnitTypePullRequests.UnitGlobalDisabled}}
|
||||
{{$prUnit := .Repository.MustGetUnit $.Context $.UnitTypePullRequests}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.pulls"}}</label>
|
||||
<div class="ui checkbox{{if $pullRequestGlobalDisabled}} disabled{{end}}"{{if $pullRequestGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_pulls" type="checkbox" data-target="#pull_box" {{if $pullRequestEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field{{if not $pullRequestEnabled}} disabled{{end}}" id="pull_box">
|
||||
<div class="field">
|
||||
<p>
|
||||
{{ctx.Locale.Tr "repo.settings.merge_style_desc"}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowMerge)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_rebase" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebase)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_rebase_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebaseMerge)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_squash" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowSquash)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_manual_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowManualMerge)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.pulls.merge_manually"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p>
|
||||
{{ctx.Locale.Tr "repo.settings.default_merge_style_desc"}}
|
||||
</p>
|
||||
<div class="ui dropdown selection">
|
||||
<select name="pulls_default_merge_style">
|
||||
<option value="merge" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "merge")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</option>
|
||||
<option value="rebase" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</option>
|
||||
<option value="rebase-merge" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase-merge")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</option>
|
||||
<option value="squash" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "squash")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</option>
|
||||
</select>{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<div class="default text">
|
||||
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "merge")}}
|
||||
{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}
|
||||
{{end}}
|
||||
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase")}}
|
||||
{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}
|
||||
{{end}}
|
||||
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase-merge")}}
|
||||
{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}
|
||||
{{end}}
|
||||
{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "squash")}}
|
||||
{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="menu">
|
||||
<div class="item" data-value="merge">{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</div>
|
||||
<div class="item" data-value="rebase">{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</div>
|
||||
<div class="item" data-value="rebase-merge">{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</div>
|
||||
<div class="item" data-value="squash">{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="default_allow_maintainer_edit" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.DefaultAllowMaintainerEdit)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls.default_allow_edits_from_maintainers"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_allow_rebase_update" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebaseUpdate)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls.allow_rebase_update"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="default_delete_branch_after_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls.default_delete_branch_after_merge"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_autodetect_manual_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AutodetectManualMerge)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls.enable_autodetect_manual_merge"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="pulls_ignore_whitespace" type="checkbox" {{if and $pullRequestEnabled ($prUnit.PullRequestsConfig.IgnoreWhitespaceConflicts)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.pulls.ignore_whitespace"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
<div class="field">
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_settings"}}</button>
|
||||
</div>
|
||||
</div>
|
51
templates/repo/settings/units/wiki.tmpl
Normal file
51
templates/repo/settings/units/wiki.tmpl
Normal file
|
@ -0,0 +1,51 @@
|
|||
<h4 class="ui top attached header" id="wiki">
|
||||
{{ctx.Locale.Tr "repo.wiki"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
{{$isWikiEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeWiki) (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}
|
||||
{{$isWikiGlobalDisabled := .UnitTypeWiki.UnitGlobalDisabled}}
|
||||
{{$isExternalWikiGlobalDisabled := .UnitTypeExternalWiki.UnitGlobalDisabled}}
|
||||
{{$isBothWikiGlobalDisabled := and $isWikiGlobalDisabled $isExternalWikiGlobalDisabled}}
|
||||
<div class="inline field">
|
||||
<label>{{ctx.Locale.Tr "repo.wiki"}}</label>
|
||||
<div class="ui checkbox{{if $isBothWikiGlobalDisabled}} disabled{{end}}"{{if $isBothWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system" name="enable_wiki" type="checkbox" data-target="#wiki_box" {{if $isWikiEnabled}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.wiki_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field{{if not $isWikiEnabled}} disabled{{end}}" id="wiki_box">
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isWikiGlobalDisabled}} disabled{{end}}"{{if $isWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="false" data-target="#external_wiki_box" {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_internal_wiki"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
{{if (not .Repository.IsPrivate)}}
|
||||
<div class="field {{if (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}disabled{{end}}">
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="globally_writeable_wiki" type="checkbox" {{if .Permission.IsGloballyWriteable $.UnitTypeWiki}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.wiki_globally_editable"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox{{if $isExternalWikiGlobalDisabled}} disabled{{end}}"{{if $isExternalWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
|
||||
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="true" data-target="#external_wiki_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalWiki}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "repo.settings.use_external_wiki"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field gt-pl-4 {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}disabled{{end}}" id="external_wiki_box">
|
||||
<label for="external_wiki_url">{{ctx.Locale.Tr "repo.settings.external_wiki_url"}}</label>
|
||||
<input id="external_wiki_url" name="external_wiki_url" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalWiki).ExternalWikiConfig.ExternalWikiURL}}">
|
||||
<p class="help">{{ctx.Locale.Tr "repo.settings.external_wiki_url_desc"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="field">
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_settings"}}</button>
|
||||
</div>
|
||||
</div>
|
130
tests/integration/repo_settings_test.go
Normal file
130
tests/integration/repo_settings_test.go
Normal file
|
@ -0,0 +1,130 @@
|
|||
// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
unit_model "code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
"code.gitea.io/gitea/tests"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRepoSettingsUnits(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, Name: "repo1"})
|
||||
session := loginUser(t, user.Name)
|
||||
|
||||
req := NewRequest(t, "GET", fmt.Sprintf("%s/settings/units", repo.Link()))
|
||||
session.MakeRequest(t, req, http.StatusOK)
|
||||
}
|
||||
|
||||
func TestRepoAddMoreUnits(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
|
||||
session := loginUser(t, user.Name)
|
||||
|
||||
// Make sure there are no disabled repos in the settings!
|
||||
setting.Repository.DisabledRepoUnits = []string{}
|
||||
unit_model.LoadUnitConfig()
|
||||
|
||||
// Create a known-good repo, with all units enabled.
|
||||
repo, _, f := CreateDeclarativeRepo(t, user, "", []unit_model.Type{
|
||||
unit_model.TypeCode,
|
||||
unit_model.TypePullRequests,
|
||||
unit_model.TypeProjects,
|
||||
unit_model.TypePackages,
|
||||
unit_model.TypeActions,
|
||||
unit_model.TypeIssues,
|
||||
unit_model.TypeWiki,
|
||||
}, nil, nil)
|
||||
defer f()
|
||||
|
||||
assertAddMore := func(t *testing.T, present bool) {
|
||||
t.Helper()
|
||||
|
||||
req := NewRequest(t, "GET", repo.Link())
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
htmlDoc.AssertElement(t, fmt.Sprintf("a[href='%s/settings/units']", repo.Link()), present)
|
||||
}
|
||||
|
||||
t.Run("no add more with all units enabled", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
assertAddMore(t, false)
|
||||
})
|
||||
|
||||
t.Run("add more if units can be enabled", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
defer func() {
|
||||
repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, []repo_model.RepoUnit{{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypePackages,
|
||||
}}, nil)
|
||||
}()
|
||||
|
||||
// Disable the Packages unit
|
||||
err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, nil, []unit_model.Type{unit_model.TypePackages})
|
||||
assert.NoError(t, err)
|
||||
|
||||
assertAddMore(t, true)
|
||||
})
|
||||
|
||||
t.Run("no add more if unit is globally disabled", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
defer func() {
|
||||
repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, []repo_model.RepoUnit{{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypePackages,
|
||||
}}, nil)
|
||||
setting.Repository.DisabledRepoUnits = []string{}
|
||||
unit_model.LoadUnitConfig()
|
||||
}()
|
||||
|
||||
// Disable the Packages unit globally
|
||||
setting.Repository.DisabledRepoUnits = []string{"repo.packages"}
|
||||
unit_model.LoadUnitConfig()
|
||||
|
||||
// Disable the Packages unit
|
||||
err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, nil, []unit_model.Type{unit_model.TypePackages})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// The "Add more" link appears no more
|
||||
assertAddMore(t, false)
|
||||
})
|
||||
|
||||
t.Run("issues & ext tracker globally disabled", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
defer func() {
|
||||
repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, []repo_model.RepoUnit{{
|
||||
RepoID: repo.ID,
|
||||
Type: unit_model.TypeIssues,
|
||||
}}, nil)
|
||||
setting.Repository.DisabledRepoUnits = []string{}
|
||||
unit_model.LoadUnitConfig()
|
||||
}()
|
||||
|
||||
// Disable both Issues and ExternalTracker units globally
|
||||
setting.Repository.DisabledRepoUnits = []string{"repo.issues", "repo.ext_issues"}
|
||||
unit_model.LoadUnitConfig()
|
||||
|
||||
// Disable the Issues unit
|
||||
err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, nil, []unit_model.Type{unit_model.TypeIssues})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// The "Add more" link appears no more
|
||||
assertAddMore(t, false)
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue