Make task time estimate optional

close #38

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-03-19 13:08:27 +01:00
parent 84c634cac3
commit 7efae81113
10 changed files with 39 additions and 54 deletions

View File

@@ -625,7 +625,6 @@ function ControlOverviewPageContent({
}); });
return; return;
} }
// Convert the time estimate components to ISO 8601 format // Convert the time estimate components to ISO 8601 format
const isoTimeEstimate = convertToISODuration(); const isoTimeEstimate = convertToISODuration();
@@ -636,7 +635,7 @@ function ControlOverviewPageContent({
controlId: data.control.id, controlId: data.control.id,
name: newTaskName, name: newTaskName,
description: newTaskDescription, description: newTaskDescription,
timeEstimate: isoTimeEstimate, timeEstimate: isoTimeEstimate === "" ? null : isoTimeEstimate,
}, },
}, },
onCompleted: () => { onCompleted: () => {

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<f972be1746bd5bb9d5100845096188f8>> * @generated SignedSource<<318d80720efe2f6e610353e3a640d786>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -15,7 +15,7 @@ export type CreateTaskInput = {
controlId: string; controlId: string;
description: string; description: string;
name: string; name: string;
timeEstimate: any; timeEstimate?: any | null | undefined;
}; };
export type ControlOverviewPageCreateTaskMutation$variables = { export type ControlOverviewPageCreateTaskMutation$variables = {
connections: ReadonlyArray<string>; connections: ReadonlyArray<string>;
@@ -34,7 +34,7 @@ export type ControlOverviewPageCreateTaskMutation$data = {
readonly id: string; readonly id: string;
readonly name: string; readonly name: string;
readonly state: TaskState; readonly state: TaskState;
readonly timeEstimate: any; readonly timeEstimate: any | null | undefined;
readonly version: number; readonly version: number;
}; };
}; };

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<84b34aa7e582728a8386d1fe1ef3fb58>> * @generated SignedSource<<084485ae03f7089bfdee310d631b01eb>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -50,7 +50,7 @@ export type ControlOverviewPageQuery$data = {
readonly id: string; readonly id: string;
readonly name: string; readonly name: string;
readonly state: TaskState; readonly state: TaskState;
readonly timeEstimate: any; readonly timeEstimate: any | null | undefined;
readonly version: number; readonly version: number;
}; };
}>; }>;

View File

@@ -0,0 +1 @@
ALTER TABLE tasks ALTER COLUMN time_estimate DROP NOT NULL;

View File

@@ -39,7 +39,7 @@ type (
UpdatedAt time.Time `db:"updated_at"` UpdatedAt time.Time `db:"updated_at"`
Version int `db:"version"` Version int `db:"version"`
AssignedTo *gid.GID `db:"assigned_to"` AssignedTo *gid.GID `db:"assigned_to"`
TimeEstimate time.Duration `db:"time_estimate"` TimeEstimate *time.Duration `db:"time_estimate"`
} }
Tasks []*Task Tasks []*Task

View File

@@ -19,6 +19,7 @@ import (
"fmt" "fmt"
"time" "time"
"gearno.de/ref"
"github.com/getprobo/probo/pkg/coredata" "github.com/getprobo/probo/pkg/coredata"
"github.com/getprobo/probo/pkg/gid" "github.com/getprobo/probo/pkg/gid"
"github.com/getprobo/probo/pkg/page" "github.com/getprobo/probo/pkg/page"
@@ -241,16 +242,21 @@ func (s FrameworkService) Import(
return nil, fmt.Errorf("cannot create global id: %w", err) return nil, fmt.Errorf("cannot create global id: %w", err)
} }
var timeEstimate *time.Duration
if task.TimeEstimate > 0 {
timeEstimate = ref.Ref(time.Duration(task.TimeEstimate) * time.Second)
}
importedTasks = append(importedTasks, &coredata.Task{ importedTasks = append(importedTasks, &coredata.Task{
ID: taskID, ID: taskID,
ControlID: controlID, ControlID: controlID,
Name: task.Name, Name: task.Name,
TimeEstimate: time.Duration(task.TimeEstimate) * time.Second,
State: coredata.TaskStateTodo, State: coredata.TaskStateTodo,
Description: task.Description, Description: task.Description,
ContentRef: "", ContentRef: "",
CreatedAt: now, CreatedAt: now,
UpdatedAt: now, UpdatedAt: now,
TimeEstimate: timeEstimate,
}) })
} }
} }

View File

@@ -35,7 +35,7 @@ type (
Name string Name string
ContentRef string ContentRef string
Description string Description string
TimeEstimate time.Duration TimeEstimate *time.Duration
AssignedTo *gid.GID AssignedTo *gid.GID
} }

View File

