# `GanttEx.History`
[🔗](https://github.com/rocket4ce/gantt_ex/blob/v0.1.0/lib/gantt_ex/history.ex#L1)

Undo and redo for a `GanttEx.Store`.

The history keeps snapshots of the store (cheap, thanks to immutable data
structures). Undoing returns the previous snapshot together with the
changes that lead to it (see `GanttEx.Store.diff/2`), so they can be
persisted like any other change.

    iex> store = GanttEx.Store.new!([%{id: 1, text: "A", start_date: ~D[2025-01-01]}])
    iex> history = GanttEx.History.new()
    iex> {:ok, changed, _} = GanttEx.Store.update_task(store, 1, %{text: "B"})
    iex> history = GanttEx.History.record(history, store)
    iex> {:ok, history, restored, [{:task_updated, task, %{changes: changes}}]} = GanttEx.History.undo(history, changed)
    iex> {task.text, changes, GanttEx.History.can_redo?(history)}
    {"A", %{text: "A"}, true}
    iex> {:ok, _history, _store, [{:task_updated, %{text: "B"}, _}]} = GanttEx.History.redo(history, restored)
    iex> GanttEx.History.undo(GanttEx.History.new(), store)
    :empty

# `t`

```elixir
@type t() :: %GanttEx.History{
  future: [GanttEx.Store.t()],
  limit: pos_integer(),
  past: [GanttEx.Store.t()]
}
```

# `can_redo?`

```elixir
@spec can_redo?(t()) :: boolean()
```

Returns `true` when there is something to redo.

# `can_undo?`

```elixir
@spec can_undo?(t()) :: boolean()
```

Returns `true` when there is something to undo.

# `new`

```elixir
@spec new(keyword()) :: t()
```

Creates an empty history.

## Options

  * `:limit` - how many steps are kept. Defaults to `50`.

# `record`

```elixir
@spec record(t(), GanttEx.Store.t()) :: t()
```

Records `store` as the state before a change. Clears the redo steps.

# `redo`

```elixir
@spec redo(t(), GanttEx.Store.t()) ::
  {:ok, t(), GanttEx.Store.t(), [GanttEx.Store.change()]} | :empty
```

Goes forward one step from `current`, or returns `:empty`.

# `undo`

```elixir
@spec undo(t(), GanttEx.Store.t()) ::
  {:ok, t(), GanttEx.Store.t(), [GanttEx.Store.change()]} | :empty
```

Goes back one step from `current`. Returns the restored store and the
changes from `current` to it, or `:empty`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
