mirror of
https://github.com/ash-project/ash_state_machine.git
synced 2024-09-19 21:03:33 +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:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
pending --> |confirm| confirmed
|
||||
confirmed --> |begin_delivery| on_its_way
|
||||
on_its_way --> |package_arrived| arrived
|
||||
on_its_way --> |error| error
|
||||
confirmed --> |error| error
|
||||
pending --> |error| error
|
||||
stateDiagram-v2
|
||||
pending --> confirmed: confirm
|
||||
confirmed --> on_its_way: begin_delivery
|
||||
on_its_way --> arrived: package_arrived
|
||||
on_its_way --> error: error
|
||||
confirmed --> error: error
|
||||
pending --> error: error
|
||||
```
|
||||
|
||||
## Learning more
|
||||
|
|
|
@ -3,18 +3,29 @@ defmodule AshStateMachine.Charts do
|
|||
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()
|
||||
def mermaid_flowchart(resource) do
|
||||
resource
|
||||
|> AshStateMachine.Info.state_machine_initial_states!()
|
||||
|> 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)
|
||||
|> elem(0)
|
||||
|> Enum.join("\n")
|
||||
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
|
||||
{lines, checked}
|
||||
else
|
||||
|
@ -24,14 +35,28 @@ defmodule AshStateMachine.Charts do
|
|||
|> transitions_from(resource)
|
||||
|> Enum.reduce({lines, checked}, fn event, {lines, checked} ->
|
||||
Enum.reduce(List.wrap(event.to), {lines, checked}, fn to, {lines, checked} ->
|
||||
name =
|
||||
case event.action do
|
||||
:* -> ""
|
||||
action -> "|#{action}|"
|
||||
lines =
|
||||
case type do
|
||||
:flow_chart ->
|
||||
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
|
||||
|
||||
lines = lines ++ ["#{state} --> #{name} #{to}"]
|
||||
add_to_chart(resource, to, lines, checked)
|
||||
add_to_chart(resource, to, lines, checked, type)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -11,6 +11,7 @@ defmodule Mix.Tasks.AshStateMachine.GenerateFlowCharts do
|
|||
|
||||
## 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
|
||||
* `--format` - Can be set to one of either:
|
||||
* `plain` - Prints just the mermaid output as text. This is the default.
|
||||
|
@ -30,8 +31,8 @@ defmodule Mix.Tasks.AshStateMachine.GenerateFlowCharts do
|
|||
|
||||
{opts, _} =
|
||||
OptionParser.parse!(argv,
|
||||
strict: [only: :keep, format: :string],
|
||||
aliases: [o: :only, f: :format]
|
||||
strict: [only: :keep, format: :string, type: :string],
|
||||
aliases: [o: :only, f: :format, t: :type]
|
||||
)
|
||||
|
||||
only =
|
||||
|
@ -47,11 +48,20 @@ defmodule Mix.Tasks.AshStateMachine.GenerateFlowCharts do
|
|||
source = state_machine.module_info(:compile)[:source]
|
||||
|
||||
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(
|
||||
source,
|
||||
"mermaid-flowchart",
|
||||
format,
|
||||
AshStateMachine.Charts.mermaid_flowchart(state_machine),
|
||||
diagram,
|
||||
"Generated Mermaid flowchart for #{inspect(state_machine)}"
|
||||
)
|
||||
end
|
||||
|
|
|
@ -154,7 +154,7 @@ defmodule AshStateMachineTest do
|
|||
|
||||
describe "charts" 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) ==
|
||||
"""
|
||||
|
|
Loading…
Reference in a new issue