Packages

phoenix_kit

1.7.173
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

221 Versions

Jump to

Compare versions

18 files changed
+166 additions
-69 deletions
unknownCHANGELOG.md
File is too large to be displayed (100 KB limit).
  @@ -1,6 +1,6 @@
1 1 {<<"links">>,[{<<"GitHub">>,<<"https://github.com/BeamLabEU/phoenix_kit">>}]}.
2 2 {<<"name">>,<<"phoenix_kit">>}.
3 - {<<"version">>,<<"1.7.172">>}.
3 + {<<"version">>,<<"1.7.173">>}.
4 4 {<<"description">>,
5 5 <<65,32,102,111,117,110,100,97,116,105,111,110,32,102,111,114,32,98,117,105,
6 6 108,100,105,110,103,32,69,108,105,120,105,114,32,80,104,111,101,110,105,
  @@ -13,24 +13,35 @@ defmodule PhoenixKit.Migrations.Postgres.V80 do
13 13 def up(%{prefix: prefix} = _opts) do
14 14 p = prefix_str(prefix)
15 15
16 - # Convert template content fields to JSONB
17 - # Existing string values are preserved as {"en": "original_value"}
18 - execute("""
19 - ALTER TABLE #{p}phoenix_kit_email_templates
20 - ALTER COLUMN subject TYPE jsonb
21 - USING jsonb_build_object('en', subject),
22 - ALTER COLUMN html_body TYPE jsonb
23 - USING jsonb_build_object('en', html_body),
24 - ALTER COLUMN text_body TYPE jsonb
25 - USING jsonb_build_object('en', text_body),
26 - ALTER COLUMN display_name TYPE jsonb
27 - USING jsonb_build_object('en', display_name),
28 - ALTER COLUMN description TYPE jsonb
29 - USING CASE
30 - WHEN description IS NULL THEN NULL
31 - ELSE jsonb_build_object('en', description)
32 - END
33 - """)
16 + # Convert template content fields to JSONB. Guarded on the current type of
17 + # `subject` (all 5 columns are converted together, so one check covers the
18 + # group) — without it, re-running this migration against an
19 + # already-converted database double-wraps the JSONB values
20 + # (`jsonb_build_object('en', subject)` where `subject` is itself already
21 + # `{"en": "..."}`). A retry can happen because this version previously
22 + # didn't record its own "COMMENT ON TABLE ... IS '80'" marker like every
23 + # other version module does, so a failure later in the same multi-version
24 + # migration run (disable_ddl_transaction; each step auto-commits) would
25 + # cause a subsequent `mix ecto.migrate` to resume from V80 again.
26 + if column_type(prefix, "phoenix_kit_email_templates", "subject") != "jsonb" do
27 + # Existing string values are preserved as {"en": "original_value"}
28 + execute("""
29 + ALTER TABLE #{p}phoenix_kit_email_templates
30 + ALTER COLUMN subject TYPE jsonb
31 + USING jsonb_build_object('en', subject),
32 + ALTER COLUMN html_body TYPE jsonb
33 + USING jsonb_build_object('en', html_body),
34 + ALTER COLUMN text_body TYPE jsonb
35 + USING jsonb_build_object('en', text_body),
36 + ALTER COLUMN display_name TYPE jsonb
37 + USING jsonb_build_object('en', display_name),
38 + ALTER COLUMN description TYPE jsonb
39 + USING CASE
40 + WHEN description IS NULL THEN NULL
41 + ELSE jsonb_build_object('en', description)
42 + END
43 + """)
44 + end
34 45
35 46 # Add locale tracking to email logs
36 47 execute("""
  @@ -42,6 +53,8 @@ defmodule PhoenixKit.Migrations.Postgres.V80 do
42 53 CREATE INDEX IF NOT EXISTS idx_email_logs_locale
43 54 ON #{p}phoenix_kit_email_logs (locale)
44 55 """)
56 +
57 + execute("COMMENT ON TABLE #{p}phoenix_kit IS '80'")
45 58 end
46 59
47 60 def down(%{prefix: prefix} = _opts) do
  @@ -68,6 +81,22 @@ defmodule PhoenixKit.Migrations.Postgres.V80 do
68 81 ALTER TABLE #{p}phoenix_kit_email_logs
69 82 DROP COLUMN IF EXISTS locale
70 83 """)
84 +
85 + execute("COMMENT ON TABLE #{p}phoenix_kit IS '79'")
86 + end
87 +
88 + defp column_type(prefix, table, column) do
89 + schema = prefix || "public"
90 +
91 + query = """
92 + SELECT data_type FROM information_schema.columns
93 + WHERE table_schema = '#{schema}' AND table_name = '#{table}' AND column_name = '#{column}'
94 + """
95 +
96 + case repo().query(query, [], log: false) do
97 + {:ok, %{rows: [[data_type]]}} -> data_type
98 + _ -> nil
99 + end
71 100 end
72 101
73 102 defp prefix_str(nil), do: ""
  @@ -7,6 +7,8 @@ defmodule PhoenixKit.ThemeConfig do
7 7 theme requires changing this module and the shared CSS asset only.
8 8 """
9 9
10 + use Gettext, backend: PhoenixKitWeb.Gettext
11 +
10 12 @default_html_theme "phoenix-light"
11 13
12 14 @custom_theme_variables %{
  @@ -99,6 +101,65 @@ defmodule PhoenixKit.ThemeConfig do
99 101 "silk" => "Silk"
100 102 }
101 103
104 + @doc """
105 + Returns the translated, user-facing label for a theme key.
106 +
107 + `@labels` is a compile-time module attribute, so it can't hold macro-expanded
108 + `gettext/1` calls directly — this function is the translated counterpart,
109 + with one literal `gettext/1` call per theme so `mix gettext.extract` can
110 + find them.
111 + """
112 + def translated_label("system"), do: gettext("System")
113 + def translated_label("phoenix-light"), do: gettext("Phoenix Light")
114 + def translated_label("phoenix-dark"), do: gettext("Phoenix Dark")
115 + def translated_label("light"), do: gettext("Light")
116 + def translated_label("dark"), do: gettext("Dark")
117 + def translated_label("cupcake"), do: gettext("Cupcake")
118 + def translated_label("bumblebee"), do: gettext("Bumblebee")
119 + def translated_label("emerald"), do: gettext("Emerald")
120 + def translated_label("corporate"), do: gettext("Corporate")
121 + def translated_label("synthwave"), do: gettext("Synthwave")
122 + def translated_label("retro"), do: gettext("Retro")
123 + def translated_label("cyberpunk"), do: gettext("Cyberpunk")
124 + def translated_label("valentine"), do: gettext("Valentine")
125 + def translated_label("halloween"), do: gettext("Halloween")
126 + def translated_label("garden"), do: gettext("Garden")
127 + def translated_label("forest"), do: gettext("Forest")
128 + def translated_label("aqua"), do: gettext("Aqua")
129 + def translated_label("lofi"), do: gettext("Lo-Fi")
130 + def translated_label("pastel"), do: gettext("Pastel")
131 + def translated_label("fantasy"), do: gettext("Fantasy")
132 + def translated_label("wireframe"), do: gettext("Wireframe")
133 + def translated_label("black"), do: gettext("Black")
134 + def translated_label("luxury"), do: gettext("Luxury")
135 + def translated_label("dracula"), do: gettext("Dracula")
136 + def translated_label("cmyk"), do: gettext("CMYK")
137 + def translated_label("autumn"), do: gettext("Autumn")
138 + def translated_label("business"), do: gettext("Business")
139 + def translated_label("acid"), do: gettext("Acid")
140 + def translated_label("lemonade"), do: gettext("Lemonade")
141 + def translated_label("night"), do: gettext("Night")
142 + def translated_label("coffee"), do: gettext("Coffee")
143 + def translated_label("winter"), do: gettext("Winter")
144 + def translated_label("dim"), do: gettext("Dim")
145 + def translated_label("nord"), do: gettext("Nord")
146 + def translated_label("sunset"), do: gettext("Sunset")
147 + def translated_label("caramellatte"), do: gettext("Caramel Latte")
148 + def translated_label("abyss"), do: gettext("Abyss")
149 + def translated_label("silk"), do: gettext("Silk")
150 + def translated_label(theme), do: Map.get(@labels, theme, theme)
151 +
152 + @doc """
153 + Returns a map of theme names to translated, user-facing labels.
154 +
155 + Same shape as `label_map/0` but locale-aware — use this (not
156 + `label_map/0`) for anything rendered to a user, including client-side JS
157 + embeds built from a JSON-encoded map.
158 + """
159 + def translated_label_map do
160 + Map.new(@labels, fn {key, _label} -> {key, translated_label(key)} end)
161 + end
162 +
102 163 @dropdown_order [
103 164 "system",
104 165 "phoenix-light",
  @@ -299,7 +360,7 @@ defmodule PhoenixKit.ThemeConfig do
299 360 defp theme_to_map(theme) do
300 361 %{
301 362 value: theme,
302 - label: Map.fetch!(@labels, theme),
363 + label: translated_label(theme),
303 364 preview_theme: Map.get(@preview_themes, theme),
304 365 type: if(theme == "system", do: :system, else: :theme)
305 366 }
  @@ -449,7 +449,7 @@ defmodule PhoenixKitWeb.Components.LayoutWrapper do
449 449
450 450 // Theme configuration and controller
451 451 const themeBaseMap = <%= ThemeConfig.base_map() |> Phoenix.json_library().encode!() |> Phoenix.HTML.raw() %>;
452 - const themeLabels = <%= ThemeConfig.label_map() |> Phoenix.json_library().encode!() |> Phoenix.HTML.raw() %>;
452 + const themeLabels = <%= ThemeConfig.translated_label_map() |> Phoenix.json_library().encode!() |> Phoenix.HTML.raw() %>;
453 453
454 454 // Admin theme controller for PhoenixKit with animated slider
455 455 const adminThemeController = {
Loading more files…