Merge new project templates into one (#24985)

Additionally simplify the `new project` template slightly.

Review hint: Disable whitespace changes.

<details><summary>Before</summary>

## New repo project

![grafik](https://github.com/go-gitea/gitea/assets/51889757/4de977e8-3688-45cd-8832-49b001e6f249)

## Edit repo project

![grafik](https://github.com/go-gitea/gitea/assets/51889757/daaf353f-6c99-48bd-b37a-a3bc64459079)

## New user/org project

![grafik](https://github.com/go-gitea/gitea/assets/51889757/6a5a3be5-f51a-4599-b75c-7adb9710d2fa)

## Edit user/org project

![grafik](https://github.com/go-gitea/gitea/assets/51889757/a4768f49-cf46-4773-8a0f-54dfdcc1c1b8)
</details>

<details><summary>After</summary>

## New repo project

![grafik](https://github.com/go-gitea/gitea/assets/51889757/3d0ac8a0-850a-4743-963c-71c66ef38d07)

## Edit repo project

![grafik](https://github.com/go-gitea/gitea/assets/51889757/6b86a1cd-e360-4a9b-aaf7-af032d0d991a)

## New user/org project

![grafik](https://github.com/go-gitea/gitea/assets/51889757/a7b0964c-e4c7-4924-842a-52a58499bc36)

## Edit user/org project

![grafik](https://github.com/go-gitea/gitea/assets/51889757/0fbc5605-afee-49bd-a44a-8646f8c55681)
</details>

---------

Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
delvh 2023-05-31 08:50:18 +02:00 committed by GitHub
parent 3a6a6342ea
commit bf27fc3596
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 90 additions and 262 deletions

View file

@ -29,7 +29,6 @@ const (
tplProjects base.TplName = "org/projects/list" tplProjects base.TplName = "org/projects/list"
tplProjectsNew base.TplName = "org/projects/new" tplProjectsNew base.TplName = "org/projects/new"
tplProjectsView base.TplName = "org/projects/view" tplProjectsView base.TplName = "org/projects/view"
tplGenericProjectsNew base.TplName = "user/project"
) )
// MustEnableProjects check if projects are enabled in settings // MustEnableProjects check if projects are enabled in settings
@ -125,14 +124,15 @@ func canWriteProjects(ctx *context.Context) bool {
return ctx.Doer != nil && ctx.ContextUser.ID == ctx.Doer.ID return ctx.Doer != nil && ctx.ContextUser.ID == ctx.Doer.ID
} }
// NewProject render creating a project page // RenderNewProject render creating a project page
func NewProject(ctx *context.Context) { func RenderNewProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.new") ctx.Data["Title"] = ctx.Tr("repo.projects.new")
ctx.Data["BoardTypes"] = project_model.GetBoardConfig() ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
ctx.Data["CardTypes"] = project_model.GetCardConfig() ctx.Data["CardTypes"] = project_model.GetCardConfig()
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx) ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
ctx.Data["PageIsViewProjects"] = true ctx.Data["PageIsViewProjects"] = true
ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink() ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink()
ctx.Data["CancelLink"] = ctx.ContextUser.HomeLink() + "/-/projects"
shared_user.RenderUserHeader(ctx) shared_user.RenderUserHeader(ctx)
ctx.HTML(http.StatusOK, tplProjectsNew) ctx.HTML(http.StatusOK, tplProjectsNew)
} }
@ -144,11 +144,7 @@ func NewProjectPost(ctx *context.Context) {
shared_user.RenderUserHeader(ctx) shared_user.RenderUserHeader(ctx)
if ctx.HasError() { if ctx.HasError() {
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx) RenderNewProject(ctx)
ctx.Data["PageIsViewProjects"] = true
ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
ctx.Data["CardTypes"] = project_model.GetCardConfig()
ctx.HTML(http.StatusOK, tplProjectsNew)
return return
} }
@ -227,8 +223,8 @@ func DeleteProject(ctx *context.Context) {
}) })
} }
// EditProject allows a project to be edited // RenderEditProject allows a project to be edited
func EditProject(ctx *context.Context) { func RenderEditProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.edit") ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsEditProjects"] = true ctx.Data["PageIsEditProjects"] = true
ctx.Data["PageIsViewProjects"] = true ctx.Data["PageIsViewProjects"] = true
@ -257,6 +253,7 @@ func EditProject(ctx *context.Context) {
ctx.Data["redirect"] = ctx.FormString("redirect") ctx.Data["redirect"] = ctx.FormString("redirect")
ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink() ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink()
ctx.Data["card_type"] = p.CardType ctx.Data["card_type"] = p.CardType
ctx.Data["CancelLink"] = fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), p.ID)
ctx.HTML(http.StatusOK, tplProjectsNew) ctx.HTML(http.StatusOK, tplProjectsNew)
} }
@ -264,11 +261,13 @@ func EditProject(ctx *context.Context) {
// EditProjectPost response for editing a project // EditProjectPost response for editing a project
func EditProjectPost(ctx *context.Context) { func EditProjectPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.CreateProjectForm) form := web.GetForm(ctx).(*forms.CreateProjectForm)
projectID := ctx.ParamsInt64(":id")
ctx.Data["Title"] = ctx.Tr("repo.projects.edit") ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsEditProjects"] = true ctx.Data["PageIsEditProjects"] = true
ctx.Data["PageIsViewProjects"] = true ctx.Data["PageIsViewProjects"] = true
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx) ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
ctx.Data["CardTypes"] = project_model.GetCardConfig() ctx.Data["CardTypes"] = project_model.GetCardConfig()
ctx.Data["CancelLink"] = fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), projectID)
shared_user.RenderUserHeader(ctx) shared_user.RenderUserHeader(ctx)
@ -277,7 +276,7 @@ func EditProjectPost(ctx *context.Context) {
return return
} }
p, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id")) p, err := project_model.GetProjectByID(ctx, projectID)
if err != nil { if err != nil {
if project_model.IsErrProjectNotExist(err) { if project_model.IsErrProjectNotExist(err) {
ctx.NotFound("", nil) ctx.NotFound("", nil)

View file

@ -30,7 +30,6 @@ const (
tplProjects base.TplName = "repo/projects/list" tplProjects base.TplName = "repo/projects/list"
tplProjectsNew base.TplName = "repo/projects/new" tplProjectsNew base.TplName = "repo/projects/new"
tplProjectsView base.TplName = "repo/projects/view" tplProjectsView base.TplName = "repo/projects/view"
tplGenericProjectsNew base.TplName = "user/project"
) )
// MustEnableProjects check if projects are enabled in settings // MustEnableProjects check if projects are enabled in settings
@ -121,12 +120,13 @@ func Projects(ctx *context.Context) {
ctx.HTML(http.StatusOK, tplProjects) ctx.HTML(http.StatusOK, tplProjects)
} }
// NewProject render creating a project page // RenderNewProject render creating a project page
func NewProject(ctx *context.Context) { func RenderNewProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.new") ctx.Data["Title"] = ctx.Tr("repo.projects.new")
ctx.Data["BoardTypes"] = project_model.GetBoardConfig() ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
ctx.Data["CardTypes"] = project_model.GetCardConfig() ctx.Data["CardTypes"] = project_model.GetCardConfig()
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects) ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["CancelLink"] = ctx.Repo.Repository.Link() + "/projects"
ctx.HTML(http.StatusOK, tplProjectsNew) ctx.HTML(http.StatusOK, tplProjectsNew)
} }
@ -136,10 +136,7 @@ func NewProjectPost(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.new") ctx.Data["Title"] = ctx.Tr("repo.projects.new")
if ctx.HasError() { if ctx.HasError() {
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects) RenderNewProject(ctx)
ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
ctx.Data["CardTypes"] = project_model.GetCardConfig()
ctx.HTML(http.StatusOK, tplProjectsNew)
return return
} }
@ -211,8 +208,8 @@ func DeleteProject(ctx *context.Context) {
}) })
} }
// EditProject allows a project to be edited // RenderEditProject allows a project to be edited
func EditProject(ctx *context.Context) { func RenderEditProject(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.projects.edit") ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsEditProjects"] = true ctx.Data["PageIsEditProjects"] = true
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects) ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
@ -237,6 +234,7 @@ func EditProject(ctx *context.Context) {
ctx.Data["content"] = p.Description ctx.Data["content"] = p.Description
ctx.Data["card_type"] = p.CardType ctx.Data["card_type"] = p.CardType
ctx.Data["redirect"] = ctx.FormString("redirect") ctx.Data["redirect"] = ctx.FormString("redirect")
ctx.Data["CancelLink"] = fmt.Sprintf("%s/projects/%d", ctx.Repo.Repository.Link(), p.ID)
ctx.HTML(http.StatusOK, tplProjectsNew) ctx.HTML(http.StatusOK, tplProjectsNew)
} }
@ -244,17 +242,20 @@ func EditProject(ctx *context.Context) {
// EditProjectPost response for editing a project // EditProjectPost response for editing a project
func EditProjectPost(ctx *context.Context) { func EditProjectPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.CreateProjectForm) form := web.GetForm(ctx).(*forms.CreateProjectForm)
projectID := ctx.ParamsInt64(":id")
ctx.Data["Title"] = ctx.Tr("repo.projects.edit") ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsEditProjects"] = true ctx.Data["PageIsEditProjects"] = true
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects) ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["CardTypes"] = project_model.GetCardConfig() ctx.Data["CardTypes"] = project_model.GetCardConfig()
ctx.Data["CancelLink"] = fmt.Sprintf("%s/projects/%d", ctx.Repo.Repository.Link(), projectID)
if ctx.HasError() { if ctx.HasError() {
ctx.HTML(http.StatusOK, tplProjectsNew) ctx.HTML(http.StatusOK, tplProjectsNew)
return return
} }
p, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id")) p, err := project_model.GetProjectByID(ctx, projectID)
if err != nil { if err != nil {
if project_model.IsErrProjectNotExist(err) { if project_model.IsErrProjectNotExist(err) {
ctx.NotFound("", nil) ctx.NotFound("", nil)

View file

@ -824,13 +824,13 @@ func registerRoutes(m *web.Route) {
m.Get("/{id}", org.ViewProject) m.Get("/{id}", org.ViewProject)
}, reqUnitAccess(unit.TypeProjects, perm.AccessModeRead)) }, reqUnitAccess(unit.TypeProjects, perm.AccessModeRead))
m.Group("", func() { //nolint:dupl m.Group("", func() { //nolint:dupl
m.Get("/new", org.NewProject) m.Get("/new", org.RenderNewProject)
m.Post("/new", web.Bind(forms.CreateProjectForm{}), org.NewProjectPost) m.Post("/new", web.Bind(forms.CreateProjectForm{}), org.NewProjectPost)
m.Group("/{id}", func() { m.Group("/{id}", func() {
m.Post("", web.Bind(forms.EditProjectBoardForm{}), org.AddBoardToProjectPost) m.Post("", web.Bind(forms.EditProjectBoardForm{}), org.AddBoardToProjectPost)
m.Post("/delete", org.DeleteProject) m.Post("/delete", org.DeleteProject)
m.Get("/edit", org.EditProject) m.Get("/edit", org.RenderEditProject)
m.Post("/edit", web.Bind(forms.CreateProjectForm{}), org.EditProjectPost) m.Post("/edit", web.Bind(forms.CreateProjectForm{}), org.EditProjectPost)
m.Post("/{action:open|close}", org.ChangeProjectStatus) m.Post("/{action:open|close}", org.ChangeProjectStatus)
@ -1159,13 +1159,13 @@ func registerRoutes(m *web.Route) {
m.Get("", repo.Projects) m.Get("", repo.Projects)
m.Get("/{id}", repo.ViewProject) m.Get("/{id}", repo.ViewProject)
m.Group("", func() { //nolint:dupl m.Group("", func() { //nolint:dupl
m.Get("/new", repo.NewProject) m.Get("/new", repo.RenderNewProject)
m.Post("/new", web.Bind(forms.CreateProjectForm{}), repo.NewProjectPost) m.Post("/new", web.Bind(forms.CreateProjectForm{}), repo.NewProjectPost)
m.Group("/{id}", func() { m.Group("/{id}", func() {
m.Post("", web.Bind(forms.EditProjectBoardForm{}), repo.AddBoardToProjectPost) m.Post("", web.Bind(forms.EditProjectBoardForm{}), repo.AddBoardToProjectPost)
m.Post("/delete", repo.DeleteProject) m.Post("/delete", repo.DeleteProject)
m.Get("/edit", repo.EditProject) m.Get("/edit", repo.RenderEditProject)
m.Post("/edit", web.Bind(forms.CreateProjectForm{}), repo.EditProjectPost) m.Post("/edit", web.Bind(forms.CreateProjectForm{}), repo.EditProjectPost)
m.Post("/{action:open|close}", repo.ChangeProjectStatus) m.Post("/{action:open|close}", repo.ChangeProjectStatus)

View file

@ -1,5 +1,5 @@
{{template "base/head" .}} {{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content repository packages"> <div role="main" aria-label="{{.Title}}" class="page-content organization projects edit-project new">
{{template "user/overview/header" .}} {{template "user/overview/header" .}}
{{template "projects/new" .}} {{template "projects/new" .}}
</div> </div>

View file

@ -1,13 +1,4 @@
<div role="main" aria-label="{{.Title}}" class="page-content repository projects edit-project new milestone"> <div class="ui container">
<div class="ui container">
<div class="navbar">
{{if and .CanWriteProjects .PageIsEditProject}}
<div class="ui right floated secondary menu">
<a class="ui small green button" href="{{$.HomeLink}}/-/projects/new">{{.locale.Tr "repo.milestones.new"}}</a>
</div>
{{end}}
</div>
<div class="ui divider"></div>
<h2 class="ui dividing header"> <h2 class="ui dividing header">
{{if .PageIsEditProjects}} {{if .PageIsEditProjects}}
{{.locale.Tr "repo.projects.edit"}} {{.locale.Tr "repo.projects.edit"}}
@ -67,21 +58,13 @@
<div class="ui container"> <div class="ui container">
<div class="ui divider"></div> <div class="ui divider"></div>
<div class="ui left"> <div class="ui left">
{{if .PageIsEditProjects}} <a class="ui cancel button" href="{{$.CancelLink}}">
<a class="ui cancel button" href="{{$.HomeLink}}/-/projects{{if eq .redirect "project"}}/{{.projectID}}{{end}}">
{{.locale.Tr "repo.milestones.cancel"}} {{.locale.Tr "repo.milestones.cancel"}}
</a> </a>
<button class="ui primary button"> <button class="ui primary button">
{{.locale.Tr "repo.projects.modify"}} {{if .PageIsEditProjects}}{{.locale.Tr "repo.projects.modify"}}{{else}}{{.locale.Tr "repo.projects.create"}}{{end}}
</button> </button>
{{else}}
<button class="ui primary button">
{{.locale.Tr "repo.projects.create"}}
</button>
{{end}}
</div> </div>
</div> </div>
</form> </form>
</div>
</div> </div>

View file

@ -1,92 +1,6 @@
{{template "base/head" .}} {{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content repository projects edit-project new milestone"> <div role="main" aria-label="{{.Title}}" class="page-content repository projects edit-project new milestone">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> {{template "projects/new" .}}
<div class="navbar">
{{template "repo/issue/navbar" .}}
{{if and .CanWriteProjects .PageIsEditProject}}
<div class="ui right floated secondary menu">
<a class="ui small green button" href="{{$.RepoLink}}/projects/new">{{.locale.Tr "repo.milestones.new"}}</a>
</div>
{{end}}
</div>
<div class="ui divider"></div>
<h2 class="ui dividing header">
{{if .PageIsEditProjects}}
{{.locale.Tr "repo.projects.edit"}}
<div class="sub header">{{.locale.Tr "repo.projects.edit_subheader"}}</div>
{{else}}
{{.locale.Tr "repo.projects.new"}}
<div class="sub header">{{.locale.Tr "repo.projects.new_subheader"}}</div>
{{end}}
</h2>
{{template "base/alert" .}}
<form class="ui form grid" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<div class="eleven wide column">
<input type="hidden" id="redirect" name="redirect" value="{{.redirect}}">
<div class="field {{if .Err_Title}}error{{end}}">
<label>{{.locale.Tr "repo.projects.title"}}</label>
<input name="title" placeholder="{{.locale.Tr "repo.projects.title"}}" value="{{.title}}" autofocus required>
</div>
<div class="field">
<label>{{.locale.Tr "repo.projects.description"}}</label>
<textarea name="content" placeholder="{{.locale.Tr "repo.projects.description_placeholder"}}">{{.content}}</textarea>
</div>
{{if not .PageIsEditProjects}}
<div class="field">
<label>{{.locale.Tr "repo.projects.template.desc"}}</label>
<div class="ui selection dropdown">
<input type="hidden" name="board_type" value="{{.type}}">
<div class="default text">{{.locale.Tr "repo.projects.template.desc_helper"}}</div>
<div class="menu">
{{range $element := .BoardTypes}}
<div class="item" data-id="{{$element.BoardType}}" data-value="{{$element.BoardType}}">{{$.locale.Tr $element.Translation}}</div>
{{end}}
</div>
</div>
</div>
{{end}}
<div class="field">
<label>{{.locale.Tr "repo.projects.card_type.desc"}}</label>
<div class="ui selection dropdown">
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
{{range $element := .CardTypes}}
{{if or (eq $.card_type $element.CardType) (and (not $.PageIsEditProjects) (eq $element.CardType 1))}}
<input type="hidden" name="card_type" value="{{$element.CardType}}">
<div class="default text">{{$.locale.Tr $element.Translation}}</div>
{{end}}
{{end}}
<div class="menu">
{{range $element := .CardTypes}}
<div class="item" data-id="{{$element.CardType}}" data-value="{{$element.CardType}}">{{$.locale.Tr $element.Translation}}</div>
{{end}}
</div>
</div>
</div>
</div>
<div class="ui container">
<div class="ui divider"></div>
<div class="ui left">
{{if .PageIsEditProjects}}
<a class="ui cancel button" href="{{.RepoLink}}/projects{{if eq .redirect "project"}}/{{.projectID}}{{end}}">
{{.locale.Tr "repo.milestones.cancel"}}
</a>
<button class="ui primary button">
{{.locale.Tr "repo.projects.modify"}}
</button>
{{else}}
<button class="ui primary button">
{{.locale.Tr "repo.projects.create"}}
</button>
{{end}}
</div>
</div>
</form>
</div>
</div> </div>
{{template "base/footer" .}} {{template "base/footer" .}}

View file

@ -1,69 +0,0 @@
{{template "base/head" .}}
<div role="main" aria-label="{{.Title}}" class="page-content repository new repo">
<div class="ui middle very relaxed page grid">
<div class="column">
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<h3 class="ui top attached header">
{{.locale.Tr "new_project"}}
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<div class="inline required field {{if .Err_Owner}}error{{end}}">
<label>{{.locale.Tr "repo.owner"}}</label>
<div class="ui selection owner dropdown">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
<span class="text truncated-item-container" title="{{.ContextUser.Name}}">
{{avatar $.Context .ContextUser 28 "mini"}}
<span class="truncated-item-name">{{.ContextUser.ShortName 40}}</span>
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu">
<div class="item truncated-item-container" data-value="{{.SignedUser.ID}}" title="{{.SignedUser.Name}}">
{{avatar $.Context .SignedUser 28 "mini"}}
<span class="truncated-item-name">{{.SignedUser.ShortName 40}}</span>
</div>
{{range .Orgs}}
<div class="item truncated-item-container" data-value="{{.ID}}" title="{{.Name}}">
{{avatar $.Context . 28 "mini"}}
<span class="truncated-item-name">{{.ShortName 40}}</span>
</div>
{{end}}
</div>
</div>
</div>
<div class="inline field {{if .Err_Title}}error{{end}}">
<label>{{.locale.Tr "repo.projects.title"}}</label>
<input name="title" placeholder="{{.locale.Tr "repo.projects.title"}}" value="{{.title}}" autofocus required>
</div>
<div class="inline field">
<label>{{.locale.Tr "repo.projects.desc"}}</label>
<textarea name="content">{{.content}}</textarea>
</div>
<div class="inline field">
<label>{{.locale.Tr "repo.projects.template.desc"}}</label>
<div class="ui selection dropdown">
<input type="hidden" name="board_type" value="{{.type}}">
<div class="default text">{{.locale.Tr "repo.projects.template.desc_helper"}}</div>
<div class="menu">
{{range $element := .BoardTypes}}
<div class="item" data-id="{{$element.BoardType}}" data-value="{{$element.BoardType}}">{{$.locale.Tr $element.Translation}}</div>
{{end}}
</div>
</div>
</div>
<div class="inline field">
<label></label>
<button class="ui green button">
{{.locale.Tr "repo.projects.create"}}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
{{template "base/footer" .}}