admin-dashboard-backend/routers/router/api/v1/grouptasks/grouptasks.go

255 lines
7.1 KiB
Go

package grouptasks
import (
"encoding/json"
"jannex/admin-dashboard-backend/modules/cache"
"jannex/admin-dashboard-backend/modules/grouptasks"
"jannex/admin-dashboard-backend/modules/structs"
"jannex/admin-dashboard-backend/modules/utils"
"jannex/admin-dashboard-backend/socketclients"
"git.ex.umbach.dev/Alex/roese-utils/rsutils"
"git.ex.umbach.dev/Alex/roese-utils/rsvalidator"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
)
func GetGroupTasks(c *fiber.Ctx) error {
// swagger:operation GET /grouptasks/{category} grouptasks grouptaskGetGroupTasks
// ---
// summary: Get group tasks
// produces:
// - application/json
// parameters:
// - name: category
// in: query
// description: Category of the group tasks
// required: true
// - name: page
// in: query
// description: Page number
// required: false
// - name: perPage
// in: query
// description: Number of items per page
// required: false
// responses:
// '200':
// description: Group tasks
// schema:
// "$ref": "#/definitions/GroupTasksResponse"
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '500':
// description: Failed to get group tasks
var params structs.GroupTasksRequest
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if !socketclients.HasXYPermission(c.Locals("userId").(string), utils.PermissionGroupTasksOverviewXYView, params.Category) {
return c.SendStatus(fiber.StatusUnauthorized)
}
var query structs.PageQuery
if err := c.QueryParser(&query); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
var categoryGroup structs.CategoryGroup
for _, cGroup := range cache.GetCategoryGroups() {
if cGroup.Category == params.Category {
categoryGroup = cGroup
}
}
return c.JSON(structs.GroupTasksResponse{
CategoryGroup: categoryGroup,
GroupTasks: grouptasks.GetAllGroupTasks(params.Category, query),
TotalPages: utils.GetTotalPages(utils.GroupTasksPaginationLimit,
[]structs.GroupTasks{},
"category = ?",
params.Category),
})
}
func GetGroupTaskSteps(c *fiber.Ctx) error {
// swagger:operation GET /grouptasks/{category}/steps/{groupTaskId} grouptasks grouptaskGetGroupTaskSteps
// ---
// summary: Get group task steps
// produces:
// - application/json
// parameters:
// - name: category
// in: query
// description: Category of the group tasks
// required: true
// - name: groupTaskId
// in: query
// description: Id of the group task
// required: true
// responses:
// '200':
// description: Group task steps
// schema:
// "$ref": "#/definitions/GroupTaskSteps"
// '400':
// description: Invalid request query
// '401':
// description: No permissions
// '500':
// description: Failed to get group task steps
var params structs.GroupTaskStepsRequest
if err := c.ParamsParser(&params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if !socketclients.HasXYPermission(c.Locals("userId").(string), utils.PermissionGroupTasksOverviewXYView, params.Category) {
return c.SendStatus(fiber.StatusUnauthorized)
}
return c.JSON(grouptasks.GetGroupTaskSteps(params.GroupTaskId))
}
func StartGroupTask(c *fiber.Ctx) error {
// swagger:operation POST /grouptasks/start grouptasks grouptaskStartGroupTask
// ---
// summary: Start a new group task
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - name: X-Api-Key
// in: header
// description: You can create a new api key in your user profile
// - name: body
// in: body
// schema:
// "$ref": "#/definitions/ApiGroupTaskRequest"
// responses:
// '200':
// description: New group task started successfully
// '400':
// description: Invalid request body
// '401':
// description: No permissions
// '422':
// description: Global inputs are not complete or no group tasks in this category
// '500':
// description: Failed to start group task
var body structs.ApiGroupTaskRequest
if err := c.BodyParser(&body); err != nil {
log.Error().Msg("Failed to parse body, err: " + err.Error())
return c.Status(fiber.StatusBadRequest).JSON(err)
}
if errValidation := rsvalidator.ValidateStruct(body); errValidation != nil {
log.Error().Msgf("Failed to validate body, err: %v", errValidation)
return c.Status(fiber.StatusBadRequest).JSON(errValidation)
}
userId := c.Locals("userId").(string)
if !socketclients.HasPermission(userId, utils.PermissionUserProfileApiKeys) || !socketclients.HasXYPermission(userId, utils.PermissionGroupTasksOverviewXYNewTask, body.Category) {
return c.SendStatus(fiber.StatusUnauthorized)
}
categoryGroup := cache.GetCategoryGroupByCategory(body.Category)
if categoryGroup.Category == "" {
return c.Status(fiber.StatusBadRequest).JSONP(fiber.Map{"err": "Category not found"})
}
group := getGroupFromCategoryGroup(categoryGroup, body.GroupId)
if group.Category == "" {
return c.Status(fiber.StatusBadRequest).JSONP(fiber.Map{"err": "GroupId not found"})
}
var bodyGlobalInputs []map[string]string
err := json.Unmarshal(body.GlobalInputs, &bodyGlobalInputs)
if err != nil {
log.Error().Msgf("Failed to unmarshal body global inputs: %v", err)
return c.SendStatus(fiber.StatusBadRequest)
}
if len(group.Tasks) == 0 || !globalInputsComplete(bodyGlobalInputs, group.GlobalInputs) {
return c.SendStatus(fiber.StatusUnprocessableEntity)
}
grouptasks.StartGroupTask(userId, structs.GroupTasks{
Category: body.Category,
GroupId: body.GroupId,
GroupName: group.Name,
Description: body.Description,
NumberOfSteps: uint8(len(group.Tasks)),
GlobalInputs: convertJsonGlobalInputToStruct(bodyGlobalInputs, group.GlobalInputs),
})
return c.SendStatus(fiber.StatusOK)
}
func getGroupFromCategoryGroup(categoryGroup structs.CategoryGroup, groupId string) structs.Group {
for _, group := range categoryGroup.Groups {
if group.Id == groupId {
return group
}
}
return structs.Group{}
}
func globalInputsComplete(bodyGlobalInputs []map[string]string, groupGlobalInputs []structs.GlobalInputs) bool {
for _, gGlobalInput := range groupGlobalInputs {
if !isInList(gGlobalInput.ParameterName, bodyGlobalInputs) {
return false
}
}
return true
}
func isInList(gParameterName string, bodyInputs []map[string]string) bool {
for _, bInput := range bodyInputs {
if bInput[gParameterName] != "" {
return true
}
}
return false
}
type GlobalInputs struct {
ParameterName string `json:"parameterName"`
Value string `json:"value"`
}
func convertJsonGlobalInputToStruct(bodyGlobalInputs []map[string]string, groupGlobalInputs []structs.GlobalInputs) string {
var globalInputs []GlobalInputs
for _, gGlobalInput := range groupGlobalInputs {
for _, bInput := range bodyGlobalInputs {
if bInput[gGlobalInput.ParameterName] != "" {
globalInputs = append(globalInputs, GlobalInputs{
ParameterName: gGlobalInput.ParameterName,
Value: bInput[gGlobalInput.ParameterName],
})
}
}
}
return rsutils.MarshalJson(globalInputs)
}