defmodule StepFlow.WorkflowView do
use StepFlow, :view
alias StepFlow.{ArtifactView, JobView, WorkflowStatusView, WorkflowView}
require Logger
def render("index.json", %{workflows: %{data: workflows, total: total}}) do
%{
data: render_many(workflows, WorkflowView, "workflow_full.json"),
total: total
}
end
def render("show.json", %{workflow: workflow, mode: mode}) do
%{data: render_one(workflow, WorkflowView, "workflow_#{mode}.json")}
end
def render("created.json", %{workflow: workflow}) do
%{data: render_one(workflow, WorkflowView, "workflow_created.json")}
end
def render("workflow_full.json", %{workflow: workflow}) do
result = %{
schema_version: workflow.schema_version,
id: workflow.id,
identifier: workflow.identifier,
is_live: workflow.is_live,
deleted: workflow.deleted,
version_major: workflow.version_major,
version_minor: workflow.version_minor,
version_micro: workflow.version_micro,
tags: workflow.tags,
reference: workflow.reference,
steps: workflow.steps,
parameters: workflow.parameters,
created_at: workflow.inserted_at,
user_uuid: workflow.user_uuid,
notification_hooks: workflow.notification_hooks,
parent_id: workflow.parent_id
}
result =
if is_list(workflow.artifacts) do
artifacts = render_many(workflow.artifacts, ArtifactView, "artifact.json")
Map.put(result, :artifacts, artifacts)
else
result
end
result =
if is_list(workflow.jobs) do
jobs = render_many(workflow.jobs, JobView, "job.json")
Map.put(result, :jobs, jobs)
else
result
end
result =
if is_list(workflow.status) do
last_status =
workflow.status
|> Enum.sort_by(fn s -> {s.inserted_at, s.id} end)
|> List.last()
state = render_one(last_status, WorkflowStatusView, "state.json")
Map.put(result, :status, state)
else
result
end
result
end
def render("workflow_simple.json", %{workflow: workflow}) do
result = %{
schema_version: workflow.schema_version,
id: workflow.id,
identifier: workflow.identifier,
is_live: workflow.is_live,
version_major: workflow.version_major,
version_minor: workflow.version_minor,
version_micro: workflow.version_micro,
created_at: workflow.inserted_at,
user_uuid: workflow.user_uuid,
notification_hooks: workflow.notification_hooks,
parent_id: workflow.parent_id
}
if is_list(workflow.status) do
last_status =
workflow.status
|> Enum.sort_by(fn s -> {s.inserted_at, s.id} end)
|> List.last()
state = render_one(last_status, WorkflowStatusView, "state.json")
Map.put(result, :status, state)
else
result
end
end
def render("workflow_created.json", %{workflow: workflow}) do
%{
id: workflow.id,
identifier: workflow.identifier,
version_major: workflow.version_major,
version_minor: workflow.version_minor,
version_micro: workflow.version_micro,
tags: workflow.tags
}
end
def render("statistics.json", %{workflows_status: []}) do
%{
data: %{
processing: 0,
error: 0,
completed: 0,
pending: 0,
bins: []
}
}
end
def render("statistics.json", %{
workflows_status: workflows_status,
time_interval: time_interval,
end_date: end_date
}) do
%{
data: %{
processing:
workflows_status
|> Enum.filter(fn s -> s.state == :processing end)
|> length(),
error:
workflows_status
|> Enum.filter(fn s -> s.state == :error end)
|> length(),
completed:
workflows_status
|> Enum.filter(fn s -> s.state == :completed end)
|> length(),
pending:
workflows_status
|> Enum.filter(fn s -> s.state == :pending end)
|> length(),
bins:
workflows_status
|> Enum.group_by(fn s ->
NaiveDateTime.diff(end_date, s.inserted_at, :second)
|> Kernel.div(time_interval)
end)
|> Enum.map(fn {bin, group} ->
%{
bin: bin,
start_date:
NaiveDateTime.add(end_date, -(bin + 1) * time_interval, :second)
|> NaiveDateTime.to_string(),
end_date:
NaiveDateTime.add(end_date, -bin * time_interval, :second)
|> NaiveDateTime.to_string(),
processing:
group
|> Enum.filter(fn s -> s.state == :processing end)
|> length(),
error:
group
|> Enum.filter(fn s -> s.state == :error end)
|> length(),
completed:
group
|> Enum.filter(fn s -> s.state == :completed end)
|> length(),
pending:
group
|> Enum.filter(fn s -> s.state == :pending end)
|> length()
}
end)
}
}
end
end