From 0492ea399eaafe27d8d2ab04c44ae529a4b4a840 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Thu, 4 Jun 2026 11:57:57 +0000 Subject: [PATCH 1/2] chore: sync updates.xml 05.20.00 from main [skip ci] --- updates.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/updates.xml b/updates.xml index 6a6ef89ef8..df6396cb65 100644 --- a/updates.xml +++ b/updates.xml @@ -1,7 +1,7 @@ @@ -87,13 +87,13 @@ mokogitea application site - 05.19.00 + 05.20.00 2026-06-04 https://git.mokoconsulting.tech/MokoConsulting/MokoGitea/releases/tag/stable - https://git.mokoconsulting.tech/MokoConsulting/MokoGitea/releases/download/stable/mokogitea-05.19.00.zip + https://git.mokoconsulting.tech/MokoConsulting/MokoGitea/releases/download/stable/mokogitea-05.20.00.zip - a0ad5e0a2c3bc8a557bd37071f6891eeedfa8fa868b186ccd1262f6260fe22e9 + 611a70dc0c394266e598598adc254fa50130310ffe21b966f820536e1714eb07 stable https://git.mokoconsulting.tech/MokoConsulting/MokoGitea/raw/branch/main/CHANGELOG.md Moko Consulting -- 2.52.0 From 877f39d4f4d24fe356b7738e386e58653209a85c Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Thu, 4 Jun 2026 07:01:42 -0500 Subject: [PATCH 2/2] fix(build): remove stale custom field API file from prior session The old API file references non-existent struct names and fields. Will be rebuilt properly after the web UI is complete. Co-Authored-By: Claude Opus 4.6 (1M context) --- routers/api/v1/repo/custom_field.go | 196 ---------------------------- 1 file changed, 196 deletions(-) delete mode 100644 routers/api/v1/repo/custom_field.go diff --git a/routers/api/v1/repo/custom_field.go b/routers/api/v1/repo/custom_field.go deleted file mode 100644 index 4a966226af..0000000000 --- a/routers/api/v1/repo/custom_field.go +++ /dev/null @@ -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) -} -- 2.52.0