Skip to content

Add admin sidebar i18n, wide-screen settings, complete Estonian catalog#531

Merged
ddon merged 8 commits into
BeamLabEU:devfrom
timujinne:dev
May 11, 2026
Merged

Add admin sidebar i18n, wide-screen settings, complete Estonian catalog#531
ddon merged 8 commits into
BeamLabEU:devfrom
timujinne:dev

Conversation

@timujinne
Copy link
Copy Markdown
Contributor

Summary

  • Wire gettext_backend to every core admin/settings Tab so the sidebar translates per locale
  • Complete the Estonian translation catalog (was 92/1143, now 1142/1143; ru already complete)
  • Widen the admin settings pages so they use the full container width on wide screens
  • Wrap previously-raw English strings in core components (badge, time_display) and on the General Settings, sitemap, and languages pages
  • Add a card-view toggle to the Custom User Fields table on /admin/settings/users

Changes by commit

  • c5fd5ba — gettext_backend on all 24 core admin tabs + card-view conversion on Custom Fields table
  • 373478f — 9 manual tab-label msgids + full Estonian translation in default.po
  • 3ea70ec — drop max-w-2xl wrappers on settings sub-pages, add grid layouts and max-w-prose
  • d867cb5 — same widescreen pass for in-core modules (sitemap, storage, referrals)
  • 1fe0ad7 — wrap badge.ex / time_display.ex strings in gettext + fix two pre-existing wrong ru translations
  • 24ceec9 — widen the top-level General Settings + wrap /admin/modules/languages
  • afcc281 — wrap sitemap settings (75 gettext calls, 56 new msgids)

