Packages
phoenix_kit
1.7.149
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/phoenix_kit/dashboard/group.ex
defmodule PhoenixKit.Dashboard.Group do
@moduledoc """
Struct representing a dashboard tab group.
Groups organize tabs in the dashboard sidebar. Each group has an ID,
an optional label, and a priority for ordering.
## Fields
- `id` - Unique group identifier atom (e.g., `:admin_main`, `:shop`)
- `label` - Optional display label (nil for unlabeled groups)
- `priority` - Sort priority (lower = first, default: 100)
- `icon` - Optional heroicon name (e.g., `"hero-cube"`)
- `collapsible` - Whether the group can be collapsed in the sidebar
- `gettext_backend` - Optional Gettext backend module for label translation (default: nil)
- `gettext_domain` - Gettext domain for translation lookups (default: "default")
"""
@enforce_keys [:id]
defstruct [
:id,
:label,
:icon,
:gettext_backend,
priority: 100,
collapsible: false,
gettext_domain: "default"
]
@type t :: %__MODULE__{
id: atom(),
label: String.t() | nil,
priority: integer(),
icon: String.t() | nil,
collapsible: boolean(),
gettext_backend: module() | nil,
gettext_domain: String.t()
}
@doc """
Returns the group's label, translated via the configured gettext backend if one is set.
Falls back to the raw label string when:
* `gettext_backend` is `nil` (default — no translation configured)
* the label is `nil` (unlabeled groups)
* gettext has no translation for the msgid (gettext's own fallback)
Reads `gettext_backend` and `gettext_domain` via `Map.get/2` rather than
pattern matching, so an old-shape struct cached in ETS or `:persistent_term`
before the 1.8.0 upgrade — which lacks those keys entirely — gracefully
falls back to the raw label instead of raising `FunctionClauseError`.
"""
@spec localized_label(t()) :: String.t() | nil
def localized_label(%__MODULE__{label: nil}), do: nil
def localized_label(%__MODULE__{label: label} = group) do
case Map.get(group, :gettext_backend) do
nil ->
label
backend ->
domain = Map.get(group, :gettext_domain) || "default"
Gettext.dgettext(backend, domain, label)
end
end
@doc """
Creates a new group from a map or keyword list.
"""
@spec new(map() | keyword()) :: t()
def new(attrs) when is_map(attrs) do
%__MODULE__{
id: attrs[:id] || attrs["id"],
label: attrs[:label] || attrs["label"],
priority: attrs[:priority] || attrs["priority"] || 100,
icon: attrs[:icon] || attrs["icon"],
collapsible: attrs[:collapsible] || attrs["collapsible"] || false,
gettext_backend: attrs[:gettext_backend] || attrs["gettext_backend"],
gettext_domain: attrs[:gettext_domain] || attrs["gettext_domain"] || "default"
}
end
def new(attrs) when is_list(attrs) do
%__MODULE__{
id: Keyword.fetch!(attrs, :id),
label: Keyword.get(attrs, :label),
priority: Keyword.get(attrs, :priority, 100),
icon: Keyword.get(attrs, :icon),
collapsible: Keyword.get(attrs, :collapsible, false),
gettext_backend: Keyword.get(attrs, :gettext_backend),
gettext_domain: Keyword.get(attrs, :gettext_domain, "default")
}
end
end