fix(build): remove stale custom field API #449
@@ -1,196 +0,0 @@
|
||||
// Copyright 2026 Moko Consulting. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
issues_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/issues"
|
||||
api "code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/structs"
|
||||
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/web"
|
||||
"code.mokoconsulting.tech/MokoConsulting/MokoGitea/services/context"
|
||||
)
|
||||
|
||||
func fieldToAPI(f *issues_model.CustomFieldDefinition) *api.CustomFieldDefinition {
|
||||
return &api.CustomFieldDefinition{
|
||||
ID: f.ID,
|
||||
RepoID: f.RepoID,
|
||||
Name: f.Name,
|
||||
FieldType: f.FieldType,
|
||||
Description: f.Description,
|
||||
Required: f.Required,
|
||||
Position: f.Position,
|
||||
Options: f.Options,
|
||||
DefaultValue: f.DefaultVal,
|
||||
Created: f.CreatedUnix.AsTime(),
|
||||
Updated: f.UpdatedUnix.AsTime(),
|
||||
}
|
||||
}
|
||||
|
||||
// ListCustomFields lists custom field definitions for a repository
|
||||
func ListCustomFields(ctx *context.APIContext) {
|
||||
fields, err := issues_model.GetCustomFieldsByRepoID(ctx, ctx.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
result := make([]*api.CustomFieldDefinition, len(fields))
|
||||
for i, f := range fields {
|
||||
result[i] = fieldToAPI(f)
|
||||
}
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
// GetCustomField gets a custom field definition by ID
|
||||
func GetCustomField(ctx *context.APIContext) {
|
||||
field, err := issues_model.GetCustomFieldDefByID(ctx, ctx.PathParamInt64("fieldId"))
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
if field == nil || field.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.APIErrorNotFound()
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, fieldToAPI(field))
|
||||
}
|
||||
|
||||
// CreateCustomField creates a new custom field definition
|
||||
func CreateCustomField(ctx *context.APIContext) {
|
||||
form := web.GetForm(ctx).(*api.CreateCustomFieldOption)
|
||||
|
||||
validTypes := map[string]bool{"text": true, "number": true, "date": true, "dropdown": true, "checkbox": true}
|
||||
if !validTypes[form.FieldType] {
|
||||
ctx.APIError(http.StatusUnprocessableEntity, "field_type must be: text, number, date, dropdown, or checkbox")
|
||||
return
|
||||
}
|
||||
|
||||
field := &issues_model.CustomFieldDefinition{
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
Name: form.Name,
|
||||
FieldType: form.FieldType,
|
||||
Description: form.Description,
|
||||
Required: form.Required,
|
||||
Position: form.Position,
|
||||
Options: form.Options,
|
||||
DefaultVal: form.DefaultValue,
|
||||
}
|
||||
if err := issues_model.CreateCustomFieldDef(ctx, field); err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusCreated, fieldToAPI(field))
|
||||
}
|
||||
|
||||
// EditCustomField updates a custom field definition
|
||||
func EditCustomField(ctx *context.APIContext) {
|
||||
form := web.GetForm(ctx).(*api.EditCustomFieldOption)
|
||||
field, err := issues_model.GetCustomFieldDefByID(ctx, ctx.PathParamInt64("fieldId"))
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
if field == nil || field.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.APIErrorNotFound()
|
||||
return
|
||||
}
|
||||
|
||||
if form.Name != nil {
|
||||
field.Name = *form.Name
|
||||
}
|
||||
if form.Description != nil {
|
||||
field.Description = *form.Description
|
||||
}
|
||||
if form.Required != nil {
|
||||
field.Required = *form.Required
|
||||
}
|
||||
if form.Position != nil {
|
||||
field.Position = *form.Position
|
||||
}
|
||||
if form.Options != nil {
|
||||
field.Options = *form.Options
|
||||
}
|
||||
if form.DefaultValue != nil {
|
||||
field.DefaultVal = *form.DefaultValue
|
||||
}
|
||||
|
||||
if err := issues_model.UpdateCustomFieldDef(ctx, field); err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, fieldToAPI(field))
|
||||
}
|
||||
|
||||
// DeleteCustomField deletes a custom field and all its values
|
||||
func DeleteCustomField(ctx *context.APIContext) {
|
||||
field, err := issues_model.GetCustomFieldDefByID(ctx, ctx.PathParamInt64("fieldId"))
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
if field == nil || field.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.APIErrorNotFound()
|
||||
return
|
||||
}
|
||||
if err := issues_model.DeleteCustomFieldDef(ctx, field.ID); err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// GetIssueCustomFields gets all custom field values for an issue
|
||||
func GetIssueCustomFields(ctx *context.APIContext) {
|
||||
values, err := issues_model.GetCustomFieldValuesMap(ctx, ctx.PathParamInt64("index"))
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
result := make([]*api.CustomFieldValue, len(values))
|
||||
for i, v := range values {
|
||||
result[i] = &api.CustomFieldValue{
|
||||
ID: v.ID,
|
||||
IssueID: v.IssueID,
|
||||
FieldID: v.FieldID,
|
||||
Value: v.Value,
|
||||
}
|
||||
}
|
||||
ctx.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
// SetIssueCustomField sets a custom field value on an issue
|
||||
func SetIssueCustomField(ctx *context.APIContext) {
|
||||
form := web.GetForm(ctx).(*api.SetCustomFieldValueOption)
|
||||
issueID := ctx.PathParamInt64("index")
|
||||
fieldID := ctx.PathParamInt64("fieldId")
|
||||
|
||||
// Verify field belongs to this repo
|
||||
field, err := issues_model.GetCustomFieldDefByID(ctx, fieldID)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
if field == nil || field.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.APIErrorNotFound()
|
||||
return
|
||||
}
|
||||
|
||||
if err := issues_model.SetCustomFieldValue(ctx, issueID, fieldID, form.Value); err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// DeleteIssueCustomField removes a custom field value from an issue
|
||||
func DeleteIssueCustomField(ctx *context.APIContext) {
|
||||
issueID := ctx.PathParamInt64("index")
|
||||
fieldID := ctx.PathParamInt64("fieldId")
|
||||
|
||||
if err := issues_model.DeleteCustomFieldValue(ctx, issueID, fieldID); err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
VERSION: 05.19.00
|
||||
VERSION: 05.20.00
|
||||
-->
|
||||
|
||||
<updates>
|
||||
@@ -87,13 +87,13 @@
|
||||
<element>mokogitea</element>
|
||||
<type>application</type>
|
||||
<client>site</client>
|
||||
<version>05.19.00</version>
|
||||
<version>05.20.00</version>
|
||||
<creationDate>2026-06-04</creationDate>
|
||||
<infourl title='MokoGitea'>https://git.mokoconsulting.tech/MokoConsulting/MokoGitea/releases/tag/stable</infourl>
|
||||
<downloads>
|
||||
<downloadurl type='full' format='zip'>https://git.mokoconsulting.tech/MokoConsulting/MokoGitea/releases/download/stable/mokogitea-05.19.00.zip</downloadurl>
|
||||
<downloadurl type='full' format='zip'>https://git.mokoconsulting.tech/MokoConsulting/MokoGitea/releases/download/stable/mokogitea-05.20.00.zip</downloadurl>
|
||||
</downloads>
|
||||
<sha256>a0ad5e0a2c3bc8a557bd37071f6891eeedfa8fa868b186ccd1262f6260fe22e9</sha256>
|
||||
<sha256>611a70dc0c394266e598598adc254fa50130310ffe21b966f820536e1714eb07</sha256>
|
||||
<tags><tag>stable</tag></tags>
|
||||
<changelogurl>https://git.mokoconsulting.tech/MokoConsulting/MokoGitea/raw/branch/main/CHANGELOG.md</changelogurl>
|
||||
<maintainer>Moko Consulting</maintainer>
|
||||
|
||||
Reference in New Issue
Block a user