Skip to content

Commit

Permalink
Default workflow states to always have position 0
Browse files Browse the repository at this point in the history
  • Loading branch information
pksunkara committed Nov 23, 2022
1 parent beeae8f commit b3be20e
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 53 deletions.
13 changes: 9 additions & 4 deletions docs/resources/team.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ resource "linear_team" "example" {
- `auto_archive_period` (Number) Period after which closed and completed issues are automatically archived, in months. **Default** `6`.
- `auto_close_period` (Number) Period after which non-completed or non-canceled issues are automatically closed, in months. **Default** `6`. *Use `0` for turning this off.*
- `backlog_workflow_state` (Attributes) Settings for the `backlog` workflow state that is created by default for the team. *Position is always `0`. This can not be deleted.* (see [below for nested schema](#nestedatt--backlog_workflow_state))
- `canceled_workflow_state` (Attributes) Settings for the `canceled` workflow state that is created by default for the team. *Position is always `4`. This can not be deleted.* (see [below for nested schema](#nestedatt--canceled_workflow_state))
- `canceled_workflow_state` (Attributes) Settings for the `canceled` workflow state that is created by default for the team. *Position is always `0`. This can not be deleted.* (see [below for nested schema](#nestedatt--canceled_workflow_state))
- `color` (String) Color of the team.
- `completed_workflow_state` (Attributes) Settings for the `completed` workflow state that is created by default for the team. *Position is always `3`. This can not be deleted.* (see [below for nested schema](#nestedatt--completed_workflow_state))
- `completed_workflow_state` (Attributes) Settings for the `completed` workflow state that is created by default for the team. *Position is always `0`. This can not be deleted.* (see [below for nested schema](#nestedatt--completed_workflow_state))
- `cycles` (Attributes) Cycle settings of the team. (see [below for nested schema](#nestedatt--cycles))
- `description` (String) Description of the team.
- `enable_issue_default_to_bottom` (Boolean) Enable moving issues to bottom of the column when changing state. **Default** `false`.
Expand All @@ -43,10 +43,10 @@ resource "linear_team" "example" {
- `icon` (String) Icon of the team.
- `no_priority_issues_first` (Boolean) Prefer issues without priority at the top during issue prioritization order. **Default** `true`.
- `private` (Boolean) Privacy of the team. **Default** `false`.
- `started_workflow_state` (Attributes) Settings for the `started` workflow state that is created by default for the team. *Position is always `2`. This can not be deleted.* (see [below for nested schema](#nestedatt--started_workflow_state))
- `started_workflow_state` (Attributes) Settings for the `started` workflow state that is created by default for the team. *Position is always `0`. This can not be deleted.* (see [below for nested schema](#nestedatt--started_workflow_state))
- `timezone` (String) Timezone of the team. **Default** `Etc/GMT`.
- `triage` (Attributes) Triage settings of the team. (see [below for nested schema](#nestedatt--triage))
- `unstarted_workflow_state` (Attributes) Settings for the `unstarted` workflow state that is created by default for the team. *Position is always `1`. This can not be deleted.* (see [below for nested schema](#nestedatt--unstarted_workflow_state))
- `unstarted_workflow_state` (Attributes) Settings for the `unstarted` workflow state that is created by default for the team. *Position is always `0`. This can not be deleted.* (see [below for nested schema](#nestedatt--unstarted_workflow_state))

### Read-Only

Expand All @@ -64,6 +64,7 @@ Optional:
Read-Only:

- `id` (String) Identifier of the workflow state.
- `position` (Number) Position of the workflow state.


<a id="nestedatt--canceled_workflow_state"></a>
Expand All @@ -78,6 +79,7 @@ Optional:
Read-Only:

- `id` (String) Identifier of the workflow state.
- `position` (Number) Position of the workflow state.


<a id="nestedatt--completed_workflow_state"></a>
Expand All @@ -92,6 +94,7 @@ Optional:
Read-Only:

- `id` (String) Identifier of the workflow state.
- `position` (Number) Position of the workflow state.


<a id="nestedatt--cycles"></a>
Expand Down Expand Up @@ -132,6 +135,7 @@ Optional:
Read-Only:

- `id` (String) Identifier of the workflow state.
- `position` (Number) Position of the workflow state.


<a id="nestedatt--triage"></a>
Expand All @@ -154,6 +158,7 @@ Optional:
Read-Only:

- `id` (String) Identifier of the workflow state.
- `position` (Number) Position of the workflow state.

## Import

Expand Down
2 changes: 1 addition & 1 deletion docs/resources/workspace_settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ resource "linear_workspace_settings" "example" {
Import is supported using the following syntax:

```shell
terraform import linear_workspace_settings.example
terraform import linear_workspace_settings.example example
```
2 changes: 1 addition & 1 deletion internal/provider/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

99 changes: 69 additions & 30 deletions internal/provider/resource_team.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ type TeamResourceEstimationModel struct {
}

type TeamResourceWorkflowStateModel struct {
Id types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Color types.String `tfsdk:"color"`
Description types.String `tfsdk:"description"`
Id types.String `tfsdk:"id"`
Position types.Float64 `tfsdk:"position"`
Name types.String `tfsdk:"name"`
Color types.String `tfsdk:"color"`
Description types.String `tfsdk:"description"`
}

type TeamResourceModel struct {
Expand Down Expand Up @@ -401,6 +402,14 @@ func (r *TeamResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagno
resource.UseStateForUnknown(),
},
},
"position": {
MarkdownDescription: "Position of the workflow state.",
Type: types.Float64Type,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
resource.UseStateForUnknown(),
},
},
"name": {
MarkdownDescription: "Name of the workflow state. **Default** `Backlog`.",
Type: types.StringType,
Expand Down Expand Up @@ -434,7 +443,7 @@ func (r *TeamResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagno
}),
},
"unstarted_workflow_state": {
MarkdownDescription: "Settings for the `unstarted` workflow state that is created by default for the team. *Position is always `1`. This can not be deleted.*",
MarkdownDescription: "Settings for the `unstarted` workflow state that is created by default for the team. *Position is always `0`. This can not be deleted.*",
Optional: true,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
Expand All @@ -449,6 +458,14 @@ func (r *TeamResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagno
resource.UseStateForUnknown(),
},
},
"position": {
MarkdownDescription: "Position of the workflow state.",
Type: types.Float64Type,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
resource.UseStateForUnknown(),
},
},
"name": {
MarkdownDescription: "Name of the workflow state. **Default** `Todo`.",
Type: types.StringType,
Expand Down Expand Up @@ -482,7 +499,7 @@ func (r *TeamResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagno
}),
},
"started_workflow_state": {
MarkdownDescription: "Settings for the `started` workflow state that is created by default for the team. *Position is always `2`. This can not be deleted.*",
MarkdownDescription: "Settings for the `started` workflow state that is created by default for the team. *Position is always `0`. This can not be deleted.*",
Optional: true,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
Expand All @@ -497,6 +514,14 @@ func (r *TeamResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagno
resource.UseStateForUnknown(),
},
},
"position": {
MarkdownDescription: "Position of the workflow state.",
Type: types.Float64Type,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
resource.UseStateForUnknown(),
},
},
"name": {
MarkdownDescription: "Name of the workflow state. **Default** `In Progress`.",
Type: types.StringType,
Expand Down Expand Up @@ -530,7 +555,7 @@ func (r *TeamResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagno
}),
},
"completed_workflow_state": {
MarkdownDescription: "Settings for the `completed` workflow state that is created by default for the team. *Position is always `3`. This can not be deleted.*",
MarkdownDescription: "Settings for the `completed` workflow state that is created by default for the team. *Position is always `0`. This can not be deleted.*",
Optional: true,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
Expand All @@ -545,6 +570,14 @@ func (r *TeamResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagno
resource.UseStateForUnknown(),
},
},
"position": {
MarkdownDescription: "Position of the workflow state.",
Type: types.Float64Type,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
resource.UseStateForUnknown(),
},
},
"name": {
MarkdownDescription: "Name of the workflow state. **Default** `Done`.",
Type: types.StringType,
Expand Down Expand Up @@ -578,7 +611,7 @@ func (r *TeamResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagno
}),
},
"canceled_workflow_state": {
MarkdownDescription: "Settings for the `canceled` workflow state that is created by default for the team. *Position is always `4`. This can not be deleted.*",
MarkdownDescription: "Settings for the `canceled` workflow state that is created by default for the team. *Position is always `0`. This can not be deleted.*",
Optional: true,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
Expand All @@ -593,6 +626,14 @@ func (r *TeamResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagno
resource.UseStateForUnknown(),
},
},
"position": {
MarkdownDescription: "Position of the workflow state.",
Type: types.Float64Type,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
resource.UseStateForUnknown(),
},
},
"name": {
MarkdownDescription: "Name of the workflow state. **Default** `Canceled`.",
Type: types.StringType,
Expand Down Expand Up @@ -817,11 +858,11 @@ func (r *TeamResource) Create(ctx context.Context, req resource.CreateRequest, r

tflog.Trace(ctx, "read team workflow states")

backlogWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "backlog", 0)
unstartedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "unstarted", 1)
startedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "started", 2)
completedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "completed", 3)
canceledWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "canceled", 4)
backlogWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "backlog")
unstartedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "unstarted")
startedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "started")
completedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "completed")
canceledWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "canceled")

if backlogWorkflowState == nil || unstartedWorkflowState == nil || startedWorkflowState == nil || completedWorkflowState == nil || canceledWorkflowState == nil {
resp.Diagnostics.AddError("Client Error", "Unable to find all workflow states in a new team")
Expand Down Expand Up @@ -950,11 +991,11 @@ func (r *TeamResource) Read(ctx context.Context, req resource.ReadRequest, resp

tflog.Trace(ctx, "read team workflow states")

backlogWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "backlog", 0)
unstartedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "unstarted", 1)
startedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "started", 2)
completedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "completed", 3)
canceledWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "canceled", 4)
backlogWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "backlog")
unstartedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "unstarted")
startedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "started")
completedWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "completed")
canceledWorkflowState := findWorkflowStateType(workflowStatesResponse.WorkflowStates.Nodes, "canceled")

if backlogWorkflowState == nil || unstartedWorkflowState == nil || startedWorkflowState == nil || completedWorkflowState == nil || canceledWorkflowState == nil {
resp.Diagnostics.AddError("Client Error", "Unable to find all workflow states when reading team")
Expand Down Expand Up @@ -1189,9 +1230,9 @@ func (r *TeamResource) ImportState(ctx context.Context, req resource.ImportState
resource.ImportStatePassthroughID(ctx, path.Root("key"), req, resp)
}

func findWorkflowStateType(workflowStates []getTeamWorkflowStatesWorkflowStatesWorkflowStateConnectionNodesWorkflowState, ty string, position float64) *getTeamWorkflowStatesWorkflowStatesWorkflowStateConnectionNodesWorkflowState {
func findWorkflowStateType(workflowStates []getTeamWorkflowStatesWorkflowStatesWorkflowStateConnectionNodesWorkflowState, ty string) *getTeamWorkflowStatesWorkflowStatesWorkflowStateConnectionNodesWorkflowState {
for _, workflowState := range workflowStates {
if workflowState.Type == ty && workflowState.Position == position {
if workflowState.Type == ty && workflowState.Position == 0 {
return &workflowState
}
}
Expand All @@ -1214,12 +1255,14 @@ func readWorkflowStateToObject(workflowState getTeamWorkflowStatesWorkflowStates
ret := types.Object{
AttrTypes: map[string]attr.Type{
"id": types.StringType,
"position": types.Float64Type,
"name": types.StringType,
"color": types.StringType,
"description": types.StringType,
},
Attrs: map[string]attr.Value{
"id": types.String{Value: workflowState.Id},
"position": types.Float64{Value: workflowState.Position},
"name": types.String{Value: workflowState.Name},
"color": types.String{Value: workflowState.Color},
"description": types.String{Null: true},
Expand All @@ -1237,12 +1280,14 @@ func updateWorkflowStateToObject(workflowState updateWorkflowStateWorkflowStateU
ret := types.Object{
AttrTypes: map[string]attr.Type{
"id": types.StringType,
"position": types.Float64Type,
"name": types.StringType,
"color": types.StringType,
"description": types.StringType,
},
Attrs: map[string]attr.Value{
"id": types.String{Value: workflowState.Id},
"position": types.Float64{Value: workflowState.Position},
"name": types.String{Value: workflowState.Name},
"color": types.String{Value: workflowState.Color},
"description": types.String{Null: true},
Expand All @@ -1258,17 +1303,14 @@ func updateWorkflowStateToObject(workflowState updateWorkflowStateWorkflowStateU

func updateTeamWorkflowStateInCreate(ctx context.Context, r *TeamResource, data types.Object, resp *resource.CreateResponse, id string) *types.Object {
var workflowStateData *TeamResourceWorkflowStateModel
var workflowStateInput WorkflowStateUpdateInput
var workflowStateResponse *updateWorkflowStateResponse
var workflowStateErr error

resp.Diagnostics.Append(data.As(ctx, &workflowStateData, types.ObjectAsOptions{})...)

if resp.Diagnostics.HasError() {
return nil
}

workflowStateInput = WorkflowStateUpdateInput{
workflowStateInput := WorkflowStateUpdateInput{
Name: workflowStateData.Name.Value,
Color: workflowStateData.Color.Value,
}
Expand All @@ -1277,7 +1319,7 @@ func updateTeamWorkflowStateInCreate(ctx context.Context, r *TeamResource, data
workflowStateInput.Description = &workflowStateData.Description.Value
}

workflowStateResponse, workflowStateErr = updateWorkflowState(ctx, *r.client, workflowStateInput, id)
workflowStateResponse, workflowStateErr := updateWorkflowState(ctx, *r.client, workflowStateInput, id)

if workflowStateErr != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update workflow state, got error: %s", workflowStateErr))
Expand All @@ -1291,17 +1333,14 @@ func updateTeamWorkflowStateInCreate(ctx context.Context, r *TeamResource, data

func updateTeamWorkflowStateInUpdate(ctx context.Context, r *TeamResource, data types.Object, resp *resource.UpdateResponse, id string) *types.Object {
var workflowStateData *TeamResourceWorkflowStateModel
var workflowStateInput WorkflowStateUpdateInput
var workflowStateResponse *updateWorkflowStateResponse
var workflowStateErr error

resp.Diagnostics.Append(data.As(ctx, &workflowStateData, types.ObjectAsOptions{})...)

if resp.Diagnostics.HasError() {
return nil
}

workflowStateInput = WorkflowStateUpdateInput{
workflowStateInput := WorkflowStateUpdateInput{
Name: workflowStateData.Name.Value,
Color: workflowStateData.Color.Value,
}
Expand All @@ -1310,7 +1349,7 @@ func updateTeamWorkflowStateInUpdate(ctx context.Context, r *TeamResource, data
workflowStateInput.Description = &workflowStateData.Description.Value
}

workflowStateResponse, workflowStateErr = updateWorkflowState(ctx, *r.client, workflowStateInput, id)
workflowStateResponse, workflowStateErr := updateWorkflowState(ctx, *r.client, workflowStateInput, id)

if workflowStateErr != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update workflow state, got error: %s", workflowStateErr))
Expand Down
Loading

0 comments on commit b3be20e

Please sign in to comment.