Packages
backpex
0.24.1
0.24.1
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.3
0.18.2
0.18.1
0.18.0
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.3
0.16.2
0.16.1
0.16.0
0.15.3
0.15.2
0.15.1
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.0
0.5.1
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.0
0.1.1
Highly customizable administration panel for Phoenix LiveView applications.
Current section
Files
Jump to
Current section
Files
mix.exs
defmodule Backpex.MixProject do
use Mix.Project
@version "0.24.1"
@source_url "https://github.com/naymspace/backpex"
@changelog_url "https://github.com/naymspace/backpex/releases"
@website_url "https://backpex.live"
# The integration tests in `integration_test` run the LiveResources of a test app against PostgreSQL and in a browser.
# Their dependencies need Elixir 1.19, so older versions of Elixir only run the unit tests in `test`.
# `INTEGRATION_TESTS=false` leaves them out on any version, with their dependencies and support code. CI runs them
# once, on the latest Elixir, and sets it for the other versions.
@integration_tests Version.match?(System.version(), ">= 1.19.0") and System.get_env("INTEGRATION_TESTS") != "false"
def project do
[
app: :backpex,
version: @version,
elixir: "~> 1.16",
elixirc_paths: elixirc_paths(Mix.env()),
test_paths: test_paths(),
compilers: [:phoenix_live_view] ++ Mix.compilers(),
start_permanent: Mix.env() == :prod,
deps: deps(),
aliases: aliases(),
gettext: gettext(),
test_coverage: test_coverage(),
usage_rules: usage_rules(),
# Hex.pm
hex: [cooldown: "3d"],
package: package(),
description: "Highly customizable administration panel for Phoenix LiveView applications.",
# Docs
name: "Backpex",
source_url: @source_url,
homepage_url: @website_url,
docs: docs()
]
end
defp test_paths do
if @integration_tests, do: ["test", "integration_test"], else: ["test"]
end
defp elixirc_paths(:test) do
if @integration_tests, do: ["lib", "test/support", "integration_test/support"], else: ["lib", "test/support"]
end
defp elixirc_paths(_), do: ["lib"]
# The threshold is the floor of the merged coverage of the unit and browser tests in CI. Raise it when coverage grows.
defp test_coverage do
[
summary: [threshold: 90],
ignore_modules: [~r/^Backpex\.(Test\.|ConnCase|DataCase|E2ECase)/]
]
end
# `mix usage_rules.sync` links the rules of these packages at the end of CODING_STANDARDS.md. It only sees dev
# dependencies, so CODING_STANDARDS.md links the rules of the test-only `phoenix_test_playwright` by hand.
defp usage_rules do
[
file: "CODING_STANDARDS.md",
usage_rules: [
{:phoenix, link: :markdown, except: [:elixir]},
{:igniter, link: :markdown},
{:sobelow, link: :markdown}
]
]
end
defp deps do
[
# development
{:ex_doc, "~> 0.40", only: [:dev, :test], runtime: false},
{:makeup_eex, "~> 2.0", only: [:dev, :test], runtime: false},
{:makeup_syntect, "~> 0.1.3", only: [:dev, :test], runtime: false},
{:credo, ">= 0.0.0", only: [:dev, :test], runtime: false},
{:mix_audit, "~> 2.0", only: [:dev, :test], runtime: false},
{:sobelow, ">= 0.0.0", only: [:dev, :test]},
{:lazy_html, ">= 0.0.0", only: :test},
{:phx_new, "~> 1.8", only: :test, runtime: false},
{:esbuild, "~> 0.10", only: :dev},
{:quokka, "~> 2.9", only: [:dev, :test], runtime: false},
{:usage_rules, "~> 1.3", only: [:dev]},
# core
{:nimble_options, "~> 1.1"},
{:gettext, ">= 0.26.0"},
# phoenix
{:phoenix, ">= 1.7.6 and < 1.9.0"},
{:phoenix_html, "~> 4.1"},
{:phoenix_html_helpers, "~> 1.0"},
{:phoenix_live_view, "~> 1.1"},
# adapters
{:ecto, "~> 3.6"},
{:postgrex, ">= 0.0.0"},
{:phoenix_ecto, "~> 4.4"},
# generators
{:igniter, "~> 0.8", optional: true},
{:igniter_js, "~> 0.5", optional: true}
] ++ integration_test_deps()
end
defp integration_test_deps do
if @integration_tests do
[
{:ecto_sql, "~> 3.10", only: :test},
{:bandit, "~> 1.14", only: :test},
{:phoenix_test, "~> 0.13.0", only: :test, runtime: false},
{:phoenix_test_playwright, "~> 0.19.0", only: :test, runtime: false},
{:a11y_audit, "~> 0.5.0", only: :test},
{:ex_machina, "~> 2.8", only: :test},
{:money, "~> 1.14", only: :test}
]
else
[]
end
end
defp package do
[
files: ~w(assets/js package.json lib priv .formatter.exs mix.exs README.md LICENSE.md usage-rules.md),
maintainers: ["Florian Arens", "Phil-Bastian Berndt", "Simon Hansen"],
licenses: ["MIT"],
links: %{
Changelog: @changelog_url,
GitHub: @source_url,
Website: @website_url
}
]
end
defp aliases do
[
lint: lint(),
ci: ci(),
"assets.build": [
"esbuild module",
"esbuild main"
],
"assets.watch": "esbuild module --watch",
"assets.check": ["assets.build", "cmd ./scripts/check_assets.sh"]
]
end
# Without the integration tests, the lock still holds their dependencies, which `deps.unlock --unused` would remove.
defp lint do
unlock_unused = if @integration_tests, do: ["deps.unlock --unused"], else: []
["compile --warnings-as-errors"] ++ unlock_unused ++ ["format", "credo", "test"]
end
# The checks of the CI job `test` that `lint` leaves out, cheap ones first. `assets.check` needs `esbuild`, which only
# the `dev` environment has, so it runs in a `dev` subprocess; the first run compiles the dependencies for `dev`.
defp ci do
[
"lint",
"cmd bun run lint:standard",
"cmd bun run test:js",
"gettext.extract --check-up-to-date",
"sobelow --config",
"docs --warnings-as-errors",
"cmd env MIX_ENV=dev mix assets.check"
]
end
defp docs do
[
main: "readme",
logo: "priv/static/images/logo.svg",
extras: extras(),
extra_section: "GUIDES",
groups_for_extras: groups_for_extras(),
groups_for_modules: groups_for_modules(),
groups_for_docs: [
Components: &(&1[:type] == :component)
],
source_ref: @version,
source_url: @source_url,
before_closing_head_tag: fn type ->
if type == :html do
"""
<script>
if (location.hostname === "hexdocs.pm") {
const script = document.createElement("script");
script.src = "https://plausible.io/js/script.js";
script.defer = true;
script.setAttribute("data-domain", "hexdocs.pm/backpex");
document.head.appendChild(script);
}
</script>
"""
end
end,
skip_code_autolink_to: [
"Ecto.Query.DynamicExpr",
"Backpex.Router.cookie_path/1"
]
]
end
defp extras do
[
{"README.md", title: "Introduction"},
# About
"guides/about/what-is-backpex.md",
"guides/about/why-we-built-backpex.md",
"guides/about/contribute-to-backpex.md",
# Get Started
"guides/get_started/installation.md",
# AI Assisted Development
"guides/ai_development/ai-development.md",
# Live Resource
"guides/live_resource/what-is-a-live-resource.md",
"guides/live_resource/templates.md",
"guides/live_resource/item-query.md",
"guides/live_resource/ordering.md",
"guides/live_resource/pagination.md",
"guides/live_resource/on_mount-hook.md",
"guides/live_resource/hooks.md",
"guides/live_resource/navigation.md",
"guides/live_resource/panels.md",
"guides/live_resource/metrics.md",
"guides/live_resource/fluid-layout.md",
"guides/live_resource/listen-to-pubsub-events.md",
"guides/live_resource/additional-classes-for-index-table-rows.md",
"guides/live_resource/user-preferences.md",
"guides/live_resource/context-assigns.md",
# Fields
"guides/fields/what-is-a-field.md",
"guides/fields/custom-fields.md",
"guides/fields/alignment.md",
"guides/fields/visibility.md",
"guides/fields/defaults.md",
"guides/fields/readonly.md",
"guides/fields/custom-alias.md",
"guides/fields/placeholder.md",
"guides/fields/debounce-and-throttle.md",
"guides/fields/index-edit.md",
"guides/fields/error-customization.md",
"guides/fields/computed-fields.md",
# Filter
"guides/filter/what-is-a-filter.md",
"guides/filter/how-to-add-a-filter.md",
"guides/filter/filter-presets.md",
"guides/filter/filter-validation.md",
"guides/filter/custom-filter.md",
"guides/filter/visibility-and-authorization.md",
# Actions
"guides/actions/item-actions.md",
"guides/actions/resource-actions.md",
# Authorization
"guides/authorization/live-resource-authorization.md",
"guides/authorization/field-authorization.md",
# Searching
"guides/searching/basic-search.md",
"guides/searching/full-text-search.md",
# Translations
"guides/translations/translations.md",
# Upgrade Guides
"guides/upgrading/v0.24.md",
"guides/upgrading/v0.23.md",
"guides/upgrading/v0.22.md",
"guides/upgrading/v0.21.md",
"guides/upgrading/v0.20.md",
"guides/upgrading/v0.19.md",
"guides/upgrading/v0.18.md",
"guides/upgrading/v0.17.md",
"guides/upgrading/v0.16.md",
"guides/upgrading/v0.15.md",
"guides/upgrading/v0.14.md",
"guides/upgrading/v0.13.md",
"guides/upgrading/v0.12.md",
"guides/upgrading/v0.11.md",
"guides/upgrading/v0.10.md",
"guides/upgrading/v0.9.md",
"guides/upgrading/v0.8.md",
"guides/upgrading/v0.7.md",
"guides/upgrading/v0.6.md",
"guides/upgrading/v0.5.md",
"guides/upgrading/v0.3.md",
"guides/upgrading/v0.2.md"
]
end
defp groups_for_extras do
[
Introduction: ~r/README/,
About: ~r/guides\/about\/.?/,
"Get Started": ~r/guides\/get_started\/.?/,
"AI Assisted Development": ~r/guides\/ai_development\/.?/,
"Live Resource": ~r/guides\/live_resource\/.?/,
Fields: ~r/guides\/fields\/.?/,
Filter: ~r/guides\/filter\/.?/,
Actions: ~r/guides\/actions\/.?/,
Authorization: ~r/guides\/authorization\/.?/,
Searching: ~r/guides\/searching\/.?/,
Translations: ~r/guides\/translations\/.?/,
"Upgrade Guides": ~r{guides/upgrading/.*}
]
end
defp groups_for_modules do
[
Adapters: ~r/Backpex\.Adapter.?/,
Components: ~r/Backpex\.HTML.?/,
Fields: ~r/Backpex\.Field.?/,
Actions: ~r/Backpex\.(ItemAction|ResourceAction).?/,
Filters: ~r/Backpex\.Filter.?/,
Metrics: ~r/Backpex\.Metric.?/,
Preferences: ~r/Backpex\.Preferences.*/,
Testing: ~r/Backpex\.Testing/
]
end
defp gettext do
[
write_reference_comments: false,
sort_by_msgid: :case_insensitive
]
end
end