# LiveUI
Set of macros for building `Phoenix.LiveView` modules to help manage database records.
This is done by configuring default implementation of `LiveUI` for a given `Ecto.Schema` struct and
initializing basic Index and Show live modules. This will in turn build the infrastructure for displaying
and processing data without need to write boilerplate code associated with `m:Phoenix.LiveView#callbacks` callbacks and HEEX templates.
`LiveUI` has the following features:
* autogenerated views for CRUD operations
* basic protocol implementation with sensible defaults
* sortable tables with pagination
* advanced search form
* format values with css, functions and components
* handles ownership to current user
* handles relations
* handles file uploads
* support to override functions for data processing
* support to override live view callbacks
* custom actions for operations on single and multiple records
* audit with record versioning
* dark and light mode
* debug mode that displays socket assigns
`LiveUI` is possible because of these libraries:
* `Cldr`
* `Ecto`
* `Faker`
* `Flop`
* `LiveInspect`
* `LiveSelect`
* `PaperTrail`
* `PetalComponents`
* `Phoenix`
## Installation
* add entry to `content` list in `assets/tailwind.config.js` - `../lib/live_ui/**/*.*ex`
* add line to `assets/css/app.css` - `@import '../../../live_ui/lib/live_ui/assets/default.css'`
* modify `root.html.heex` template - `<body class="bg-amber-50 dark:bg-gray-900 antialiased">`
* add `js-cookie` to `js/vendor` for theme switcher - <https://github.com/js-cookie/js-cookie>
* add theme switcher hook to `assets/js/app.js`
```javascript
const ColorSchemeHook = {
deadViewCompatible: true,
mounted() {
this.init()
},
updated() {
this.init()
},
init() {
initScheme()
this.el.addEventListener("click", window.toggleScheme)
},
}
```
* add switcher code to head in `root.html.heex` - `<LiveUI.Components.Core.color_scheme_switch_js />`
* add switcher icon to body in `root.html.heex` - `<LiveUI.Components.Core.color_scheme_switch />`
### Cldr
Add `Cldr` module:
``` elixir
defmodule MyApp.Cldr do
use Cldr,
default_locale: "en",
otp_app: :my_app,
providers: [Cldr.Number, Money, Cldr.Calendar, Cldr.DateTime],
gettext: MyAppWeb.Gettext
end
```
### LiveSelect
Add hook to `assets/js/app.js` - <https://hexdocs.pm/live_select/readme.html#javascript-hooks>
### Petal components
Instalation guide - <https://petal.build/components#install_petal_components>
## Configuration
```elixir
# live ui
config :live_ui,
debug: true,
repo: MyApp.Repo,
cldr: MyApp.Cldr,
ignored_fields: [:token, :hashed_password, :first_version_id, :current_version_id]
# petal components
config :petal_components, :error_translator_function, {MyAppWeb.CoreComponents, :translate_error}
# flop
config :flop, repo: MyApp.Repo, default_limit: 10, max_limit: 100
# cldr
config :ex_cldr, default_backend: LiveUI.Cldr
config :my_app, LiveUI.Cldr, locales: ["en"]
# paper trail (optional)
config :paper_trail,
repo: MyApp.Repo,
originator: [name: :user, model: MyApp.User],
strict_mode: true
```
There is a sample aplication bundled with the project that has all these set up, just run
`mix ecto.setup` to generate some random data and start the server with `iex -S mix phx.server`.
Admin credentials are `admin@example.com/password`.
## Minimal setup
Ecto schema:
```elixir
defmodule MyApp.User do
use Ecto.Schema
schema "users" do
field :name, :string
field :email, :string
timestamps()
end
end
```
Router entry:
```elixir
scope "/", MyAppWeb do
live_ui("/users", UserLive, MyApp.User)
end
```
Protocol file:
```elixir
defimpl LiveUI, for: MyApp.User do
use LiveUI.Protocol
end
```
Live modules:
```elixir
defmodule MyAppWeb.UserLive.Index do
use LiveUI.Views.Index, for: MyApp.User
end
defmodule MyAppWeb.UserLive.Show do
use LiveUI.Views.Show, for: MyApp.User
end
```
## Is it any good?
[Yes](https://news.ycombinator.com/item?id=3067434)