defmodule AshHqWeb.Pages.Home do @moduledoc "The home page" use Phoenix.LiveComponent alias AshHqWeb.Components.{CalloutText, CodeExample, Feature} import AshHqWeb.Components.CodeExample, only: [to_code: 1] def render(assigns) do ~H"""
Model your domain,
Build with a tool-chain.
<:description> building blocks that scale with the complexity of your application. <:icon> <:description> Easily create rich, customizable, full featured backed by Absinthe. <:icon> <:description> Create JSON:API spec compliant apis in not days. <:icon> alt-curly <:description> Effortless authentication with and out of the box. <:icon> <:description> A thriving community of people to <:icon> <:description> Add row and field level policies to to data. <:icon> <:description> for splitting your application by tenant. <:icon> <:description> Postgres, Ets, Mnesia, CSV and <:icon> <:description> A you can drop right into your application. <:icon> <:description> A suite of tools for you to extensions and DSLs. <:icon> <:description> Custom tracers and rich telemetry events allow you to export <:icon> <:description> Works great with and all the other in the Elixir ecosystem. <:icon>

Service delivery partner

specializes in providing custom solutions that ensure the success of your Ash Framework projects. Leveraging extensive knowledge of both Ash Framework and the broader Elixir ecosystem, our team is well-equipped to craft personalized projects, implement innovative features, or optimize your existing codebases. Reach out to learn more about how our tailored solutions can make your project excel.

Backed by our
<.testimonial text="The ease of defining our domain model and configuring Ash to generate a powerful GraphQL API has been a game-changer. What used to be complex and time-consuming has become simplicity itself." author="Alan Heywood" title="CTO, HereTask" /> <.testimonial text="Through its declarative extensibility, Ash delivers more than you'd expect: Powerful APIs with filtering/sorting/pagination/calculations/aggregations, pub/sub, authorization, rich introspection, GraphQL... It's what empowers this solo developer to build an ambitious ERP!" author="Frank Dugan III" title="System Specialist, SunnyCor Inc." class_overrides="md:-mt-20" /> <.testimonial text="I’m constantly blown away with the quality of work and support the Ash community has put into this project. It’s gotten to the point that I can’t imagine starting a new Elixir project that doesn’t use Ash." author="Brett Kolodny" title="Full stack engineer, MEW" class_overrides="md:-mt-4" /> <.testimonial text="Ash is an incredibly powerful idea that gives Alembic a massive competitive advantage. It empowers us to build wildly ambitious applications for our clients with tiny teams, while consistently delivering the high level of quality that our customers have come to expect." author="Josh Price" title="Technical Director, Alembic" class_overrides="md:-mt-20" /> <.testimonial text="Ash Framework enabled us to build a robust platform for delivering financial services using bitcoin. Ash proved itself to our team by handling innovative use cases with ease and it continues to evolve ahead of our growing list of needs." author="Yousef Janajri" title="CTO & Co-Founder, Coinbits" class_overrides="md:-mt-4" /> <.testimonial text="The more I’ve used Ash, the more blown away I am by how much I get out of it – and how little boilerplate I have to write. I’m yet to encounter a situation where I would need to fight the “Ash way” of doing things, but the framework still allows me to choose how I build my software." author="Juha Lehtonen" title="Senior Software Developer" class_overrides="md:-mt-20" />

It wouldn't be possible without our amazing community.
and counting!

<%= for %{login: login, avatar_url: avatar_url, html_url: html_url} <- @contributors do %> {login} <% end %>
Become a contributor
<.live_component module={CodeExample} id="define-a-resource" class="grow w-full lg:w-min max-w-[1000px]" code={post_example()} title="Define a resource" />
<.live_component module={CodeExample} class="w-full" collapsible id="use-it-programmatically" code={changeset_example()} title="Use it programmatically" /> <.live_component module={CodeExample} class="w-auto" collapsible id="graphql-interface" code={graphql_example()} title="Add a GraphQL interface" /> <.live_component module={CodeExample} class="w-auto" collapsible start_collapsed id="authorization-policies" code={policies_example()} title="Add authorization policies" /> <.live_component module={CodeExample} class="w-auto" collapsible start_collapsed id="aggregates" code={aggregate_example()} title="Define aggregates and calculations" /> <.live_component module={CodeExample} class="w-auto" collapsible start_collapsed id="pubsub" code={notifier_example()} title="Broadcast changes over Phoenix PubSub" /> <.live_component module={CodeExample} class="w-atuo" collapsible start_collapsed id="live-view" code={live_view_example()} title="Use it with Phoenix LiveView" />
""" end attr(:class_overrides, :string, default: "") attr :title, :string attr :author, :string attr :text, :string def testimonial(assigns) do ~H"""

"<%= @text %>"

<%= @author %>

<%= @title %>

""" end def mount(socket) do contributors = AshHq.Github.Contributor.in_order!() {:ok, assign( socket, signed_up: false, contributor_count: Enum.count(contributors), contributors: contributors, email_form: AshPhoenix.Form.for_create(AshHq.MailingList.Email, :create, api: AshHq.MailingList, upsert?: true, upsert_identity: :unique_email ) )} end def handle_event("toggle-theme", _, socket) do if socket.assigns.theme == :default do {:noreply, assign(socket, :theme, :dark)} else {:noreply, assign(socket, :theme, :default)} end end def handle_event("validate_email_form", %{"form" => form}, socket) do {:noreply, assign(socket, email_form: AshPhoenix.Form.validate(socket.assigns.email_form, form))} end def handle_event("submit_email_form", _, socket) do case AshPhoenix.Form.submit(socket.assigns.email_form) do {:ok, _} -> {:noreply, assign(socket, :signed_up, true)} {:error, form} -> {:noreply, assign(socket, email_form: form)} end end @changeset_example """ post = Example.Post.create!(%{ text: "Declarative programming is fun!" }) Example.Post.react!(post, %{type: :like}) Example.Post |> Ash.Query.filter(likes > 10) |> Ash.Query.sort(likes: :desc) |> Ash.read!() """ |> to_code() defp changeset_example do @changeset_example end @live_view_example """ def mount(_params, _session, socket) do form = AshPhoenix.Form.for_create(Example.Post, :create) {:ok, assign(socket, :form, form)} end def handle_event("validate", %{"form" => input}, socket) do form = AshPhoenix.Form.validate(socket.assigns.form, input) {:ok, assign(socket, :form, form)} end def handle_event("submit", _, socket) do case AshPhoenix.Form.submit(socket.assigns.form) do {:ok, post} -> {:ok, redirect_to_post(socket, post)} {:error, form_with_errors} -> {:noreply, assign(socket, :form, form_with_errors)} end end """ |> to_code() defp live_view_example do @live_view_example end @graphql_example """ graphql do type :post queries do get :get_post, :read list :feed, :read end mutations do create :create_post, :create update :react_to_post, :react end end """ |> to_code() defp graphql_example do @graphql_example end @policies_example """ policies do policy action_type(:read) do authorize_if expr(visibility == :everyone) authorize_if relates_to_actor_via([:author, :friends]) end end """ |> to_code() defp policies_example do @policies_example end @notifier_example """ pub_sub do module ExampleEndpoint prefix "post" publish_all :create, ["created"] publish :react, ["reaction", :id] event: "reaction" end """ |> to_code() defp notifier_example do @notifier_example end @aggregate_example """ aggregates do count :likes, :reactions do filter expr(type == :like) end count :dislikes, :reactions do filter expr(type == :dislike) end end calculations do calculate :like_ratio, :float do expr(likes / (likes + dislikes)) end end """ |> to_code() defp aggregate_example do @aggregate_example end @post_example """ defmodule Example.Post do use Ash.Resource, data_layer: AshPostgres.DataLayer resource do description "A post is the primary sharable entity in our system" end postgres do table "posts" repo Example.Repo end attributes do attribute :text, :string do allow_nil? false description "The body of the text" end attribute :visibility, :atom do constraints [ one_of: [:friends, :everyone] ] description "Which set of users this post should be visible to" end end actions do update :react do argument :type, Example.Types.ReactionType do allow_nil? false end change manage_relationship( :type, :reactions, type: :append ) end end relationships do belongs_to :author, Example.User do allow_nil? true end has_many :reactions, Example.Reaction end end """ |> to_code() defp post_example do @post_example end end