@@ -5,12 +5,14 @@ package project
5
5
6
6
import (
7
7
"context"
8
+ "errors"
8
9
"fmt"
9
10
"regexp"
10
11
11
12
"code.gitea.io/gitea/models/db"
12
13
"code.gitea.io/gitea/modules/setting"
13
14
"code.gitea.io/gitea/modules/timeutil"
15
+ "code.gitea.io/gitea/modules/util"
14
16
15
17
"xorm.io/builder"
16
18
)
@@ -82,6 +84,17 @@ func (b *Board) NumIssues(ctx context.Context) int {
82
84
return int (c )
83
85
}
84
86
87
+ func (b * Board ) GetIssues (ctx context.Context ) ([]* ProjectIssue , error ) {
88
+ issues := make ([]* ProjectIssue , 0 , 5 )
89
+ if err := db .GetEngine (ctx ).Where ("project_id=?" , b .ProjectID ).
90
+ And ("project_board_id=?" , b .ID ).
91
+ OrderBy ("sorting, id" ).
92
+ Find (& issues ); err != nil {
93
+ return nil , err
94
+ }
95
+ return issues , nil
96
+ }
97
+
85
98
func init () {
86
99
db .RegisterModel (new (Board ))
87
100
}
@@ -150,12 +163,27 @@ func createBoardsForProjectsType(ctx context.Context, project *Project) error {
150
163
return db .Insert (ctx , boards )
151
164
}
152
165
166
+ // maxProjectColumns max columns allowed in a project, this should not bigger than 127
167
+ // because sorting is int8 in database
168
+ const maxProjectColumns = 20
169
+
153
170
// NewBoard adds a new project board to a given project
154
171
func NewBoard (ctx context.Context , board * Board ) error {
155
172
if len (board .Color ) != 0 && ! BoardColorPattern .MatchString (board .Color ) {
156
173
return fmt .Errorf ("bad color code: %s" , board .Color )
157
174
}
158
-
175
+ res := struct {
176
+ MaxSorting int64
177
+ ColumnCount int64
178
+ }{}
179
+ if _ , err := db .GetEngine (ctx ).Select ("max(sorting) as max_sorting, count(*) as column_count" ).Table ("project_board" ).
180
+ Where ("project_id=?" , board .ProjectID ).Get (& res ); err != nil {
181
+ return err
182
+ }
183
+ if res .ColumnCount >= maxProjectColumns {
184
+ return fmt .Errorf ("NewBoard: maximum number of columns reached" )
185
+ }
186
+ board .Sorting = int8 (util .Iif (res .ColumnCount > 0 , res .MaxSorting + 1 , 0 ))
159
187
_ , err := db .GetEngine (ctx ).Insert (board )
160
188
return err
161
189
}
@@ -189,7 +217,17 @@ func deleteBoardByID(ctx context.Context, boardID int64) error {
189
217
return fmt .Errorf ("deleteBoardByID: cannot delete default board" )
190
218
}
191
219
192
- if err = board .removeIssues (ctx ); err != nil {
220
+ // move all issues to the default column
221
+ project , err := GetProjectByID (ctx , board .ProjectID )
222
+ if err != nil {
223
+ return err
224
+ }
225
+ defaultColumn , err := project .GetDefaultBoard (ctx )
226
+ if err != nil {
227
+ return err
228
+ }
229
+
230
+ if err = board .moveIssuesToAnotherColumn (ctx , defaultColumn ); err != nil {
193
231
return err
194
232
}
195
233
@@ -242,21 +280,15 @@ func UpdateBoard(ctx context.Context, board *Board) error {
242
280
// GetBoards fetches all boards related to a project
243
281
func (p * Project ) GetBoards (ctx context.Context ) (BoardList , error ) {
244
282
boards := make ([]* Board , 0 , 5 )
245
-
246
- if err := db .GetEngine (ctx ).Where ("project_id=? AND `default`=?" , p .ID , false ).OrderBy ("sorting" ).Find (& boards ); err != nil {
283
+ if err := db .GetEngine (ctx ).Where ("project_id=?" , p .ID ).OrderBy ("sorting, id" ).Find (& boards ); err != nil {
247
284
return nil , err
248
285
}
249
286
250
- defaultB , err := p .getDefaultBoard (ctx )
251
- if err != nil {
252
- return nil , err
253
- }
254
-
255
- return append ([]* Board {defaultB }, boards ... ), nil
287
+ return boards , nil
256
288
}
257
289
258
- // getDefaultBoard return default board and ensure only one exists
259
- func (p * Project ) getDefaultBoard (ctx context.Context ) (* Board , error ) {
290
+ // GetDefaultBoard return default board and ensure only one exists
291
+ func (p * Project ) GetDefaultBoard (ctx context.Context ) (* Board , error ) {
260
292
var board Board
261
293
has , err := db .GetEngine (ctx ).
262
294
Where ("project_id=? AND `default` = ?" , p .ID , true ).
@@ -316,3 +348,42 @@ func UpdateBoardSorting(ctx context.Context, bs BoardList) error {
316
348
return nil
317
349
})
318
350
}
351
+
352
+ func GetColumnsByIDs (ctx context.Context , projectID int64 , columnsIDs []int64 ) (BoardList , error ) {
353
+ columns := make ([]* Board , 0 , 5 )
354
+ if err := db .GetEngine (ctx ).
355
+ Where ("project_id =?" , projectID ).
356
+ In ("id" , columnsIDs ).
357
+ OrderBy ("sorting" ).Find (& columns ); err != nil {
358
+ return nil , err
359
+ }
360
+ return columns , nil
361
+ }
362
+
363
+ // MoveColumnsOnProject sorts columns in a project
364
+ func MoveColumnsOnProject (ctx context.Context , project * Project , sortedColumnIDs map [int64 ]int64 ) error {
365
+ return db .WithTx (ctx , func (ctx context.Context ) error {
366
+ sess := db .GetEngine (ctx )
367
+ columnIDs := util .ValuesOfMap (sortedColumnIDs )
368
+ movedColumns , err := GetColumnsByIDs (ctx , project .ID , columnIDs )
369
+ if err != nil {
370
+ return err
371
+ }
372
+ if len (movedColumns ) != len (sortedColumnIDs ) {
373
+ return errors .New ("some columns do not exist" )
374
+ }
375
+
376
+ for _ , column := range movedColumns {
377
+ if column .ProjectID != project .ID {
378
+ return fmt .Errorf ("column[%d]'s projectID is not equal to project's ID [%d]" , column .ProjectID , project .ID )
379
+ }
380
+ }
381
+
382
+ for sorting , columnID := range sortedColumnIDs {
383
+ if _ , err := sess .Exec ("UPDATE `project_board` SET sorting=? WHERE id=?" , sorting , columnID ); err != nil {
384
+ return err
385
+ }
386
+ }
387
+ return nil
388
+ })
389
+ }
0 commit comments