ash-project / ash_admin

A super-admin UI dashboard for Ash Framework applications, built with Phoenix LiveView.
https://hexdocs.pm/ash_admin
MIT License
102 stars 48 forks source link

Missing ThingyWeb.LayoutView module #38

Closed dolfinus closed 1 year ago

dolfinus commented 1 year ago

Describe the bug

I'm currently poking with the stick into ash_example. Then I try to add and use ash_admin, I've got an exception about missing ThingyWeb.LayoutView module:

Server: localhost:4000 (http)
Request: GET /
** (exit) an exception was raised:
    ** (UndefinedFunctionError) function ThingyWeb.LayoutView.render/2 is undefined (module ThingyWeb.LayoutView is not available)
        ThingyWeb.LayoutView.render("root.html", %{__changed__: %{actor: true, ash_live_config: true, me: true, tickets: true}, actor: #Helpdesk.Accounts.User<__meta__: #Ecto.Schema.Metadata<:loaded, "users">, id: "ca908d60-bc4c-4740-a4e9-1edbe770674d", first_name: "mef", last_name: nil, representative: false, admin: true, aggregates: %{}, calculations: %{}, __order__: nil, ...>, ash_live_config: %{me: %{callback: #Function<2.17681511/1 in HelpdeskWeb.HomeLive.mount/3>, last_fetched_at: -576460734887, opts: [results: :keep, refetch_interval: 300000, subscribe: ["ticket:assigned_to:ca908d60-bc4c-4740-a4e9-1edbe770674d"]]}, tickets: %{callback: #Function<3.17681511/2 in HelpdeskWeb.HomeLive.mount/3>, last_fetched_at: -576460734873, opts: [api: Helpdesk.Tickets.Api, results: :keep, refetch_interval: 60000, subscribe: ["user:updated:ca908d60-bc4c-4740-a4e9-1edbe770674d", "ticket:updated:ca908d60-bc4c-4740-a4e9-1edbe770674d"]]}}, conn: %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{__changed__: %{actor: true, ash_live_config: true, me: true, tickets: true}, actor: #Helpdesk.Accounts.User<__meta__: #Ecto.Schema.Metadata<:loaded, "users">, id: "ca908d60-bc4c-4740-a4e9-1edbe770674d", first_name: "mef", last_name: nil, representative: false, admin: true, aggregates: %{}, calculations: %{}, __order__: nil, ...>, ash_live_config: %{me: %{callback: #Function<2.17681511/1 in HelpdeskWeb.HomeLive.mount/3>, last_fetched_at: -576460734887, opts: [results: :keep, refetch_interval: 300000, subscribe: ["ticket:assigned_to:ca908d60-bc4c-4740-a4e9-1edbe770674d"]]}, tickets: %{callback: #Function<3.17681511/2 in HelpdeskWeb.HomeLive.mount/3>, last_fetched_at: -576460734873, opts: [api: Helpdesk.Tickets.Api, results: :keep, refetch_interval: 60000, subscribe: ["user:updated:ca908d60-bc4c-4740-a4e9-1edbe770674d", "ticket:updated:ca908d60-bc4c-4740-a4e9-1edbe770674d"]]}}, content: {:safe, ["", ["", [60, "div"], "", [" data", 45, "phx-main", 61, 34, "true", 34, " data", 45, "phx-session", 61, 34, "SFMyNTY.g2gDaAJhBXQAAAAIZAACaWRtAAAAFHBoeC1GelZpNHRJME9nT01WQUFsZAAMbGl2ZV9zZXNzaW9uaAJkAAdkZWZhdWx0bggA0dXtddRiNRdkAApwYXJlbnRfcGlkZAADbmlsZAAIcm9vdF9waWRkAANuaWxkAAlyb290X3ZpZXdkABtFbGl4aXIuSGVscGRlc2tXZWIuSG9tZUxpdmVkAAZyb3V0ZXJkABlFbGl4aXIuSGVscGRlc2tXZWIuUm91dGVyZAAHc2Vzc2lvbnQAAAAAZAAEdmlld2QAG0VsaXhpci5IZWxwZGVza1dlYi5Ib21lTGl2ZW4GAAa961-FAWIAAVGA.A3XPnfaTIjTIQLEyHMTYT3bynM7GVas0hw7obMAG4n0", 34, " data", 45, "phx-static", 61, 34, "SFMyNTY.g2gDaAJhBXQAAAADZAAKYXNzaWduX25ld2wAAAABZAAFYWN0b3JqZAAFZmxhc2h0AAAAAGQAAmlkbQAAABRwaHgtRnpWaTR0STBPZ09NVkFBbG4GAAi961-FAWIAAVGA.4a6FjBrNlSIF6hNahzCSlUvjzSip9Qs5gwAIEuCNFJQ", 34, " id=\"", "phx-FzVi4tI0OgOMVAAl", 34], "", '>', "", ["", ["<main role=\"main\" class=\"container\">\n", ["", ["\n  <section class=\"phx-hero\">\n    <h1>", "Welcome to Helpdesk, Anonymous user!", "</h1>\n    <h2>Please pass user ID into <code>User-Id</code> header to log in</h2>\n  </section>\n"], ""], "\n</main>\n"], ""], "", [60, 47, "div", 62], ""], ""]}, flash: %{}, layout: false, live_action: nil, live_module: HelpdeskWeb.HomeLive, me: nil, tickets: %{__first__?: true, __struct__: Ash.Page.Offset, count: 0, limit: 5, more?: false, offset: 0, rerun: {#Ash.Query<resource: Helpdesk.Tickets.Ticket, filter: #Ash.Filter<representative.id == "ca908d60-bc4c-4740-a4e9-1edbe770674d">, limit: 6>, [page: [count: true, limit: 5], verbose?: false, actor: #Helpdesk.Accounts.User<__meta__: #Ecto.Schema.Metadata<:loaded, "users">, id: "ca908d60-bc4c-4740-a4e9-1edbe770674d", first_name: "mef", last_name: nil, representative: false, admin: true, aggregates: %{}, calculations: %{}, __order__: nil, ...>, authorize?: false, return_query?: false]}, results: []}}, body_params: %{}, cookies: %{"_helpdesk_key" => "SFMyNTY.g3QAAAACbQAAAAtfY3NyZl90b2tlbm0AAAAYeEI4TDQ5T3Rrd3ROQnhYaXliZFROY1JZbQAAAAd1c2VyX2lkbQAAACRjYTkwOGQ2MC1iYzRjLTQ3NDAtYTRlOS0xZWRiZTc3MDY3NGQ.0w9UtKmxxAfHefVTRW5X6dqC7ICSnK770uG5VrOwyrE"}, halted: false, host: "localhost", method: "GET", owner: #PID<0.646.0>, params: %{}, path_info: [], path_params: %{}, port: 4000, private: %{HelpdeskWeb.Router => {[], %{Absinthe.Plug => ["gql"], Absinthe.Plug.GraphiQL => ["playground"]}}, :before_send => [#Function<0.20795500/1 in Plug.CSRFProtection.call/2>, #Function<2.36663997/1 in Phoenix.Controller.fetch_flash/2>, #Function<0.84243074/1 in Plug.Session.before_send/2>, #Function<0.11807388/1 in Plug.Telemetry.call/2>, #Function<1.86886788/1 in Phoenix.LiveReloader.before_send_inject_reloader/3>], :phoenix_endpoint => HelpdeskWeb.Endpoint, :phoenix_flash => %{}, :phoenix_format => "html", :phoenix_layout => false, :phoenix_live_view => {HelpdeskWeb.HomeLive, [action: nil, router: HelpdeskWeb.Router], %{extra: %{session: %{}}, name: :default, vsn: 1672351501289117137}}, :phoenix_request_logger => {"request_logger", "request_logger"}, :phoenix_root_layout => {ThingyWeb.LayoutView, :root}, :phoenix_router => HelpdeskWeb.Router, :phoenix_template => "template.html", :phoenix_view => Phoenix.LiveView.Static, :plug_session => %{"_csrf_token" => "xB8L49OtkwtNBxXiybdTNcRY", "user_id" => "ca908d60-bc4c-4740-a4e9-1edbe770674d"}, :plug_session_fetch => :done}, query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %{"_helpdesk_key" => "SFMyNTY.g3QAAAACbQAAAAtfY3NyZl90b2tlbm0AAAAYeEI4TDQ5T3Rrd3ROQnhYaXliZFROY1JZbQAAAAd1c2VyX2lkbQAAACRjYTkwOGQ2MC1iYzRjLTQ3NDAtYTRlOS0xZWRiZTc3MDY3NGQ.0w9UtKmxxAfHefVTRW5X6dqC7ICSnK770uG5VrOwyrE"}, req_headers: [{"accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"}, {"accept-encoding", "gzip, deflate, br"}, {"accept-language", "en-US,en;q=0.8,ru-RU;q=0.5,ru;q=0.3"}, {"connection", "keep-alive"}, {"cookie", "_helpdesk_key=SFMyNTY.g3QAAAACbQAAAAtfY3NyZl90b2tlbm0AAAAYeEI4TDQ5T3Rrd3ROQnhYaXliZFROY1JZbQAAAAd1c2VyX2lkbQAAACRjYTkwOGQ2MC1iYzRjLTQ3NDAtYTRlOS0xZWRiZTc3MDY3NGQ.0w9UtKmxxAfHefVTRW5X6dqC7ICSnK770uG5VrOwyrE"}, {"host", "localhost:4000"}, {"sec-fetch-dest", "document"}, {"sec-fetch-mode", "navigate"}, {"sec-fetch-site", "none"}, {"sec-fetch-user", "?1"}, {"upgrade-insecure-requests", "1"}, {"user-agent", "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0"}, {"user-id", "ca908d60-bc4c-4740-a4e9-1edbe770674d"}], request_path: "/", resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "FzVi4tGYmfIVjFQAAAAF"}, {"x-frame-options", "SAMEORIGIN"}, {"x-xss-protection", "1; mode=block"}, {"x-content-type-options", "nosniff"}, {"x-download-options", "noopen"}, {"x-permitted-cross-domain-policies", "none"}, {"cross-origin-window-policy", "deny"}], scheme: :http, script_name: [], secret_key_base: :..., state: :unset, status: nil}, content: {:safe, ["", ["", [60, "div"], "", [" data", 45, "phx-main", 61, 34, "true", 34, " data", 45, "phx-session", 61, 34, "SFMyNTY.g2gDaAJhBXQAAAAIZAACaWRtAAAAFHBoeC1GelZpNHRJME9nT01WQUFsZAAMbGl2ZV9zZXNzaW9uaAJkAAdkZWZhdWx0bggA0dXtddRiNRdkAApwYXJlbnRfcGlkZAADbmlsZAAIcm9vdF9waWRkAANuaWxkAAlyb290X3ZpZXdkABtFbGl4aXIuSGVscGRlc2tXZWIuSG9tZUxpdmVkAAZyb3V0ZXJkABlFbGl4aXIuSGVscGRlc2tXZWIuUm91dGVyZAAHc2Vzc2lvbnQAAAAAZAAEdmlld2QAG0VsaXhpci5IZWxwZGVza1dlYi5Ib21lTGl2ZW4GAAa961-FAWIAAVGA.A3XPnfaTIjTIQLEyHMTYT3bynM7GVas0hw7obMAG4n0", 34, " data", 45, "phx-static", 61, 34, "SFMyNTY.g2gDaAJhBXQAAAADZAAKYXNzaWduX25ld2wAAAABZAAFYWN0b3JqZAAFZmxhc2h0AAAAAGQAAmlkbQAAABRwaHgtRnpWaTR0STBPZ09NVkFBbG4GAAi961-FAWIAAVGA.4a6FjBrNlSIF6hNahzCSlUvjzSip9Qs5gwAIEuCNFJQ", 34, " id=\"", "phx-FzVi4tI0OgOMVAAl", 34], "", '>', "", ["", ["<main role=\"main\" class=\"container\">\n", ["", ["\n  <section class=\"phx-hero\">\n    <h1>", "Welcome to Helpdesk, Anonymous user!", "</h1>\n    <h2>Please pass user ID into <code>User-Id</code> header to log in</h2>\n   (truncated)

There can I fetch this module from? Google failed to find something related to this.

To Reproduce

  1. Clone this repo https://github.com/dolfinus/ash_example, branch test
  2. mix phx.server
  3. Open http://localhost:4000 изображение

Expected behavior

A clear and concise description of what you expected to happen.

Runtime Erlang/OTP 25 [erts-13.1.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns] Elixir 1.14.0 (compiled with Erlang/OTP 25) Linux 6.1.1-1-MANJARO #1 SMP PREEMPT_DYNAMIC Wed Dec 21 23:21:50 UTC 2022 x86_64 GNU/Linux

Dependency resolution completed:
  absinthe 1.7.0
  absinthe_plug 1.5.8
  ash 2.4.30
  ash_admin 0.7.1
  ash_graphql 0.22.3
  ash_phoenix 1.2.3
  ash_postgres 1.2.6
  castore 0.1.20
  comparable 1.0.0
  connection 1.1.0
  cowboy 2.9.0
  cowboy_telemetry 0.4.0
  cowlib 2.11.0
  dataloader 1.0.10
  db_connection 2.4.3
  decimal 2.0.0
  ecto 3.9.4
  ecto_psql_extras 0.7.10
  ecto_sql 3.9.2
  elixir_make 0.7.3
  ets 0.8.1
  file_system 0.2.10
  floki 0.34.0
  gettext 0.20.0
  jason 1.4.0
  mime 2.0.3
  nimble_options 0.5.2
  nimble_parsec 1.2.3
  phoenix 1.6.15
  phoenix_ecto 4.4.0
  phoenix_html 3.2.0
  phoenix_live_dashboard 0.7.2
  phoenix_live_reload 1.4.1
  phoenix_live_view 0.18.3
  phoenix_pubsub 2.1.1
  phoenix_template 1.0.0
  phoenix_view 2.0.2
  picosat_elixir 0.2.3
  plug 1.14.0
  plug_cowboy 2.6.0
  plug_crypto 1.2.3
  postgrex 0.16.5
  ranch 1.8.0
  sourceror 0.11.2
  spark 0.3.2
  stream_data 0.5.0
  surface 0.9.1
  table_rex 3.1.1
  telemetry 1.1.0
  telemetry_metrics 0.6.1
  telemetry_poller 1.0.0
  typable 0.3.0

Additional context

-

zachdaniel commented 1 year ago

Hey @dolfinus sad to say but ash_example is probably too old to really play with. I'm not sure whats wrong with the combination of it and ash_admin, but if you want a recent example with working admin, I'd checkout ash_hq https://github.com/ash-project/ash_hq/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc

zachdaniel commented 1 year ago

(for the record, that repo has been "archived". Its still accessible, but isn't intended to be a good example anymore).

dolfinus commented 1 year ago

Could you please add to ash_example description a note with an URL of new example repo? As well a note to ash_policy that is not simply archived, but now a part of Ash itself

zachdaniel commented 1 year ago

Sure, will do 👍🏻