Test plan

  • mix format clean
  • mix credo --strict 0 issues
  • mix compile (no warnings-as-errors)
  • mix dialyzer passes
  • Visual check of admin sidebar in ru/et locale on a parent app
  • Visual check of each /admin/settings/* page on wide screen

timujinne added 7 commits May 10, 2026 21:28
… table

Wire all 24 core Tab registrations to PhoenixKitWeb.Gettext so
Tab.localized_label/1 can translate them at render time.

Tab wiring (lib/phoenix_kit/dashboard/admin_tabs.ex):
- admin_subtab/8 helper now includes gettext_backend (covers 12 subtabs)
- All 7 inline %Tab{} literals: :admin_dashboard, :admin_users,
  :admin_activity, :admin_media, :admin_modules_page, :admin_settings,
  :admin_settings_media

Tab wiring (built-in modules):
- lib/phoenix_kit/jobs.ex (:admin_jobs)
- lib/modules/seo/seo.ex (:admin_settings_seo)
- lib/modules/sitemap/sitemap.ex (:admin_settings_sitemap)
- lib/modules/languages/languages.ex (:admin_settings_languages)
- lib/modules/maintenance/maintenance.ex (:admin_settings_maintenance)
- lib/modules/referrals/referrals.ex (:admin_settings_referrals)

Custom User Fields table (lib/phoenix_kit_web/live/settings/users.html.heex):
- Convert classic <.table_default> to toggleable mode with card/table view
- Add :toolbar_title (field count) and :toolbar_actions (Add button) slots
- Add :card_actions :let={field} slot with Toggle / Edit / Delete buttons
  using btn-sm + visible labels (more room than the cramped table cell)
- Remove now-redundant standalone Add Custom Field button below the table
- Empty-state branch and outer Enum.empty?/1 ternary unchanged

Mirrors the pattern used in
lib/phoenix_kit_web/live/settings/integrations.html.heex.

Default groups (label: nil) intentionally skip gettext_backend.

mix format clean. mix credo --strict 0 issues.
priv/gettext/default.pot + en/ru/et default.po — add 9 manually-maintained
msgids for tab labels that mix gettext.extract doesn't pick up (plain
label: "..." strings, no dgettext macro at call site):

  Activity, Authorization, Dimensions, General, Live Sessions,
  Maintenance, Manage Users, Media, Referrals

  ru translations: Активность, Авторизация, Размеры, Общие,
    Активные сессии, Обслуживание, Управление пользователями,
    Медиа, Рефералы
  et translations: Tegevus, Volitamine, Mõõtmed, Üldine,
    Aktiivsed sessioonid, Hooldus, Halda kasutajaid,
    Meedia, Soovitused

priv/gettext/et/LC_MESSAGES/default.po — fill 1042 previously-empty
msgstr entries with Estonian translations, anchored to existing 92
translated entries for terminology consistency. Glossary anchors:
Dashboard→Töölaud, Users→Kasutajad, Roles→Rollid, Permissions→Õigused,
Sessions→Sessioonid, Settings→Seaded, Save→Salvesta, Cancel→Tühista,
Delete→Kustuta, Edit→Muuda, Required→Kohustuslik, etc.

After translation et/default.po is at 1142/1143 (only the PO header
empty msgstr remains, as the format requires). mix gettext.merge clean:
1151 unchanged, 0 new, 0 removed.

Russian was already at 1142/1142 before this commit — only the 9 new
tab-label entries needed adding.
Remove inner max-w-2xl/3xl constraints from settings pages so content
uses the full container width instead of being capped at ~512-768px.

lib/phoenix_kit_web/live/settings/users.html.heex:
- drop max-w-2xl mx-auto outer wrapper (line 17)
- wrap Default Role + Default Status selects in grid grid-cols-1
  md:grid-cols-2 gap-6 so they sit side-by-side on md+ screens
- whitespace-nowrap on User Access header cell and on the User Editable
  / Admin Only badges to prevent two-word labels from wrapping inside
  the cell

lib/phoenix_kit_web/live/settings/authorization.html.heex:
- drop max-w-2xl mx-auto wrapper
- wrap Background Image (Desktop) + (Mobile) image pickers in grid
  grid-cols-1 md:grid-cols-2 gap-6

lib/phoenix_kit_web/live/settings/seo.html.heex:
- drop max-w-3xl from the card and remove the now-redundant
  flex justify-center wrapper

lib/phoenix_kit_web/live/settings/integration_form.html.heex:
- bump max-w-2xl mx-auto to max-w-4xl mx-auto on both new-mode steps
  (provider picker and setup form) — forms benefit from a moderate cap
  for readability vs. ultra-wide stretch

mix format && mix credo --strict clean.
…reens

Remove the narrow outer wrappers so module settings pages use the full
container width.

lib/modules/sitemap/web/settings.html.heex:
- drop max-w-6xl mx-auto outer wrapper (line 30) — let the page use the
  container width

lib/modules/storage/web/settings.html.heex:
- drop max-w-6xl from container wrapper (line 9) — container mx-auto
  alone is enough; the extra cap was redundant and constraining

lib/modules/referrals/web/settings.html.heex:
- drop max-w-4xl mx-auto outer wrapper (line 17)

max-w-xs caps on short numeric inputs (sampling rate, retention days,
max codes per user, etc.) are kept — those fields look weird stretched.

mix format && mix credo --strict clean.
Highest-leverage i18n fix: these two components render English status
text on every admin page that shows users, sessions, activity, email
logs, referral codes, integrations. One wrap, dozens of pages translate.

lib/phoenix_kit_web/components/core/badge.ex:
- import gettext via use Gettext, backend: PhoenixKitWeb.Gettext
- status_text/2: Inactive / Unconfirmed / Active wrapped
- code_status_text/1: Expired / Active wrapped
- category_badge/1: replace String.capitalize(@category) with
  category_text/1 helper that maps system/marketing/transactional
  to gettext'd msgids; unknown categories still fall back to
  String.capitalize/1
- enabled_badge/1: Active / Disabled wrapped

lib/phoenix_kit_web/components/core/time_display.ex:
- import gettext
- format_time_ago/1 fallback: Unknown wrapped (em-dash literal kept raw)
- format_seconds_ago/1: 4 relative-time strings wrapped with %{count}
  interpolation
- format_expiration/1: No expiration wrapped
- format_age/1: Today wrapped

lib/phoenix_kit_web/live/users/users.html.heex:280:
- one hardcoded <span>Inactive</span> in the users table wrapped

priv/gettext/{default.pot, en, ru, et}/LC_MESSAGES/default.po:
- add 8 new msgids manually (gettext.extract would mark our
  manually-maintained tab labels as obsolete, so .pot stays
  hand-curated):
  Expired, Transactional, No expiration, Today,
  %{count}s ago, %{count}m ago, %{count}h ago, %{count}d ago
- ru: 'Истёк', 'Транзакционный', 'Без срока действия', 'Сегодня',
  '%{count} с назад', '%{count} мин назад', '%{count} ч назад',
  '%{count} дн назад'
- et: 'Aegunud', 'Tehinguline', 'Aegumiseta', 'Täna',
  '%{count} s tagasi', '%{count} min tagasi', '%{count} t tagasi',
  '%{count} päeva tagasi'

Fix pre-existing wrong ru translations:
- msgid 'Inactive' was translated as 'Неактивные пользователи' (plural
  stat-card label) — wrong for the singular status-badge context that
  is its main use. Now 'Неактивен'.
- msgid 'Disabled' was 'Отключенные аккаунты' — now 'Отключено'.

mix format && mix credo --strict clean.
…text

Two related UI fixes that got missed earlier.

lib/phoenix_kit_web/live/settings.html.heex:
- The top-level /admin/settings (General Settings) page kept its
  'max-w-2xl mx-auto' inner wrapper because the earlier widescreen
  pass only swept the lib/phoenix_kit_web/live/settings/ subdir, not
  the file at lib/phoenix_kit_web/live/settings.html.heex sitting at
  the live/ root. Drop the wrapper so the page renders at full
  container width like the other settings pages.

lib/phoenix_kit_web/live/modules/languages.html.heex:
- Audit had flagged ~17 hardcoded English strings. 29 gettext calls
  now (was 2). Wrapped section headers (Summary, Enabled Languages,
  Available Languages, Language Configuration, Frontend Language
  Switcher, Switcher Settings, Live Preview, Generated Code,
  Implementation Notes), per-row chips (Default language, Default,
  Reorder, Done), feature toggles (Show Flags, Show Names, Native
  Names, Go to Home, Hide Current), and empty-state copy. Interpolated
  bullets with embedded code blocks are left raw on purpose — they
  need ngettext / structural rewrites that don't belong in this pass.

priv/gettext/{default.pot, en, ru, et}/LC_MESSAGES/default.po:
- 21 new msgids appended manually with #: source refs into
  lib/phoenix_kit_web/live/modules/languages.html.heex; en falls back
  to msgid; ru and et filled inline with translations.
- Also fix the pre-existing wrong ru translation of msgid 'Disable'
  (was 'Отключенные аккаунты' — Disabled accounts plural label —
  now 'Отключить', the imperative verb form that matches its actual
  use as a button label.
lib/modules/sitemap/web/settings.html.heex:
- 75 gettext() calls (was 0). Wrapped every user-facing English string:
  section headers, status pills, change-frequency dropdown options
  (always/hourly/daily/weekly/monthly/yearly/never), priority labels,
  table column headers, form labels and placeholders, action buttons
  (Generate, Regenerate, Preview, Download, Reset, Refresh), modal
  titles, alert messages, info-panel hints.

  XML/sitemap literals (<urlset>, <url>, <loc>, ...) and sample
  output kept raw — those are technical markers, not UI copy.

priv/gettext/{default.pot, en, ru, et}/LC_MESSAGES/default.po:
- 56 new msgids appended manually with #: source refs (Enabled,
  Disabled, Actions, Site URL, Quick Actions, Close reused from the
  existing catalog).
- en uses fallback; ru and et translations filled inline.
Copy link
Copy Markdown
Contributor Author

@timujinne timujinne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #531 Review — Add admin sidebar i18n, wide-screen settings, complete Estonian catalog

Reviewer: CLAUDE (Opus 4.7)
Verdict: REQUEST_CHANGES — one HIGH-severity user-visible i18n bug + one MEDIUM PO maintenance bug.
Scope: 7 commits, 23 files, +3,967 / -2,587. Wires gettext_backend on 24 core admin tabs, completes the Estonian catalog (1142/1143), widens 8 settings pages, adds a card-view toggle to the Custom Fields table, and wraps core badge.ex / time_display.ex / General Settings / sitemap / languages strings in gettext.

Summary by commit

Commit Subject Notes
c5fd5ba Tab gettext_backend + card-view Custom Fields OK with caveats (see #3, #4)
373478f Tab msgids + ET catalog completion OK
3ea70ec Widen settings pages OK (see #6)
d867cb5 Widen module settings OK
1fe0ad7 Wrap badge.ex + time_display.ex HIGH bug (see #1); also fixes pre-existing RU mistranslations
24ceec9 Widen General Settings + wrap /admin/modules/languages MEDIUM PO bug (see #2)
afcc281 Wrap sitemap settings (75 calls) MEDIUM PO bug (see #2)

BUG — HIGH

1. "Active" badge in users table left untranslated while adjacent "Inactive" is wrapped

lib/phoenix_kit_web/live/users/users.html.heex:277-282 after this PR:

<%= if user.is_active do %>
  <span class="badge badge-outline badge-xs h-auto">Active</span>
<% else %>
  <span class="badge badge-error badge-xs h-auto">
    {gettext("Inactive")}
  </span>
<% end %>

The diff explicitly wraps "Inactive" (the false branch) but leaves "Active" (the true branch) raw in the same if/else. Result on a non-English locale: the badge will read translated "Mitteaktiivne / Неактивен" for inactive users, but plain English "Active" for active users on the same page. This is in the main /admin/users listing — a heavily-trafficked admin page.

Fix: wrap to {gettext("Active")}. The msgid "Active" already exists in all catalogs (Aktiivne, Активен, etc. — verified in the ET diff at line where existing Active was translated to Aktiivne), so no PO file changes required.


BUG — MEDIUM

2. 73 of 94 new PO entries lack #: source references (pot/en/ru/et default.po)

The two later batches added in commits 24ceec9 ("Languages" — 21 msgids) and afcc281 ("Sitemap" — 52 msgids) append entries to the .pot and .po files without #: source/file.heex:line lines, e.g.:

msgid "Summary"
msgstr "Сводка"

msgid "Languages Enabled"
msgstr "Включенные языки"
...

By contrast, the earlier batch in commit 373478f (9 tab-label msgids) and the badge/time batch in 1fe0ad7 (8 msgids) do include refs:

#: lib/phoenix_kit/dashboard/admin_tabs.ex:148
#, elixir-autogen, elixir-format
msgid "Activity"
msgstr "Активность"

The afcc281 commit message claims: "56 new msgids appended manually with #: source refs" — but the diff shows they were appended without refs. Same applies to the 24ceec9 commit message claim of "21 new msgids appended manually with #: source refs".

Impact: when someone next runs mix gettext.extract --merge against the codebase (which extracts these strings from the HEEX templates — they all use gettext(...)), gettext-merge will either:

  • Add the missing #: refs (in which case the changes will then need re-committing), OR
  • Mark the existing entries as duplicates of the freshly-extracted entries and emit warnings.

Either way the PO files are not in a "clean post-extract" state, which the PR's test plan implies they should be (mix gettext.merge clean: 1151 unchanged, 0 new, 0 removed was claimed for ET).

Fix: add the #: ref lines back, e.g.:

#: lib/phoenix_kit_web/live/modules/languages.html.heex:23
#, elixir-autogen, elixir-format
msgid "Summary"
msgstr "Сводка"

(Easiest path: run mix gettext.extract --merge once, then re-translate the freshly-blanked ru/et entries — they'll all match the existing translations in this PR by msgid.)

Note the same affects all four files: priv/gettext/default.pot, priv/gettext/en/LC_MESSAGES/default.po, priv/gettext/ru/LC_MESSAGES/default.po, priv/gettext/et/LC_MESSAGES/default.po.


IMPROVEMENT — MEDIUM

3. Custom Fields card-mode label-format inconsistency

lib/phoenix_kit_web/live/settings/users.html.heex:367-389 card_fields callback:

[
  %{label: gettext("Key:"), value: field["key"]},
  %{label: gettext("Type"), value: field["type"]},
  %{label: gettext("Required"), value: ...},
  %{label: gettext("Status"), value: ...},
  %{label: gettext("User Access"), value: ...}
]

Key: has a trailing colon, the other four do not. In card mode this renders as "Key: my_field / Type my_field / Required Yes / Status Enabled / User Access User Editable" — visually uneven.

Fix: either drop the colon on "Key:" (preferred, matches other labels and avoids a new msgid lookup if "Key" isn't already in the catalog) or add colons to the other four (worse, requires four new msgids).

4. Table-mode action buttons lost their mobile text fallback labels

Diff at users.html.heex:454-472 (table-mode action buttons) removes:

- <.icon name="hero-eye" class="w-3 h-3 hidden sm:inline" />
- <span class="sm:hidden whitespace-nowrap">{gettext("Disable")}</span>
+ <.icon name="hero-eye" class="w-3 h-3" />

Before: mobile users (< sm) saw a text label; desktop saw an icon with data-tip tooltip.
After: all viewports see icon-only with data-tip. On touchscreens, tooltip (daisyUI hover-only) does not appear, so mobile users see a row of three indistinguishable ghost-icon buttons.

The PR introduces the card-view toggle as the intended mobile UX (card_actions slot has visible labels), so a user can switch — but the table view remains the default and unfriendly on touch. Either:

  • (a) Restore the sm:hidden text spans inside the table cells, OR
  • (b) Auto-default the table to card view on small viewports via the toggleable component's responsive behavior (if supported).

Same icon-only regression in the table-mode Edit and Delete buttons.

5. format_expiration/1 still renders English month names

lib/phoenix_kit_web/components/core/time_display.ex:208:

defp format_expiration(date) do
  Calendar.strftime(date, "%B %d, %Y")
end

The PR wrapped the nil branch (gettext("No expiration")) but left the date-formatting branch hard-coded to a US-English month-name format. On et/ru locales this will render e.g. "May 11, 2026" instead of "11.05.2026" or "11 мая 2026". Pre-existing, out of scope for this PR's stated goal — but worth a follow-up issue, since the file has now been touched for i18n and a future reader will assume it's fully localized.


NITPICK

6. Removed flex justify-center wrapper in seo.html.heex

lib/phoenix_kit_web/live/settings/seo.html.heex drops both max-w-3xl and the flex justify-center wrapper. The card now spans full width. The page contains only one toggle, so a full-width card has a lot of empty real-estate on wide screens. Consider keeping a soft cap (e.g., max-w-4xl mx-auto like the integration form bumps to) for aesthetic purposes. Minor visual call.

7. Russian translation collapse

Two distinct msgids collapse to the same RU translation:

msgid ru msgstr
Languages Enabled Включенные языки
Enabled Languages Включенные языки

Same in ET: both → Lubatud keeled / variations. The English source distinguishes "Languages Enabled" (stat-card noun) from "Enabled Languages" (section heading); the translations don't. Acceptable but reduces editorial nuance. Consider Количество включённых языков for the stat label vs. Включённые языки for the section.

8. ET %{count}h ago%{count} t tagasi uses a single-letter "t"

Modern Estonian UIs usually use h (hour) or the full word tundi. A bare t reads as "t" the letter, not "tunni". Compare with %{count} min tagasi which uses the conventional abbreviation. Suggest %{count} h tagasi for consistency.

9. "%{count}s/m/h/d ago" are plain gettext, not ngettext

For ru/et these are grammatically odd at count = 1 ("1 päeva tagasi" reads as "1 day-genitive ago"; should be "1 päev tagasi" for the singular). The commit message explicitly notes this is deferred: "need ngettext / structural rewrites that don't belong in this pass." Acceptable scope decision.

10. Hardcoded confirm() text remains English

onclick="return confirm('Are you sure you want to delete this field?')" in both the table-mode and card-mode Delete buttons in users.html.heex. Pre-existing, but two clean spots within the file being touched. A gettext interpolation here would close out the page's i18n coverage.

11. Commit-message claim mismatch

The afcc281 and 24ceec9 commit messages assert that msgids were "appended manually with #: source refs". The diffs show otherwise (see #2). Update the commit body or re-commit with refs to keep the audit trail honest.


What's good

  • Tab gettext-backend wiring is uniform and complete — the helper-function change in admin_subtab/8 covers 12 subtabs; the 7 inline %Tab{} literals are individually updated; 6 built-in modules (jobs, seo, sitemap, languages, maintenance, referrals) are all wired. Consistent pattern.
  • The two pre-existing wrong RU translations were caught and fixed in passing ("Inactive" was "Неактивные пользователи" plural-stat-card text used in singular-badge context; "Disabled" was "Отключенные аккаунты" plural-noun used as a button label). Both now correct: "Неактивен", "Отключено". Plus "Disable" fixed from "Отключенные аккаунты" to imperative "Отключить".
  • HEEX hygiene clean<%!-- --%> comments throughout, no HTML comment leakage, all tags balanced after the structural moves in seo.html.heex and settings.html.heex.
  • Widescreen pass is targetedmax-w-xs caps on short numeric inputs (sample rate, retention, etc.) deliberately preserved per commit message. Verified no max-w-xs removals in the sitemap diff. Grid layouts (grid-cols-1 md:grid-cols-2 gap-6) added where two short selects/inputs sit side-by-side. Reasonable.
  • max-w-prose added to inline alert-info / alert-warning panels in users.html.heex — keeps explanatory copy readable instead of stretching across the full container. Nice touch.
  • max-w-4xl instead of removing the cap entirely on the integration form steps — sensible compromise. Same pattern would benefit seo.html.heex (see #6).
  • Custom Fields table → toggleable card-view mirrors the existing pattern from integrations.html.heex. The :toolbar_title / :toolbar_actions / :card_actions slot usage is conventional. The standalone "Add Custom Field" button beneath the table is correctly retired in favor of the toolbar variant.
  • ET catalog completion is solid — sampled translations (Salvesta, Tühista, Kustuta, Muuda, Kohustuslik, Lubatud, Tehinguline, etc.) are accurate, glossary anchors are preserved, placeholders (%{count}, %{provider}, %{role_name}, %{language}, etc.) preserved across all sampled entries — no placeholder drops detected.
  • Pre-existing <urlset> markers in sitemap copy are preserved as literal text in both ru and et translations — the HEEX {...} interpolation will HTML-escape them at render time, so they'll display as &lt;urlset&gt; to users. Correct.

Test plan additions (suggested)

The PR test plan flags [ ] Visual check of admin sidebar in ru/et locale and [ ] Visual check of each /admin/settings/* page on wide screen as still TODO. To these, add:

  • Visit /admin/users on ru/et and confirm both Active and Inactive badges translate (catches #1).
  • Run mix gettext.extract --merge on the branch; verify it reports 0 new, 0 removed (will surface #2 if unresolved).
  • Toggle /admin/settings/users Custom Fields card view on mobile; verify all four action buttons render with visible labels (regression check for #4).
  • Verify card view on a 320px viewport doesn't truncate User Editable / Admin Only (the whitespace-nowrap keeps them on one line in the table; need to confirm card mode handles this too).

Verdict

REQUEST_CHANGES — issue #1 is a one-line visible-string fix; issue #2 needs a 73-entry catalog touch-up (or single mix gettext.extract --merge followed by re-paste of the new ru/et translations). Once those land, the rest is solid and the PR is ready.

Adjacent 'Inactive' badge in the same if/else block was already wrapped
in gettext; 'Active' was left raw. Visible English on every non-en
/admin/users row showing an active user.

Reuses existing 'Active' msgid in default.pot (already translated in
ru/et). No new msgid needed.
@ddon ddon merged commit 3187d80 into BeamLabEU:dev May 11, 2026
timujinne added a commit to timujinne/phoenix_kit that referenced this pull request May 11, 2026
Resolved conflicts in priv/gettext/{et,ru}/LC_MESSAGES/default.po by taking
upstream/dev side. Rationale:

et:
- Sessions: Sessioonid (consistent with "Aktiivsed sessioonid")
- Settings: Seaded (consistent with rest of file)
- Health:   Seisund (more semantic)
- Big block: upstream's gettext.extract already covered all admin_tabs.ex
  msgids from PRs BeamLabEU#530/BeamLabEU#531 with matching translations; the orphan "Home"
  entry added in this branch had no source reference (admin_dashboard
  label is "Dashboard", not "Home") and was dropped.

ru:
- Permissions: Права (consistent with "Права для", "Права обновлены")
- Big block: same reasoning as et.

PR's gettext_backend wiring in admin_tabs.ex (8 tabs), registry.ex (2
tabs), and jobs.ex (1 tab) preserved by the merge.
timujinne added a commit to timujinne/phoenix_kit that referenced this pull request May 17, 2026
- Execution plan for ecommerce admin UI i18n (ru/et)
- Phase 3 two-stage review report (spec + quality)
- Phase 4 live verification report (Decor 3D Print)
- fuzzy_fix_list working notes
- Carry over PR BeamLabEU#531 original review doc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants