mirror of
https://github.com/ash-project/ash_state_machine.git
synced 2024-09-20 05:13:26 +12:00
improvement: make state diagrams the default chart
docs: docs improvements
This commit is contained in:
parent
f86b2f6692
commit
bd66b9236f
4 changed files with 54 additions and 19 deletions
|
@ -107,13 +107,13 @@ end
|
||||||
run `mix ash_state_machine.generate_flow_charts` to generate flow charts for your resources. See the task documentation for more. Here is a chart generated from the example above:
|
run `mix ash_state_machine.generate_flow_charts` to generate flow charts for your resources. See the task documentation for more. Here is a chart generated from the example above:
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
stateDiagram-v2
|
||||||
pending --> |confirm| confirmed
|
pending --> confirmed: confirm
|
||||||
confirmed --> |begin_delivery| on_its_way
|
confirmed --> on_its_way: begin_delivery
|
||||||
on_its_way --> |package_arrived| arrived
|
on_its_way --> arrived: package_arrived
|
||||||
on_its_way --> |error| error
|
on_its_way --> error: error
|
||||||
confirmed --> |error| error
|
confirmed --> error: error
|
||||||
pending --> |error| error
|
pending --> error: error
|
||||||
```
|
```
|
||||||
|
|
||||||
## Learning more
|
## Learning more
|
||||||
|
|
|
@ -3,18 +3,29 @@ defmodule AshStateMachine.Charts do
|
||||||
Returns a mermaid flow chart of a given state machine resource.
|
Returns a mermaid flow chart of a given state machine resource.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@spec mermaid_state_diagram(Ash.Resource.t()) :: String.t()
|
||||||
|
def mermaid_state_diagram(resource) do
|
||||||
|
resource
|
||||||
|
|> AshStateMachine.Info.state_machine_initial_states!()
|
||||||
|
|> Enum.reduce({["stateDiagram-v2"], MapSet.new()}, fn state, {lines, checked} ->
|
||||||
|
add_to_chart(resource, state, lines ++ [], checked, :state_diagram)
|
||||||
|
end)
|
||||||
|
|> elem(0)
|
||||||
|
|> Enum.join("\n")
|
||||||
|
end
|
||||||
|
|
||||||
@spec mermaid_flowchart(Ash.Resource.t()) :: String.t()
|
@spec mermaid_flowchart(Ash.Resource.t()) :: String.t()
|
||||||
def mermaid_flowchart(resource) do
|
def mermaid_flowchart(resource) do
|
||||||
resource
|
resource
|
||||||
|> AshStateMachine.Info.state_machine_initial_states!()
|
|> AshStateMachine.Info.state_machine_initial_states!()
|
||||||
|> Enum.reduce({["flowchart TD"], MapSet.new()}, fn state, {lines, checked} ->
|
|> Enum.reduce({["flowchart TD"], MapSet.new()}, fn state, {lines, checked} ->
|
||||||
add_to_chart(resource, state, lines ++ [], checked)
|
add_to_chart(resource, state, lines ++ [], checked, :flow_chart)
|
||||||
end)
|
end)
|
||||||
|> elem(0)
|
|> elem(0)
|
||||||
|> Enum.join("\n")
|
|> Enum.join("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
defp add_to_chart(resource, state, lines, checked) do
|
defp add_to_chart(resource, state, lines, checked, type) do
|
||||||
if state in checked do
|
if state in checked do
|
||||||
{lines, checked}
|
{lines, checked}
|
||||||
else
|
else
|
||||||
|
@ -24,14 +35,28 @@ defmodule AshStateMachine.Charts do
|
||||||
|> transitions_from(resource)
|
|> transitions_from(resource)
|
||||||
|> Enum.reduce({lines, checked}, fn event, {lines, checked} ->
|
|> Enum.reduce({lines, checked}, fn event, {lines, checked} ->
|
||||||
Enum.reduce(List.wrap(event.to), {lines, checked}, fn to, {lines, checked} ->
|
Enum.reduce(List.wrap(event.to), {lines, checked}, fn to, {lines, checked} ->
|
||||||
name =
|
lines =
|
||||||
case event.action do
|
case type do
|
||||||
:* -> ""
|
:flow_chart ->
|
||||||
action -> "|#{action}|"
|
name =
|
||||||
|
case event.action do
|
||||||
|
:* -> ""
|
||||||
|
action -> "|#{action}|"
|
||||||
|
end
|
||||||
|
|
||||||
|
lines ++ ["#{state} --> #{name} #{to}"]
|
||||||
|
|
||||||
|
:state_diagram ->
|
||||||
|
name =
|
||||||
|
case event.action do
|
||||||
|
:* -> ""
|
||||||
|
action -> ": #{action}"
|
||||||
|
end
|
||||||
|
|
||||||
|
lines ++ ["#{state} --> #{to}#{name}"]
|
||||||
end
|
end
|
||||||
|
|
||||||
lines = lines ++ ["#{state} --> #{name} #{to}"]
|
add_to_chart(resource, to, lines, checked, type)
|
||||||
add_to_chart(resource, to, lines, checked)
|
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,6 +11,7 @@ defmodule Mix.Tasks.AshStateMachine.GenerateFlowCharts do
|
||||||
|
|
||||||
## Command line options
|
## Command line options
|
||||||
|
|
||||||
|
* `--type` - generates a given type. Valid values are `"state_diagram"` and `"flow_chart"`. Defaults to `"state_diagram"`.
|
||||||
* `--only` - only generates the given Flow file
|
* `--only` - only generates the given Flow file
|
||||||
* `--format` - Can be set to one of either:
|
* `--format` - Can be set to one of either:
|
||||||
* `plain` - Prints just the mermaid output as text. This is the default.
|
* `plain` - Prints just the mermaid output as text. This is the default.
|
||||||
|
@ -30,8 +31,8 @@ defmodule Mix.Tasks.AshStateMachine.GenerateFlowCharts do
|
||||||
|
|
||||||
{opts, _} =
|
{opts, _} =
|
||||||
OptionParser.parse!(argv,
|
OptionParser.parse!(argv,
|
||||||
strict: [only: :keep, format: :string],
|
strict: [only: :keep, format: :string, type: :string],
|
||||||
aliases: [o: :only, f: :format]
|
aliases: [o: :only, f: :format, t: :type]
|
||||||
)
|
)
|
||||||
|
|
||||||
only =
|
only =
|
||||||
|
@ -47,11 +48,20 @@ defmodule Mix.Tasks.AshStateMachine.GenerateFlowCharts do
|
||||||
source = state_machine.module_info(:compile)[:source]
|
source = state_machine.module_info(:compile)[:source]
|
||||||
|
|
||||||
if is_nil(only) || Path.expand(source) in only do
|
if is_nil(only) || Path.expand(source) in only do
|
||||||
|
diagram =
|
||||||
|
case opts[:type] || "state_diagram" do
|
||||||
|
"state_diagram" ->
|
||||||
|
AshStateMachine.Charts.mermaid_state_diagram(state_machine)
|
||||||
|
|
||||||
|
"flow_chart" ->
|
||||||
|
AshStateMachine.Charts.mermaid_flowchart(state_machine)
|
||||||
|
end
|
||||||
|
|
||||||
Mix.Mermaid.generate_diagram(
|
Mix.Mermaid.generate_diagram(
|
||||||
source,
|
source,
|
||||||
"mermaid-flowchart",
|
"mermaid-flowchart",
|
||||||
format,
|
format,
|
||||||
AshStateMachine.Charts.mermaid_flowchart(state_machine),
|
diagram,
|
||||||
"Generated Mermaid flowchart for #{inspect(state_machine)}"
|
"Generated Mermaid flowchart for #{inspect(state_machine)}"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -154,7 +154,7 @@ defmodule AshStateMachineTest do
|
||||||
|
|
||||||
describe "charts" do
|
describe "charts" do
|
||||||
test "it generates the appropriate chart" do
|
test "it generates the appropriate chart" do
|
||||||
AshStateMachine.Charts.mermaid_flowchart(Order) |> IO.puts()
|
AshStateMachine.Charts.mermaid_state_diagram(Order) |> IO.puts()
|
||||||
|
|
||||||
assert AshStateMachine.Charts.mermaid_flowchart(ThreeStates) ==
|
assert AshStateMachine.Charts.mermaid_flowchart(ThreeStates) ==
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in a new issue