# `Cinder.UrlManager`
[🔗](https://github.com/sevenseacat/cinder/blob/v0.16.0/lib/cinder/url_manager.ex#L1)

URL state management for Cinder table components.

Handles encoding and decoding of table state (filters, pagination, sorting)
to/from URL parameters for browser history and bookmark support.

# `filter`

```elixir
@type filter() :: %{type: atom(), value: filter_value(), operator: atom()}
```

# `filter_value`

```elixir
@type filter_value() ::
  String.t()
  | [String.t()]
  | %{from: String.t(), to: String.t()}
  | %{min: String.t(), max: String.t()}
```

# `sort_by`

```elixir
@type sort_by() :: [{String.t(), :asc | :desc}]
```

# `table_state`

```elixir
@type table_state() :: %{
  filters: %{required(String.t()) =&gt; filter()},
  current_page: integer(),
  sort_by: sort_by(),
  page_size: integer(),
  default_page_size: integer(),
  search_term: String.t()
}
```

# `url_params`

```elixir
@type url_params() :: %{required(atom()) =&gt; String.t()}
```

# `decode_cursor`

Decodes keyset cursor from URL parameter for keyset pagination.

Used for both `after` and `before` cursor parameters.
Returns nil for missing or empty cursor parameters.

## Examples

    iex> Cinder.UrlManager.decode_cursor("g2wAAAABbQAAAARha3Vsag==")
    "g2wAAAABbQAAAARha3Vsag=="

    iex> Cinder.UrlManager.decode_cursor(nil)
    nil

    iex> Cinder.UrlManager.decode_cursor("")
    nil

# `decode_filters`

Decodes filters from URL parameters using column definitions.

Uses column metadata to properly parse filter values according to their types.

# `decode_page`

Decodes page number from URL parameter.

Returns 1 for invalid or missing page parameters.

## Examples

    iex> Cinder.UrlManager.decode_page("5")
    5

    iex> Cinder.UrlManager.decode_page("invalid")
    1

    iex> Cinder.UrlManager.decode_page(nil)
    1

# `decode_page_size`

Decodes page size from URL parameter.

Returns 25 for invalid or missing page_size parameters.

## Examples

    iex> Cinder.UrlManager.decode_page_size("50")
    50

    iex> Cinder.UrlManager.decode_page_size("invalid")
    25

    iex> Cinder.UrlManager.decode_page_size(nil)
    25

# `decode_sort`

# `decode_sort`

Decodes sort string from URL parameters.

Parses Ash sort string format into sort tuples.
Fields prefixed with "-" are descending, others are ascending.

## Examples

    iex> Cinder.UrlManager.decode_sort("-title,created_at")
    [{"title", :desc}, {"created_at", :asc}]

    iex> Cinder.UrlManager.decode_sort("--payment_date,++created_at")
    [{"payment_date", :desc_nils_last}, {"created_at", :asc_nils_first}]

    iex> Cinder.UrlManager.decode_sort("-+score,+-priority")
    [{"score", :asc_nils_last}, {"priority", :desc_nils_first}]

# `decode_state`

Decodes URL parameters into table state components.

Takes URL parameters and column definitions to properly decode filter values
based on their types.

## Examples

    iex> url_params = %{"title" => "test", "page" => "2", "sort" => "-title"}
    iex> columns = [%{field: "title", filterable: true, filter_type: :text}]
    iex> Cinder.UrlManager.decode_state(url_params, columns)
    %{
      filters: %{"title" => %{type: :text, value: "test", operator: :contains}},
      current_page: 2,
      sort_by: [{"title", :desc}]
    }

# `encode_filters`

Encodes filters for URL parameters.

Converts filter values to strings appropriate for URL encoding.
Different filter types are encoded differently:
- Multi-select: comma-separated values
- Date/number ranges: "from,to" or "min,max" format
- Others: string representation

# `encode_sort`

Encodes sort state for URL parameters.

Converts sort tuples to Ash-compatible sort string format.
Descending sorts are prefixed with "-".

## Examples

    iex> Cinder.UrlManager.encode_sort([{"title", :desc}, {"created_at", :asc}])
    "-title,created_at"

    iex> Cinder.UrlManager.encode_sort([{"payment_date", :desc_nils_last}, {"created_at", :asc_nils_first}])
    "--payment_date,++created_at"

    iex> Cinder.UrlManager.encode_sort([{"score", :asc_nils_last}, {"priority", :desc_nils_first}])
    "-+score,+-priority"

# `encode_state`

Encodes table state into URL parameters.

## Examples

    iex> state = %{
    ...>   filters: %{"title" => %{type: :text, value: "test", operator: :contains}},
    ...>   current_page: 2,
    ...>   sort_by: [{"title", :desc}]
    ...> }
    iex> Cinder.UrlManager.encode_state(state)
    %{title: "test", page: "2", sort: "-title"}

# `ensure_multiselect_fields`

Ensures multi-select fields are included in filter parameters.

Multi-select filters that have no selected values need to be explicitly
included as empty arrays to distinguish from filters that weren't processed.

# `notify_state_change`

Sends state change notification to parent LiveView.

Used by components to notify their parent when table state changes,
allowing the parent to update the URL accordingly.

# `validate_url_params`

Validates URL parameters for potential security issues.

Performs basic validation to ensure URL parameters are safe to process.
Returns {:ok, params} for valid parameters or {:error, reason} for invalid ones.

---

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