PhoenixKitCatalogue.Web.Settings (PhoenixKitCatalogue v0.44.2)

Copy Markdown View Source

Read/write helpers for the catalogue's operational settings — the AI-translation sweep the PhoenixKitCatalogue.Workers.TranslationSweepWorker reads on every tick, and the admin-list preferences the web layer reads at render time.

PhoenixKitCatalogue.Web.SettingsLive (Settings → Catalogue) is the page that writes them. It arrived late: the sweep keys shipped with no UI at all, so turning the sweep on was an operator call into update_* and nobody could see it was off (boss via Max, 2026-09-21).

Kept as a thin module rather than folding the keys into PhoenixKitCatalogue itself: the worker and the templates only ever read, the settings page only ever writes, and neither needs the other's concerns.

keytypedefault
catalogue_row_context_menu_enabledbooltrue
catalogue_item_seo_fields_visibleboolfalse
catalogue_translation_sweep_enabledboolfalse
catalogue_translation_sweep_interval_minutesint60
catalogue_translation_sweep_langsjsonsee below
catalogue_translation_sweep_max_per_runint200

catalogue_translation_sweep_langs defaults to every enabled language except the primary one — computed at read time (not stored) so a language toggled on/off in the languages module is picked up without a settings write. Stored as %{"codes" => [...]} rather than a bare JSON array: PhoenixKit.Settings's value_json column is an Ecto :map, which rejects a top-level list.

Summary

Functions

Does a right-click on an admin list row open that row's menu at the pointer?

Does the item form show its URL slug, SEO title and SEO description?

Is the automatic sweep enabled?

Minutes between sweep ticks.

Target languages the sweep considers. Defaults to every enabled language except the primary one when nothing is stored; a stored list is intersected with the enabled languages, so a language disabled after the setting was written stops receiving sweep jobs — the same check the Translations page applies to a manual Translate.

Maximum number of translation jobs one sweep tick enqueues.

Turns the right-click row menu on or off.

Shows or hides the item form's slug and SEO fields.

Toggles the automatic sweep. Flipping it ON seeds the sweep's self-rescheduling chain (TranslationSweepWorker.ensure_scheduled/0) — the boot-time bootstrap only seeds it when already enabled (additive for hosts that never opt in), so this write is what starts the chain the first time an operator turns the sweep on.

Sets the sweep interval, in minutes.

Sets the sweep's target languages.

Sets the per-tick enqueue cap.

Functions

context_menu_enabled?()

@spec context_menu_enabled?() :: boolean()

Does a right-click on an admin list row open that row's menu at the pointer?

Default true — the gesture is what a desktop user expects of a list, and a row that offers nothing on right-click reads as unfinished. Off leaves the browser's own menu in place everywhere (Copy, Inspect, Open in new tab), which is the reason to want it off.

Read at render time by the row components, which simply omit the data-row-menu-context attribute when it is false — so turning it off removes the wiring rather than disabling it in the browser.

seo_fields_visible?()

@spec seo_fields_visible?() :: boolean()

Does the item form show its URL slug, SEO title and SEO description?

Default false: the current client has no use for them and they crowd the form (boss via Max, 2026-09-21: "hidden for now"). Hidden is not gone — the form still carries their stored values, so a save keeps them, and turning this on brings the fields back with their contents.

sweep_enabled?()

@spec sweep_enabled?() :: boolean()

Is the automatic sweep enabled?

sweep_interval_minutes()

@spec sweep_interval_minutes() :: pos_integer()

Minutes between sweep ticks.

sweep_langs()

@spec sweep_langs() :: [String.t()]

Target languages the sweep considers. Defaults to every enabled language except the primary one when nothing is stored; a stored list is intersected with the enabled languages, so a language disabled after the setting was written stops receiving sweep jobs — the same check the Translations page applies to a manual Translate.

sweep_max_per_run()

@spec sweep_max_per_run() :: pos_integer()

Maximum number of translation jobs one sweep tick enqueues.

update_context_menu_enabled(enabled?)

@spec update_context_menu_enabled(boolean()) :: {:ok, struct()} | {:error, term()}

Turns the right-click row menu on or off.

update_seo_fields_visible(visible?)

@spec update_seo_fields_visible(boolean()) :: {:ok, struct()} | {:error, term()}

Shows or hides the item form's slug and SEO fields.

update_sweep_enabled(enabled?)

@spec update_sweep_enabled(boolean()) :: {:ok, struct()} | {:error, term()}

Toggles the automatic sweep. Flipping it ON seeds the sweep's self-rescheduling chain (TranslationSweepWorker.ensure_scheduled/0) — the boot-time bootstrap only seeds it when already enabled (additive for hosts that never opt in), so this write is what starts the chain the first time an operator turns the sweep on.

update_sweep_interval_minutes(minutes)

@spec update_sweep_interval_minutes(pos_integer()) ::
  {:ok, struct()} | {:error, term()}

Sets the sweep interval, in minutes.

update_sweep_langs(langs)

@spec update_sweep_langs([String.t()]) :: {:ok, struct()} | {:error, term()}

Sets the sweep's target languages.

update_sweep_max_per_run(n)

@spec update_sweep_max_per_run(pos_integer()) :: {:ok, struct()} | {:error, term()}

Sets the per-tick enqueue cap.