├── .github
└── funding.yml
├── .gitignore
├── basics.md
├── basics
├── helpers.md
├── localization.md
├── navigation.md
├── page.md
└── screens
│ ├── navigation.jpg
│ ├── page_slots.jpg
│ ├── page_title.jpg
│ └── page_view.jpg
├── charts
├── area.md
├── bar.md
├── basics.md
├── donut.md
├── number.md
├── progress.md
└── screens
│ ├── bar.png
│ ├── donut.png
│ ├── number.png
│ ├── progress.png
│ └── variants.png
├── configuration.md
├── crud
├── actions.md
├── forms.md
├── index.md
├── model.md
├── screens
│ ├── action_modal_fields.png
│ ├── message_danger.png
│ ├── message_info.png
│ ├── message_success.png
│ ├── message_warning.png
│ ├── preview.gif
│ └── search.png
├── search.md
├── show.md
└── table.md
├── fields
├── block.md
├── boolean.md
├── checkboxes.md
├── conditions.md
├── date-time.md
├── icon.md
├── image.md
├── input.md
├── introduction.md
├── list.md
├── masks.md
├── modal.md
├── password.md
├── radio.md
├── range.md
├── relation.md
├── route.md
├── screens
│ ├── conditions
│ │ └── conditions_radio.gif
│ ├── datetime
│ │ ├── date_and_time.png
│ │ └── example.png
│ ├── image
│ │ ├── expand.png
│ │ └── first_big.png
│ ├── range
│ │ └── example.png
│ ├── relation
│ │ ├── inline.png
│ │ ├── picker.jpg
│ │ └── tags.png
│ └── validation
│ │ └── validation_1.png
├── select.md
├── textarea.md
├── validation.md
└── wysiwyg.md
├── frontend
├── components.md
├── javascript.md
└── vue.md
├── installation.md
├── packages
├── .DS_Store
├── 2fa.md
├── bladesmith.md
├── location.md
├── meta.md
├── pages.md
├── rehearsal.md
└── screens
│ ├── lazy.png
│ ├── maps.png
│ ├── nav-field.png
│ ├── nav-result.png
│ ├── pages_screen.jpg
│ └── verify.gif
├── prologue
├── about.md
├── art.md
├── contribution.md
├── screens
│ ├── cbl.jpeg
│ ├── elements.jpeg
│ ├── iter-font.jpeg
│ ├── jb.jpeg
│ └── logo-colors.jpeg
├── sponsorware.md
└── upgrade.md
└── readme.md
/.github/funding.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [litstack]
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
--------------------------------------------------------------------------------
/basics.md:
--------------------------------------------------------------------------------
1 | # Basics
2 |
3 | ## Introduction
4 |
5 | This document describes the main components that help to understand how a
6 | litstack application is built.
7 |
8 | ## The `./lit` Folder
9 |
10 | After [installing](../installation.md) Litstack the `./lit` folder is created in
11 | your laravel application. Think of it as an its own **isolated** laravel
12 | application in your laravel application. It contains the `./lit/resources`
13 | folder containing assets and views, an `./lit/app` folder with the php classes
14 | for your **Litstack** app and other folders that are also present in the root
15 | folder.
16 |
17 | ::: tip
18 |
19 | Isolating your administration application from your app provides a clear
20 | structure of your actual business logic.
21 |
22 | :::
23 |
24 | ## Creator Commands
25 |
26 | For almost every creator commands provided by laravel, there is a similar one
27 | that creates the corresponding files into the `./lit` folder. The commands use
28 | the `lit` prefix instead of `make`.
29 |
30 | ```shell
31 | php artisan lit:controller
32 | php artisan lit:request
33 | php artisan lit:job
34 | ```
35 |
36 | ### Livewire
37 |
38 | There is a creator command for livewire as well:
39 |
40 | ```php
41 | php artisan lit:livewire Counter
42 | ```
43 |
44 | ## Permissions
45 |
46 | Litstack brings a simple user-friendly permissions handler. Additionally there
47 | is an easy way to create or delete the existing permissions using the migration
48 | `./database/migrations/______________________make_permissions.php`.
49 |
50 | Configure the desired permission groups in it and create them with the artisan
51 | command `lit:permissions`.
52 |
53 | ```shell
54 | php artisan lit:permissions
55 | ```
56 |
57 | ::: tip
58 |
59 | Add the `lit:permissions` command to your **deploy** script to keep the
60 | permissions in your production database up to date.
61 |
62 | :::
63 |
--------------------------------------------------------------------------------
/basics/helpers.md:
--------------------------------------------------------------------------------
1 | # Helpers
2 |
3 | ## Introduction
4 |
5 | The package includes a variety of global helper **PHP** `functions`.
6 |
7 | ::: tip
8 |
9 | The package includes useful **Vue** `mixins` as well. Read the
10 | [Vue mixins](../frontend/vue.md#mixins) section to learn more about the existing
11 | `mixins`.
12 |
13 | :::
14 |
15 | ## Lit Facade
16 |
17 | The `Lit` singleton contains some helpers which are related to the application.
18 |
19 | ### `installed()`
20 |
21 | The `installed` method checks if the package has been installed. This can be
22 | useful in service providers.
23 |
24 | ```php
25 | use Ignite\Support\Facades\Lit;
26 |
27 | if(! Lit::installed()) {
28 | return;
29 | }
30 | ```
31 |
32 | ### `route($name)`
33 |
34 | If a route is added to the route file `lit/routes/web.php`, the prefix `lit` is
35 | added to the name. The helper route also adds this prefix as well. Depending on
36 | your preferences you can use the laravel helper `route` or the Litstack helper
37 | to call up a route.
38 |
39 | ```php
40 | // lit/routes/web.php
41 |
42 | Route::get('dashboard', DashboardController::class)->name('dashboard');
43 | ```
44 |
45 | ```php
46 | Dashboard
47 | // Is the same as:
48 | Dashboard
49 | ```
50 |
51 | ### `url($url)`
52 |
53 | If you don't want to use the route name to call a route but directly specify the
54 | url, you can use the `url` helper which prepends the `route_prefix` from the
55 | config **lit.php** to your url.
56 |
57 | ```php
58 | Dashboard
59 | ```
60 |
61 | ## Miscellaneous
62 |
63 | ### `__lit($key, $replace)`
64 |
65 | The `__lit` method returns the translation using the application locale for the
66 | authenticated user.
67 |
68 | ```php
69 | __lit('messages.welcome', ['name' => 'Spatie'])
70 | ```
71 |
72 | ### `fa($group, $icon)`
73 |
74 | The `fa` helper makes it easy to include
75 | [Fontawesome](https://fontawesome.com/icons?d=gallery) icons.
76 |
77 | ```php
78 | fa('home') //
79 | fa('fal', 'abacus') //
80 | ```
81 |
82 | ### `lit()`
83 |
84 | The `lit` method returns the `Ignite\Support\Facades\Lit` singelton.
85 |
86 | ```php
87 | lit()->installed();
88 |
89 | // Is the same as:
90 |
91 | use Ignite\Support\Singletons\Lit;
92 | Lit::installed();
93 | ```
94 |
95 | ### `lit_user()`
96 |
97 | The `lit_user` method returns the authenticated user model.
98 |
99 | ```php
100 | {{ lit_user()->email }}
101 | ```
102 |
--------------------------------------------------------------------------------
/basics/localization.md:
--------------------------------------------------------------------------------
1 | # Localization
2 |
3 | ## Introduction
4 |
5 | The application can be managed multilingual. The translation of your admin panel can
6 | be done in `php` using
7 | [laravel's localization](https://laravel.com/docs/7.x/localization) service or
8 | in `vue` using
9 | [vue-i18n](https://kazupon.github.io/vue-i18n/docs/formatting.html). It uses the
10 | **laravel** syntax for translation string. All translation strings are formatted so they can be used
11 | in `vue-i18n` as well.
12 |
13 | In Laravel applications that include the litstack package, there are **two** different
14 | locales, one for your website and one for the admin application. So for example,
15 | a user can manage german content in the admin application and still see the
16 | interface in the english version.
17 |
18 | The following examples refer to the translations which look like this:
19 |
20 | ```php{lit/resources/lang/en/messages.php}
21 | return [
22 | "welcome": "Welcome, :name"
23 | ];
24 | ```
25 |
26 | ## Configuration
27 |
28 | ### Translating Litstack
29 |
30 | Translations of the admin panel are managed in the [litstack/lang](https://github.com/litstack/lang) repository, if it doesn't contain your language, you are welcome to contribute. The languages in which your admin panel should be translatable can be specified in the `lit.translatable` config.
31 |
32 | ### Translating App
33 |
34 | You can configure the translatability of your app in the `config/translatable.php` config.
35 |
36 | ::: tip
37 |
38 | If more than one locale is specified, form fields can be edited in multiple languages.
39 |
40 | :::
41 |
42 | ## PHP
43 |
44 | To translate your admin panel using the locale of the authenticated litstack user, the `__lit()` helper method is
45 | used, just like `__()` from laravel's
46 | [localization](https://laravel.com/docs/7.x/localization#retrieving-translation-strings).
47 |
48 | ```php
49 | __lit('messages.welcome', ['name', 'Jannes'])
50 | ```
51 |
52 | Pluralization can be used with the `__lit_choice` function or the short version
53 | `__lit_c`.
54 |
55 | ```php
56 | 'apples' => '{0} There are none|[1,19] There are some|[20,*] There are many',
57 |
58 | ...
59 |
60 | __lit_choice('apples', 10)
61 | __lit_c('apples', 10)
62 | ```
63 |
64 | ## Vue
65 |
66 | In `Vue` the [vue-i18n](https://kazupon.github.io/vue-i18n/introduction.html)
67 | format is used.
68 |
69 | ```javascript
70 |
71 |
72 | {{ $t('messages.welcome', { name: 'Jannes' }) }}
73 |
74 |
75 | ```
76 |
77 | ::: tip
78 |
79 | You may also use the Laravel localization helpers in Vue components.
80 |
81 | - \_\_()
82 | - trans()
83 | - trans_choice()
84 |
85 | :::
86 |
87 | ## Determine Locale
88 |
89 | To determine the locale the function `getLocale` can be used on the `Lit` facade
90 | like this:
91 |
92 | ```php
93 | use Ignite\Support\Facades\Lit;
94 |
95 | $litLocale = Lit::getLocale();
96 |
97 | if (Lit::isLocale('en')) {
98 | //
99 | }
100 | ```
101 |
102 | ## Add Path
103 |
104 | By default the path `lit/resources/lang` is imported for the admin translation.
105 | You can register any number of paths with localization files in your service
106 | providers. However, it is recommended to keep the translations for the admin
107 | application and your website separate.
108 |
109 | ```php
110 | use Ignite\Support\Facades\Lang;
111 |
112 | Lang::addPath(base_path('yourpath/lang/'));
113 | ```
114 |
115 | ::: tip
116 |
117 | All translation attributes are merged, which makes it easy to extend existing
118 | localizations for parts like **validation** or others.
119 |
120 | :::
121 |
--------------------------------------------------------------------------------
/basics/navigation.md:
--------------------------------------------------------------------------------
1 | # Navigation
2 |
3 | ## Introduction
4 |
5 | Your admin app by default contains two navigations: the **topbar** and your
6 | **main** navigation.
7 |
8 | Both navigation instances are configured in
9 | `lit/app/Config/NavigationConfig.php` which looks as follows:
10 |
11 | ```php{lit/app/Config/NavigationConfig.php}
12 | class NavigationConfig extends Config
13 | {
14 | public function topbar(Navigation $nav)
15 | {
16 | // Build your topbar navigation in here.
17 | }
18 |
19 | public function main(Navigation $nav)
20 | {
21 | // Build your main navigation in here.
22 | }
23 | }
24 | ```
25 |
26 | 
27 |
28 | ### Topbar
29 |
30 | The **topbar** navigation is meant for managing less important parts of your
31 | application, such as language and/or permissions.
32 |
33 | ### Main
34 |
35 | The **main** navigation is intended to provide quick access to the important
36 | components of your application. These could be for example Models or page
37 | content. Entries of the main navigation can be divided into
38 | [sections](#sections), additionally [groups](#groups) can be created which are
39 | displayed as a dropdown. More than one depth is not possible here.
40 |
41 | ## Building the Navigation
42 |
43 | The following explains how the navigations are built. The procedure is the same
44 | for the **topbar** and the **main** navigation. With a difference that only the
45 | **main** navigation can contain groups.
46 |
47 | ### Sections
48 |
49 | A section can contain a list of entries. An optional title can be prepended to
50 | the entries like shown in the example:
51 |
52 | ```php
53 | $nav->section([
54 |
55 | // The Section title describes the following set of navigation entries.
56 | $nav->title('Bookings'),
57 |
58 | ...
59 | ]);
60 | ```
61 |
62 | ### Entry
63 |
64 | Simple entries have a `title`, a `link`, and an `icon`. The
65 | [Font Awesome](https://fontawesome.com/icons?d=gallery&m=free) icons are
66 | included by default.
67 |
68 | ```php
69 | $nav->entry('Home', [
70 | 'link' => route('your.route'), // Route
71 | 'icon' => '' // Font Awesome icon
72 | ]),
73 | ```
74 |
75 | ### Groups
76 |
77 | Create nested navigation entries in groups.
78 |
79 | ```php
80 | $nav->group([
81 | 'title' => 'Pages',
82 | 'icon' => '',
83 | ], [
84 |
85 | $nav->entry(...),
86 | ...
87 |
88 | ]),
89 | ```
90 |
91 | ### Authorization
92 |
93 | To hide navigation entries from users without the necessary permission, an
94 | `authorize` closure can be specified in which permissions for the logged in
95 | litstack user can be queried.
96 |
97 | ```php
98 | use Ignite\User\Models\User;
99 |
100 | $nav->entry('Home', [
101 | // ...
102 |
103 | 'authorize' => function(User $user) {
104 | return $user->can('read page-home');
105 | }
106 | ]),
107 | ```
108 |
109 | ### Presets
110 |
111 | To build navigation entries, for example for Crud models, you can use navigation
112 | presets in which the corresponding `route` and `authorization` have already been
113 | defined. This is useful in most cases, especially to maintain the correct
114 | `authorization`. To edit the entry further you can specify an array with the
115 | navigation entry elements in a second parameter.
116 |
117 | ```php
118 | $nav->preset('crud.departments', [
119 | 'icon' => fa('building')
120 | ]),
121 | ```
122 |
123 | ::: tip
124 |
125 | A list of all registered navigation presets can be displayed with
126 | `php artisan lit:nav`.
127 |
128 | :::
129 |
--------------------------------------------------------------------------------
/basics/page.md:
--------------------------------------------------------------------------------
1 | # Page
2 |
3 | ## Introduction
4 |
5 | Pages are a fundamental part of the package. They provide a convenient and yet
6 | powerful way to configure pages for the Vue application in PHP. They can be
7 | used to integrate **Blade Views**, **Vue components** or ready-made components
8 | such as **charts** or form fields for models.
9 |
10 | Pages are used to configure forms with fields, index pages, dashboards with
11 | charts or basically any kind of page for the admin backend.
12 |
13 | ## Create a Page
14 |
15 | A page can be simply created by returning an instance of `Ignite\Page\Page` like
16 | so:
17 |
18 | ```php
19 | namespace Lit\Controllers;
20 |
21 | use Ignite\Page\Page;
22 |
23 | class MyPageController
24 | {
25 | public function __invoke()
26 | {
27 | $page = new Page;
28 |
29 | return $page->title('My Page');
30 | }
31 | }
32 | ```
33 |
34 | This will show an empty page with the title `My Page`:
35 |
36 | 
37 |
38 | ## View
39 |
40 | You can easily integrate your own blade components with using `view`:
41 |
42 | ```php
43 | $page = new Page;
44 |
45 | $page->view('hello');
46 |
47 | return $page->title('My Page');
48 | ```
49 |
50 | ```php
51 |
52 |
53 |
54 |
Hello World!
55 |
56 |
57 |
58 | ```
59 |
60 | And voila we have our first Page with content saying `Hello World!` using pure
61 | Blade.
62 |
63 | 
64 |
65 | ## Component
66 |
67 | Just like Blade Views, Vue components can be easily integrated into your page.
68 | To do this, the **name** of the desired Vue component must be passed as the
69 | first parameter to the `component method:
70 |
71 | ```php
72 | $page->component('my-component');
73 | ```
74 |
75 | You may also pass a **prop** to the component:
76 |
77 | ```php
78 | $page->component('my-component')->prop('color', 'green');
79 | ```
80 |
81 | Or bind an array that should be passed as **props** to the component:
82 |
83 | ```php
84 | $page->component('my-component')->bind([
85 | 'title' => 'My Title',
86 | 'color' => 'green'
87 | ]);
88 | ```
89 |
90 | ## Bind Data
91 |
92 | You may want to bind global data to all views and components contained in the
93 | page. This can be done by passing an array containing the data to the `bind`
94 | method like this:
95 |
96 | ```php
97 | $page->bind($data);
98 | ```
99 |
100 | The data is now accessible in Blade Views and is passed to Vue components as
101 | props. However, you might want to pass data only to Blade Views or only to Vue
102 | components. You can use `bindToView` and `bindToVue` in that case:
103 |
104 | ```php
105 | $page->bindToView($data);
106 | $page->bindToVue($data);
107 | ```
108 |
109 | ## Expand
110 |
111 | The container of your Page has a maximum width by default. However, you can
112 | expand the container to the full width. For example, to be able to display large
113 | tables completely.
114 |
115 | ```php
116 | $page->expand();
117 | ```
118 |
119 | ## Slots
120 |
121 | On a page there are different **slots** to which elements such as buttons can be
122 | added. These slots are located in two areas:
123 |
124 | - **navigation** - a `sticky` bar on the top of every page
125 | - **header** - contains a title that describes the pages content
126 |
127 | The following screenshot shows the existing slots and where they are located.
128 |
129 | 
130 |
131 | Views or Vue components can be added to each slot:
132 |
133 | ```php
134 | $page->navigationLeft()->view('my_button');
135 | $page->navigationLeft()->component('my-button');
136 | ```
137 |
138 | ### Navigation
139 |
140 | Available slots for the **navigation** are: `left`, `right`, `controls`
141 |
142 | ```php
143 | $page->navigationLeft();
144 | $page->navigationRight();
145 | $page->navigationControls();
146 | ```
147 |
148 | ### Header
149 |
150 | Available slots for the **header** are: `left`, `right`
151 |
152 | ```php
153 | $page->headerLeft();
154 | $page->headerRight();
155 | ```
156 |
--------------------------------------------------------------------------------
/basics/screens/navigation.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/basics/screens/navigation.jpg
--------------------------------------------------------------------------------
/basics/screens/page_slots.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/basics/screens/page_slots.jpg
--------------------------------------------------------------------------------
/basics/screens/page_title.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/basics/screens/page_title.jpg
--------------------------------------------------------------------------------
/basics/screens/page_view.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/basics/screens/page_view.jpg
--------------------------------------------------------------------------------
/charts/area.md:
--------------------------------------------------------------------------------
1 | # Area Chart
2 |
3 | 
4 |
5 | An area chart is generated by adding the `--area` flag to the artisan command
6 | `lit:chart {name}`.
7 |
8 | ```shell
9 | php artisan lit:chart SalesProductsChart --area
10 | ```
11 |
12 | ## Configuration
13 |
14 | Which data is displayed in your chart is configured in the `value` method as
15 | shown below.
16 |
17 | ```php
18 | public function value($query)
19 | {
20 | return $this->count($query);
21 | }
22 | ```
23 |
24 | Possible methods:
25 |
26 | ```php
27 | return $this->count($query);
28 | return $this->average($query, 'price');
29 | return $this->min($query, 'price');
30 | return $this->max($query, 'price');
31 | return $this->sum($query, 'price');
32 | ```
33 |
--------------------------------------------------------------------------------
/charts/bar.md:
--------------------------------------------------------------------------------
1 | # Bar Chart
2 |
3 |
4 |
5 |
6 |
7 | A bar chart is generated by adding the `--bar` flag to the artisan command
8 | `lit:chart {name}`.
9 |
10 | ```shell
11 | php artisan lit:chart SalesProductsChart --bar
12 | ```
13 |
14 | ## Configuration
15 |
16 | Which data is displayed in your chart is configured in the `value` method as
17 | shown below.
18 |
19 | ```php
20 | public function value($query)
21 | {
22 | return $this->count($query);
23 | }
24 | ```
25 |
26 | Possible methods:
27 |
28 | ```php
29 | return $this->count($query);
30 | return $this->average($query, 'price');
31 | return $this->min($query, 'price');
32 | return $this->max($query, 'price');
33 | return $this->sum($query, 'price');
34 | ```
35 |
--------------------------------------------------------------------------------
/charts/basics.md:
--------------------------------------------------------------------------------
1 | # Charts
2 |
3 | ## Introduction
4 |
5 | Charts can be used to visualize model data and give the user an overview of
6 | whats going on in his application in a selected time period. Charts can be
7 | displayed on dashboards, index pages as well as on crud detail pages.
8 |
9 | ## Create via Artisan
10 |
11 | Each chart has its own config file. The artisan command `lit:chart {name}`
12 | generates the chart config into `./lit/app/Config/Charts`.
13 |
14 | ```shell
15 | php artisan lit:chart SalesCountChart --area
16 | ```
17 |
18 | When no type is given as a flag the default chart type `area` will be generated.
19 |
20 | ```shell
21 | php artisan lit:chart MyChart --area
22 | # Creates an area chart.
23 |
24 | php artisan lit:chart MyChart --bar
25 | # Creates a bar chart.
26 |
27 | php artisan lit:chart MyChart --donut
28 | # Creates a donut chart.
29 |
30 | php artisan lit:chart MyChart --number
31 | # Creates a number chart.
32 |
33 | php artisan lit:chart MyChart --progress
34 | # Creates a progress chart.
35 | ```
36 |
37 | The command `lit:chart` creates a chart config in `./lit/app/Config/Charts`.
38 |
39 | With the `--model` option you can directly specify the name of the model:
40 |
41 | ```shell
42 | php artisan lit:chart MyChart --model=Booking
43 | ```
44 |
45 | ## Configure
46 |
47 | Next your chart needs to be configured. Every chart type needs its corresponding
48 | Model class and a title.
49 |
50 | ```php
51 | use App\Models\Sale;
52 |
53 | public $model = Sale::class;
54 |
55 | public function title()
56 | {
57 | return 'Sales Count';
58 | }
59 | ```
60 |
61 | Additionally, each chart type needs a specific configuration, which are linked
62 | below:
63 |
64 | - [Area Chart](area.md)
65 | - [Bar Chart](bar.md)
66 | - [Donut Chart](donut.md)
67 | - [Number Chart](number.md)
68 | - [Progress](progress.md)
69 |
70 | ### Display Relationship Data
71 |
72 | In some cases you may want to display the data of relations on a detail page of
73 | a crud model. To do so, you need to specify the name of the relation for the
74 | model in the relation property.
75 |
76 | Let's assume that you want to display the number of bookings related to a user
77 | and have created an **area** chart with the name `UserBookingsChart`. The config
78 | for this would look as follows:
79 |
80 | With the `--relation` flag the **property** is placed in the class when
81 | generating the chart config.
82 |
83 | ```shell
84 | php artisan lit:chart UserBookingsChart --model=User --relation=bookings
85 | ```
86 |
87 | ```php{lit/app/Config/Charts/UserBookingsChart.php}
88 | count($query);
109 | }
110 | }
111 | ```
112 |
113 | ## Register Charts
114 |
115 | Charts can be registered on pages that extend the `Ignite\Page\Page` class. For
116 | example: `CrudShow` and `CrudIndex`.
117 |
118 | ```php
119 | use Lit\Config\Charts\SalesCountChart;
120 |
121 | $page->chart(SalesCountChart::class);
122 | ```
123 |
124 | :::tip
125 |
126 | Use a [form](../crud/forms.md) as a dashboard by only displaying charts on it.
127 |
128 | :::
129 |
130 | ### Customize Card
131 |
132 | Each chart is displayed in a card. You may customize them to your needs.
133 |
134 | #### Variant
135 |
136 | You may display the card in 3 different variants: `primary`, `secondary`,
137 | `white`
138 |
139 | ```php
140 | use Lit\Config\Charts\SalesCountChart;
141 |
142 | $container->chart(SalesCountChart::class)->variant('primary');
143 | $container->chart(SalesCountChart::class)->variant('secondary');
144 | $container->chart(SalesCountChart::class)->variant('white');
145 | ```
146 |
147 | 
148 |
149 | #### Width
150 |
151 | The width of the chart is indicated by `width`.
152 |
153 | ```php
154 | use Lit\Config\Charts\SalesCountChart;
155 |
156 | $container->chart(SalesCountChart::class)->width(1 / 3);
157 | ```
158 |
159 | #### Height
160 |
161 | The height of the chart is indicated by `height`.
162 |
163 | ```php
164 | use Lit\Config\Charts\SalesCountChart;
165 |
166 | $container->chart(SalesCountChart::class)->height('100px');
167 | ```
168 |
169 | ## Number Formatting
170 |
171 | In the `mount` method the chart can be configured. You can set **format**,
172 | **prefixes**, **suffixes** and **currencies**.
173 |
174 | ```php
175 | public function mount(Chart $chart)
176 | {
177 | $chart->format('0,0')->prefix('$ ')->suffix(' cm');
178 |
179 | // The currency method adds the needed format and suffix:
180 | $chart->currency('€');
181 | }
182 | ```
183 |
--------------------------------------------------------------------------------
/charts/donut.md:
--------------------------------------------------------------------------------
1 | # DonutChart
2 |
3 |
4 |
5 |
6 |
7 | A donut chart is generated by adding the `--donut` flag to the artisan command
8 | `lit:chart {name}`.
9 |
10 | ```shell
11 | php artisan lit:chart SalesProductsChart --donut
12 | ```
13 |
14 | ## Configuration
15 |
16 | Which data is displayed in your chart is configured in the `value` method as
17 | shown below. Unlike other chart types, an array with the desired data must be
18 | returned.
19 |
20 | ```php
21 | public function value($query)
22 | {
23 | return [
24 | $this->count((clone $query)->where('product', 't-shirt')),
25 | $this->count((clone $query)->where('product', 't-shirt')),
26 | ];
27 | }
28 | ```
29 |
30 | Possible methods:
31 |
32 | ```php
33 | return $this->count($query);
34 | return $this->average($query, 'price');
35 | return $this->min($query, 'price');
36 | return $this->max($query, 'price');
37 | return $this->sum($query, 'price');
38 | ```
39 |
40 | For each array item that is returned in the value method, a label must be
41 | specified in the `labels` method:
42 |
43 | ```php
44 | public function labels(): array
45 | {
46 | return [
47 | 'T-shirt',
48 | 'Jacket',
49 | ];
50 | }
51 | ```
52 |
--------------------------------------------------------------------------------
/charts/number.md:
--------------------------------------------------------------------------------
1 | # Number Chart
2 |
3 |
4 |
5 |
6 |
7 | A number chart is generated by adding the `--number` flag to the artisan command
8 | `lit:chart {name}`.
9 |
10 | ```shell
11 | php artisan lit:chart SalesProductsChart --number
12 | ```
13 |
14 | ## Configuration
15 |
16 | Which data is displayed in your chart is configured in the `value` method as
17 | shown below.
18 |
19 | ```php
20 | public function value($query)
21 | {
22 | return $this->count($query);
23 | }
24 | ```
25 |
26 | Possible methods:
27 |
28 | ```php
29 | return $this->count($query);
30 | return $this->average($query, 'price');
31 | return $this->min($query, 'price');
32 | return $this->max($query, 'price');
33 | return $this->sum($query, 'price');
34 | ```
35 |
--------------------------------------------------------------------------------
/charts/progress.md:
--------------------------------------------------------------------------------
1 | # Progress Chart
2 |
3 |
4 |
5 |
6 |
7 | A progress chart is generated by adding the `--progress` flag to the artisan
8 | command `lit:chart {name}`.
9 |
10 | ```shell
11 | php artisan lit:chart SalesProgressChart --progress
12 | ```
13 |
14 | ## Configuration
15 |
16 | Which data is displayed in your chart is configured in the `value` method as
17 | shown below.
18 |
19 | ```php
20 | public function value($query)
21 | {
22 | return $this->count($query);
23 | }
24 | ```
25 |
26 | Possible methods:
27 |
28 | ```php
29 | return $this->count($query);
30 | return $this->average($query, 'price');
31 | return $this->min($query, 'price');
32 | return $this->max($query, 'price');
33 | return $this->sum($query, 'price');
34 | ```
35 |
--------------------------------------------------------------------------------
/charts/screens/bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/charts/screens/bar.png
--------------------------------------------------------------------------------
/charts/screens/donut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/charts/screens/donut.png
--------------------------------------------------------------------------------
/charts/screens/number.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/charts/screens/number.png
--------------------------------------------------------------------------------
/charts/screens/progress.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/charts/screens/progress.png
--------------------------------------------------------------------------------
/charts/screens/variants.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/charts/screens/variants.png
--------------------------------------------------------------------------------
/configuration.md:
--------------------------------------------------------------------------------
1 | # Configuration
2 |
3 | ## Introduction
4 |
5 | A configuration file can be found in the laravel config directory
6 | `config/lit.php`.
7 |
8 | ## Basics
9 |
10 | In the following some basic configurations for the admin backend are explained.
11 | All specific configurations are explained in the corresponding documentation.
12 |
13 | Basic configuration keys:
14 |
15 | - `route_prefix` Backend route prefix.
16 | - `default_route` Redirect after login. `route_prefix` is already prepended.
17 | - `login.username` Allow logging in using username or email.
18 | - `translatable` Controls the multilingualism of the admin interface.
19 |
20 | ## Styles And Scripts
21 |
22 | Styles and Scripts can easily be added to your the application:
23 |
24 | ```php
25 | use Ignite\Support\Facades\Lit;
26 |
27 | Lit::style('path/to/your/style.css');
28 | Lit::script('path/to/your/script.js');
29 | ```
30 |
--------------------------------------------------------------------------------
/crud/actions.md:
--------------------------------------------------------------------------------
1 | # Actions
2 |
3 | ## Introduction
4 |
5 | Actions are a convenient feature to create reusable tasks for models. Each
6 | action can be placed in different locations. For example in your index table or
7 | on a detail page of a model.
8 |
9 | ## Create
10 |
11 | Create an action via artisan:
12 |
13 | ```shell
14 | php artisan lit:action MyAction
15 | ```
16 |
17 | The created actions are located in `./lit/app/Actions`.
18 |
19 | ```php
20 | namespace Lit\Actions;
21 |
22 | use Illuminate\Support\Collection;
23 |
24 | class MyAction
25 | {
26 | public function run(Collection $models)
27 | {
28 | // Do Something.
29 | }
30 | }
31 | ```
32 |
33 | ## Responses
34 |
35 | When a `message` is returned via a json response, a toast is displayed in the
36 | lower right corner of the page containing the message. This can be displayed in
37 | four variants: `success`, `info`, `warning`, `danger`. The default is `success`.
38 |
39 | ```php
40 | public function run(Collection $models)
41 | {
42 | return response()->json(['message' => 'Hello there!', 'variant' => 'info']);
43 | }
44 | ```
45 |
46 | There is a helper for each variant:
47 |
48 | ```php
49 | return response()->success('My message.');
50 | return response()->info('My message.');
51 | return response()->warning('My message.');
52 | return response()->danger('My message.');
53 | ```
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | ### Redirects
63 |
64 | In some cases you may want to redirect the user to another page after the action
65 | has been executed. This can be done as usual by returning a
66 | [redirect](https://laravel.com/docs/7.x/redirects).
67 |
68 | ```php
69 | public function run(Collection $models)
70 | {
71 | // Do Something.
72 |
73 | return redirect('your/redirect/url');
74 | }
75 | ```
76 |
77 | ## Confirm Modal
78 |
79 | If your action has the function modal, the execution of the action must be
80 | confirmed via a modal.
81 |
82 | ```php
83 | namespace Lit\Actions;
84 |
85 | use Illuminate\Support\Collection;
86 | use Ignite\Page\Actions\ActionModal;
87 |
88 | class MyAction
89 | {
90 | public function modal(ActionModal $modal)
91 | {
92 | $modal->confirmVariant('primary')
93 | ->confirmText('Run')
94 | ->message('Do you want to run the Action?');
95 | }
96 |
97 | public function run(Collection $models)
98 | {
99 | // Do Something.
100 | }
101 | }
102 | ```
103 |
104 | ## Fields
105 |
106 | Form fields can be added to the confirm modal of an action. The values of these
107 | fields are passed to the action. This allows you, for example, to let the user
108 | type in a message to be sent by mail, as shown the following example.
109 |
110 | ```php
111 | use Illuminate\Support\Collection;
112 | use Ignite\Page\Actions\ActionModal;
113 | use Ignite\Page\Actions\AttributeBag;
114 |
115 | public function modal(ActionModal $modal)
116 | {
117 | $modal->form(function($form) {
118 | $form->text('message')->title('Message');
119 | });
120 | }
121 |
122 | public function run(Collection $models, AttributeBag $attributes)
123 | {
124 | foreach($models as $model) {
125 | Mail::to($model)->send(new ExampleEmail($attributes->message));
126 | }
127 | }
128 | ```
129 |
130 |
131 |
132 |
133 |
134 | ## Display the Action
135 |
136 | ### In a Table
137 |
138 | There are multiple places where an `action` can be displayed in a table, first
139 | of all an action can be executed for all selected items:
140 |
141 | ```php
142 | // CrudConfig
143 |
144 | use Lit\Actions\MyAction;
145 |
146 | public function index(CrudIndex $page)
147 | {
148 | $page->table(...)
149 | ->action('My Action', MyAction::class);
150 | }
151 | ```
152 |
153 | Additionally actions can be displayed in table columns to make important actions
154 | more accessible. You can add either one action as a button or several actions as
155 | dropdown to a column:
156 |
157 | ```php
158 | use Lit\Actions\MyAction;
159 | use Lit\Actions\OtherAction;
160 |
161 | $page->table(function($table) {
162 | // Single action as button:
163 | $table->action('My Action', MyAction::class);
164 |
165 | // Multiple actions as dropdown:
166 | $table->actions([
167 | 'My Action' => MyAction::class,
168 | 'Other Action' => OtherAction::class,
169 | ]);
170 | });
171 | ```
172 |
173 | ### On a Page
174 |
175 | Actions can also be displayed on the show page of a crud, even in the slots
176 | `navigationLeft`, `navigationRight`, `navigationControls`, `headerLeft` and
177 | `headerRight`:
178 |
179 | 
180 |
181 | ```php
182 | // CrudConfig
183 |
184 | use Lit\Actions\MyAction;
185 |
186 | public function show(CrudShow $page)
187 | {
188 | $page->navigationLeft()->action('My Action', MyAction::class);
189 | $page->navigationRight()->action('My Action', MyAction::class);
190 | $page->navigationControls()->action('My Action', MyAction::class);
191 | $page->headerLeft()->action('My Action', MyAction::class);
192 | $page->headerRight()->action('My Action', MyAction::class);
193 | }
194 | ```
195 |
196 | You may even place it somewhere on your page:
197 |
198 | ```php
199 | $page->card(function($page) {
200 | $page->action('My Action', MyAction::class);
201 | });
202 | ```
203 |
204 | The `variant` of the actions that are displayed as buttons can be adjusted:
205 |
206 | ```php
207 | $page->headerLeft()
208 | ->action('My Action', MyAction::class)
209 | ->variant('outline-primary');
210 | ```
211 |
212 | ## Conditional Actions
213 |
214 | You may want to display actions depending on the value of a model attribute.
215 | This can be achieved by applying any of the existing
216 | [field dependencies](../fields/conditions.md#usage) to your action like this:
217 |
218 | ```php
219 | $page->headerLeft()
220 | ->action('cancel', CancelBookingAction::class)
221 | ->whenNot('state', 'canceled');
222 | ```
223 |
--------------------------------------------------------------------------------
/crud/forms.md:
--------------------------------------------------------------------------------
1 | # Forms
2 |
3 | ## Introduction
4 |
5 | Forms provide a convenient way to store, organize and maintain data of many
6 | kinds, such as your page content. You may create as many `Forms` as you like.
7 |
8 | Think of a `form` as a model with **dynamic** attributes. Its structure may
9 | change at any time. `Forms` are being managed on a crud-page just like
10 | [crud models](model.md).
11 |
12 | Forms are grouped into form `collections` to keep the overview. For example, the
13 | forms **home** and **faq**, which contain the page content for the pages
14 | **home** and **faq**, could be included in the `collection` **pages**.
15 |
16 | ## Generate Form
17 |
18 | A `form` can be created using the following artisan command:
19 |
20 | ```shell
21 | php artisan lit:form
22 | ```
23 |
24 | A wizard will take you through all required steps. You may also create the form by adding the **collection** and the **name** as arguments to the artisan command:
25 |
26 | ```php
27 | php artisan lit:form pages home
28 | ```
29 |
30 | The corresponding `config`
31 | and the `controller` is created afterwards.
32 |
33 | A config file and a controller will be generated. Checkout the [model](model.md)
34 | documentation to learn how to apply **permissions** on forms.
35 |
36 | ## Navigation
37 |
38 | Add the navigation entry by adding the namespace of the newly generated config
39 | to your navigation.
40 |
41 | ```php{lit/app/Config/NavigationConfig.php}
42 | use Lit\Config\Pages\HomeConfig;
43 |
44 | $nav->preset(HomeConfig::class, ['icon' => fa('home')]),
45 | ```
46 |
47 | ## Configuration
48 |
49 | Define the form config in the created config file:
50 | `Config/Form/{collection}/{form}Config.php`. First the controller must be
51 | specified in the config:
52 |
53 | ```php
54 | use Lit\Controllers\Form\Pages\HomeController;
55 |
56 | /**
57 | * Controller class.
58 | *
59 | * @var string
60 | */
61 | public $controller = HomeController::class;
62 | ```
63 |
64 | ### Form Fields
65 |
66 | All form fields for the form are specified in the `show` method:
67 |
68 | ```php
69 | public function show($page)
70 | {
71 | $page->card(function($form) {
72 | $form->input('title');
73 | });
74 | }
75 | ```
76 |
77 | Read the [Crud Show](show.md) documentation to learn more on how to customize
78 | your forms.
79 |
80 | ## Retrieve Data
81 |
82 | In order to retrieve the form data, you have to add the **Form Facade** to your
83 | controller. Data can now be easily retrieved with the `load` function like this:
84 |
85 | ```php
86 | use Ignite\Support\Facades\Form;
87 |
88 | $form = Form::load('pages', 'home');
89 | ```
90 |
91 | This allows the data to be passed directly to a
92 | [View](https://laravel.com/docs/7.x/blade#displaying-data).
93 |
94 | ```php
95 | use Ignite\Support\Facades\Form;
96 |
97 | return view('home')->with([
98 | 'home' => Form::load('pages', 'home')
99 | ]);
100 | ```
101 |
102 | and be used in a Blade template:
103 |
104 | ```php
105 | {{ $home->title }}
106 | ```
107 |
108 | ### Load Using Namespace
109 |
110 | If you want to load the form data of a single config, you can also use the
111 | static load function of the config. This allows you to "click" directly into the
112 | class in your editor.
113 |
114 | ```php
115 | use Lit\Config\Form\Pages\Home;
116 |
117 | $home = HomeConfig::load();
118 |
119 | echo $home->title;
120 | ```
121 |
122 | ### Retrieve A Full Collection
123 |
124 | It is also possible to load all data for a collection as shown in the example:
125 |
126 | ```php
127 | use Ignite\Support\Facades\Form;
128 |
129 | $settings = Form::load('settings');
130 |
131 | echo $settings->main->title;
132 | ```
133 |
--------------------------------------------------------------------------------
/crud/index.md:
--------------------------------------------------------------------------------
1 | # Index Config
2 |
3 | ## Introduction
4 |
5 | Each Crud configuration can have an index page that shows an overview of the
6 | models. This index page is configured in the `index` method of its corresponding
7 | config.
8 |
9 | ```php
10 | use Ignite\Crud\CrudIndex;
11 |
12 | public function index(CrudIndex $page)
13 | {
14 | // Build your index page here.
15 | }
16 | ```
17 |
18 | `Ignite\Crud\CrudIndex` is an instance of `Ignite\Page\Page` so all functions
19 | described in the [Page](../basics/page.md) documentation can be used. This
20 | includes binding Vue components or Blade views components to a page:
21 |
22 | ```php
23 | $page->component('foo'); // Vue component
24 | $page->view('foo'); // Blade view
25 | ```
26 |
27 | In the Config for a CRUD model its index table is defined.
28 |
29 | ## Table
30 |
31 | The index table is built using the method `table` like this:
32 |
33 | ```php
34 | use Ignite\Crud\CrudIndex;
35 |
36 | public function index(CrudIndex $page)
37 | {
38 | $page->table(function($table) {
39 | $table->col('Name')->value('{first_name} {last_name}');
40 | });
41 | }
42 | ```
43 |
44 | The [table config](table.md) describes how columns with **images**,
45 | **relations** and much more can be built.
46 |
47 | ## Eager Loading
48 |
49 | Eager loadings can be performed in the `query` method. Here you can modify the
50 | query that is executed when loading the index table items.
51 |
52 | ```php
53 | use Ignite\Crud\CrudIndex;
54 |
55 | public function index(CrudIndex $page)
56 | {
57 | $page->table(...)
58 | ->query(function($query) {
59 | $query->with('department')->withCount('projects_count');
60 | });
61 | }
62 | ```
63 |
64 | ## Search
65 |
66 | All attributes to be searched for are specified in `search`. You can also
67 | specify `relations` and their attributes.
68 |
69 | ```php
70 | use Ignite\Crud\CrudIndex;
71 |
72 | public function index(CrudIndex $page)
73 | {
74 | $page->table(...)->search('title', 'department.name');
75 | }
76 | ```
77 |
78 | ## Sort
79 |
80 | You can sort by all model `attributes` as well as `relations` `attributes`. The
81 | sortBy attributes are specified as follows: `{attributes}.{desc|asc}`. The
82 | default attribute to sort by is specified in the `sortByDefault` method.
83 |
84 | ```php
85 | use Ignite\Crud\CrudIndex;
86 |
87 | public function index(CrudIndex $page)
88 | {
89 | $page->table(...)->sortByDefault('id.desc');
90 | }
91 | ```
92 |
93 | In this example you can see how the array for the sort attributes can look like
94 | to sort by `id` or by a `relation`.
95 |
96 | ```php
97 | use Ignite\Crud\CrudIndex;
98 |
99 | public function index(CrudIndex $page)
100 | {
101 | $page->table(...)
102 | ->sortBy([
103 | 'id.desc' => 'New first',
104 | 'id.asc' => 'Old first',
105 | 'department.name.desc' => 'Department A-Z',
106 | 'department.name.asc' => 'Department Z-A'
107 | ]);
108 | }
109 | ```
110 |
111 | :::tip
112 |
113 | In case of long loading times when sorted by relation attributes it can help to
114 | add an [index](https://laravel.com/docs/7.x/migrations#indexes) on the column
115 | that connects the relation.
116 |
117 | :::
118 |
119 | ## Filter
120 |
121 | Filters are specified in groups. Laravel's model
122 | [`scopes`](https://laravel.com/docs/7.x/eloquent#local-scopes) are used to
123 | filter the index table as shown in the example:
124 |
125 | ```php{lit/app/Config/PostConfig.php}
126 | use Ignite\Crud\CrudIndex;
127 |
128 | public function index(CrudIndex $page)
129 | {
130 | $page->table(...)
131 | ->filter([
132 | 'Department' => [
133 | 'development' => 'Development',
134 | 'marketing' => 'Marketing',
135 | ],
136 | ]);
137 | }
138 | ```
139 |
140 | ```php{app/Models/Post.php}
141 | public function scopeDevelopment()
142 | {
143 | return $this->hasOne('App\Models\Department')->where('name', 'development');
144 | }
145 |
146 | public function scopeMarketing()
147 | {
148 | return $this->hasOne('App\Models\Department')->where('name', 'marketing');
149 | }
150 | ```
151 |
152 | ### Default Filter
153 |
154 | You may also specify one or more default filter that will be used after the page
155 | is loaded:
156 |
157 | ```php{lit/app/Config/PostConfig.php}
158 | $page->table(...)
159 | ->defaultFilter('development')
160 | ->filter([
161 | 'Department' => [
162 | 'development' => 'Development',
163 | 'marketing' => 'Marketing',
164 | ],
165 | ]);
166 | ```
167 |
168 | ### Custom Filter With Form Fields
169 |
170 | To add filters with form fields like e.g. `checkboxes` or `date` pickers you can
171 | create custom filters. A filter is generated via the artisan command
172 | `lit:filter`:
173 |
174 | ```shell
175 | php artisan lit:filter MyCustomFilter
176 | ```
177 |
178 | The following class will the be generated:
179 |
180 | ```php{lit/app/Filters/MyCustomFilter.php}
181 |
182 | namespace Lit\Filters;
183 |
184 | use Ignite\Crud\Filter\Filter;
185 | use Ignite\Crud\Filter\FilterForm;
186 | use Ignite\Support\AttributeBag;
187 | use Illuminate\Database\Eloquent\Builder;
188 |
189 | class MyCustomFilter extends Filter
190 | {
191 | /**
192 | * Apply field attributes to query.
193 | *
194 | * @param Builder $query
195 | * @param AttributeBag $attributes
196 | * @var void
197 | */
198 | public function apply($query, AttributeBag $attributes)
199 | {
200 | //
201 | }
202 |
203 | /**
204 | * Add filter form fields.
205 | *
206 | * @param FilterForm $form
207 | * @return void
208 | */
209 | public function form(FilterForm $form)
210 | {
211 | //
212 | }
213 | }
214 | ```
215 |
216 | #### Add Form Fields
217 |
218 | You can now add fields like this:
219 |
220 | ```php
221 | public function form(FilterForm $form)
222 | {
223 | $form->datetime('from');
224 | $form->datetime('to');
225 | }
226 | ```
227 |
228 | Or Checkboxes:
229 |
230 | ```php
231 | use App\Models\Tag;
232 |
233 | public function form(FilterForm $form)
234 | {
235 | $options = Tag::all()->pluck('name')->toArray();
236 |
237 | $form->checkboxes('tags')->options($options);
238 | }
239 | ```
240 |
241 | #### Apply Field Attributes To The Query
242 |
243 | The next thing you want to do is to apply the field attributes to the query:
244 |
245 | ```php
246 | public function apply($query, AttributeBag $attributes)
247 | {
248 | if ($attributes->from) {
249 | $query->where('created_at', '>=', $attributes->from);
250 | }
251 |
252 | if ($attributes->to) {
253 | $query->where('created_at', '<', $attributes->to);
254 | }
255 | }
256 | ```
257 |
258 | #### Use Custom Filter
259 |
260 | The custom Filter can now be used for your CRUD index:
261 |
262 | ```php{lit/app/Config/PostConfig.php}
263 | use Lit\Filters\MyCustomFilter;
264 |
265 | $page->table(...)
266 | ->filter([
267 | 'Button Text' => MyCustomFilter::class,
268 | ]);
269 | ```
270 |
271 | ## Pagination
272 |
273 | The maximum number of items to be displayed on a page is defined in `perPage`.
274 | The default is `10`.
275 |
276 | ```php
277 | use Ignite\Crud\CrudIndex;
278 |
279 | public function index(CrudIndex $page)
280 | {
281 | $page->table(...)->perPage(5);
282 | }
283 | ```
284 |
--------------------------------------------------------------------------------
/crud/model.md:
--------------------------------------------------------------------------------
1 | # Models
2 |
3 | ## Introduction
4 |
5 | The main task of an admin panel is to manage data. Litstack offers easy editing
6 | and managing of
7 | [Laravel Eloquent Models](https://laravel.com/docs/7.x/eloquent). It lets you
8 | attach a variety of **form fields** to model attributes. There are **relation
9 | fields** that to link any available models in any laravel relation, and the
10 | ability to attach fields to attributes from pivot tables.
11 |
12 | The administrative views of a model include two views. An index view with a
13 | table and a detail view in which information for a single model can be displayed
14 | or edited. These are configured in litstack in the so-called configs. The
15 | `./lit/app/Config/Crud` directory contains all configuration files for your
16 | CRUD-Models. Each model may have one or more config files.
17 |
18 | ::: tip
19 |
20 | Configurations can be created for existing Models.
21 |
22 | :::
23 |
24 | Litstack also uses the following Open-Source packages to extend the
25 | functionality of Models:
26 |
27 | - [Astronomic Translatable](https://docs.astrotomic.info/laravel-translatable/)
28 | Used for Model translations.
29 | - [Spatie Medialibrary](https://docs.spatie.be/laravel-medialibrary/v8/introduction/)
30 | Used for media management.
31 | - [Cviebrock Sluggable](https://github.com/cviebrock/eloquent-sluggable) Used
32 | to apply slugs to model attributes.
33 |
34 | ## Generate Config
35 |
36 | Assuming you want to generate a crud-config for the Model with the name `Post`,
37 | you can simply generate a crud-config for the model using the `lit:crud`
38 | command.
39 |
40 | ```shell
41 | php artisan lit:crud Post
42 | ```
43 |
44 | Executing the command will create all necessary files, unless they already
45 | exist:
46 |
47 | - The migration for the `posts` Table
48 | - The model `App\Models\Post`
49 | - The config `./lit/app/Config/Crud/PostConfig`
50 | - The controller `./lit/app/Http/Controllers/Crud/PostController`
51 |
52 | Now the config can be added to the navigation so it can be reached via your
53 | admin panel.
54 |
55 | ```php{lit/app/Config/NavigationConfig.php}
56 | use Lit\Config\Crud\PostConfig;
57 |
58 | $nav->preset(PostConfig::class, ['icon' => fa('newspaper')]),
59 | ```
60 |
61 | ### Config Name
62 |
63 | Since you are able to create **multiple** configurations for the same model, in
64 | some cases you may want to use a config name that does not begin with the class
65 | name of the model. The name of the config can be given as the second argument to
66 | the `lit:crud` command:
67 |
68 | ```shell
69 | php artisan lit:crud User StargazerConfig
70 | ```
71 |
72 | ## Media
73 |
74 | If your model should have media like pictures or pdfs, it needs to implement the
75 | `Spatie\MediaLibrary\HasMedia` **interface** and use the **trait**
76 | `Ignite\Crud\Models\Traits\HasMedia`, as shown in the following example:
77 |
78 | ```php{app/Models/Post.php}
79 | namespace App\Models;
80 |
81 | use Ignite\Crud\Models\Traits\HasMedia;
82 | use Illuminate\Database\Eloquent\Model;
83 | use Spatie\MediaLibrary\HasMedia as HasMediaContract;
84 |
85 | class Test extends Model implements HasMediaContract
86 | {
87 | use HasMedia;
88 |
89 | // ...
90 | }
91 | ```
92 |
93 | Litstack generates the a Model with the needed requirements by adding the
94 | `--media` (or short `-m`) options to the `lit:crud` command:
95 |
96 | ```shell
97 | php artisan lit:crud Post -m
98 | ```
99 |
100 | Now you can add images to your model via the [image field](../fields/image.md).
101 |
102 | ## Translatable
103 |
104 | The litstack form fields make managing translatable content easier than ever:
105 |
106 | ```php
107 | $form->input('title')->translatable();
108 | ```
109 |
110 | To use translatable fields in models the correct configuration is required,
111 | which is done from within the **migration** and the **model**, as described
112 | below.
113 |
114 | ::: tip
115 |
116 | The required configuration is generated automatically by adding the
117 | `--translatable` (or short `-t`) option to the `lit:crud` command.
118 |
119 | :::
120 |
121 | ### Migration
122 |
123 | In the migration a second table must be created, which contains the translatable
124 | fields. For `posts` this would be `post_translations`. All required **columns**
125 | can be added to the translations table by using `translates` with the name of
126 | the table to be translated. In the following example the column title is
127 | translatable for the posts table.
128 |
129 | ```php{database/migrations/*create_posts_table.php}
130 | Schema::create('posts', function (Blueprint $table) {
131 | $table->bigIncrements('id');
132 | $table->timestamps();
133 | });
134 | Schema::create('post_translations', function (Blueprint $table) {
135 | $table->translates('posts');
136 | $table->string('title');
137 | });
138 | ```
139 |
140 | ### Model
141 |
142 | Your translation model, in our case post, needs the **interface**
143 | `Astrotomic\Translatable\Contracts\Translatable` and the **trait**
144 | `Ignite\Crud\Models\Traits\Translatable`. Furthermore, all translatable
145 | attributes are specified in the `translatedAttributes` property.
146 |
147 | ```php{app/Models/Post.php}
148 | setLocale('en');
218 | echo $post->title; // Echo's english value.
219 |
220 | app()->setLocale('de');
221 | echo $post->title; // Echo's german value.
222 | ```
223 |
224 | ::: tip
225 |
226 | Read more about translatable models in the
227 | [package documentation](https://docs.astrotomic.info/laravel-translatable/).
228 |
229 | :::
230 |
231 | ## Sluggable
232 |
233 | Models that should have one or more slugs need the trait
234 | `Ignite\Crud\Models\Traits\Sluggable`. The trait is automatically added to the
235 | mode when it is created by the command `lit:crud` with the option `--slug`
236 | (short `-s`):
237 |
238 | ```shell
239 | php artisan lit:crud Post -s
240 | ```
241 |
242 | The `sluggable` method of the model specifies which attributes contain slugs and
243 | from which attributes the slugs are built. In the following example the column
244 | `slug` contains the slug that is built from the value of `title`.
245 |
246 | ```php
247 | namespace App\Models;
248 |
249 | use Ignite\Crud\Models\Traits\Sluggable;
250 | use Illuminate\Database\Eloquent\Model;
251 |
252 | class Post extends Model
253 | {
254 | use Sluggable;
255 |
256 | protected $fillable = ['title'];
257 |
258 | public function sluggable(): array
259 | {
260 | return [
261 | 'slug' => [
262 | 'source' => 'title',
263 | ],
264 | ];
265 | }
266 | }
267 | ```
268 |
269 | ::: tip
270 |
271 | Read more about the sluggable options in the
272 | [package documentation](https://github.com/cviebrock/eloquent-sluggable).
273 |
274 | :::
275 |
276 | ::: warning
277 |
278 | Make sure the **Sluggable** trait and configuration are in the correct Model
279 | when using **translatable** Models.
280 |
281 | :::
282 |
283 | ## Fill Model On Create & Update
284 |
285 | You may want fill attributes to the model before it gets created or updated from
286 | the user via a crud form. This can be achieved by modifying the Model in either
287 | `fillOnStore` or `fillOnUpdate` the crud controller.
288 |
289 | The following example show's how to assign an author to a post by setting the
290 | `author_id` to the authenticated litstack user id.
291 |
292 | ```php{lit/app/Http/Controllers/Crud/PostController.php}
293 | namespace Lit\Http\Controllers\Crud;
294 |
295 | use Ignite\Crud\Controllers\CrudController;
296 | use Lit\Models\User;
297 |
298 | class PostController extends CrudController
299 | {
300 | public function fillOnStore($post)
301 | {
302 | $post->author_id = lit_user()->id;
303 | }
304 |
305 | public function fillOnUpdate($post)
306 | {
307 | // ...
308 | }
309 | }
310 | ```
311 |
312 | ## Permissions
313 |
314 | Litstack brings not only a super simple **permission manager**, but also a
315 | simple way to create permissions and bind them to crud models. The desired
316 | permissions just need to be added to the migration `*_make_permissions.php` and
317 | will be added to the database by executing the `lit:permissions` command.
318 |
319 | ### Create Permissions
320 |
321 | So let's create crud permissions for our posts example. So we add `posts` to the
322 | `crudPermissionGroups` property. This will create the following permissions:
323 |
324 | - `create posts`
325 | - `read posts`
326 | - `update posts`
327 | - `delete posts`
328 |
329 | ```php{database/migrations/______________________make_permissions.php}
330 | protected $crudPermissionGroups = [
331 | // ...
332 |
333 | 'posts'
334 | ];
335 | ```
336 |
337 | and execute the command:
338 |
339 | ```shell
340 | php artisan lit:permissions
341 | ```
342 |
343 | ### Apply Permissions
344 |
345 | The controller that comes with the crud contains the authorize method. The
346 | second parameter is the operation to be executed. So now we can check if the
347 | authenticated user has the permission to operate on the group `posts` by
348 | returning `$user->can("{$operation} posts")`:
349 |
350 | ```php{lit/app/Http/Controllers/Crud/PostController.php}
351 | can("{$operation} posts");
372 | }
373 | }
374 | ```
375 |
376 | ### Authorize individual Models
377 |
378 | You may want to authorize individual models. This can be achieved by adding the
379 | initial query in the `query` method. The following example shows how models can
380 | be hidden by users who did not create them:
381 |
382 | ```php{lit/app/Http/Controllers/Crud/PostController.php}
383 | class PostController
384 | {
385 | public function query($query)
386 | {
387 | $query->where('created_by', lit_user()->id);
388 | }
389 | }
390 | ```
391 |
392 | ## Navigation
393 |
394 | Add the navigation entry by adding the config namespace preset to your
395 | navigation.
396 |
397 | ```php
398 | $nav->preset(PostConfig::class, ['icon' => fa('newspaper')]),
399 | ```
400 |
401 | ## Configuration
402 |
403 | Define the CRUD-Config in the created config file:
404 | `Config/Crud/{model}Config.php`. First the model and the controller must be
405 | specified in the config:
406 |
407 | ```php
408 | use App\Models\Article;
409 | use Lit\Controllers\Crud\ArticleController;
410 | use Ignite\Crud\Config\CrudConfig;
411 |
412 | class ArticleConfig extends CrudConfig
413 | {
414 | /**
415 | * Model class.
416 | *
417 | * @var string
418 | */
419 | public $model = Article::class;
420 |
421 | /**
422 | * Controller class.
423 | *
424 | * @var string
425 | */
426 | public $controller = ArticleController::class;
427 | }
428 | ```
429 |
430 | ### Index Table, Create & Update Form
431 |
432 | Next, the configuration for the [Index Table](index.md) and the **create** and
433 | **update** [Form](show.md) can be adjusted.
434 |
--------------------------------------------------------------------------------
/crud/screens/action_modal_fields.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/crud/screens/action_modal_fields.png
--------------------------------------------------------------------------------
/crud/screens/message_danger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/crud/screens/message_danger.png
--------------------------------------------------------------------------------
/crud/screens/message_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/crud/screens/message_info.png
--------------------------------------------------------------------------------
/crud/screens/message_success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/crud/screens/message_success.png
--------------------------------------------------------------------------------
/crud/screens/message_warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/crud/screens/message_warning.png
--------------------------------------------------------------------------------
/crud/screens/preview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/crud/screens/preview.gif
--------------------------------------------------------------------------------
/crud/screens/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/crud/screens/search.png
--------------------------------------------------------------------------------
/crud/search.md:
--------------------------------------------------------------------------------
1 | # Search
2 |
3 | You can make models searchable and allow your user to quickly find what they are
4 | looking for.
5 |
6 | 
7 |
8 | ## Setup
9 |
10 | First you need to enable the search by adding the
11 | `Ignite\Search\SearchServiceProvider` service provider to you `lit` config:
12 |
13 | ```php
14 | // ...
15 |
16 | 'providers' => [
17 | // ...
18 | \Ignite\Search\SearchServiceProvider::class,
19 | ]
20 | ```
21 |
22 | Now you choose the crud's that should be searchable and edit the displayed
23 | search result by adding the `searchResult` method to the associated crud config:
24 |
25 | ```php
26 | use App\Models\Order;
27 | use Ignite\Search\Result;
28 |
29 | class OrderConfig extends CrudConfig
30 | {
31 | // ...
32 |
33 | public function searchResult(Result $result, Order $order)
34 | {
35 | $result
36 | ->title("Order #{$order->id}")
37 | ->description($order->products()->count().' Products.')
38 | ->hint("Created By {$order->user->name}")
39 | ->icon(fa('shopping-cart'));
40 | }
41 | }
42 | ```
43 |
44 | And finally register the crud config to your search in the created
45 | `SearchConfig`:
46 |
47 | ```php{lit/app/Config/SearchConfig.php}
48 | public function main(Search $search)
49 | {
50 | $search
51 | ->add(OrderConfig::class)
52 | ->add(CustomerConfig::class);
53 | }
54 | ```
55 |
56 | ## Image Preview
57 |
58 | To add an image preview you may pass the image to the search result:
59 |
60 | ```php
61 | public function searchResult(Result $result, User $user)
62 | {
63 | $result
64 | ->title($user->name)
65 | ->description($user->email)
66 | ->image($user->profile_image);
67 | }
68 | ```
69 |
--------------------------------------------------------------------------------
/crud/show.md:
--------------------------------------------------------------------------------
1 | # Show Config
2 |
3 | ## Introduction
4 |
5 | In the `show` method of a **Form** or a **CRUD** config all components and
6 | fields are configured for editing the data.
7 |
8 | ```php
9 | use Ignite\Crud\CrudShow;
10 |
11 | public function show(CrudShow $page)
12 | {
13 | // Define the page here.
14 | }
15 | ```
16 |
17 | `Ignite\Crud\CrudShow` is an instance of `Ignite\Page\Page` so all functions
18 | described in the [Page](../basics/page.md) documentation can be used. This
19 | includes binding Vue components or Blade views to a page:
20 |
21 | ```php
22 | $page->component('foo'); // Vue component
23 | $page->view('foo'); // Blade view
24 | ```
25 |
26 | ## Card
27 |
28 | Form fields must be grouped into `cards`. You are free to create only one or any
29 | number of cards for a form.
30 |
31 | ```php
32 | use Ignite\Crud\CrudShow;
33 |
34 | public function show(CrudShow $page)
35 | {
36 | $page->card(function ($form) {
37 |
38 | // Build your form in here.
39 |
40 | $form->input('first_name')->title('First Name');
41 |
42 | });
43 | }
44 | ```
45 |
46 | All available fields can be found in the documentation under
47 | [Fields](../fields/introduction.md).
48 |
49 | ### Customize Card
50 |
51 | You may customize your card with the following options:
52 |
53 | | Method | Description |
54 | | --------------------- | ------------------------------------------------------------------- |
55 | | `$card->title('Foo')` | The title description for the card. |
56 | | `$card->width(1/2)` | Width of the card. |
57 | | `$card->secondary()` | Gives your card a secondary background, for less important content |
58 |
59 | ## Group
60 |
61 | With `group` fields can be grouped in a column. This is useful to organize form
62 | elements of different heights side by side.
63 |
64 | ```php
65 | $form->group(function($form) {
66 | // Build your form inside the col.
67 | })->width(6);
68 | ```
69 |
70 | ## Info
71 |
72 | A good content administration interface includes **descriptions** that help the
73 | user to quickly understand what is happening on the interface. Such information
74 | can be created outside and inside of cards like this:
75 |
76 | ```php
77 | use Ignite\Crud\CrudShow;
78 |
79 | public function show(CrudShow $page)
80 | {
81 | $page->info('Address')
82 | ->width(4)
83 | ->text('This address appears on your invoices.')
84 | ->text(...);
85 |
86 | // ...
87 | }
88 | ```
89 |
90 | ## Preview
91 |
92 | 
93 |
94 | You may want to provide a direct **preview** of the crud's associated page. This
95 | can be done using the `preview` method in your crud or form like this:
96 |
97 | ```php
98 | use Ignite\Crud\CrudShow;
99 |
100 | public function show(CrudShow $page)
101 | {
102 | $page->preview(function($post = null, $locale) {
103 | return route('posts.show', [
104 | 'slug' => $post->slug ?? ''
105 | ]);
106 | });
107 | }
108 | ```
109 |
110 | You may even provide a route for every language, so the user gets a preview for
111 | all languages:
112 |
113 | ```php
114 | $page->preview(function($post = null, $locale) {
115 | return route($locale.'.posts.show', [
116 | 'slug' => $post->translate($locale)->slug ?? ''
117 | ]);
118 | });
119 | ```
120 |
121 | ### Default Device
122 |
123 | The default device can be changed in the config `lit.php` under
124 | 'crud.preview.default_device'.
125 |
126 | ```php
127 | 'crud' => [
128 | 'preview' => [
129 | // Available devices: mobile, tablet, desktop
130 | 'default_device' => 'desktop'
131 | ]
132 | ],
133 | ```
134 |
--------------------------------------------------------------------------------
/crud/table.md:
--------------------------------------------------------------------------------
1 | # Table
2 |
3 | ## Introduction
4 |
5 | `tables` can be easily configured in the backend. You can easily display
6 | attributes, relationships or include your own `Vue` components to adjust the
7 | table as needed. The following explains how to customize the tables to your
8 | needs.
9 |
10 | ## Column Value
11 |
12 | ### Text
13 |
14 | Casual text columns are added with the function `col($label)`. Attached are all
15 | methods for configuring the column.
16 |
17 | ```php
18 | $table->col('Name');
19 | ```
20 |
21 | The `value` of the column is indicated by the function value. You can specify
22 | model attributes in curly brackets to include them in the text flow.
23 |
24 | ```php
25 | $table->col('Name')->value('{first_name} {last_name}');
26 | ```
27 |
28 | #### Display Relationship Attributes
29 |
30 | It is also possible to display the attribute of relationships. In this case
31 | attributes must be separated with a dot like this:
32 |
33 | ```php
34 | $table->col('Product')->value('{product.name}');
35 | ```
36 |
37 | #### Display Options
38 |
39 | Maybe you want to display a value representative for a state, this can be
40 | achieved by passing the attribute name as the first and an array of options as
41 | the second parameter to the value method:
42 |
43 | ```php
44 | use App\Models\Product;
45 |
46 | $table->col('State')->value('state', [
47 | Product::AVAILABLE => 'available',
48 | Product::OUT_OF_STOCK => 'out of stock',
49 | ]);
50 | ```
51 |
52 | ### Text Alignment
53 |
54 | You may set the text align to right like shown in the following examples:
55 |
56 | ```php
57 | $table->col('amount')->value('{amount} €')->right();
58 | $table->col('state')->value('{state}')->center();
59 | ```
60 |
61 | ### Strip Html
62 |
63 | For example, if you want to display the value of a `wysiwyg` field, it makes
64 | sense to strip the **html tags** and specify a maximum number of characters like
65 | this:
66 |
67 | ```php
68 | $table->col('Text')
69 | ->value('{text}')
70 | ->stripHtml()
71 | ->maxChars(50);
72 | ```
73 |
74 | ### Regex
75 |
76 | Perform a regular expression search and replace:
77 |
78 | ```php
79 | $table->col('Fruit')
80 | ->value('orange')
81 | ->regex('/\b(\w*orange\w*)\b/im', 'apple'); // Replaces orange with apple.
82 | ```
83 |
84 | ### Money
85 |
86 | Let's assume that you want to display an amount of money in a column. For this
87 | the `money` method with the desired attribute can be used. The amount is
88 | formatted and the column can be sorted by the attribute.
89 |
90 | ```php
91 | $table->money('amount');
92 | ```
93 |
94 | #### Currency
95 |
96 | For formatting the
97 | [formatCurrency](https://www.php.net/manual/de/numberformatter.formatcurrency.php)
98 | method of the PHP
99 | [NumberFormatter](https://www.php.net/manual/de/class.numberformatter.php) is
100 | used. This makes it possible to choose the 3-letter ISO 4217 currency code. The
101 | default currency code is `EUR`.
102 |
103 | ```php
104 | $table->money('amount', 'USD');
105 | ```
106 |
107 | Additionally, the language can be specified as a third parameter. However, the
108 | locale of the authenticated user is used by default.
109 |
110 | ```php
111 | $table->money('amount', 'USD', 'en_US');
112 | ```
113 |
114 | Useful **ISO 4217** codes:
115 |
116 | | Code | Currency | Example (`de_DE`) |
117 | | ------- | ----------------- | ----------------- |
118 | | `"EUR"` | Euro | `"10,00 €"` |
119 | | `"USD"` | US Dollar | `"10,00 $"` |
120 | | `"AUD"` | Australian Dollar | `"10,00 AU$"` |
121 | | `"CHF"` | Swiss Franc | `"10,00 CHF"` |
122 | | `"GGP"` | Pound | `"10,00 £"` |
123 |
124 | ### Date
125 |
126 | To display a formatted date, you may use the `date` method. A parameter with the
127 | desired formatting is required.
128 |
129 | ```php
130 | $table->date('created_at', 'Y-m-d');
131 | ```
132 |
133 | ## Reduce Width
134 |
135 | With the function `small` the column is reduced to the minimum width.
136 |
137 | ```php
138 | $table->col('Icon')->value('{icon}')->small();
139 | ```
140 |
141 | ## Sortable
142 |
143 | A table column can be sorted directly by clicking on the column in the table
144 | head. To achieve this, you simply have to specify the name of the attribute you
145 | want to sort by.
146 |
147 | ```php
148 | $table->col('Name')->value('{first_name} {last_name}')->sortBy('first_name');
149 | ```
150 |
151 | You may even sort by related column.
152 |
153 | ```php
154 | $table->col('Product')->value('{product.name}')->sortBy('product.name');
155 | ```
156 |
157 | :::tip
158 |
159 | In case of long loading times when sorted by relation attributes it can help to
160 | add an [index](https://laravel.com/docs/7.x/migrations#indexes) on the column
161 | that connects the relation.
162 |
163 | :::
164 |
165 | ## Form Fields
166 |
167 | In litstack form fields can be placed in table columns, this allows the user to
168 | edit attributes directly in the table similar to excel. Each column can contain
169 | only one form field.
170 |
171 | ```php
172 | $table->field('Name')->input('{name}');
173 | ```
174 |
175 | If you want to modify the
176 |
177 | ## Action
178 |
179 | You may make [actions](actions.md) available directly in a table column:
180 |
181 | ```php
182 | use Lit\Actions\SendMailAction;
183 |
184 | $table->action('Send Mail', SendMailAction::class)->label('Mail');
185 | ```
186 |
187 | ::: tip
188 |
189 | Use conditions to only show actions for certain models:
190 |
191 | ```php
192 | $table->action('Cancel', CancelBookingAction::class)
193 | ->whenNot('state', 'canceled');
194 | ```
195 |
196 | :::
197 |
198 | ### Multiple Actions
199 |
200 | You can also place multiple actions in one column. These are then accessible via
201 | a dropdown button
202 |
203 | ```php
204 | use Lit\Actions\FooAction;
205 | use Lit\Actions\BarAction;
206 |
207 | $table->actions([
208 | 'Foo' => FooAction::class,
209 | 'Bar' => BarAction::class,
210 | ])->label('Actions');
211 | ```
212 |
213 | ## Image
214 |
215 | If an image is to be displayed in a table, the image url must also be specified
216 | using the `src` method. If the image was uploaded via the `Image` Field, the
217 | conversions specified in the config file **lit.php** can be displayed.
218 |
219 | ```php
220 | $table->image('Image')->src('{image.url}');
221 | ```
222 |
223 | ::: tip
224 |
225 | Display **media conversion** for images that where uploaded via the `Image`
226 | field.
227 |
228 | Example: `$column->src('{image.conversion_urls.sm}')`
229 |
230 | :::
231 |
232 | ### Avatar
233 |
234 | You may use avatar to display a rounded image.
235 |
236 | ```php
237 | $table->avatar('Image')->src('{image.conversion_urls.sm}');
238 | ```
239 |
240 | ### maxWidth, maxHeight
241 |
242 | Furthermore, a `maxWidth` and a `maxHeight` can be defined.
243 |
244 | ```php
245 | $table->image('Image')
246 | ->src('{image.conversion_urls.sm}')
247 | ->maxWidth('50px')
248 | ->maxHeight('50px');
249 | ```
250 |
251 | ### Square
252 |
253 | Set a width and a height if the image should simply be displayed as a square:
254 |
255 | ```php
256 | $table->image('Image')
257 | ->src('{image.conversion_urls.sm}')
258 | ->square('50px'); // Displays the image as 50 x 50 px square using object-fit: cover
259 | ```
260 |
261 | ## Progress
262 |
263 | Often you want to display the progress of a model directly in a table column.
264 | Litstack provides the progress column for this purpose:
265 |
266 | ```php
267 | $table->progress('value', $max = 100)->label('Progress');
268 | ```
269 |
270 | ## Relation
271 |
272 | In some cases, you may want to link a relation directly in your table. This can
273 | be achieved by using the `relation` method. The related `name` of the relation
274 | and the related crud config must be specified.
275 |
276 | ```php
277 | use Ignite\Support\Facades\Config;
278 | use Lit\Config\Crud\ProductConfig;
279 |
280 | $table->relation('product', ProductConfig::class)
281 | ->value('{product.name}') // Related attribute to be displayed.
282 | ->sortBy('product.name');
283 | ```
284 |
285 | ### MorphTo
286 |
287 | I case your relationship is of the type
288 | [MorphTo](https://laravel.com/docs/8.x/eloquent-relationships#one-to-many-polymorphic-model-structure),
289 | you need to apply the config classes and values for all models like this:
290 |
291 | ```php
292 | use App\Models\Post;
293 | use App\Models\Video;
294 | use Lit\Config\Crud\PostConfig;
295 | use Lit\Config\Crud\VideoConfig;
296 |
297 | $table->relation('commentable', [
298 | Post::class => PostConfig::class,
299 | Video::class => VideoConfig::class,
300 | ])->value([
301 | Post::class => '{commentable.title}',
302 | Video::class => '{commentable.title}',
303 | ]);
304 | ```
305 |
306 | ## Toggle
307 |
308 | To edit the boolean state of a model directly in a table, a **switch** can be
309 | displayed in a column using `toggle`. The name of the corresponding attribute
310 | must be specified as the first parameter. In addition, the `routePrefix` for the
311 | update route must be specified, if the table is built in a CRUD or form config,
312 | simply use the config function `routePrefix`.
313 |
314 | ```php
315 | $table->toggle('active')
316 | ->label('Live')
317 | ->sortBy('active');
318 | ```
319 |
320 | ::: warning
321 |
322 | Please use an inline `boolean` form field instead of the toggle column since it
323 | might be dropped in **4.x**.
324 |
325 | ```php
326 | $table->field('Live', fn($column) => $column->sortBy('active'))
327 | ->boolean('active');
328 | ```
329 |
330 | :::
331 |
332 | ## Blade View
333 |
334 | With the `view` method you can easily add Blade Views to your table column:
335 |
336 | ```php
337 | $table->view('lit::columns.hello')->label('Hello');
338 | ```
339 |
340 | ```html{lit/resources/views/columns/hello.blade.php}
341 |
342 | Hello World!
343 |
344 | ```
345 |
346 | ### Vue in Blade components
347 |
348 | You can use Vue components in your blade component:
349 |
350 | ```html{lit/resources/views/columns/hello.blade.php}
351 |
352 | Hello World!
353 |
354 | ```
355 |
356 | Use the **prop** `item` to display model attributes:
357 |
358 | ```html{lit/resources/views/columns/hello.blade.php}
359 |
360 | ```
361 |
362 | ## Vue Component
363 |
364 | You can also integrate your own Vue components into columns. The component
365 | **name** is specified as the first parameter, the label must be specified
366 | separately. Additionally props can be defined.
367 |
368 | ```php
369 | $table->component('my-table-component')
370 | ->label('State')
371 | ->prop('variants' => [
372 | 'active' => 'success',
373 | 'complete' => 'primary',
374 | 'failed' => 'danger'
375 | ])
376 | ->sortBy('state');
377 | ```
378 |
379 | Your component could look like this:
380 |
381 | ```javascript
382 |
383 |
384 | {{ item.state }}
385 |
386 |
387 |
402 | ```
403 |
404 | Read the [Extend Vue](../basics/vue.md#bootstrap-vue) section to learn how to
405 | register your own Vue components.
406 |
--------------------------------------------------------------------------------
/fields/block.md:
--------------------------------------------------------------------------------
1 | # Block
2 |
3 | ## Introduction
4 |
5 | Block fields are used to map repetitive content. They can contain any number of
6 | so called **repeatables**, which you can string together in any order. A
7 | **repeatable** can be regarded as a separate individual form. As well a preview
8 | table can be set for every block. If field values are to be displayed as
9 | preview, they must be written in **curly brackets**.
10 |
11 | ```php
12 | $form->block('content')
13 | ->title('Content')
14 | ->repeatables(function($repeatables) {
15 |
16 | // Add as many repeatables as you want.
17 | $repeatables->add('text', function($form, $preview) {
18 | // The block preview.
19 | $preview->col('{text}');
20 |
21 | // Containing as many form fields as you want.
22 | $form->input('text')
23 | ->title('Text');
24 | });
25 |
26 | $repeatables->add('image', function($form, $preview) {
27 | $preview->col('{}');
28 |
29 | $form->image('image')
30 | ->title('Image');
31 | });
32 | });
33 | ```
34 |
35 | ### Preparing the Model
36 |
37 | Block fields can be added to CRUD-Models as well as to forms. Blocks don't need
38 | a dedicated column in the model, as they are stored in a database table
39 | centrally.
40 |
41 | The repeatables can be loaded to your model using the `repeatables` **relation**
42 | method.
43 |
44 | ```php
45 | public function content()
46 | {
47 | return $this->repeatables('content');
48 | }
49 | ```
50 |
51 | You can now receive the block data like this:
52 |
53 | ```php
54 | Post::find($id)->content;
55 | ```
56 |
57 | ## Binding Views
58 |
59 | You can directly bind a view to a repeatable to use it in the frontend where you
60 | display your block:
61 |
62 | ```php{3}
63 | $repeatables->add('text', function($form, $preview) {
64 | // ...
65 | })->view('repeatables.text');
66 | ```
67 |
68 | You may even bind Blade x components using the `x` method:
69 |
70 | ```php{3}
71 | $repeatables->add('text', function($form, $preview) {
72 | // ...
73 | })->x('repeatables.text');
74 | ```
75 |
76 | ## Reusable Repeatables
77 |
78 | Sometimes you want to use repeatables in different places. Reusable repeatables
79 | can be created using the `lit:repeatable` command. The **preview** and **form**
80 | can then be configured in the newly generated class in the `lit/app/Repeatables`
81 | directory.
82 |
83 | ```shell
84 | php artisan lit:repeatable text
85 | ```
86 |
87 | The generated class can be added to a block by passing the **namespace** as the
88 | first parameter to the `add` method:
89 |
90 | ```php
91 | use Lit\Repeatables\TextRepeatable;
92 |
93 | $repeatables->add(TextRepeatable::class);
94 | ```
95 |
96 | ## Frontend
97 |
98 | To use the repeatables of a block in the frontend you can loop over them and
99 | display the content depending on the repeatable `type`, like this:
100 |
101 | ```php
102 | @foreach($model->content as $repeatable)
103 | @if($repeatable->type == 'text')
104 | {{ $repeatable->text }}
105 | @elseif($repeatable->type == 'image')
106 | {{-- ... --}}
107 | @endif
108 | @endforeach
109 | ```
110 |
111 | However you can simply use the blade directive `block`, which does exactly that
112 | for you.
113 |
114 | ```php
115 | @block($model->content)
116 | ```
117 |
118 | ::: warning
119 |
120 | The `block` directive needs a View or a Blade x component bound to the
121 | repeatable in order to be displayed.
122 |
123 | :::
124 |
125 | ## Methods
126 |
127 | | Method | Description |
128 | | ----------------------- | -------------------------------------------------- |
129 | | `$field->title()` | The title description for this field. |
130 | | `$field->repeatables()` | A closure where all repeatable blocks are defined. |
131 | | `$field->width()` | Width of the field. |
132 | | `$field->blockWidth()` | Width of a block. |
133 |
134 | ## Repeatable Methods
135 |
136 | | Method | Description |
137 | | ----------------------- | ------------------------------------------------ |
138 | | `$repeatable->button()` | The title for the repeatable. |
139 | | `$repeatable->view()` | The View describing the repeatable. |
140 | | `$repeatable->x()` | The Blade x component describing the repeatable. |
141 |
--------------------------------------------------------------------------------
/fields/boolean.md:
--------------------------------------------------------------------------------
1 | # Boolean
2 |
3 | ## Usage
4 |
5 | The boolean field adds a switch to a boolean attribute.
6 |
7 | ```php
8 | $form->boolean('active')
9 | ->title('Live')
10 | ->hint('Put the site online.')
11 | ->width(1/3);
12 | ```
13 |
14 | Add the `boolean`
15 | [cast](https://laravel.com/docs/5.2/eloquent-mutators#attribute-casting) to your
16 | model:
17 |
18 | ```php
19 | protected $casts = [
20 | 'active' => 'boolean'
21 | ];
22 | ```
23 |
24 | ## Methods
25 |
26 | | Method | Description |
27 | | ----------------------------------- | ------------------------------------------------------------------ |
28 | | `$field->title('Live')` | The title description for this field. |
29 | | `$field->hint('Foo.')` | A short hint that should describe how to use the field. |
30 | | `$field->info('...')` | Question mark with tooltip. (Can contain longer field descriptions) |
31 | | `$field->width(1/2)` | Width of the field. |
32 | | `$field->rules('required')` | Rules that should be applied when **updating** and **creating**. |
33 | | `$field->creationRules('required')` | Rules that should be applied when **creating**. |
34 | | `$field->updateRules('required')` | Rules that should be applied when **updating**. |
35 |
--------------------------------------------------------------------------------
/fields/checkboxes.md:
--------------------------------------------------------------------------------
1 | # Checkboxes
2 |
3 | ## Introduction
4 |
5 | Multiple checkboxes. The selected values are stored as an array.
6 |
7 | ## Usage
8 |
9 | The following example shows a list of fruits that can be selected using
10 | checkboxes.
11 |
12 | ```php
13 | $form->checkboxes('fruits')
14 | ->title('Fruits')
15 | ->options([
16 | 'orange' => 'Orange',
17 | 'apple' => 'Apple',
18 | 'pineapple' => 'Pineapple',
19 | 'grape' => 'Grape',
20 | ])
21 | ->hint('Select your fruits.')
22 | ->width(6);
23 | ```
24 |
25 | ### Cast
26 |
27 | Add the `array`
28 | [cast](https://laravel.com/docs/5.2/eloquent-mutators#attribute-casting) to your
29 | model:
30 |
31 | ```php
32 | protected $casts = [
33 | 'fruits' => 'array'
34 | ];
35 | ```
36 |
37 | ## Methods
38 |
39 | | Method | Description |
40 | | ----------------------------------- | ---------------------------------------------------------------------- |
41 | | `$field->title('Foo')` | The title description for this field. |
42 | | `$field->hint('Foo.')` | A short hint that should describe how to use the field.` |
43 | | `$field->info('...')` | Question mark with tooltip. (Can contain longer field descriptions) |
44 | | `$field->width(1/2)` | Width of the field. |
45 | | `$field->options(['foo', 'bar'])` | An array with checkbox values and descriptions. |
46 | | `$field->stacked()` | Places each checkbox one over the other instead of next to each other. |
47 | | `$field->rules('required')` | Rules that should be applied when **updating** and **creating**. |
48 | | `$field->creationRules('required')` | Rules that should be applied when **creating**. |
49 | | `$field->updateRules('required')` | Rules that should be applied when **updating**. |
50 |
--------------------------------------------------------------------------------
/fields/conditions.md:
--------------------------------------------------------------------------------
1 | # Conditional Fields
2 |
3 | ## Introduction
4 |
5 | Field **conditions** can be used to display fields when a model attribute has a
6 | certain value. Individual fields or field groups can be made dependent on model
7 | values.
8 |
9 | 
10 |
11 | ## Usage
12 |
13 | The following example shows an input field that only gets displayed if model
14 | attribute `type` has the value `news`:
15 |
16 | ```php
17 | $form->select('type')
18 | ->options([
19 | 'news' => 'News',
20 | 'blog' => 'Blog',
21 | ])
22 | ->title('Type');
23 |
24 | $form->input('news_title')
25 | ->title('Title')
26 | ->when('type, 'news');
27 | ```
28 |
29 | A variety of conditions are available for any field:
30 |
31 | | Condition | Description |
32 | | ------------------------------------------- | ------------------------------------------- |
33 | | `$field->when('type', 'foo')` | Matches the exact given value. |
34 | | `$field->whenNot('type', 'foo')` | When field doesn't match the given value. |
35 | | `$field->whenContains('type', 'foo')` | Matches the given substring or array value. |
36 | | `$field->whenNotContains('type', 'foo')` | When field doesn't contain the given value. |
37 | | `$field->whenIn('type', ['foo', 'bar'])` | When field is any of the given values. |
38 | | `$field->whenNotIn('type', ['foo', 'bar'])` | When field is not any of the given values. |
39 |
40 | ### Conditional Groups
41 |
42 | Conditions can also be applied to groups:
43 |
44 | ```php{4}
45 | $form->group(function($form) {
46 |
47 | $form->input('news_title')->title('Title');
48 | $form->input('news_text')->title('Text');
49 |
50 | })->when('type', 'news');
51 | ```
52 |
53 | ### Multiple Conditions
54 |
55 | You may chain as many conditions in a row by adding `or` to the desired
56 | condition:
57 |
58 | ```php
59 | $form->input('title')->title('Title')
60 | ->when($field, 'news')
61 | ->orWhen($field, 'blog');
62 | ```
63 |
--------------------------------------------------------------------------------
/fields/date-time.md:
--------------------------------------------------------------------------------
1 | # DateTime
2 |
3 | ## Introduction
4 |
5 | A DateTime-Picker.
6 |
7 |
8 |
9 |
10 |
11 | ## Examples
12 |
13 | The following example shows the basic usage of the `datetime` field.
14 |
15 | ```php
16 | $form->datetime('publish_at')
17 | ->title('Date')
18 | ->formatted('l')
19 | ->hint('Chose a date.')
20 | ->width(6);
21 | ```
22 |
23 | ### Shortcut
24 |
25 | ```php
26 | $form->dt('publish_at') // dt and datetime work the same
27 | ```
28 |
29 | ### Date and Time
30 |
31 | You may enable to pick a time as well by settings `onlyDate` to false:
32 |
33 | ```php{3}
34 | $form->datetime('publish_at')
35 | ->title('Date')
36 | ->onlyDate(false)
37 | ->formatted('l')
38 | ->hint('Chose a date.')
39 | ->width(6);
40 | ```
41 |
42 |
43 |
44 |
45 |
46 | ## Methods
47 |
48 | | Method | Description |
49 | | ----------------------------------- | ---------------------------------------------------------------- |
50 | | `$field->title('Publish At')` | The title description for this field. |
51 | | `$field->formatted('LL')` | The shown datetime format. (Useful formats listed below.) |
52 | | `$field->hint('Pick a date.')` | A closure where all repeatable blocks are defined. |
53 | | `$field->onlyDate()` | Pick date only (default: `true`). |
54 | | `$field->onlyTime()` | Pick time only (default: `false`). |
55 | | `$field->minuteInterval(15)` | Timepicker minute interval (default: `5`). |
56 | | `$field->width(1/2)` | Width of the field. |
57 | | `$field->rules('required')` | Rules that should be applied when **updating** and **creating**. |
58 | | `$field->creationRules('required')` | Rules that should be applied when **creating**. |
59 | | `$field->updateRules('required')` | Rules that should be applied when **updating**. |
60 |
61 | ## Formats
62 |
63 | Useful formats:
64 |
65 | | Key | Example Result |
66 | | ------ | -------------------------------- |
67 | | `LT` | 2:15 PM |
68 | | `LTS` | 2:15:52 PM |
69 | | `L` | 12/08/2019 |
70 | | `l` | 12/8/2019 |
71 | | `LL` | December 8, 2019 |
72 | | `ll` | Dec 8, 2019 |
73 | | `LLL` | December 8, 2019 2:15 PM |
74 | | `lll` | Dec 8, 2019 2:15 PM |
75 | | `LLLL` | Sunday, December 8, 2019 2:15 PM |
76 | | `llll` | Sun, Dec 8, 2019 2:15 PM |
77 |
--------------------------------------------------------------------------------
/fields/icon.md:
--------------------------------------------------------------------------------
1 | # Icon
2 |
3 | An icon picker field.
4 |
5 | ```php
6 | $form->icon('icon')
7 | ->title('Icon')
8 | ->icons([
9 | '',
10 | '',
11 | // ...
12 | ])
13 | ->hint('Choose your icon.')
14 | ->width(2);
15 | ```
16 |
17 | If the number of icons is high, it is recommended to `require` the icons from a
18 | file.
19 |
20 | ```php
21 | ->icon(require('.../icons.php'));
22 | ```
23 |
24 | ## Add Your Own Icons
25 |
26 | To import your own icons you have to specify the corresponding `css` file in the
27 | config `lit.php`.
28 |
29 | ```php
30 | 'assets' => [
31 | // ...
32 | 'css' => [
33 | '/icons/icons.css', // Add your icon's css file.
34 | // ...
35 | ],
36 | ],
37 | ```
38 |
39 | ## Methods
40 |
41 | | Method | Description |
42 | | -------------------------------------------- | --------------------------------------------------------------------------- |
43 | | `$field->title('Foo')` | The title description for this field. |
44 | | `$field->hint('Foo.')` | A short hint that should describe how to use the field. |
45 | | `$field->info('...')` | Question mark with tooltip. (Can contain longer field descriptions) |
46 | | `$field->width(1/2)` | Width of the field. |
47 | | `$field->icons([''])` | List of selectable icons. (By default all fontawesome icons are selectable) |
48 | | `$field->rules('required')` | Rules that should be applied when **updating** and **creating**. |
49 | | `$field->creationRules('required')` | Rules that should be applied when **creating**. |
50 | | `$field->updateRules('required')` | Rules that should be applied when **updating**. |
51 |
--------------------------------------------------------------------------------
/fields/image.md:
--------------------------------------------------------------------------------
1 | # Image
2 |
3 | ## Introduction
4 |
5 | A drag and drop image uploader using Spatie's
6 | [medialibary](https://docs.spatie.be/laravel-medialibrary/v7/introduction/).
7 |
8 | ## Model Setup
9 |
10 | To attach images to a model, only the media **contract** and the media **trait**
11 | must be added to the model.
12 |
13 | ```php
14 | use Ignite\Crud\Models\Traits\HasMedia;
15 | use Spatie\MediaLibrary\HasMedia as HasMediaContract;
16 |
17 | class Post extends Model implements HasMediaContract
18 | {
19 | use HasMedia;
20 | }
21 | ```
22 |
23 | ## Basics
24 |
25 | For all images that are uploaded an input field for `alt` and `title` is
26 | displayed, with `translatable` these two fields are made translatable.
27 |
28 | ```php
29 | $form->image('images') // images is the corresponding media collection.
30 | ->translatable()
31 | ->title('Images')
32 | ->hint('Image Collection.')
33 | ->maxFiles(5);
34 | ```
35 |
36 | Add the image attribute to your model:
37 |
38 | ```php
39 | public function getImagesAttribute()
40 | {
41 | return $this->getMedia('images');
42 | }
43 | ```
44 |
45 | ## Crop
46 |
47 | To crop the image to a desired ratio before uploading it, a ratio can be defined
48 | using the method `crop`.
49 |
50 | ```php{3}
51 | $form->image('images')->title('Images')->crop(16 / 9);
52 | ```
53 |
54 | ::: tip
55 |
56 | If no ratio is passed as a parameter to the crop method, the image can be freely
57 | cropped.
58 |
59 | :::
60 |
61 | ## Expand
62 |
63 | By default the images are displayed as a square. However, this view is not
64 | suitable for example for header images. With **expand** you can display the
65 | image at full size.
66 |
67 | ```php{2}
68 | $form->image('header_image')->title('Header Image')->expand();
69 | ```
70 |
71 | 
72 |
73 | ## Preview Image
74 |
75 | In the case that the first image from the list should be used as a preview
76 | image, you can use `firstBig` to display the first image bigger to show that it
77 | has a special importance.
78 |
79 | ```php{3}
80 | $form->image('images')
81 | ->title('Images')
82 | ->firstBig()
83 | ->hint('The first image is the preview image.');
84 | ```
85 |
86 | 
87 |
88 | ## Conversions
89 |
90 | In the config `lit.mediaconversions` all conversions groups are specified. If
91 | you would like a model to use another conversion group than `default`, the group
92 | name can be set using the attribute `mediaconversions`.
93 |
94 | ```php
95 | class Post extends Model implements HasMediaContract
96 | {
97 | ...
98 |
99 | /**
100 | * Media conversions group.
101 | *
102 | * @var string
103 | */
104 | protected $mediaconversions = 'other';
105 | }
106 | ```
107 |
108 | ::: warning
109 |
110 | To display conversion urls it is important to set the env `APP_URL` to the url
111 | you are working in.
112 |
113 | :::
114 |
115 | ## Max. File Size
116 |
117 | The maximum allowed file size for an image can be specified using the
118 | `maxFileSize` method. The file size is given in **megabytes**. The default value
119 | is 12 mb.
120 |
121 | ```php{3}
122 | $form->image('images')->title('Images')->maxFileSize(25);
123 | ```
124 |
125 | ## Methods
126 |
127 | | Method | Description |
128 | | -------------------------- | ------------------------------------------------------------------ |
129 | | `$field->title('Image')` | The title for this form field. |
130 | | `$field->translatable()` | Should the field be translatable. |
131 | | `$field->hint('Foo.')` | A short hint that should describe how to use the form field.` |
132 | | `$field->info('...')` | Question mark with tooltip. (Can contain longer field descriptions) |
133 | | `$field->width(1/2)` | Width of the form field. |
134 | | `$field->sortable()` | Should the images be sortable? (default: `true`) |
135 | | `$field->maxFiles(1)` | Maximum number of uploadable images. (default: `5`) |
136 | | `$field->maxFileSize(100)` | Maximum file size. (default: `12`) |
137 | | `$field->expand()` | Expand the preview image to its full width. |
138 | | `$field->crop(16/9)` | Opens a Crop-Tool before the upload. (default: `false`) |
139 | | `$field->showFullImage()` | Display's the full image inside of the square box. |
140 | | `$field->firstBig()` | Display's the first image bigger. |
141 |
--------------------------------------------------------------------------------
/fields/input.md:
--------------------------------------------------------------------------------
1 | # Input
2 |
3 | A basic text input field.
4 |
5 | ```php
6 | $form->input('title')
7 | ->title('Title')
8 | ->placeholder('Title')
9 | ->hint('The Title is shown at the top of the page.')
10 | ->width(1/2);
11 | ```
12 |
13 | ## Prepend & Append
14 |
15 | For units or similar, values can be appended or prepended to the input field.
16 |
17 | ```php
18 | $form->input('length')
19 | ->title('Length')
20 | ->type('number')
21 | ->placeholder('The length in cm')
22 | ->hint('Enter the length in cm.')
23 | ->append('cm')
24 | ->width(12);
25 | ```
26 |
27 | ## Methods
28 |
29 | | Method | Description |
30 | | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
31 | | `$field->title()` | The title description for this form field. |
32 | | `$field->placeholder()` | The placeholder for this form field. |
33 | | `$field->type()` | Sets an input type for the input. [Available types](https://bootstrap-vue.js.org/docs/components/form-input#input-type): **text**, **number**, **email**, **password**, **search**, **url**, **tel**, **date**, **time**, **range**, **color** |
34 | | `$field->hint()` | A short hint that should describe how to use the form field. |
35 | | `$field->info('...')` | Question mark with tooltip. (Can contain longer field descriptions) |
36 | | `$field->width()` | Width of the field. |
37 | | `$field->translatable()` | Should the form field be translatable? For translatable crud models, the translatable fields are automatically recognized. |
38 | | `$field->max()` | Max characters. |
39 | | `$field->prepend()` | Prepend the field. |
40 | | `$field->append()` | Append the field. |
41 | | `$field->rules()` | Rules that should be applied when **updating** and **creating**. |
42 | | `$field->creationRules()` | Rules that should be applied when **creating**. |
43 | | `$field->updateRules()` | Rules that should be applied when **updating**. |
44 |
--------------------------------------------------------------------------------
/fields/introduction.md:
--------------------------------------------------------------------------------
1 | # Fields
2 |
3 | ## Introduction
4 |
5 | Fields can be used to make database entries easily editable. Each field is
6 | appended one or more columns of a database table.
7 | [Validation Rules](https://laravel.com/docs/8.x/validation) can be added to
8 | fields and it can be determined who can edit a field.
9 |
10 | ## Basics
11 |
12 | When you create a field you must first specify the `attribute` that the field
13 | refers to. Like in the following example an input field refers to `first_name`.
14 |
15 | ```php
16 | $form->input('first_name');
17 | ```
18 |
19 | Every field requires a title.
20 |
21 | ```php
22 | $form->input('first_name')->title('Firstname');
23 | ```
24 |
25 | Furthermore the width can be specified either in **12** columns as in bootstrap,
26 | or in fractions. The fractions are converted into columns.
27 |
28 | ```php
29 | $form->input('first_name')->title('Firstname')->width(4);
30 | // Is the same as:
31 | $form->input('first_name')->title('Firstname')->width(1 / 3);
32 | ```
33 |
34 | ## Authorization
35 |
36 | With the `authorize` method it can be determined if the user has the permission
37 | for a field. If the user does not have the required authorization, the field is
38 | not displayed.
39 |
40 | ```php
41 | $form->input('first_name')->authorize(function($user) {
42 | return $user->can('edit user-name');
43 | });
44 | ```
45 |
46 | ## Readonly
47 |
48 | If you want the user to see the field, but not be able to edit it, you can use
49 | the `readOnly` function.
50 |
51 | ```php
52 | $form->input('first_name')->readOnly(! lit_user()->can('edit user-name'));
53 | ```
54 |
--------------------------------------------------------------------------------
/fields/list.md:
--------------------------------------------------------------------------------
1 | # List
2 |
3 | ## Introduction
4 |
5 | A list field with nested items. It can be used to build **navigations** with
6 | nested entries.
7 |
8 | ```php
9 | $form->list('menue')
10 | ->title('Menue')
11 | ->previewTitle('{title}')
12 | ->form(function($form) {
13 | $form->input('title')
14 | ->title('Title');
15 | });
16 | ```
17 |
18 | :::tip
19 |
20 | Add creation **rules** to the fields of your list to prevent the creation of
21 | empty items
22 |
23 | :::
24 |
25 | ### Preparing the Model
26 |
27 | List fields can be added to CRUD-Models as well as to forms. Lists don't need a
28 | dedicated column in the model, as they are stored in a database table centrally.
29 |
30 | ```php
31 | public function menue()
32 | {
33 | return $this->listItems('menue');
34 | }
35 | ```
36 |
37 | You can now receive the list items like this:
38 |
39 | ```php
40 | Post::find($id)->menue;
41 | ```
42 |
43 | ## Max Depth
44 |
45 | The maximum depth of the list levels can be specified with `maxDepth`. The
46 | default value is `3`.
47 |
48 | ```php{3}
49 | $form->list('menue')
50 | ->title('Menue')
51 | ->maxDepth(4)
52 | ->previewTitle('{title}')
53 | ->form(function($form) {
54 | $form->input('title')
55 | ->title('Title');
56 | });
57 | ```
58 |
59 | ## Retrieve Data
60 |
61 | ## Methods
62 |
63 | | Method | Description |
64 | | ----------------------- | ------------------------------------------ |
65 | | `$field->title()` | The title description for this form field. |
66 | | `$field->form()` | The corresponding form to the list item. |
67 | | `$field->previewTitle()`| Title that describes the form. |
68 | | `$field->maxDepth()` | Title that describes the form. |
69 |
--------------------------------------------------------------------------------
/fields/masks.md:
--------------------------------------------------------------------------------
1 | # Field Masks
2 |
3 | ## Introduction
4 |
5 | Apply input masks to your field to indicate the format of valid input values.
6 | Litstack makes use of [Cleave.js](https://nosir.github.io/cleave.js/) to apply
7 | masks to form fields.
8 |
9 | ## Basic Usage
10 |
11 | To add masks to your form field you may specify the desired mask options by
12 | passing an array to the `mask` method of your field:
13 |
14 | ```php
15 | $form->input('credit_card')->mask([
16 | 'creditCard': true
17 | ]);
18 | ```
19 |
20 | Checkout some useful masks on
21 | [nosir.github.io/cleave.js](https://nosir.github.io/cleave.js/).
22 |
23 | ## Add Addons
24 |
25 | To make use of cleave js addons like phone number masks of your country, you
26 | need to add the script of the desired addon to your `lit` config so it will be
27 | loaded.
28 |
29 | ```php{config/lit.php}
30 | 'assets' => [
31 | // ...
32 | 'scripts' => [
33 | // ...
34 | // Add us phone number.
35 | 'https://cdnjs.cloudflare.com/ajax/libs/cleave.js/1.6.0/addons/cleave-phone.us.js'
36 | ],
37 | ]
38 | ```
39 |
40 | The US phone number mask can now be applied like this:
41 |
42 | ```php
43 | $form->input('phone_number')->mask([
44 | 'phone' => true,
45 | 'phoneRegionCode' => 'us',
46 | ]);
47 | ```
48 |
49 | ## Conditional Options
50 |
51 | You may use attribute values to add conditional options by adding the attribute
52 | in curly brackets:
53 |
54 | ```php
55 | $form->select('country')->options([
56 | 'de' => 'de',
57 | 'us' => 'us',
58 | ]);
59 |
60 | $form->input('title')->mask([
61 | 'phone' => true,
62 | 'phoneRegionCode' => '{country}',
63 | ]);
64 | ```
65 |
--------------------------------------------------------------------------------
/fields/modal.md:
--------------------------------------------------------------------------------
1 | # Modal
2 |
3 | Form fields inside a `modal`.
4 |
5 | ```php
6 | $form->modal('update_email')
7 | ->title('E-Mail')
8 | ->name('Update E-Mail')
9 | ->form(function($form) {
10 | $form->input('email')->title('E-Mail');
11 | });
12 | ```
13 |
14 | ## Confirm with Password
15 |
16 | Appends a password field to the end of the form that is required to confirm the
17 | modal form using the current users password.
18 |
19 | ```php{4}
20 | $form->modal('update_email')
21 | ->title('E-Mail')
22 | ->name('Update E-Mail')
23 | ->confirmWithPassword()
24 | ->form(function($form) {
25 | $form->input('email')->title('E-Mail');
26 | });
27 | ```
28 |
29 | ## Methods
30 |
31 | | Method | Description |
32 | | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
33 | | `$field->title()` | The title description for this field. |
34 | | `$field->placeholder()` | The placeholder for this field. |
35 | | `$field->hint()` | A short hint that should describe how to use the field.` |
36 | | `$field->info()` | Question mark with tooltip. (Can contain longer field descriptions) |
37 | | `$field->width()` | Width of the field. |
38 | | `$field->confirmWithPassword()` | Appends a password field to the end of the form that is required to confirm the modal form using the current users password. |
39 |
--------------------------------------------------------------------------------
/fields/password.md:
--------------------------------------------------------------------------------
1 | # Password
2 |
3 | ## Introduction
4 |
5 | A `password` input Field.
6 |
7 | ```php
8 | $form->password('password')
9 | ->title('Password');
10 | ```
11 |
12 | ## Confirm Form
13 |
14 | Update or create form requires a password confirmation.
15 |
16 | ```php{3}
17 | $form->password('password')
18 | ->title('Password')
19 | ->confirm();
20 | ```
21 |
22 | ## Confirm Password
23 |
24 | Password fields can be used to update and confirm user passwords using the
25 | following `rules`.
26 |
27 | ```php
28 | $modal->password('password')
29 | ->title('New Password')
30 | ->rules('required', 'min:5')
31 | ->minScore(0);
32 |
33 | $modal->password('password_confirmation')
34 | ->rules('required', 'same:password')
35 | ->dontStore()
36 | ->title('New Password')
37 | ->noScore();
38 | ```
39 |
40 | ## Methods
41 |
42 | | Method | Description |
43 | | ------------------------------------ | ------------------------------------------------------------------------------ |
44 | | `$field->title('Password')` | The title description for this field. |
45 | | `$field->placeholder('Password')` | The placeholder for this field. |
46 | | `$field->hint('Choose a Password.')` | A short hint that should describe how to use the field.` |
47 | | `$field->info('...')` | Question mark with tooltip. (Can contain longer field descriptions) |
48 | | `$field->width(1/2)` | Width of the field. |
49 | | `$field->confirm()` | Requires the user to type in the current password to confirm update or create. |
50 | | `$field->rulesOnly()` | The password wont be stored, only validation rules are used. |
51 | | `$field->rules('min:5')` | Rules that should be applied when **updating** and **creating**. |
52 | | `$field->creationRules('min:5')` | Rules that should be applied when **creating**. |
53 | | `$field->updateRules('min:5')` | Rules that should be applied when **updating**. |
54 |
--------------------------------------------------------------------------------
/fields/radio.md:
--------------------------------------------------------------------------------
1 | # Radio
2 |
3 | Radio inputs.
4 |
5 | ```php
6 | $form->radio('type')
7 | ->title('Type')
8 | ->options([
9 | 'article' => 'Article',
10 | 'hint' => 'Hint',
11 | ]);
12 | ```
13 |
14 | ## Methods
15 |
16 | | Method | Description |
17 | | ------------------------- | ------------------------------------------------------------------- |
18 | | `$field->title()` | The title description for this field. |
19 | | `$field->hint()` | A short hint that should describe how to use the field.` |
20 | | `$field->info()` | Question mark with tooltip. (Can contain longer field descriptions) |
21 | | `$field->width()` | Width of the field. |
22 | | `$field->options()` | An array with checkbox values and descriptions. |
23 | | `$field->stacked()` | Places each radio one over the other instead of next to each other. |
24 | | `$field->rules()` | Rules that should be applied when **updating** and **creating**. |
25 | | `$field->creationRules()` | Rules that should be applied when **creating**. |
26 | | `$field->updateRules()` | Rules that should be applied when **updating**. |
27 |
--------------------------------------------------------------------------------
/fields/range.md:
--------------------------------------------------------------------------------
1 | # Range
2 |
3 | ## Introduction
4 |
5 | A range slider.
6 |
7 | 
8 |
9 | ## Example
10 |
11 | ```php
12 | $form->range('range')
13 | ->title('Range')
14 | ->min(1)
15 | ->max(4)
16 | ->step(1)
17 | ->hint('Range.')
18 | ->width(1/2);
19 | ```
20 |
21 | ## Methods
22 |
23 | | Method | Description |
24 | | ------------------------- | ------------------------------------------------------------------ |
25 | | `$field->title()` | The title description for this field. |
26 | | `$field->hint()` | A short hint that should describe how to use the field.` |
27 | | `$field->info()` | Question mark with tooltip. (Can contain longer field descriptions) |
28 | | `$field->width()` | Width of the field. |
29 | | `$field->min()` | Minimum value. |
30 | | `$field->max()` | Maximum value. |
31 | | `$field->step()` | Steps. (default: 1) |
32 | | `$field->rules()` | Rules that should be applied when **updating** and **creating**. |
33 | | `$field->creationRules()` | Rules that should be applied when **creating**. |
34 | | `$field->updateRules()` | Rules that should be applied when **updating**. |
35 |
--------------------------------------------------------------------------------
/fields/relation.md:
--------------------------------------------------------------------------------
1 | # Relation
2 |
3 | ## Introduction
4 |
5 | A relation picker. Relation pickers can be created for any relation of your
6 | model.
7 |
8 | 
9 |
10 | The relation field requires the name of the relation that should be edited. The
11 | type of the relation is automatically recognized and displayed accordingly.
12 |
13 | The relations Field can only be used for **Crud Models** and not in **Forms** or
14 | **Blocks**. For Forms or Blocks the [oneRelation](#onerelation-and-manyrelation)
15 | or [manyRelation](#onerelation-and-manyrelation) field can be used.
16 |
17 | ```php
18 | $form->relation('articles')
19 | ->title('Articles')
20 | ->preview(function ($table) {
21 | // Build the preview table in here.
22 | $table->col('title'); // In this case we are showing the article title.
23 | });;
24 | ```
25 |
26 | In the Model:
27 |
28 | ```php
29 | public function articles()
30 | {
31 | return $this->hasMany('App/Models/Article');
32 | }
33 | ```
34 |
35 | ## Preview
36 |
37 | The table preview is configured in preview.
38 |
39 | ```php
40 | $form->relation('articles')
41 | ->title('Articles')
42 | ->preview(function ($table) {
43 | // Build the preview table in here.
44 | $table->col('title'); // In this case we are showing the article title.
45 | });
46 | ```
47 |
48 | However you don't need to define a new preview table every time you create a new
49 | relation field. You can simply display the index table of the related Model by
50 | setting settings its Crud config class in the `use` method list this:
51 |
52 | ```php
53 | use Lit\Config\Crud\ArticleConfig;
54 |
55 | $form->relation('articles')
56 | ->title('Articles')
57 | ->use(ArticleConfig::class);
58 | ```
59 |
60 | ### Display Pivot Data
61 |
62 | You may load and display data from the pivot table of a many to many relation.
63 |
64 | In the following example we want to display when a subscription of a user
65 | expires:
66 |
67 | First load the pivot data by specifying the desired columns in the `withPivot`
68 | method:
69 |
70 | ```php
71 | $index->query(function($query) {
72 | $query->withPivot('expires_at');
73 | });
74 | ```
75 |
76 | Now we can display the `expires_at` attribute like this:
77 |
78 | ```php
79 | $field->preview(function ($table) {
80 | $table->col('subscriptions.pivot.expires_at');
81 | });
82 | ```
83 |
84 | ## Sortable
85 |
86 | If the relation should be sortable, the related query in your Model must be
87 | sorted by an `orderColumn`.
88 |
89 | ```php
90 | public function articles()
91 | {
92 | return $this->hasMany('App/Models/Article')->orderBy('order_column');
93 | }
94 | ```
95 |
96 | Now the sortable attribute can be added:
97 |
98 | ```php
99 | $form->relation('articles')
100 | ->title('Articles')
101 | ->sortable()
102 | ->preview(function ($table) {
103 | $table->col('Title')->value('{title}');
104 | });
105 | ```
106 |
107 | ## Filter
108 |
109 | With a **filter** you can specify which models can be selected for a relation.
110 |
111 | ```php
112 | $form->relation('articles')
113 | ->title('Articles')
114 | ->filter(function($query) {
115 | $query->where('created_by', lit_user()->id);
116 | });
117 | ```
118 |
119 | ## Forms
120 |
121 | You can edit the **related attributes** in a modal by configuring fields in the
122 | form method:
123 |
124 | ```php
125 | $form->relation('articles')
126 | ->form(function($form) {
127 | $form->wysiwyg('text')->title('text');
128 | });
129 | ```
130 |
131 | ### Create A New Relationship Model
132 |
133 | You may also add a create form so the user can create new relationship models
134 | directly:
135 |
136 | ```php
137 | $form->relation('articles')
138 | ->create(function($form) {
139 | $form->wysiwyg('text')->title('text');
140 | });
141 | ```
142 |
143 | ::: tip
144 |
145 | Set a create and edit form using the `createAndUpdateForm`.
146 |
147 | :::
148 |
149 | ### Pivot Fields
150 |
151 | Sometimes you may want to edit pivot data such as the `expired_at` date of a
152 | **subscription**. Therefore the `pivot` method must be prepended to the field.
153 |
154 | ```php
155 | $field->form(function($form) {
156 | $form->pivot()->datetime('expires_at')->title('Expires At');
157 | });
158 | ```
159 |
160 | ## Inline Fields
161 |
162 | You may even add inline fields to your relationship table. The following example
163 | show's how to add an relationship to opening hours that can be created and
164 | edited directly:
165 |
166 | 
167 |
168 | ```php
169 | $form->relation('openingHours')
170 | ->title('Opening Hours')
171 | ->showTableHead()
172 | ->deleteUnlinked()
173 | ->hideRelationLink()
174 | ->names([
175 | 'singular' => 'Opening Hour',
176 | 'plural' => 'Opening Hours',
177 | ])
178 | ->preview(function ($preview) {
179 | $preview->col('Week Day')->value('{week_day}');
180 |
181 | $preview->field('Opening Time')
182 | ->datetime('opening_time')
183 | ->onlyTime()
184 | ->minuteInterval(15);
185 |
186 | $preview->field('Closing Time')
187 | ->datetime('closing_time')
188 | ->onlyTime()
189 | ->minuteInterval(15);
190 | })
191 | ->create(function ($form) {
192 | $form->select('week_day')
193 | ->title('Wochentag')
194 | ->options([
195 | 'monday' => 'Monday',
196 | 'tuesday' => 'Tuesday',
197 | 'wednesday' => 'Wednesday',
198 | 'thursday' => 'Thursday',
199 | 'friday' => 'Friday',
200 | 'saturday' => 'Saturday',
201 | 'sunday' => 'Sunday',
202 | ]);
203 | $form->datetime('opening_time')
204 | ->onlyTime()
205 | ->minuteInterval(15)
206 | ->width(1 / 2);
207 |
208 | $form->datetime('closing_time')
209 | ->onlyTime()
210 | ->minuteInterval(15)
211 | ->width(1 / 2);
212 | });
213 | ```
214 |
215 | ## Eager Loading & Appending Accessors
216 |
217 | With query, **relationships** & **accessors** that should be displayed can be
218 | **eager loaded** or **appended**.
219 |
220 | ```php
221 | $form->relation('articles')
222 | ->title('Articles')
223 | ->query(function($query) {
224 | $query->with('author')->append('comments_count');
225 | })
226 | ->preview(function ($table) {
227 | $table->col('Author')->value('{author.first_name} {author.last_name}');
228 | $table->col('Comments')->value('{comments_count} comments');
229 | });
230 | ```
231 |
232 | ## Allow Direct Unlink
233 |
234 | To switch off the modal in which unlinking a relation is confirmed, `confirm`
235 | must be set to false.
236 |
237 | ```php
238 | $form->relation('articles')
239 | ->confirm(false);
240 | ```
241 |
242 | ## Delete Unlinked Model
243 |
244 | You may wish to delete a relation when it has been unlinked:
245 |
246 | ```php
247 | $form->relation('articles')
248 | ->deleteUnlinked();
249 | ```
250 |
251 | ## Tags
252 |
253 | For **many relations** a `tag` preview can be generated by passing `tags` to the
254 | `type` method. Therefore the **attribute** that should be displayed in the tag
255 | must be specified using `tagValue`. Furthermore the variant can be specified
256 | with `tagVariant`.
257 |
258 | ```php
259 | $form->relation('tags')
260 | ->title('Tags')
261 | ->type('tags')
262 | ->tagValue('{value}');
263 | ```
264 |
265 | 
266 |
267 | ## oneRelation And manyRelation
268 |
269 | Every Laravel relation needs its corresponding database setup. For example the
270 | belongsTo relation needs an extra column that stores the id of the related
271 | Model. However you migth want to create relations without going through the
272 | process of creating a new migration to add the required columns/tables. For this
273 | there is the `oneRelation` and `manyRelation`. They can simply be added to your
274 | Models or Forms.
275 |
276 | The following example shows the simple setup of a the relation field that works
277 | for both:
278 |
279 | ```php
280 | use App\Models\Article;
281 |
282 | $form->manyRelation('articles')
283 | ->title('Articles')
284 | ->model(Article::class)
285 | ->preview(function($preview) {
286 | //...
287 | });
288 | ```
289 |
290 | In the Model:
291 |
292 | ```php
293 | public function articles()
294 | {
295 | return $this->manyRelation('App/Models/Article', 'articles');
296 | }
297 | ```
298 |
299 | :::tip
300 |
301 | `oneRelation` and `manyRelation` can be used in Forms.
302 |
303 | :::
304 |
305 | ## Methods
306 |
307 | | Method | Description |
308 | | ------------------------------- | --------------------------------------------------------------------------------------------------------- |
309 | | `$field->title(')` | The title description for this field. |
310 | | `$field->hint(')` | A short hint that should describe how to use the field.` |
311 | | `$field->width()` | Width of the field. |
312 | | `$field->filter()` | Initial query builder for the selectable relations. |
313 | | `$field->query()` | Modify preview query with eager loads and accessors that should be displayed. |
314 | | `$field->preview()` | A **closure** to define the table preview of the corresponding relation. |
315 | | `$field->confirm()` | Modal pops when unlinking the relation and asks to confirm. (default: `true`) |
316 | | `$field->deleteUnlinked()` | Deletes the relation Model after unlinking the relation. (default: `false`) |
317 | | `$field->sortable()` | Sortable relation (only works for `many` relations). |
318 | | `$field->small()` | Small table column height. |
319 | | `$field->maxItems()` | Set a maximum number of selectable items (only works for `many` relations). |
320 | | `$field->create()` | Define form fields for a create form so users can crete new relationship models directly. |
321 | | `$field->form()` | Define form fields so the user can update relation ship attributes. |
322 | | `$field->createAndUpdateForm()` | Define the same form fields for `create` and `form`. |
323 | | `$field->showTableHead()` | Whether the table head should be shown. (default: `false`) |
324 | | `$field->type()` | The preview type (default: `table`) can be `tags` for **many relations** and `link` for **one relations** |
325 | | `$field->tagValue()` | The attribute that should be displayed in the tag. |
326 | | `$field->tagVariant()` | The bootstrap variant of the tag. (default: `info`) |
327 | | `$field->linkValue()` | The attributes that should be displayed as the link. |
328 |
--------------------------------------------------------------------------------
/fields/route.md:
--------------------------------------------------------------------------------
1 | # Route Field
2 |
3 | ## Introduction
4 |
5 | A route picker field that lets you select routes from a predefined collection.
6 |
7 | ## Usage
8 |
9 | The route field requires the **name** of the [collection](#route-collection)
10 | that should be used for this field. Additionally a **title** is required.
11 |
12 | ```php
13 | $form->route('route')
14 | ->collection('app')
15 | ->title('Pick an Url');
16 | ```
17 |
18 | ## Route Collection
19 |
20 | To be able to select routes in your route field you must first register a route
21 | collection in a [service provider](https://laravel.com/docs/7.x/providers). The
22 | registered collection can then be used again and again in different places. The
23 | following example registers a collection with the name **app**.
24 |
25 | ```php
26 | use Ignite\Crud\Fields\Route;
27 |
28 | Route::register('app', function($collection) {
29 | // Define your route collection in here.
30 | });
31 | ```
32 |
33 | ### Add Route
34 |
35 | The selectable routes are configured in the closure using the `route` method.
36 | The first parameter is the **title** that represents the route followed by an
37 | identifier and a function that returns the actual route.
38 |
39 | ```php
40 | $collection->route('Home', 'home', function() {
41 | return route('home');
42 | });
43 | ```
44 |
45 | :::tip
46 |
47 | Use the [arrow function](https://www.php.net/manual/en/functions.arrow.php)
48 | short cut:
49 |
50 | ```php
51 | $collection->route('Home', 'home', fn($locale) => route('home'));
52 | ```
53 |
54 | :::
55 |
56 | ### Add Group
57 |
58 | You can group routes for example into model show routes.
59 |
60 | ```php
61 | $collection->group('Articles', function($group) {
62 | $articles = Article::all();
63 |
64 | foreach($articles as $article) {
65 | $group->route($article->title, $article->id, function() use ($article) {
66 | return route('articles.show', $article->id));
67 | });
68 | }
69 | });
70 | ```
71 |
72 | ### Localization
73 |
74 | The closure in which the route is returned is given the current **locale** as
75 | parameter.
76 |
77 | ```php
78 | $collection->route('Home', 'home' function($locale) {
79 | return route("{$locale}.home");
80 | });
81 | ```
82 |
83 | ## Prepare Model
84 |
85 | If the route field is used in Models the route cast must be specified:
86 |
87 | ```php
88 | use Ignite\Crud\Casts\Route;
89 |
90 | $casts = [
91 | 'route' => Route::class
92 | ];
93 | ```
94 |
95 | ## Frontend
96 |
97 | You can output the value of your route directly in Blade, for example in the
98 | **href** attribute like this:
99 |
100 | ```php
101 | My Link
102 | ```
103 |
104 | You can check if the route is active:
105 |
106 | ```php
107 | @if($model->route->isActive())
108 | Hello World!
109 | @endif
110 | ```
111 |
112 | You may use the `isActive` method to add optional classes to your link:
113 |
114 | ```php
115 |
119 | My Link
120 |
121 | ```
122 |
--------------------------------------------------------------------------------
/fields/screens/conditions/conditions_radio.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/fields/screens/conditions/conditions_radio.gif
--------------------------------------------------------------------------------
/fields/screens/datetime/date_and_time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/fields/screens/datetime/date_and_time.png
--------------------------------------------------------------------------------
/fields/screens/datetime/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/fields/screens/datetime/example.png
--------------------------------------------------------------------------------
/fields/screens/image/expand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/fields/screens/image/expand.png
--------------------------------------------------------------------------------
/fields/screens/image/first_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/fields/screens/image/first_big.png
--------------------------------------------------------------------------------
/fields/screens/range/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/fields/screens/range/example.png
--------------------------------------------------------------------------------
/fields/screens/relation/inline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/fields/screens/relation/inline.png
--------------------------------------------------------------------------------
/fields/screens/relation/picker.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/fields/screens/relation/picker.jpg
--------------------------------------------------------------------------------
/fields/screens/relation/tags.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/fields/screens/relation/tags.png
--------------------------------------------------------------------------------
/fields/screens/validation/validation_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/fields/screens/validation/validation_1.png
--------------------------------------------------------------------------------
/fields/select.md:
--------------------------------------------------------------------------------
1 | # Select
2 |
3 | A select field.
4 |
5 | ```php
6 | $form->select('article_type')
7 | ->title('Type')
8 | ->options([
9 | 1 => 'News',
10 | 2 => 'Info',
11 | ])
12 | ->hint('Select the article type.');
13 | ```
14 |
15 | ## BelongsTo
16 |
17 | A select can be used for `belongsTo` relations.
18 |
19 | ```php
20 | $form->select('article_id')
21 | ->title('Article')
22 | ->options(
23 | Article::all()->mapWithKeys(function($item, $key){
24 | return [$item->id => $item->title];
25 | })->toArray()
26 | )
27 | ->hint('Select Article.');
28 | ```
29 |
30 | ## Methods
31 |
32 | | Methods | Description |
33 | | ------------------------- | ---------------------------------------------------------------------- |
34 | | `$field->title()` | The title description for this field. |
35 | | `$field->options()` | An array with the options, can be a simple array or key => value pairs |
36 | | `$field->hint()` | A short hint that should describe how to use the field.` |
37 | | `$field->info()` | Question mark with tooltip. (Can contain longer field descriptions) |
38 | | `$field->width()` | Width of the field. |
39 | | `$field->rules()` | Rules that should be applied when **updating** and **creating**. |
40 | | `$field->creationRules()` | Rules that should be applied when **creating**. |
41 | | `$field->updateRules()` | Rules that should be applied when **updating**. |
42 |
--------------------------------------------------------------------------------
/fields/textarea.md:
--------------------------------------------------------------------------------
1 | # Textarea
2 |
3 | Basic textarea field.
4 |
5 | ```php
6 | $form->textarea('text')
7 | ->translatable()
8 | ->title('Description')
9 | ->placeholder('Type something...')
10 | ->hint('The Description for some Object.')
11 | ->width(1/2);
12 | ```
13 |
14 | ## Methods
15 |
16 | | Method | Description |
17 | | ------------------------- | --------------------------------------------------------------------------------------------------------------------- |
18 | | `$field->title()` | The title description for this field. |
19 | | `$field->placeholder()` | The placeholder for this field. |
20 | | `$field->hint()` | A short hint that should describe how to use the field.` |
21 | | `$field->info()` | Question mark with tooltip. (Can contain longer field descriptions) |
22 | | `$field->width()` | Width of the field. |
23 | | `$field->translatable()` | Should the field be translatable? For translatable crud models, the translatable fields are automatically recognized. |
24 | | `$field->max()` | Max characters. |
25 | | `$field->rows()` | Number of rows. |
26 | | `$field->maxRows()` | Maximum number of rows. |
27 | | `$field->rules()` | Rules that should be applied when **updating** and **creating**. |
28 | | `$field->creationRules()` | Rules that should be applied when **creating**. |
29 | | `$field->updateRules()` | Rules that should be applied when **updating**. |
30 |
--------------------------------------------------------------------------------
/fields/validation.md:
--------------------------------------------------------------------------------
1 | # Field Validation
2 |
3 | Fields that are not **validated** entail security risks, any values can be
4 | stored for all fillable attributes without validation. It is therefore highly
5 | recommended to append validation rules to any field that handles a fillable
6 | attribute. The
7 | [Laravel documentation](https://laravel.com/docs/7.x/validation#available-validation-rules)
8 | describes all existing rules that can be used for request validation.
9 |
10 | ## Attach Rules
11 |
12 | The following example shows how the rules are attached to a field:
13 |
14 | ```php
15 | $form->input('text')
16 | ->title('Text')
17 | ->rules('required', 'min:10', 'max:50');
18 | ```
19 |
20 | The **error messages** are displayed directly below the field. The **title** is
21 | displayed as attribute.
22 |
23 | 
24 |
25 | ::: tip
26 |
27 | litstack only sends fields that have changed when saving. So keep in mind that
28 | you probably want add the `required` rule to `creationRules`.
29 |
30 | :::
31 |
32 | ## Update Rules
33 |
34 | All rules specified via the method `rules` apply to the creation and updating of
35 | a model. Rules that should only apply for updating a model are defined in
36 | `updateRules` like this:
37 |
38 | ```php
39 | $form->input('text')
40 | ->title('Text')
41 | ->rules('min:10')
42 | ->updateRules('max:50');
43 | ```
44 |
45 | ## Creation Rules
46 |
47 | Similarly, rules can be specified only for creating a model.
48 |
49 | ```php
50 | $form->input('text')
51 | ->title('Text')
52 | ->rules('min:10', 'max:50')
53 | ->creationRules('required');
54 | ```
55 |
--------------------------------------------------------------------------------
/fields/wysiwyg.md:
--------------------------------------------------------------------------------
1 | # WYSIWYG
2 |
3 | A **W**hat-**Y**ou-**S**ee-**I**s-**W**hat-You-**G**et editor using
4 | [tiptap](https://github.com/scrumpy/tiptap).
5 |
6 | ```php
7 | $form->wysiwyg('text')
8 | ->translatable()
9 | ->colors([
10 | '#4951f2', '#f67693', '#f6ed76', '#9ff2ae', '#83c2ff'
11 | ])
12 | ->title('Description')
13 | ->hint('What you see is what you get field.');
14 | ```
15 |
16 | ## Methods
17 |
18 | | Method | Description |
19 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------- |
20 | | `$field->title()` | The title description for this field. |
21 | | `$field->hint()` | A short hint that should describe how to use the field.` |
22 | | `$field->info()` | Question mark with tooltip. (Can contain longer field descriptions) |
23 | | `$field->width()` | Width of the field. |
24 | | `$field->translatable()` | Should the field be translatable? For translatable crud models, the translatable fields are automatically recognized. |
25 | | `$field->max()` | Max characters. |
26 | | `$field->colors()` | Array of colors the the text can be painted in. |
27 | | `$field->tableHasHeader()` | Determines if wysiwyg tables should have an header. |
28 | | `$field->rules()` | Rules that should be applied when **updating** and **creating**. |
29 | | `$field->creationRules()` | Rules that should be applied when **creating**. |
30 | | `$field->updateRules()` | Rules that should be applied when **updating**. |
31 |
--------------------------------------------------------------------------------
/frontend/components.md:
--------------------------------------------------------------------------------
1 | # Vue Components
2 |
3 | ## Introduction
4 |
5 | The package comes along with **bootstrap-vue** and a few components that can be
6 | used to build pages that fit the package's style. To ensure that users of the
7 | admin interface can find their way around quickly and easily on all sites, it is
8 | recommended to follow the following guidelines.
9 |
10 | The package's components have the prefix `lit-`.
11 |
12 | ## Custom Pages
13 |
14 | Custom pages for the admin panel consist of a `container`, the topbar
15 | `navigation` and a `header`. The following content can be created as you like.
16 |
17 | The following example shows how the root template of a page looks like.
18 |
19 | ```javascript
20 |
21 |
22 |
23 |
24 |
25 | // Build your page here.
26 |
27 |
28 |
29 |
34 | ```
35 |
36 | It is recommended to wrap your page content with a b-row and lit-col components.
37 |
38 | ```javascript
39 |
40 |
41 | ...
42 |
43 | ...
44 | ...
45 |
46 |
47 |
48 | ```
49 |
50 | ## Navigation
51 |
52 | The topbar navigation is designed to make it easier for the user to navigate
53 | through the interface and display important controls while scrolling.
54 |
55 | ```javascript
56 |
57 | ```
58 |
59 | ### Go Back
60 |
61 | In the topbar navigation a **back** button can be displayed. All pages in admin
62 | application should be reached via at most one more link from the main
63 | navigation, i.e. an **overview** page and the **detail** page.
64 |
65 | To display the back link a text for the button and a link must be passed as prop
66 | to the navigation.
67 |
68 | ```php
69 |
70 | ```
71 |
72 | ### Controls
73 |
74 | To display controls in the tooltip, simply specify an array with component
75 | names.
76 |
77 | ```javascript
78 |
79 | ```
80 |
81 | The components for the controls must use the bootstrap `b-dropdown-item` as a
82 | root component like so:
83 |
84 | ```javascript
85 |
86 |
87 | Action
88 |
89 |
90 |
91 |
101 | ```
102 |
103 | Furthermore, the `left` and `right` slot can be used to display buttons
104 | directly.
105 |
106 | ```php
107 |
108 |
109 | Left Action
110 |
111 |
112 | Right Action
113 |
114 |
115 | ```
116 |
117 | ## Header
118 |
119 | The page header consists of an `h3` header. The title can either be specified
120 | via the prop `title` or designed in the main slot.
121 |
122 | As well the header can contain controls that should be displayed under the
123 | header. The controls are displayed with the slots `actions` and `actions-right`.
124 |
125 | ```javascript
126 |
127 |
128 | Left Action
129 |
130 |
131 | Right Action
132 |
133 |
134 | ```
135 |
136 | ## Spinner
137 |
138 | The spinner can be displayed with the component `lit-spinner`.
139 |
140 | ```javascript
141 |
142 |
143 |
144 | ```
145 |
--------------------------------------------------------------------------------
/frontend/javascript.md:
--------------------------------------------------------------------------------
1 | # Javascript
2 |
3 | ## Introduction
4 |
5 | If you build your own Vue components it makes sense to know about the helpers
6 | available in Javascript.
7 |
8 | ## Axios
9 |
10 | The javascript global `axios` is configured with the route prefix specified in
11 | the config **lit.php**. It is recommended to set a try around the function when
12 | executing an axios request.
13 |
14 | ```javascript
15 | async func() {
16 | let response;
17 | try {
18 | response = await axios.get('my-route')
19 | } catch(e) {
20 | return
21 | }
22 |
23 | ...
24 | }
25 | ```
26 |
27 | ::: tip
28 |
29 | For requests that shouldn't use the admin `route_prefix` the global `_axios` can
30 | be used.
31 |
32 | :::
33 |
34 | ## Helpers
35 |
36 | In javascript and all Vue components the global variable `Lit` is available.
37 | This includes the following helpers:
38 |
39 | - `baseURL`
40 | - `config`
41 |
42 | ### `Lit.baseURL`
43 |
44 | The `route_prefix` set in config **lit.php**, with a front slash before and
45 | after the prefix.
46 |
47 | ```php
48 | // config/lit.php
49 | 'route_prefix' => 'admin' // Lit.baseURL would be /admin/
50 | ```
51 |
52 | ```javascript
53 |
54 | Link
55 |
56 | ```
57 |
58 | ### `Lit.config`
59 |
60 | All attributes from the config **lit.php**.
61 |
62 | ## Event Bus
63 |
64 | The event bus can be called via the global Lit like this:
65 |
66 | ```javascript
67 | Lit.bus.$on(event, callback);
68 | Lit.bus.$once(event, callback);
69 | Lit.bus.$off(event, callback);
70 | Lit.bus.$emit(event, callback);
71 | ```
72 |
73 | ## Events
74 |
75 | Some useful events:
76 |
77 | - `saved` - Executed when saved.
78 | - `saveCanceled` - When save has been canceled.
79 |
--------------------------------------------------------------------------------
/frontend/vue.md:
--------------------------------------------------------------------------------
1 | # Vue
2 |
3 | ## Introduction
4 |
5 | The admin interface can be extended with custom Vue components for numerous
6 | purposes. This documents describes how custom Vue components can be added to the
7 | application.
8 |
9 | ## Extend Vue
10 |
11 | To include your own `Vue` components in the admin application, the local npm
12 | package `vendor/litstack/litstack` has to be installed. This can be done using
13 | the following artisan command:
14 |
15 | ```shell
16 | php artisan lit:extend
17 | ```
18 |
19 | At the beginning of your `webpack.mix.js` the import of the Litstack mix config
20 | will be added automatically. Two files are compiled:
21 |
22 | - `lit/resources/js/app.js` => `public/lit/js/app.js`
23 | - `lit/resources/sass/app.scss` => `public/lit/css/app.css`
24 |
25 | Add them to **assets** in the config.
26 |
27 | ```php{config/lit.php}
28 | 'assets' => [
29 | 'app_js' => '/lit/js/app.js',
30 | 'scripts' => [
31 | // Add more js files here ...
32 | ],
33 | 'styles' => [
34 | // Add more css files here ...
35 | ],
36 | ],
37 | ```
38 |
39 | All javascript files can be found in `lit/resources/js`.
40 |
41 | ::: tip
42 |
43 | Components that are created in the `components` folder are automatically
44 | registered.
45 |
46 | :::
47 |
48 | Run `npm run watch` and you are good to go.
49 |
50 | ::: warning
51 |
52 | Don't forget to compile your assets every time you **update** the package.
53 |
54 | :::
55 |
56 | ## Register Vue Components
57 |
58 | Vue Components that are located in the `./lit/resources/js/components` folder
59 | are automatically globally registered. They can be used for example in Pages,
60 | Tables or anywhere where you want to include Vue components.
61 |
62 | ## Bootstrap Vue
63 |
64 | To make it easy to build uniform Litstack pages, the package uses
65 | [Bootstrap Vue](https://bootstrap-vue.org/docs/components) for all frontend
66 | components. Bootstrap Vue comes with a large number of components to cover all
67 | the necessary areas needed to build an application.
68 |
69 | ## Mixins
70 |
71 | - [can](#mixin-can)
72 | - [user](#mixin-user)
73 |
74 |
75 |
76 | ### `can({permission})`
77 |
78 | The `can` mixin checks if the authenticated user has a permission.
79 |
80 | ```js
81 | {{ message }}
82 | ```
83 |
84 |
85 |
86 | ### `user()`
87 |
88 | The `user` mixin returns the authenticated User Model.
89 |
90 | ```js
91 | {{ user().name }}
92 | ```
93 |
94 | ## Localization
95 |
96 | [i18n-vue](https://kazupon.github.io/vue-i18n/docs/formatting.html) is used for
97 | the translation in Vue. All translations that are available in **php** are
98 | available in **i18n-vue** as well like shown in the example:
99 |
100 | ```php{lit/resources/lang/en/message.php}
101 | return [
102 | "welcome": "Welcome to Litstack"
103 | ];
104 | ```
105 |
106 | ```javascript
107 |
108 | {{ $t('message.welcome') }}
109 |
110 | ```
111 |
--------------------------------------------------------------------------------
/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | ## Requirements
4 |
5 | An existing Laravel project is required to install the package as well as a
6 | database connection. The package requires **PHP 7.4+** and **Laravel 7+**. As
7 | well as all
8 | [requirements](https://docs.spatie.be/laravel-medialibrary/v8/requirements) of
9 | **spatie/laravel-medialibrary 8.2+**.
10 |
11 | ## Setup
12 |
13 | Installing the package into an existing Laravel application via Composer:
14 |
15 | ```shell
16 | composer require litstack/litstack
17 | ```
18 |
19 | The application will automatically register the needed service providers. The
20 | next step is to process all publishes and migrations by typing the following
21 | artisan command:
22 |
23 | ```shell
24 | php artisan lit:install
25 | ```
26 |
27 | Now all models have been moved to the `app/models` folder, all required files
28 | have been published and all migrations have been executed.
29 |
30 | The admin interface can be reached via the standard route `/admin`. The route
31 | may be changed in the config file `lit.php` by changing the `route_prefix` key.
32 |
33 | The final step is to create an admin user so you can log in to the backend:
34 |
35 | ```shell
36 | php artisan lit:admin
37 | ```
38 |
39 | The wizard will guide you through the process of entering the required user
40 | data.
41 |
--------------------------------------------------------------------------------
/packages/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/packages/.DS_Store
--------------------------------------------------------------------------------
/packages/2fa.md:
--------------------------------------------------------------------------------
1 | # 2 Factor Authentication
2 |
3 |
6 |
7 | ## Introduction
8 |
9 | A package to add 2 Factor Authentication to your litstack application. Secure
10 | the login or the submitting of forms.
11 |
12 | ## The verify Field
13 |
14 | With the verify field a form can be confirmed with a one time password become.
15 |
16 | ```php
17 | $form->input('header');
18 |
19 | $form->needsVerification();
20 | ```
21 |
22 | 
23 |
24 | ::: tip
25 |
26 | If the authenticated user hasn't activated 2 factor authentication for his
27 | account. He is asked to verify the form using his password.
28 |
29 | :::
30 |
31 |
38 |
39 | ## Setup
40 |
41 |
53 |
54 | Install the package via composer:
55 |
56 | ```shell
57 | composer require litstack/2fa
58 | ```
59 |
60 | ## User Model
61 |
62 | Too enable 2 factor authentication on the model used for the litstack
63 | authentication it must add the 2 columns to the corresponding table:
64 |
65 | ```shell
66 | pa make:migration add_two_fa_columns_to_lit_users_table
67 | ```
68 |
69 | ```php
70 | class AddTwoFaColumnsToLitUsersTable extends Migration
71 | {
72 | public function up()
73 | {
74 | Schema::table('lit_users', function (Blueprint $table) {
75 | $table->boolean('two_fa_enabled');
76 | $table->text('two_fa_secret');
77 | });
78 | }
79 |
80 | public function down()
81 | {
82 | Schema::table('lit_users', function (Blueprint $table) {
83 | $table->dropColumn('two_fa_enabled');
84 | $table->dropColumn('two_fa_secret');
85 | });
86 | }
87 | }
88 | ```
89 |
90 | Execute the migration:
91 |
92 | ```shell
93 | php artisan migrate
94 | ```
95 |
96 | Now your Model needs to implement the `Litstack\TwoFA\Authenticatable` contract
97 | and use the `Litstack\TwoFA\HasTwoFactorAuthentication` trait:
98 |
99 | ```php{lit/app/Models/User.php}
100 | // ...
101 |
102 | use Litstack\TwoFA\Authenticatable as TwoFA;
103 | use Litstack\TwoFA\HasTwoFactorAuthentication;
104 |
105 | class User extends Authenticatable implements CanResetPasswordContract, TwoFA
106 | {
107 | use HasTwoFactorAuthentication;
108 |
109 | // ...
110 | }
111 | ```
112 |
113 | The final thing you need to do, is adding the `two_fa_secret` to the `hidden`
114 | attributes of your model and the `two_fa_enabled` as a **boolean** `cast` like
115 | this:
116 |
117 | ```php{lit/app/Models/User.php}
118 | /**
119 | * Hidden attributes.
120 | *
121 | * @var array
122 | */
123 | protected $hidden = ['password', 'two_fa_secret'];
124 |
125 | /**
126 | * The attributes that should be cast to native types.
127 | *
128 | * @var array
129 | */
130 | protected $casts = [
131 | 'email_verified_at' => 'datetime',
132 | 'two_fa_enabled' => 'boolean',
133 | ];
134 | ```
135 |
--------------------------------------------------------------------------------
/packages/bladesmith.md:
--------------------------------------------------------------------------------
1 | # Bladesmith
2 |
3 |
4 |
5 | ## Introduction
6 |
7 | A package with helper functions and Blade components for your
8 | [Litstack](https://github.com/litstack/litstack) project.
9 |
10 | ## Sponsorware
11 |
12 | Bladesmith was created by
13 | **[Lennart Carstens-Behrens](https://twitter.com/lennartcb)** under the
14 | **[Sponsorware license](https://github.com/sponsorware/docs)**.
15 |
16 | ::: tip
17 |
18 | [Sponsor litstack](https://github.com/sponsors/litstack) to get access to this
19 | package.
20 |
21 | :::
22 |
23 | ## Setup
24 |
25 | Add the Litstack repository to your application's composer.json file:
26 |
27 | ```json
28 | "repositories": [
29 | {
30 | "type": "composer",
31 | "url": "https://store.litstack.io"
32 | }
33 | ],
34 | ```
35 |
36 | ```shell
37 | composer require litstack/bladesmith
38 | ```
39 |
40 | To include all styles and scripts the `x-styles` tag must be placed in the head
41 | and the `x-scripts` tag at the end of the body.
42 |
43 | ```html
44 |
45 |
46 |
47 | ...
48 |
49 |
50 |
51 |
52 | ...
53 |
54 |
55 |
56 |
57 | ```
58 |
59 | ## Image
60 |
61 | The image component uses lazy loading to preview a base64 string of the image
62 | before loading it. The image will be loaded when it gets scrolled into the
63 | screen. The component also outputs the appropriate media conversion for the
64 | corresponding screen sizes.
65 |
66 | The component requires an image parameter with a media model:
67 |
68 | ```php
69 |
70 | ```
71 |
72 | 
73 |
74 | Lazy loading may disabled by setting the `lazy` attribute to false:
75 |
76 | ```php
77 |
78 | ```
79 |
80 | ## Building Navigations in Litstack
81 |
82 | Every page needs a navigation. Building it often takes time, especially if the
83 | design has to be adapted exactly to your needs. The Ui kit comes with a simple
84 | extensive solution to include all possible navigations types that are built with
85 | a `list` field in a short time.
86 |
87 | ### Create the Form
88 |
89 | We start by creating a form in that we can build our navigation:
90 |
91 | ```shell
92 | php artisan lit:form navigations main_navigation
93 | ```
94 |
95 | The next step is to add a `nav` field to the newly created config file:
96 |
97 | ```php
98 | namespace Lit\Config\Form\Navigations;
99 |
100 | class MainNavigationConfig extends FormConfig
101 | {
102 | public function show(CrudShow $page)
103 | {
104 | $page->card(function ($form) {
105 | $form->nav('main')->title('Main Navigation')->maxDepth(3);
106 | });
107 | }
108 | }
109 | ```
110 |
111 |
112 |
113 |
114 |
115 | Now we can simply pass the list field to the `x-lit-nav-list` component and a
116 | navigation is created that can be build in the litstack backend:
117 |
118 | ### Display the Navigation
119 |
120 | ```php
121 | use Ignite\Support\Facades\Form;
122 |
123 | $nav = Form::load('navigations', 'main_navigation');
124 |
125 |
126 | ```
127 |
128 | This will result in the following simple horizontal navigation:
129 |
130 |
131 |
132 |
133 |
134 | Customize the navigation using the following options
135 |
136 | | Method | Description |
137 | | ------------- | ---------------------------------------------------------------------- |
138 | | `layout` | Can be `horizontal` or `vertical`. (default is `vertical`) |
139 | | `dropdown` | Wether the navigation should be a dropdown menue on `mouseover`. |
140 | | `depth` | Max depth. |
141 | | `subLevel` | Start depth. |
142 | | `expandable` | Only display's level one, all child levels can be expanded on `click`. |
143 | | `class` | Navigation class. |
144 | | `activeClass` | Class of active items. (default is: `lit--active`) |
145 |
146 | ## Translatable Routes
147 |
148 | Build translated routes in the form of `/en/home`, `/de/startseite` made easy.
149 |
150 | Make sure to translate your routes within your translation-files in the
151 | `resources` directory, for example:
152 |
153 | ```php
154 | // lang/de/routes.php
155 |
156 | return [
157 | 'home' => 'startseite'
158 | ];
159 | ```
160 |
161 | You can now simply add translated Routes to your preferred routes file using the
162 | `__()` helper in the uri string like this:
163 |
164 | ```php
165 | Route::trans('/__(routes.home)', 'HomeController@show')->name('home');
166 | ```
167 |
168 | A translated route will be created for all locales defined in your
169 | `translatable` config. The locale will be prepended to the given **uri** and
170 | **name**. So the routes for the previous example would be:
171 |
172 | - `en.home` => `/en/home`
173 | - `de.home` => `/de/startseite`
174 |
175 | The `__route` helper prepends the current locale to the given name and returns
176 | the corresponding route:
177 |
178 | ```php
179 |
180 | ...
181 |
182 | ```
183 |
184 | ### Switching Languages
185 |
186 | You may want to place a link to the different language route on your website. To
187 | do this, the `translate` method can be applied to the current route with the
188 | desired locale.
189 |
190 | ```php
191 | Deutsch
192 | ```
193 |
194 | #### With Parameters
195 |
196 | For routes with parameters a translator must be specified. A translator is a
197 | controller method that returns the route parameters for the desired locale. The
198 | translator method receives the desired locale and the parameters for the current
199 | locale.
200 |
201 | ```php
202 | // ./routes/web.php
203 | Route::trans('/{slug}', 'MyController@show')->translator('getSlug')->name('home');
204 |
205 | // ./app/Http/Controllers/MyController.php
206 |
207 | ...
208 |
209 | class MyController extends Controller
210 | {
211 | ...
212 |
213 | public function getSlug($locale, $slug)
214 | {
215 | $slug = Post::whereTranslation('slug', $slug)
216 | ->first()
217 | ->translate($locale)
218 | ->slug;
219 |
220 | return ['slug' => $slug];
221 | }
222 | }
223 | ```
224 |
225 | ### Language Switch
226 |
227 | The Blade component `x-lit-localize` creates a link to the translated routes of
228 | all locales.
229 |
230 | ```html
231 |
232 | ```
233 |
234 | Result:
235 |
236 | ```html
237 | EN
238 | DE
239 | ```
240 |
241 | You may change the content of the link By passing a slot with the name of the
242 | locale:
243 |
244 | ```html
245 |
246 |
247 | English
248 |
249 |
250 | Deutsch
251 |
252 |
253 | ```
254 |
255 | Result:
256 |
257 | ```html
258 | English
259 | Deutsch
260 | ```
261 |
262 | ## Helpers
263 |
264 | ### `child_is_active`
265 |
266 | The child is active determines wether a list item has a child with an active
267 | route. The following example will add the `is-active` class when a list item has
268 | an active `route` that is added from route field.
269 |
270 | ```php
271 | $form->route('route_field')->collection('app')->title('Pick a route.');
272 | ```
273 |
274 | ```php
275 | @foreach($data->list as $item)
276 |
277 | {{ $item->title }}
278 |
279 | @endforeach
280 | ```
281 |
282 | ## Customize Views
283 |
284 | If you want to customize the blade components, you can simply publish them and
285 | edit them as desired.
286 |
287 | ```shell
288 | php artisan vendor:publish --provider="Litstack\Bladesmith\BladesmithServiceProvider" --tag=views
289 | ```
290 |
--------------------------------------------------------------------------------
/packages/location.md:
--------------------------------------------------------------------------------
1 | # Location
2 |
3 |
4 |
5 | ## Introduction
6 |
7 | The location package ships with a google maps field that let's you benefit from
8 | the extensive places api, to search for location's or pick one from the map.
9 |
10 | 
11 |
12 | ## Sponsorware
13 |
14 | Bladesmith was created by
15 | **[Lennart Carstens-Behrens](https://twitter.com/lennartcb)** under the
16 | **[Sponsorware license](https://github.com/sponsorware/docs)**.
17 |
18 | ::: tip
19 |
20 | [Sponsor litstack](https://github.com/sponsors/litstack) to get access to this
21 | package.
22 |
23 | :::
24 |
25 | ## Setup
26 |
27 | Add the Litstack repository to your application's composer.json file:
28 |
29 | ```json
30 | "repositories": [
31 | {
32 | "type": "composer",
33 | "url": "https://store.litstack.io"
34 | }
35 | ],
36 | ```
37 |
38 | ```shell
39 | composer require litstack/location
40 | ```
41 |
42 | ### Get A Google Api Key
43 |
44 | Now you need to get an api key to make use of google maps in your litstack
45 | project.
46 |
47 | - Go to the
48 | [Google credentials page](https://console.cloud.google.com/projectselector2/apis/credentials).
49 | - Create an Api Key.
50 | - Enable the following
51 | [libraries](https://console.cloud.google.com/apis/library) for your newly
52 | generated API Key
53 | ([Maps Javascript API](https://console.cloud.google.com/apis/library/maps-backend.googleapis.com),
54 | [Places API](https://console.cloud.google.com/apis/library/places-backend.googleapis.com))
55 |
56 | The api key must now be added to your config under
57 | `lit.location.google_api_key`:
58 |
59 | ```php{config/lit.php}
60 | 'location' => [
61 | 'google_api_key' => env('GOOGLE_MAPS_API_KEY'),
62 | ],
63 | ```
64 |
65 | ## Maps Field
66 |
67 | The maps field let's the user pick location by searching for it or clicking
68 | somewhere on the map.
69 |
70 | The map field requires 2 parameters, the first one is the name of the latitude
71 | attribute, the second parameter is the longitude attribute name.
72 |
73 | ```php
74 | $form->map('lat', 'lng');
75 | ```
76 |
77 | ### Store Place Attributes
78 |
79 | The maps field let's you store additional information about places to your
80 | Model. This can be achieved by passing an array as a third parameter to the maps
81 | field, containing the desired attributes and the database column in which the
82 | attribute should be stored. In the following example the `formatted_address`
83 | would be stored in the `street` column.
84 |
85 | ```php
86 | $form->map('lat', 'lng', [
87 | 'formatted_address' => 'street',
88 | ]);
89 | ```
90 |
91 | The following attributes are available:
92 |
93 | | Method | Description |
94 | | ------------------- | ----------------------------- |
95 | | `formatted_address` | The formatted address name. |
96 | | `street_number` | The location's street number. |
97 | | `street_name` | The location's street name. |
98 | | `state` | The location's state. |
99 | | `city` | The location's city name. |
100 | | `country` | The location's country. |
101 | | `postal_code` | The location's postal code. |
102 |
--------------------------------------------------------------------------------
/packages/meta.md:
--------------------------------------------------------------------------------
1 | # Meta
2 |
3 | ## Introduction
4 |
5 | A package to easily add meta for crud models and forms to your page.
6 |
7 | ## Installation
8 |
9 | The package can be installed via composer and will autoregister.
10 |
11 | ```bash
12 | composer require litstack/meta
13 | ```
14 |
15 | You can now publish and migrate the migration for your meta model:
16 |
17 | ```shell
18 | php artisan vendor:publish --provider="Litstack\Meta\MetaServiceProvider" --tag=migrations
19 | php artisan migrate
20 | ```
21 |
22 | ## Usage
23 |
24 | Start by preparing your Model by using the `HasMeta` Trait and implement the
25 | `metaable` Contract:
26 |
27 | ```php
28 | use Litstack\Meta\Metaable;
29 | use Litstack\Meta\Traits\HasMeta;
30 |
31 | class Post extends Model implements Metaable
32 | {
33 | use HasMeta;
34 | }
35 | ```
36 |
37 | > Forms don't need further setup
38 |
39 | In order to display the form in litstack edit your model-config:
40 |
41 | ```php
42 | use Litstack\Meta\Traits\CrudHasMeta;
43 |
44 | class PostConfig extends CrudConfig
45 | {
46 | use CrudHasMeta;
47 |
48 | // …
49 |
50 | public function show(CrudShow $page)
51 | {
52 | $this->meta($page);
53 | }
54 | }
55 | ```
56 |
57 | You may disable certain fields in the meta modal:
58 |
59 | ```php
60 | $this->meta($page, disable: [
61 | 'description',
62 | 'keywords'
63 | ]);
64 | ```
65 |
66 | To display the meta-fields in your template, simply use the ``
67 | component and pass it the `metaFields` of your model.
68 |
69 | ```php
70 |
71 | ...
72 |
73 | ...
74 |
75 | ```
76 |
77 | ## Default Values / Customizing / Overriding
78 |
--------------------------------------------------------------------------------
/packages/pages.md:
--------------------------------------------------------------------------------
1 | # Pages
2 |
3 |
4 |
5 | ## Introduction
6 |
7 | A package to turn your litstack application into a **CMS**. Add new pages to
8 | your application via the litstack interface.
9 |
10 | 
11 |
12 | ## Sponsorware
13 |
14 | Litstack pages was created by
15 | **[Lennart Carstens-Behrens](https://twitter.com/lennartcb)** under the
16 | **[Sponsorware license](https://github.com/sponsorware/docs)**.
17 |
18 | ## Setup
19 |
20 | Add the Litstack repository to your application's composer.json file:
21 |
22 | ```json
23 | "repositories": [
24 | {
25 | "type": "composer",
26 | "url": "https://store.litstack.io"
27 | }
28 | ],
29 | ```
30 |
31 | Install the package via composer:
32 |
33 | ```shell
34 | composer require litstack/pages
35 | ```
36 |
37 | Publish the migrations and migrate:
38 |
39 | ```shell
40 | php artisan vendor:publish --provider="Litstack\Pages\PagesServiceProvider"
41 |
42 | php artisan migrate
43 | ```
44 |
45 | ## Setup a pages collection
46 |
47 | With the artisan command lit:pages a new pages collection is created. For
48 | example `blog`:
49 |
50 | ```shell
51 | php artisan lit:pages Blog
52 | ```
53 |
54 | A config is created and two controllers, one for the backend in
55 | `./lit/app/Controllers/Pages` and one for your application in
56 | `./app/Http/Controllers/Pages`.
57 |
58 | In the config you can configure the route prefix and the possible repeatables.
59 | The url of the page consists of the route prefix specified in the config and the
60 | sluggified page title. So a route for the following case could be
61 | `/blog/my-title`. If the page is translatable a route is created for each locale
62 | specified in the config like so:
63 |
64 | - `en/blog/{slug}`
65 | - `en/blog/{slug}`
66 |
67 | ```php{lit/app/Config/Pages/BlogConfig.php}
68 | class BlogConfig extends PagesConfig
69 | {
70 | ...
71 |
72 | public function appRoutePrefix(string $locale = null)
73 | {
74 | return "blog";
75 | }
76 |
77 | public function repeatables(Repeatables $rep)
78 | {
79 | // Build your repeatables in here.
80 | }
81 | }
82 | ```
83 |
84 | In the controller the page model is loaded with the method `getFjordPage`. This
85 | can now be passed to a view like this:
86 |
87 | ```php{app/Http/Controllers/Pages}
88 | use Litstack\Pages\ManagesPages;
89 | use Illuminate\Http\Request;
90 |
91 | class PagesController
92 | {
93 | use ManagesPages;
94 |
95 | public function __invoke(Request $request, $slug)
96 | {
97 | $page = $this->getFjordPage($slug);
98 |
99 | return view('pages.blog')->withPage($page);
100 | }
101 | }
102 | ```
103 |
104 | ## Route Field
105 |
106 | To be able to select the pages in a route field you must first add them to a
107 | route collection as described in the
108 | [route field](../fields/route.md#register-routes) documentation.
109 |
110 | FjordPages extends to Eloquent Collection with the helper method
111 | `addToRouteCollection` that lets you add a list of pages directly to a route
112 | collection:
113 |
114 | ```php
115 | use Ignite\Crud\Fields\Route;
116 | use Litstack\Pages\Models\Page;
117 |
118 | Route::register('app', function($collection) {
119 | Page::collection('blog')->get()->addToRouteCollection('Blog', $collection);
120 | });
121 | ```
122 |
--------------------------------------------------------------------------------
/packages/rehearsal.md:
--------------------------------------------------------------------------------
1 | # Rehearsal
2 |
3 | ## Introduction
4 |
5 | An [orchestra](https://github.com/orchestral/testbench) extension to simplify
6 | testing packages in a litstack application environment.
7 |
8 | ## Installation
9 |
10 | Install the package via composer:
11 |
12 | ```shell
13 | composer require --dev litstack/rehearsal
14 | ```
15 |
16 | ## Usage
17 |
18 | To run tests in a litstack environment, your test class only needs to extend
19 | `Litstack\Rehearsal\TestCase`.
20 |
21 | ```php
22 | use Litstack\Rehearsal\TestCase as LitstackTestCase;
23 |
24 | class TestCase extends LitstackTestCase
25 | {
26 | public function test_litstack_is_installed()
27 | {
28 | $this->assertTrue(lit()->installed());
29 | }
30 | }
31 | ```
32 |
33 | This testcase is an extension of `Orchestra\Testbench\TestCase`. All its
34 | functions can be used. Read more on how to test your packages in the
35 | [orchestra docs](https://github.com/orchestral/testbench)
36 |
--------------------------------------------------------------------------------
/packages/screens/lazy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/packages/screens/lazy.png
--------------------------------------------------------------------------------
/packages/screens/maps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/packages/screens/maps.png
--------------------------------------------------------------------------------
/packages/screens/nav-field.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/packages/screens/nav-field.png
--------------------------------------------------------------------------------
/packages/screens/nav-result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/packages/screens/nav-result.png
--------------------------------------------------------------------------------
/packages/screens/pages_screen.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/packages/screens/pages_screen.jpg
--------------------------------------------------------------------------------
/packages/screens/verify.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/packages/screens/verify.gif
--------------------------------------------------------------------------------
/prologue/about.md:
--------------------------------------------------------------------------------
1 | # About Litstack
2 |
3 | ## Who Are We
4 |
5 |
6 |
7 |

8 |
Jannes
Behrens
9 |
10 |
11 |

12 |
Lennart
Carstens-Behrens
13 |
14 |
15 |
16 | Hello there! We are very happy that you are stopping by. **We** are Jannes
17 | Behrens and Lennart Carstens-Behrens, two cousins from northern Germany who work
18 | together at the [Alle Wetter](https://aw-studio.de) Studio for Design and
19 | Development. We are passionate developers and have been working together for
20 | years on hobby projects and continued our collaboration shortly after Jannes and
21 | Gerrit founded Alle Wetter in 2016. The artwork is made by our experienced
22 | designer (Head of design at Alle Wetter) Uwe Steffens. Grüße an dich Uwe!
23 |
24 | ## How It Started
25 |
26 | In the middle of 2018 we thought for the first time about building our own cms.
27 | Requirements in projects became more complex and none of the existing systems
28 | offered a satisfactory solution. At that time we couldn't have imagined what
29 | would be develope from this idea now two years later: **litstack**. Along the
30 | way, we tried things out, rejected ideas and looked for the best ways to create
31 | a system that would meet both, developer & user experience: A clear and
32 | appealing user interface and a beginner-friendly yet powerful backend. The love
33 | for detail also cost a lot of time and nightly sessions. But we are more than
34 | happy with what has come out of it and that we can contribute to the
35 | **Open-Source** world with this project.
36 |
37 | On our way we always found immediate application in customer projects and the
38 | positive feedback motivated us in continuing our work.
39 |
40 | ### From CMS to Admin Panel
41 |
42 | After some time the idea of a **cms** changed to an **admin panel**, which has
43 | the possibility to perform the task of a cms. The management of data is the main
44 | problem to be solved in a modern web app. Be it an **API** or **internal product
45 | managing**. Everything is covered by an administration panel.
46 |
47 | ## Our Goal
48 |
49 | With litstack we try to simplify our life as developers, since we use it daily
50 | and continuously change or improve things due to our customers needs.
51 | Additionally we want to provide an attractive frontend that is not only clear
52 | but also fun to use.
53 |
54 | ### Backend
55 |
56 | #### Headless
57 |
58 | Our main goal is to provide a headless system that can be integrated into
59 | existing systems and above all does not make your project dependent on us.
60 |
61 | #### DX
62 |
63 | Our great example for the goals we pursue for the litstack backend is the
64 | [Laravel framework](https://laravel.com). Beginner-friendly yet powerful and
65 | easy to extend in all possible directions. All in a way that can be managed well
66 | and for a long time through clean architecture & code.
67 |
68 | ### Frontend
69 |
70 | There are many systems that have an overhead of things that most users rarely
71 | need. We want to make it easy to build a navigation system that lets the user
72 | find the important components of his application immediately: A scalable
73 | Interface where A baker who changes the title of his site once a month as well
74 | as the administrator of complex booking systems can easily find their way
75 | around. A logical and clear placement of the components on a clean surface.
76 |
--------------------------------------------------------------------------------
/prologue/art.md:
--------------------------------------------------------------------------------
1 | # Artwork
2 |
3 | ## Introduction
4 |
5 | The artwork is made by **Uwe Steffen**, Head of Design at
6 | [Alle Wetter](https://aw-studio.de) Studio for Design and Development. You can
7 | find the logo and sketch files in the
8 | [litstack/art](https://github.com/litstack/art) repository.
9 |
10 | 
11 |
12 | 
13 |
14 | 
15 |
--------------------------------------------------------------------------------
/prologue/contribution.md:
--------------------------------------------------------------------------------
1 | # Contribution Guide
2 |
3 | ## Bug Reports
4 |
5 | To be able to track bug reports directly, we recommends pull-request before
6 | posting in the issue tracker. If you have difficulties reproducing the bug for a
7 | pull request, issue reports are of course welcome.
8 |
9 | ## Support Questions
10 |
11 | The GitHub issue tracker is reserved for bugs reports or feature requests. If
12 | you have questions, feel free to post them on
13 | [stackoverflow](https://stackoverflow.com/) or our
14 | [discord chanel](https://discord.gg/u4qpb5P).
15 |
16 | ::: tip
17 |
18 | Please keep in mind that the community will benefit if a **solved problem** can
19 | be found via google on stackoverflow.
20 |
21 | :::
22 |
23 | ## Compiled Assets
24 |
25 | If you are submitting a change that will affect a compiled file, such as most of
26 | the files in `resources/sass` or `resources/js` of any litstack repository, do
27 | not commit the compiled files. Due to their large size, they cannot
28 | realistically be reviewed by a maintainer. This could be exploited as a way to
29 | inject malicious code into Litstack. In order to defensively prevent this, all
30 | compiled files will be generated and committed by Litstack maintainers.
31 |
32 | ## Security Vulnerabilities
33 |
34 | If you discover a security vulnerability within Litstack, please send an email
35 | to Lennart Carstens-Behrens at lennart.carbe@gmail.com or Jannes Behrens at
36 | jannes@aw-studio.de. All security vulnerabilities will be promptly addressed.
37 |
38 | ## Coding Style
39 |
40 | Litstack follows the PSR-2 coding standard as laravel. The
41 | [Style CI](https://styleci.io/) included in the repository uses the
42 | [laravel preset](https://docs.styleci.io/presets#laravel) to keep the code in a
43 | familiar laravel standard.
44 |
45 | ::: tip
46 |
47 | Checkout an example of an example of a laravel PHPDoc on the
48 | [laravel website](https://laravel.com/docs/7.x/contributions#phpdoc).
49 |
50 | :::
51 |
52 | ### PHP CS Fixer
53 |
54 | Litstack uses a [PHP CS Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer)
55 | config whose goal is to closely match the coding standard of laravel. The fixer
56 | can be executed with the following composer command.
57 |
58 | ```shell
59 | composer style
60 | ```
61 |
62 | ## Testing
63 |
64 | Tests are divided into two parts. `PHP` tests for the backend via
65 | [PHPUnit](https://phpunit.readthedocs.io/en/9.2/) and `Javascript` test for the
66 | frontend via [Jest](https://jestjs.io/). Depending on what you are working on
67 | you may only want to test one part.
68 |
69 | Installing the test dependencies can be done by installing the composer and/or
70 | npm packages:
71 |
72 | ```shell
73 | composer install && npm install
74 | ```
75 |
76 | ### PHP Tests
77 |
78 | Run the php tests via **composer**:
79 |
80 | ```shell
81 | composer test
82 | ```
83 |
84 | Some tests require a chromedriver to be running on port `9515`. If you want to
85 | cover them as well before pushing to your repository you may start a
86 | chromedriver before:
87 |
88 | ```shell
89 | chromedriver --port=9515
90 | ```
91 |
92 | ### Javascript Tests
93 |
94 | Run the javascript tests via **npm**:
95 |
96 | ```shell
97 | npm test:js
98 | ```
99 |
--------------------------------------------------------------------------------
/prologue/screens/cbl.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/prologue/screens/cbl.jpeg
--------------------------------------------------------------------------------
/prologue/screens/elements.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/prologue/screens/elements.jpeg
--------------------------------------------------------------------------------
/prologue/screens/iter-font.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/prologue/screens/iter-font.jpeg
--------------------------------------------------------------------------------
/prologue/screens/jb.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/prologue/screens/jb.jpeg
--------------------------------------------------------------------------------
/prologue/screens/logo-colors.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/litstack/docs/66b8e6f4ce6ec184127102dc63553cbad41a7b03/prologue/screens/logo-colors.jpeg
--------------------------------------------------------------------------------
/prologue/sponsorware.md:
--------------------------------------------------------------------------------
1 | # Sponsorware
2 |
3 | ## Introduction
4 |
5 | Litstack is made available to the community as an open-source project. We are
6 | spending our free time to improve and maintain this project. Therefore we are
7 | very happy that you are considering supporting this through sponsoring. We also
8 | give something back for our sponsors. Extensive screencasts and helpfull
9 | additional package for litstack like bladesmith or pages.
10 |
11 | ## How it Works
12 |
13 | To get access to the sponsorware go to
14 | [github.com/sponsors/litstack](https://github.com/sponsors/litstack) and read
15 | the tier section on the right side. Select a tier to get access to the desired
16 | sponsorware.
17 |
18 | ### Screencasts
19 |
20 | To get access to the screencasts go to
21 | [litstack.io/screencasts](https://litstack.io/screencasts) and log in with your
22 | github account. You will then be shown the sponsorware videos.
23 |
24 | ### Packages
25 |
26 | To get access to the packages bladesmith and pages you can send an email to
27 | `lennart.carbe@gmail.com`. Lennart will then send you an access token to install
28 | the private composer packages.
29 |
--------------------------------------------------------------------------------
/prologue/upgrade.md:
--------------------------------------------------------------------------------
1 | # Upgrade Guide
2 |
3 | ## Upgrading from 2.4 to 3.x
4 |
5 | Due to a trademark dispute, the name used in version 2.4 for this package had to
6 | be changed. Considering the fact that this will cause big breaking changes, we
7 | have decided to make significant changes in the architecture. Unfortunately this
8 | also means that we cannot provide an upgrade guide. However you are free to
9 | develop your own solution and if possible make it available to the community.
10 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Litstack Documentation
2 |
3 | The online version of the documentation can be reached under
4 | [https://litstack.io/docs](https://litstack.io/docs)
5 |
6 | ## Index
7 |
8 | - ## Prologue
9 | - [About](prologue/about.md)
10 | - [Artwork](prologue/art.md)
11 | - [Upgrade Guide](prologue/upgrade.md)
12 | - [Contribution](prologue/contribution.md)
13 | - [Sponsorware](prologue/sponsorware.md)
14 | - ## Getting Started
15 | - [Installation](installation.md)
16 | - [Configuration](configuration.md)
17 | - ## Basics
18 | - [Basics](basics.md)
19 | - [Navigation](basics/navigation.md)
20 | - [Page](basics/page.md)
21 | - [Localization](basics/localization.md)
22 | - [Helpers](basics/helpers.md)
23 | - ## CRUD
24 | - [Model](crud/model.md)
25 | - [Forms](crud/forms.md)
26 | - [Index Config](crud/index.md)
27 | - [Show Config](crud/show.md)
28 | - [Table](crud/table.md)
29 | - [Actions](crud/actions.md)
30 | - [Search](crud/search.md)
31 | - ## Fields
32 | - [Introduction](fields/introduction.md)
33 | - [Block](fields/block.md)
34 | - [Boolean](fields/boolean.md)
35 | - [Checkboxes](fields/checkboxes.md)
36 | - [Date/Time](fields/date-time.md)
37 | - [Icon](fields/icon.md)
38 | - [Image](fields/image.md)
39 | - [Input](fields/input.md)
40 | - [List](fields/list.md)
41 | - [Modal](fields/modal.md)
42 | - [Password](fields/password.md)
43 | - [Radio](fields/radio.md)
44 | - [Range](fields/range.md)
45 | - [Relation](fields/relation.md)
46 | - [Route](fields/route.md)
47 | - [Select](fields/select.md)
48 | - [Textarea](fields/textarea.md)
49 | - [WYSIWYG](fields/wysiwyg.md)
50 | - [Validation](fields/validation.md)
51 | - [Conditional Fields](fields/conditions.md)
52 | - [Masks](fields/masks.md)
53 | - ## Charts
54 | - [Basics](charts/basics.md)
55 | - [Area Chart](charts/area.md)
56 | - [Bar Chart](charts/bar.md)
57 | - [Number](charts/number.md)
58 | - [Donut Chart](charts/donut.md)
59 | - [Progress](charts/progress.md)
60 | - ## Frontend
61 | - [Javascript](frontend/javascript.md)
62 | - [Vue](frontend/vue.md)
63 | - ## Official Packages
64 | - [Location / Maps](packages/location.md)
65 | - [Meta](packages/meta.md)
66 | - [Bladesmith](packages/bladesmith.md)
67 | - [Pages](packages/pages.md)
68 | - [2 Factor Authentication](packages/2fa.md)
69 | - [Rehearsal](packages/rehearsal.md)
70 |
--------------------------------------------------------------------------------