Comments (11)
from phoenix_storybook.
Ok, so after some digging, I found the issue. It was that I wasn't properly specifying the attributes in the story. This led to a death spiral that was not reported in an obvious way. I stuck some debug code into a couple of Storyboard modules and I could see that the attributes:
property was nil
and this meant that when I referenced one of the attributes in the component, it borked.
For the record, my Header1 story now looks like this:
defmodule Storybook.ChromeComponents.Header1 do
use PhoenixStorybook.Story, :component
alias Elixir.MultiplyerWeb.ChromeComponents
def function, do: &ChromeComponents.header1/1
def attributes, do: [%Attr{ id: :current_user, type: :map }, %Attr{ id: :class, type: :string}]
def variations do
[
%Variation{
id: :default,
description: "Default Header",
attributes: %{ current_user: %{ email: "[email protected]"} },
slots: []
}
]
end
end
The new problem is that now it all compiles and displays (mostly) properly, but the actual HTML/CSS from the components is not being emitted properly into the Playground | Preview tab.
I will keep digging ...
from phoenix_storybook.
Aha! And now I know why the component HTML isn't displaying. It is there, but it's a <header...>
HTML component, so of course that isn't going to show up inside a random <div...>
in the middle of the page. 🤦♂️
So, this is solved, but now I have an entirely different issue!
from phoenix_storybook.
Wow! My friend, you are a legend!
It's funny, just before you sent this thru I was looking at the other docs on "Late evaluation" and was wondering what that was all about.
Thanks again for taking the time here! Very much appreciated.
from phoenix_storybook.
coding is walking from one issue to another, it seems you are in the right direction
feel free to open another ticket if you need help, I'm not super fast to answer but I still try to do my best!
from phoenix_storybook.
Yeah, it sure is. I have now managed to get all of the values that I need populated for the AshAuthentication form, but I am now getting a doozy of an error that looks like something is going wrong with the parsing of the .story.exs
file.
The Story looks like this:
defmodule MultiplyerWeb.Storybook.AuthLive.AuthForm do
use PhoenixStorybook.Story, :live_component
# required
def component, do: MultiplyerWeb.AuthLive.AuthForm
def attributes do
[
%Attr{
id: :current_user,
type: :map
},
%Attr{
id: :class,
type: :string
},
%Attr{
id: :is_register?,
type: :boolean
},
%Attr{
id: :form,
type: AshPhoenix.Form
},
%Attr{
id: :trigger_action,
type: :string
},
%Attr{
id: :action,
type: :string
},
%Attr{
id: :myself,
type: :map
},
%Attr{
id: :cta,
type: :string
},
%Attr{
id: :errors,
type: :boolean
}
]
end
def variations do
[
%Variation{
id: :sign_in_with_password,
description: "AuthForm: sign in with password",
attributes: %{
current_user: %{email: "[email protected]"},
class: "",
is_register?: false,
form: AshPhoenix.Form.for_read(Multiplyer.Accounts.User, :sign_in_with_password),
cta: "Sign-in",
action: "sign-in",
errors: false
},
slots: []
}
]
end
end
And the error when it tries to recompile looks like this:
[debug] compiling storybook file: live_components/auth_live/auth_form.story.exs
[info] Sent 500 in 100ms
[error] #PID<0.1723.0> running Phoenix.Endpoint.SyncCodeReloadPlug (connection #PID<0.1170.0>, stream id 22) terminated
Server: localhost:4000 (http)
Request: GET /storybook/live_components/auth_live/auth_form
** (exit) an exception was raised:
** (TokenMissingError) nofile:1:6665: missing terminator: ] (for "[" starting at line 1)
|
1 | %{data: nil, id: "form", name: "form", type: :read, opts: [as: "form", warn_on_unhandled_errors?: true], forms: %{}, params: %{}, resource: Multiplyer.Accounts.User, source: %{timeout: nil, offset: 0, select: nil, sort: [], context: %{private: %{}}, load: [], filter: %{resource: Multiplyer.Accounts.User, __struct__: Ash.Filter, expression: %{left: %{attribute: %{default: nil, name: :email, type: Ash.Type.CiString, description: nil, source: :email, __struct__: Ash.Resource.Attribute, constraints: [casing: nil, allow_empty?: false, trim?: true], allow_nil?: false, private?: false, sensitive?: false, always_select?: false, filterable?: true, generated?: false, match_other_defaults?: false, primary_key?: false, update_default: nil, writable?: true}, resource: Multiplyer.Accounts.User, __struct__: Ash.Query.Ref, simple_equality?: nil, bare?: nil, input?: false, relationship_path: []}, right: nil, operator: :==, __struct__: Ash.Query.Operator.Eq, embedded?: false, __predicate__?: true, __operator__?: true}}, arguments: %{}, lock: nil, params: %{}, limit: nil, resource: Multiplyer.Accounts.User, __struct__: Ash.Query, errors: [%{type: :argument, path: [], stacktrace: %{stacktrace: [{Ash.Query, :"-require_arguments/2-fun-0-", 2, [file: ~c"lib/ash/query/query.ex", line: 499]}, {Enum, :"-reduce/3-lists^foldl/2-0-", 3, [file: ~c"lib/enum.ex", line: 2510]}, {Ash.Query, :for_read, 4, [file: ~c"lib/ash/query/query.ex", line: 437]}, {AshPhoenix.Form, :for_read, 3, [file: ~c"lib/ash_phoenix/form/form.ex", line: 798]}, {MultiplyerWeb.Storybook.AuthLive.AuthForm, :variations, 0, [file: ~c"storybook/live_components/auth_live/auth_form.story.exs", line: 57]}, {PhoenixStorybook.StoryLive, :"-render_content/2-fun-6-", 2, [file: ~c"lib/phoenix_storybook/live/story_live.ex", line: 361]}, {Phoenix.LiveView.Diff, :traverse, 7, [file: ~c"lib/phoenix_live_view/diff.ex", line: 386]}, {Phoenix.LiveView.Diff, :"-traverse_dynamic/7-fun-0-", 4, [file: ~c"lib/phoenix_live_view/diff.ex", line: 538]}, {Enum, :"-reduce/3-lists^foldl/2-0-", 3, [file: ~c"lib/enum.ex", line: 2510]}, {Phoenix.LiveView.Diff, :traverse, 7, [file: ~c"lib/phoenix_live_view/diff.ex", line: 384]}, {Phoenix.LiveView.Diff, :"-traverse_dynamic/7-fun-0-", 4, [file: ~c"lib/phoenix_live_view/diff.ex", line: 538]}, {Enum, :"-reduce/3-lists^foldl/2-0-", 3, [file: ~c"lib/enum.ex", line: 2510]}, {Phoenix.LiveView.Diff, :traverse, 7, [file: ~c"lib/phoenix_live_view/diff.ex", line: 384]}, {Phoenix.LiveView.Diff, :render, 3, [file: ~c"lib/phoenix_live_view/diff.ex", line: 136]}, {Phoenix.LiveView.Static, :to_rendered_content_tag, 4, [file: ~c"lib/phoenix_live_view/static.ex", line: 252]}, {Phoenix.LiveView.Static, :render, 3, [file: ~c"lib/phoenix_live_view/static.ex", line: 135]}, {Phoenix.LiveView.Controller, :live_render, 3, [file: ~c"lib/phoenix_live_view/controller.ex", line: 39]}, {Phoenix.Router, :__call__, 5, [file: ~c"lib/phoenix/router.ex", line: 430]}], __struct__: Ash.Error.Stacktrace}, resource: Multiplyer.Accounts.User, __struct__: Ash.Error.Query.Required, vars: [], __exception__: true, field: :password, query: nil, class: :invalid, error_context: [], changeset: nil}, %{type: :argument, path: [], stacktrace: %{stacktrace: [{Ash.Query, :"-require_arguments/2-fun-0-", 2, [file: ~c"lib/ash/query/query.ex", line: 499]}, {Enum, :"-reduce/3-lists^foldl/2-0-", 3, [file: ~c"lib/enum.ex", line: 2510]}, {Ash.Query, :for_read, 4, [file: ~c"lib/ash/query/query.ex", line: 437]}, {AshPhoenix.Form, :for_read, 3, [file: ~c"lib/ash_phoenix/form/form.ex", line: 798]}, {MultiplyerWeb.Storybook.AuthLive.AuthForm, :variations, 0, [file: ~c"storybook/live_components/auth_live/auth_form.story.exs", line: 57]}, {PhoenixStorybook.StoryLive, :"-render_content/2-fun-6-", 2, [file: ~c"lib/phoenix_storybook/live/story_live.ex", line: 361]}, {Phoenix.LiveView.Diff, :traverse, 7, [file: ~c"lib/phoenix_live_view/diff.ex", line: 386]}, {Phoenix.LiveView.Diff, :"-traverse_dynamic/7-fun-0-", 4, [file: ~c"lib/phoenix_live_view/diff.ex", line: 538]}, {Enum, :"-reduce/3-lists^foldl/2-0-", 3, [file: ~c"lib/enum.ex", line: 2510]}, {Phoenix.LiveView.Diff, :traverse, 7, [file: ~c"lib/phoenix_live_view/diff.ex", line: 384]}, {Phoenix.LiveView.Diff, :"-traverse_dynamic/7-fun-0-", 4, [file: ~c"lib/phoenix_live_view/diff.ex", line: 538]}, {Enum, :"-reduce/3-lists^foldl/2-0-", 3, [file: ~c"lib/enum.ex", line: 2510]}, {Phoenix.LiveView.Diff, :traverse, 7, [file: ~c"lib/phoenix_live_view/diff.ex", line: 384]}, {Phoenix.LiveView.Diff, :render, 3, [file: ~c"lib/phoenix_live_view/diff.ex", line: 136]}, {Phoenix.LiveView.Static, :to_rendered_content_tag, 4, [file: ~c"lib/phoenix_live_view/static.ex", line: 252]}, {Phoenix.LiveView.Static, :render, 3, [file: ~c"lib/phoenix_live_view/static.ex", line: 135]}, {Phoenix.LiveView.Controller, :live_render, 3, [file: ~c"lib/phoenix_live_view/controller.ex", line: 39]}, {Phoenix.Router, :__call__, 5, [file: ~c"lib/phoenix/router.ex", line: 430]}], __struct__: Ash.Error.Stacktrace}, resource: Multiplyer.Accounts.User, __struct__: Ash.Error.Query.Required, vars: [], __exception__: true, field: :email, query: nil, class: :invalid, error_context: [], changeset: nil}], action: %{name: :sign_in_with_password, type: :read, description: "Attempt to sign in using a username and password.", manual: nil, filter: nil, metadata: [%{default: nil, name: :token, type: Ash.Type.String, description: "A JWT which the user can use to authenticate to the API.", __struct__: Ash.Resource.Actions.Metadata, constraints: [allow_empty?: false, trim?: true], allow_nil?: false}], arguments: [%{default: nil, name: :email, type: Ash.Type.CiString, description: "The identity to use for retrieving the user.", __struct__: Ash.Resource.Actions.Argument, constraints: [casing: nil, allow_empty?: false, trim?: true], allow_nil?: false, private?: false, sensitive?: false}, %{default: nil, name: :password, type: Ash.Type.String, description: "The password to check for the matching user.", __struct__: Ash.Resource.Actions.Argument, constraints: [allow_empty?: false, trim?: true], allow_nil?: false, private?: false, sensitive?: true}], __struct__: Ash.Resource.Actions.Read, get_by: [], preparations: [%{__struct__: Ash.Resource.Preparation, preparation: {AshAuthentication.Strategy.Password.SignInPreparation, []}}], get?: true, modify_query: nil, pagination: false, primary?: false, touches_resources: [], transaction?: false}, valid?: false, phase: :preparing, distinct: nil, aggregates: %{}, calculations: %{}, tenant: nil, api: nil, after_action: [#Function<1.91439281/2 in AshAuthentication.Strategy.Password.SignInPreparation.prepare/3>], load_through: %{}, invalid_keys: %{map: %{}, __struct__: MapSet}, around_transaction: [], before_action: [#Function<0.91439281/1 in AshAuthentication.Strategy.Password.SignInPreparation.prepare/3>], distinct_sort: [], __validated_for_action__: :sign_in_with_password, action_failed?: false}, __struct__: AshPhoenix.Form, errors: nil, action: :sign_in_with_password, valid?: false, method: "post", api: nil, changed?: false, transform_errors: nil, form_keys: [], any_removed?: false, touched_forms: %{map: %{}, __struct__: MapSet}, added?: false, just_submitted?: false, submit_errors: nil, warn_on_unhandled_errors?: true, prepare_source: nil, transform_params: nil, prepare_params: nil, original_data: nil, submitted_once?: false}
| (truncated)
That's quite the debug dump! I have no idea where to even look to sort this one out! 🤷
from phoenix_storybook.
This is equally hard for me to debug :)
It seems that the form
attribute is causing the issue but I still don't get why.
Can you open a repo with a minimal story reproducing the issue?
You can fork https://github.com/phenixdigital/phoenix_storybook_sample and create a new story in it
from phoenix_storybook.
In order to do that, I would need to add Ash and Ash Authentication to it. What about I give you access to my repo? It's actually a pretty simple test app that I am working with. I'm trying to build an Ash app, and I have a non-trivial front-end template that I'm cutting up and trying to implement as a shell app in Elixir/Phoenix/Ash. If I add @cblavier to my repo, you could dl it and see it working (or not working, as the case may be) in situ. The app is not much more complex than the sample app, but it already has Ash/etc in it, so it will be a bit easier (I think). Would that work?
from phoenix_storybook.
ok, let's do that
I'll have a look later this week
from phoenix_storybook.
Ok, I have added you to the repo. If you start it up on localhost and visit this URL, you will see the problem:
http://localhost:4000/storybook/live_components/auth_live/auth_form
[debug] compiling storybook file: live_components/auth_live/auth_form.story.exs
[info] Sent 500 in 452ms
[error] #PID<0.1341.0> running Phoenix.Endpoint.SyncCodeReloadPlug (connection #PID<0.1340.0>, stream id 1) terminated
Server: localhost:4000 (http)
Request: GET /storybook/live_components/auth_live/auth_form
** (exit) an exception was raised:
** (TokenMissingError) nofile:1:9571: missing terminator: ] (for "[" starting at line 1)
|
1 | %{data: nil, id: "form", name: "form", type: :create, opts: [as: "form", warn_on_unhandled_errors?: true], forms: %{}, params: %{}, resource: Multiplyer...<snip>
Let me know how you go. And thanks a ton for doing this!
PS: Please forgive my (very bad!) JS and other front-end content. I am using Storybook as a way to teach myself from scratch how a modern front-end works.
from phoenix_storybook.
Just nailed it, with a feature I even forgot I wrote 😅
You need to use late evaluation otherwise the evaluation of the AshPhoenix.Form
at compile time totally messes up the component code and would also give you the following code preview which is something you probably don't want ;-)
So you need to turn this line:
form: AshPhoenix.Form.for_create(Multiplyer.Accounts.User, :register_with_password),
into this
form: {:eval, ~s|AshPhoenix.Form.for_create(Multiplyer.Accounts.User, :register_with_password)|},
from phoenix_storybook.
Related Issues (20)
- Stories with large attributes fail to load HOT 3
- Hex release not independently compilable HOT 2
- Make CSRF token optional
- Generated stories have `Elixir.` prefix in aliases and for function components
- Compile failure with earmark 1.4.41 HOT 3
- `theme` Attribute does not render in the example code HOT 4
- Strange whitebar on chrome/safari since MacOS Sonoma update
- Inter font makes request to external source
- Add `defer` attribute to `<script>` tag HOT 1
- Global Color Change HOT 1
- Prefix event names in StoryLive
- Elixir warning for slice with negative steps
- allow passing additional options to story HOT 1
- Compatibility with Phoenix HTML 4.0.0
- error: undefined function (there is no such import) nofile:1 HOT 2
- Following phx.gen.storybook Instructions Breaks All CSS on Pages HOT 2
- How can I add components from different module than CoreComponents? HOT 1
- bug: setting up storybook breaks homepage rendering (CSS) HOT 3
- protocol consolidation in storybook files HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from phoenix_storybook.