mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	| @@ -36,6 +36,7 @@ type ProjectBoard struct { | |||||||
| 	ID      int64 `xorm:"pk autoincr"` | 	ID      int64 `xorm:"pk autoincr"` | ||||||
| 	Title   string | 	Title   string | ||||||
| 	Default bool `xorm:"NOT NULL DEFAULT false"` // issues not assigned to a specific board will be assigned to this board | 	Default bool `xorm:"NOT NULL DEFAULT false"` // issues not assigned to a specific board will be assigned to this board | ||||||
|  | 	Sorting int8 `xorm:"DEFAULT 0"` | ||||||
|  |  | ||||||
| 	ProjectID int64 `xorm:"INDEX NOT NULL"` | 	ProjectID int64 `xorm:"INDEX NOT NULL"` | ||||||
| 	CreatorID int64 `xorm:"NOT NULL"` | 	CreatorID int64 `xorm:"NOT NULL"` | ||||||
| @@ -157,15 +158,24 @@ func getProjectBoard(e Engine, boardID int64) (*ProjectBoard, error) { | |||||||
| 	return board, nil | 	return board, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // UpdateProjectBoard updates the title of a project board | // UpdateProjectBoard updates a project board | ||||||
| func UpdateProjectBoard(board *ProjectBoard) error { | func UpdateProjectBoard(board *ProjectBoard) error { | ||||||
| 	return updateProjectBoard(x, board) | 	return updateProjectBoard(x, board) | ||||||
| } | } | ||||||
|  |  | ||||||
| func updateProjectBoard(e Engine, board *ProjectBoard) error { | func updateProjectBoard(e Engine, board *ProjectBoard) error { | ||||||
| 	_, err := e.ID(board.ID).Cols( | 	var fieldToUpdate []string | ||||||
| 		"title", |  | ||||||
| 	).Update(board) | 	if board.Sorting != 0 { | ||||||
|  | 		fieldToUpdate = append(fieldToUpdate, "sorting") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if board.Title != "" { | ||||||
|  | 		fieldToUpdate = append(fieldToUpdate, "title") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	_, err := e.ID(board.ID).Cols(fieldToUpdate...).Update(board) | ||||||
|  |  | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -178,7 +188,7 @@ func GetProjectBoards(projectID int64) (ProjectBoardList, error) { | |||||||
| func getProjectBoards(e Engine, projectID int64) ([]*ProjectBoard, error) { | func getProjectBoards(e Engine, projectID int64) ([]*ProjectBoard, error) { | ||||||
| 	var boards = make([]*ProjectBoard, 0, 5) | 	var boards = make([]*ProjectBoard, 0, 5) | ||||||
|  |  | ||||||
| 	if err := e.Where("project_id=? AND `default`=?", projectID, false).Find(&boards); err != nil { | 	if err := e.Where("project_id=? AND `default`=?", projectID, false).OrderBy("Sorting").Find(&boards); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -277,3 +287,17 @@ func (bs ProjectBoardList) LoadIssues() (IssueList, error) { | |||||||
| 	} | 	} | ||||||
| 	return issues, nil | 	return issues, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // UpdateProjectBoardSorting update project board sorting | ||||||
|  | func UpdateProjectBoardSorting(bs ProjectBoardList) error { | ||||||
|  | 	for i := range bs { | ||||||
|  | 		_, err := x.ID(bs[i].ID).Cols( | ||||||
|  | 			"sorting", | ||||||
|  | 		).Update(bs[i]) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|   | |||||||
| @@ -487,10 +487,10 @@ type UserCreateProjectForm struct { | |||||||
| 	UID       int64 `binding:"Required"` | 	UID       int64 `binding:"Required"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // EditProjectBoardTitleForm is a form for editing the title of a project's | // EditProjectBoardForm is a form for editing a project board | ||||||
| // board | type EditProjectBoardForm struct { | ||||||
| type EditProjectBoardTitleForm struct { | 	Title   string `binding:"Required;MaxSize(100)"` | ||||||
| 	Title string `binding:"Required;MaxSize(100)"` | 	Sorting int8 | ||||||
| } | } | ||||||
|  |  | ||||||
| //    _____  .__.__                   __ | //    _____  .__.__                   __ | ||||||
|   | |||||||
| @@ -403,7 +403,7 @@ func DeleteProjectBoard(ctx *context.Context) { | |||||||
|  |  | ||||||
| // AddBoardToProjectPost allows a new board to be added to a project. | // AddBoardToProjectPost allows a new board to be added to a project. | ||||||
| func AddBoardToProjectPost(ctx *context.Context) { | func AddBoardToProjectPost(ctx *context.Context) { | ||||||
| 	form := web.GetForm(ctx).(*auth.EditProjectBoardTitleForm) | 	form := web.GetForm(ctx).(*auth.EditProjectBoardForm) | ||||||
| 	if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(models.AccessModeWrite, models.UnitTypeProjects) { | 	if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(models.AccessModeWrite, models.UnitTypeProjects) { | ||||||
| 		ctx.JSON(403, map[string]string{ | 		ctx.JSON(403, map[string]string{ | ||||||
| 			"message": "Only authorized users are allowed to perform this action.", | 			"message": "Only authorized users are allowed to perform this action.", | ||||||
| @@ -481,9 +481,9 @@ func checkProjectBoardChangePermissions(ctx *context.Context) (*models.Project, | |||||||
| 	return project, board | 	return project, board | ||||||
| } | } | ||||||
|  |  | ||||||
| // EditProjectBoardTitle allows a project board's title to be updated | // EditProjectBoard allows a project board's to be updated | ||||||
| func EditProjectBoardTitle(ctx *context.Context) { | func EditProjectBoard(ctx *context.Context) { | ||||||
| 	form := web.GetForm(ctx).(*auth.EditProjectBoardTitleForm) | 	form := web.GetForm(ctx).(*auth.EditProjectBoardForm) | ||||||
| 	_, board := checkProjectBoardChangePermissions(ctx) | 	_, board := checkProjectBoardChangePermissions(ctx) | ||||||
| 	if ctx.Written() { | 	if ctx.Written() { | ||||||
| 		return | 		return | ||||||
| @@ -493,6 +493,10 @@ func EditProjectBoardTitle(ctx *context.Context) { | |||||||
| 		board.Title = form.Title | 		board.Title = form.Title | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if form.Sorting != 0 { | ||||||
|  | 		board.Sorting = form.Sorting | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if err := models.UpdateProjectBoard(board); err != nil { | 	if err := models.UpdateProjectBoard(board); err != nil { | ||||||
| 		ctx.ServerError("UpdateProjectBoard", err) | 		ctx.ServerError("UpdateProjectBoard", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -853,7 +853,7 @@ func RegisterRoutes(m *web.Route) { | |||||||
| 				m.Get("/new", repo.NewProject) | 				m.Get("/new", repo.NewProject) | ||||||
| 				m.Post("/new", bindIgnErr(auth.CreateProjectForm{}), repo.NewProjectPost) | 				m.Post("/new", bindIgnErr(auth.CreateProjectForm{}), repo.NewProjectPost) | ||||||
| 				m.Group("/{id}", func() { | 				m.Group("/{id}", func() { | ||||||
| 					m.Post("", bindIgnErr(auth.EditProjectBoardTitleForm{}), repo.AddBoardToProjectPost) | 					m.Post("", bindIgnErr(auth.EditProjectBoardForm{}), repo.AddBoardToProjectPost) | ||||||
| 					m.Post("/delete", repo.DeleteProject) | 					m.Post("/delete", repo.DeleteProject) | ||||||
|  |  | ||||||
| 					m.Get("/edit", repo.EditProject) | 					m.Get("/edit", repo.EditProject) | ||||||
| @@ -861,7 +861,7 @@ func RegisterRoutes(m *web.Route) { | |||||||
| 					m.Post("/{action:open|close}", repo.ChangeProjectStatus) | 					m.Post("/{action:open|close}", repo.ChangeProjectStatus) | ||||||
|  |  | ||||||
| 					m.Group("/{boardID}", func() { | 					m.Group("/{boardID}", func() { | ||||||
| 						m.Put("", bindIgnErr(auth.EditProjectBoardTitleForm{}), repo.EditProjectBoardTitle) | 						m.Put("", bindIgnErr(auth.EditProjectBoardForm{}), repo.EditProjectBoard) | ||||||
| 						m.Delete("", repo.DeleteProjectBoard) | 						m.Delete("", repo.DeleteProjectBoard) | ||||||
| 						m.Post("/default", repo.SetDefaultProjectBoard) | 						m.Post("/default", repo.SetDefaultProjectBoard) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -72,7 +72,7 @@ | |||||||
| 		<div class="board"> | 		<div class="board"> | ||||||
| 			{{ range $board := .Boards }} | 			{{ range $board := .Boards }} | ||||||
|  |  | ||||||
| 			<div class="ui segment board-column"> | 			<div class="ui segment board-column" data-id="{{.ID}}" data-sorting="{{.Sorting}}" data-url="{{$.RepoLink}}/projects/{{$.Project.ID}}/{{.ID}}"> | ||||||
| 				<div class="board-column-header"> | 				<div class="board-column-header"> | ||||||
| 					<div class="ui large label board-label">{{.Title}}</div> | 					<div class="ui large label board-label">{{.Title}}</div> | ||||||
| 					{{if and $.CanWriteProjects (not $.Repository.IsArchived) $.PageIsProjects (ne .ID 0)}} | 					{{if and $.CanWriteProjects (not $.Repository.IsArchived) $.PageIsProjects (ne .ID 0)}} | ||||||
|   | |||||||
| @@ -8,6 +8,34 @@ export default async function initProject() { | |||||||
|   const {Sortable} = await import(/* webpackChunkName: "sortable" */'sortablejs'); |   const {Sortable} = await import(/* webpackChunkName: "sortable" */'sortablejs'); | ||||||
|   const boardColumns = document.getElementsByClassName('board-column'); |   const boardColumns = document.getElementsByClassName('board-column'); | ||||||
|  |  | ||||||
|  |   new Sortable( | ||||||
|  |     document.getElementsByClassName('board')[0], | ||||||
|  |     { | ||||||
|  |       group: 'board-column', | ||||||
|  |       draggable: '.board-column', | ||||||
|  |       animation: 150, | ||||||
|  |       onSort: () => { | ||||||
|  |         const board = document.getElementsByClassName('board')[0]; | ||||||
|  |         const boardColumns = board.getElementsByClassName('board-column'); | ||||||
|  |  | ||||||
|  |         boardColumns.forEach((column, i) => { | ||||||
|  |           if (parseInt($(column).data('sorting')) !== i) { | ||||||
|  |             $.ajax({ | ||||||
|  |               url: $(column).data('url'), | ||||||
|  |               data: JSON.stringify({sorting: i}), | ||||||
|  |               headers: { | ||||||
|  |                 'X-Csrf-Token': csrf, | ||||||
|  |                 'X-Remote': true, | ||||||
|  |               }, | ||||||
|  |               contentType: 'application/json', | ||||||
|  |               method: 'PUT', | ||||||
|  |             }); | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ); | ||||||
|  |  | ||||||
|   for (const column of boardColumns) { |   for (const column of boardColumns) { | ||||||
|     new Sortable( |     new Sortable( | ||||||
|       column.getElementsByClassName('board')[0], |       column.getElementsByClassName('board')[0], | ||||||
| @@ -74,6 +102,7 @@ export default async function initProject() { | |||||||
|  |  | ||||||
|     window.location.reload(); |     window.location.reload(); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   $('.delete-project-board').each(function () { |   $('.delete-project-board').each(function () { | ||||||
|     $(this).click(function (e) { |     $(this).click(function (e) { | ||||||
|       e.preventDefault(); |       e.preventDefault(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user