@@ -386,7 +386,7 @@ type Task implements Node {
name: String! name: String!
description: String! description: String!
state: TaskState! state: TaskState!
timeEstimate: Duration! timeEstimate: Duration
assignedTo: People @goField(forceResolver: true) assignedTo: People @goField(forceResolver: true)
evidences( evidences(
@@ -633,7 +633,7 @@ input CreateTaskInput {
controlId: ID! controlId: ID!
name: String! name: String!
description: String! description: String!
timeEstimate: Duration! timeEstimate: Duration
assignedToId: ID assignedToId: ID
} }

View File

@@ -2477,7 +2477,7 @@ type Task implements Node {
name: String! name: String!
description: String! description: String!
state: TaskState! state: TaskState!
timeEstimate: Duration! timeEstimate: Duration
assignedTo: People @goField(forceResolver: true) assignedTo: People @goField(forceResolver: true)
evidences( evidences(
@@ -2724,7 +2724,7 @@ input CreateTaskInput {
controlId: ID! controlId: ID!
name: String! name: String!
description: String! description: String!
timeEstimate: Duration! timeEstimate: Duration
assignedToId: ID assignedToId: ID
} }
@@ -10441,14 +10441,11 @@ func (ec *executionContext) _Task_timeEstimate(ctx context.Context, field graphq
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(time.Duration) res := resTmp.(*time.Duration)
fc.Result = res fc.Result = res
return ec.marshalNDuration2timeᚐDuration(ctx, field.Selections, res) return ec.marshalODuration2ᚖtimeᚐDuration(ctx, field.Selections, res)
} }
func (ec *executionContext) fieldContext_Task_timeEstimate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { func (ec *executionContext) fieldContext_Task_timeEstimate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -14606,7 +14603,7 @@ func (ec *executionContext) unmarshalInputCreateTaskInput(ctx context.Context, o
it.Description = data it.Description = data
case "timeEstimate": case "timeEstimate":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("timeEstimate")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("timeEstimate"))
data, err := ec.unmarshalNDuration2timeᚐDuration(ctx, v) data, err := ec.unmarshalODuration2ᚖtimeᚐDuration(ctx, v)
if err != nil { if err != nil {
return it, err return it, err
} }
@@ -18246,9 +18243,6 @@ func (ec *executionContext) _Task(ctx context.Context, sel ast.SelectionSet, obj
} }
case "timeEstimate": case "timeEstimate":
out.Values[i] = ec._Task_timeEstimate(ctx, field, obj) out.Values[i] = ec._Task_timeEstimate(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1)
}
case "assignedTo": case "assignedTo":
field := field field := field
@@ -19990,21 +19984,6 @@ func (ec *executionContext) marshalNDeleteVendorPayload2ᚖgithubᚗcomᚋgetpro
return ec._DeleteVendorPayload(ctx, sel, v) return ec._DeleteVendorPayload(ctx, sel, v)
} }
func (ec *executionContext) unmarshalNDuration2timeᚐDuration(ctx context.Context, v any) (time.Duration, error) {
res, err := graphql.UnmarshalDuration(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNDuration2timeᚐDuration(ctx context.Context, sel ast.SelectionSet, v time.Duration) graphql.Marshaler {
res := graphql.MarshalDuration(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
}
}
return res
}
func (ec *executionContext) marshalNEvidence2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐEvidence(ctx context.Context, sel ast.SelectionSet, v *types.Evidence) graphql.Marshaler { func (ec *executionContext) marshalNEvidence2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐEvidence(ctx context.Context, sel ast.SelectionSet, v *types.Evidence) graphql.Marshaler {
if v == nil { if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {

View File

@@ -121,7 +121,7 @@ type CreateTaskInput struct {
ControlID gid.GID `json:"controlId"` ControlID gid.GID `json:"controlId"`
Name string `json:"name"` Name string `json:"name"`
Description string `json:"description"` Description string `json:"description"`
TimeEstimate time.Duration `json:"timeEstimate"` TimeEstimate *time.Duration `json:"timeEstimate,omitempty"`
AssignedToID *gid.GID `json:"assignedToId,omitempty"` AssignedToID *gid.GID `json:"assignedToId,omitempty"`
} }
@@ -373,7 +373,7 @@ type Task struct {
Name string `json:"name"` Name string `json:"name"`
Description string `json:"description"` Description string `json:"description"`
State coredata.TaskState `json:"state"` State coredata.TaskState `json:"state"`
TimeEstimate time.Duration `json:"timeEstimate"` TimeEstimate *time.Duration `json:"timeEstimate,omitempty"`
AssignedTo *People `json:"assignedTo,omitempty"` AssignedTo *People `json:"assignedTo,omitempty"`
Evidences *EvidenceConnection `json:"evidences"` Evidences *EvidenceConnection `json:"evidences"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`