Gisle Aune
1 year ago
16 changed files with 387 additions and 81 deletions
-
22entities/item.go
-
16entities/project.go
-
2frontend/src/lib/components/project/ProjectMain.svelte
-
5frontend/src/lib/components/project/RequirementSection.svelte
-
2frontend/src/lib/models/project.ts
-
24internal/genutils/slice.go
-
49internal/validate/tags.go
-
22models/project.go
-
7ports/httpapi/projects.go
-
36ports/mysql/db.go
-
36ports/mysql/items.go
-
181ports/mysql/projects.go
-
31usecases/items/service.go
-
1usecases/projects/repository.go
-
4usecases/projects/result.go
-
30usecases/projects/service.go
@ -0,0 +1,24 @@ |
|||||
|
package genutils |
||||
|
|
||||
|
func SliceWithUniques[T comparable](slice []T, elemsToAdd []T) []T { |
||||
|
newSlice := slice[:len(slice):len(slice)] |
||||
|
|
||||
|
addLoop: |
||||
|
for _, elem := range elemsToAdd { |
||||
|
for _, existing := range slice { |
||||
|
if existing == elem { |
||||
|
continue addLoop |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
newSlice = append(newSlice, elem) |
||||
|
} |
||||
|
|
||||
|
return newSlice |
||||
|
} |
||||
|
|
||||
|
func SliceWithout[T comparable](originals []T, elemsToRemove []T) []T { |
||||
|
return Retain(originals, func(v T) bool { |
||||
|
return !Contains(elemsToRemove, v) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
package validate |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"git.aiterp.net/stufflog3/stufflog3/internal/genutils" |
||||
|
"git.aiterp.net/stufflog3/stufflog3/models" |
||||
|
) |
||||
|
|
||||
|
func Tags(existingTags, addTags, removeTags []string) error { |
||||
|
for i, tag := range addTags { |
||||
|
if !Tag(tag) { |
||||
|
return models.BadInputError{ |
||||
|
Object: "ItemInput", |
||||
|
Field: "addTags", |
||||
|
Problem: fmt.Sprintf("Invalid tag: %s", tag), |
||||
|
Element: tag, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if genutils.Contains(addTags[:i], tag) { |
||||
|
return models.BadInputError{ |
||||
|
Object: "ItemUpdate", |
||||
|
Field: "addTags", |
||||
|
Problem: fmt.Sprintf("The tag %s already exists!", tag), |
||||
|
Element: tag, |
||||
|
} |
||||
|
} |
||||
|
if genutils.Contains(existingTags, tag) { |
||||
|
return models.BadInputError{ |
||||
|
Object: "ItemUpdate", |
||||
|
Field: "addTags", |
||||
|
Problem: fmt.Sprintf("The tag %s already exists!", tag), |
||||
|
Element: tag, |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
for _, tag := range removeTags { |
||||
|
if !genutils.Contains(existingTags, tag) { |
||||
|
return models.BadInputError{ |
||||
|
Object: "ItemUpdate", |
||||
|
Field: "removeTags", |
||||
|
Problem: fmt.Sprintf("The tag %s does not exist!", tag), |
||||
|
Element: tag, |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return nil |
||||
|
} |
@ -1,16 +1,20 @@ |
|||||
package models |
package models |
||||
|
|
||||
type ProjectUpdate struct { |
type ProjectUpdate struct { |
||||
Name *string `json:"name,omitempty"` |
|
||||
OwnerID *string `json:"ownerId,omitempty"` |
|
||||
Status *Status `json:"status,omitempty"` |
|
||||
Description *string `json:"description,omitempty"` |
|
||||
|
Name *string `json:"name,omitempty"` |
||||
|
OwnerID *string `json:"ownerId,omitempty"` |
||||
|
Status *Status `json:"status,omitempty"` |
||||
|
Description *string `json:"description,omitempty"` |
||||
|
AddTags []string `json:"addTags"` |
||||
|
RemoveTags []string `json:"removeTags"` |
||||
} |
} |
||||
|
|
||||
type RequirementUpdate struct { |
type RequirementUpdate struct { |
||||
Name *string `json:"name"` |
|
||||
Description *string `json:"description"` |
|
||||
Status *Status `json:"status"` |
|
||||
IsCoarse *bool `json:"isCoarse"` |
|
||||
AggregateRequired *int `json:"aggregateRequired"` |
|
||||
|
Name *string `json:"name"` |
||||
|
Description *string `json:"description"` |
||||
|
Status *Status `json:"status"` |
||||
|
IsCoarse *bool `json:"isCoarse"` |
||||
|
AggregateRequired *int `json:"aggregateRequired"` |
||||
|
AddTags []string `json:"addTags"` |
||||
|
RemoveTags []string `json:"removeTags"` |
||||
} |
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue