Closed darh closed 1 year ago
Stale issue message
For today: Tomaž will finish most of what needs to be done. The CRUD parts will be finished
CRUD stuff is sorted. We'll discuss buttons, expressions, and layout actions with @Fajfa tomorrow.
To add from me:
Debating how access control should be done...
My current thoughts are either:
Currently, I'm leaning more towards the second option but I'm contemplating if such granular RBAC is overkill for page layouts. A counterargument would be module fields which also have their own RBAC rules.
I'm considering the first option because page layouts are basically an extension to the page wrapper so it doesn't really make sense to have granular RBAC on layouts also.
Picking the second option primarily for consistency (modules and module fields). For most cases, wildcard allows will do. Might re-think before the feature goes out.
Second option for me as well, 1st - consistency. 2nd - defining a primary layout can be done on admin level, secondary on a less-permissive level ie content editor. I have a feeling editors will need this feature, especially on bigger projects.
At a later point (probably during test fest) I'll be adding some extra test cases
For today: write integration tests for CRUD operations
For today: define specs for supporting page layout actions
Actions introduce a new flexible way of trivially defining custom user journeys such as multi-step onboarding for a subscription, invoice billing, and payment systems, ...
Currently, pages can have these actions (which also fall under the corresponding button):
With the introduction of page layouts, we need additional bits to navigate between different layouts. We can take this further and provide additional mechanisms to provide access to the interaction state for more flexibility such as storing intermediate variables (can remove some prompts and temporary hidden fields).
new
the layout acts like the old new button
edit
the layout acts like the old edit button
submit
the layout acts like the old submit button
delete
the layout acts like the old delete button
clone
the layout acts like the old clone button
back
the layout acts like the old back button
goto(ident)
The action navigates to the specified page layout. This action can be used to navigate between different layouts using identifiers.
Note the same could be done with eval
but a convenience function could be nice.
gotoPage(ident)
the action navigates to the specified page (a redirect) This action can be used to navigate between different pages using their identifiers.
An example use-case would be where a user onboarding would span over multiple resources, such as subscriptions and payment methods. After completing one (on one page), we can automatically send them off to a different page where they'd complete a different bit of the story.
eval(expr1, expr2, ..., exprN)
The action runs the given expressions and keeps the results in the interaction session This action can be used to manipulate the interaction session to hold custom values, and define expressions based on arbitrary session values (such as counters).
An example use-case would be where we have 5 layouts representing 5 steps, each layout defines an expression of i++
and each layout shows only when the value on i
is correct. Can be replaced with goto and good layout handles, but this could be a nice addition.
The expression should be evaluated on the backend endpoint.
The variable assignment could be done in a similar manner to how we do workflow expression steps (target
, type
, expr
).
run(ident)
The action runs the defined automation. The used identifier would be the same as what the event bus sees.
Note this might require a bunch of work so we should probs omit it for V1.
On the front end, this would be represented as a button. But, an additional improvement would be to bind multiple actions under the same button.
A solid example would be to define the following chain: evaluate some values, update the record, save the record, gotoPage. This would all be under the same button.
When a single button holds multiple actions, they are executed in the same order they appear in. How we handle errors is up for debate. My suggestion is to just kill it and show the error.
When you navigate to a page, we initialize a new interaction session. This session holds a few pre-defined variables (we'll decide on what; probably viewport, user, roles, ...) as well as some space for arbitrary values.
The state should exist as long as the user is interacting with the current page, potentially surviving refresh.
When evaluating expressions, the session should be included as a variable.
Potentially, the session could interact with records and UI elements.
Button struct {
ButtomID uint64
Placement string
Meta any
Label string
// ...
Actions []Action
}
Action struct {
Kind string
Params any
}
@Fajfa
V1 middle grounds
When rendering a layout (on a specific view) if the button can exist and is enabled, show it, else (if it either can't exist or is disabled), don't show it.
Some clarifications:
@tjerman
@Fajfa
Tested and confirming that this looks and works good. Moving the ticket to Done, we will add the CL later as a part of the mention docs ticket above.
About
Supporting multi-page views enables us to improve the UX of end-users interacting with our low-code applications. Multi page views enable us to define different dashboards for different user roles, wizard-like flows for creating complex modules such as a subscription plan.
The current generation of our webapp will provide a simpler solution where we will expand on the idea in future iterations.
How
Each page now defines a list of layouts where each layout may define an expression. The expression determines if the layout can be shown based on the current situation.
When visiting a page, the page render logic iterates the list and shows the first layout where the expression evaluates into
true
. If there are layouts with no expressions, prioritise those.Each layout can define a set of actions it can perform; create, update, delete record & move to next layout & redirect to next page.
Move layout action
The move layout action would permit you to go to the next layout where a user can interact with different bits and pieces. The action should accept some layout identifier (ID, label, handle, ...) and move to it.
The exact details of how users would redirect to other layouts should be discussed.
Here, be careful, to properly handle state updates as the page should hold a single state for all of the layouts the user goes through.
When we would move to a layout that doesn't belong to this page, we should save the ongoing record (and potentially prompt a notification before doing so).
Other actions
The rest of the actions simply define what (combination of) button(s) we should show in the toolbar.
Concerns/considerations:
Expression
Expressions should work similarly to how we've solved it for conditional fields. Expressions can access the current record, authenticated user and it's roles, date & time.
Refs
Original spec draft: https://docs.google.com/document/d/135EvSkCeU1tiNHNnztLf8PWsjzCpFtBwwUNFIFsSjrU/edit