From 7cdcc0108a999c3141db434b1f4807062380dd7d Mon Sep 17 00:00:00 2001 From: Alexander Nikushkin Date: Sat, 28 Oct 2023 22:54:37 +0500 Subject: [PATCH 1/7] docs: refactoring structure --- config/menu.php | 132 +++++++----------- .../views/pages/en/components/alert.blade.php | 2 +- .../pages/en/components/dropdown.blade.php | 2 +- .../pages/en/components/popover.blade.php | 2 +- .../en/components/progress_bar.blade.php | 4 +- .../pages/en/components/spinner.blade.php | 4 +- .../views/pages/en/components/toast.blade.php | 2 +- .../pages/en/components/tooltip.blade.php | 2 +- .../pages/en/resources/table_styles.blade.php | 2 +- .../block.blade.php | 0 .../button.blade.php | 0 .../pages/ru/components/collapse.blade.php | 84 +++++------ .../pages/ru/components/divider.blade.php | 96 ++++++++----- .../donut_chart.blade.php | 0 .../heading.blade.php | 0 .../views/pages/ru/components/index.blade.php | 16 +-- .../layout.blade.php | 0 .../line_chart.blade.php | 0 .../metrics_value.blade.php} | 54 +++++-- .../views/pages/ru/components/tabs.blade.php | 70 +++++----- .../pages/ru/decorations/collapse.blade.php | 38 ----- .../pages/ru/decorations/divider.blade.php | 82 ----------- .../pages/ru/decorations/index.blade.php | 15 -- .../views/pages/ru/decorations/tabs.blade.php | 42 ------ .../views/pages/ru/fields/enum.blade.php | 2 +- .../views/pages/ru/fields/index.blade.php | 2 +- .../views/pages/ru/metrics/index.blade.php | 16 --- .../ru/{components => ui}/alert.blade.php | 2 +- .../ru/{components => ui}/badge.blade.php | 0 .../ru/{components => ui}/boolean.blade.php | 0 .../pages/ru/{components => ui}/box.blade.php | 0 .../{components => ui}/breadcrumbs.blade.php | 0 .../ru/{components => ui}/card.blade.php | 0 .../views/pages/ru/ui/collapse.blade.php | 58 ++++++++ resources/views/pages/ru/ui/divider.blade.php | 54 +++++++ .../ru/{components => ui}/dropdown.blade.php | 2 +- .../ru/{components => ui}/files.blade.php | 0 .../ru/{components => ui}/form.blade.php | 0 .../ru/{components => ui}/grid.blade.php | 0 .../ru/{components => ui}/icon.blade.php | 0 resources/views/pages/ru/ui/index.blade.php | 19 +++ .../ru/{components => ui}/link.blade.php | 0 .../ru/{components => ui}/loader.blade.php | 0 .../ru/{components => ui}/modal.blade.php | 0 .../ru/{components => ui}/offcanvas.blade.php | 0 .../{components => ui}/paginations.blade.php | 0 .../ru/{components => ui}/popover.blade.php | 2 +- .../{components => ui}/progress_bar.blade.php | 4 +- .../ru/{components => ui}/rating.blade.php | 0 .../shared/colors.blade.php | 0 .../shared/placement.blade.php | 0 .../{components => ui}/shared/sizes.blade.php | 0 .../shared/themes-colors.blade.php | 0 .../{components => ui}/shared/type.blade.php | 0 .../ru/{components => ui}/spinner.blade.php | 4 +- .../ru/{components => ui}/table.blade.php | 0 resources/views/pages/ru/ui/tabs.blade.php | 40 ++++++ .../ru/{components => ui}/thumbnail.blade.php | 0 .../ru/{components => ui}/title.blade.php | 0 .../ru/{components => ui}/toast.blade.php | 2 +- .../ru/{components => ui}/tooltip.blade.php | 2 +- 61 files changed, 416 insertions(+), 442 deletions(-) rename resources/views/pages/ru/{decorations => components}/block.blade.php (100%) rename resources/views/pages/ru/{decorations => components}/button.blade.php (100%) rename resources/views/pages/ru/{metrics => components}/donut_chart.blade.php (100%) rename resources/views/pages/ru/{decorations => components}/heading.blade.php (100%) rename resources/views/pages/ru/{decorations => components}/layout.blade.php (100%) rename resources/views/pages/ru/{metrics => components}/line_chart.blade.php (100%) rename resources/views/pages/ru/{metrics/value.blade.php => components/metrics_value.blade.php} (57%) delete mode 100644 resources/views/pages/ru/decorations/collapse.blade.php delete mode 100644 resources/views/pages/ru/decorations/divider.blade.php delete mode 100644 resources/views/pages/ru/decorations/index.blade.php delete mode 100644 resources/views/pages/ru/decorations/tabs.blade.php delete mode 100644 resources/views/pages/ru/metrics/index.blade.php rename resources/views/pages/ru/{components => ui}/alert.blade.php (98%) rename resources/views/pages/ru/{components => ui}/badge.blade.php (100%) rename resources/views/pages/ru/{components => ui}/boolean.blade.php (100%) rename resources/views/pages/ru/{components => ui}/box.blade.php (100%) rename resources/views/pages/ru/{components => ui}/breadcrumbs.blade.php (100%) rename resources/views/pages/ru/{components => ui}/card.blade.php (100%) create mode 100644 resources/views/pages/ru/ui/collapse.blade.php create mode 100644 resources/views/pages/ru/ui/divider.blade.php rename resources/views/pages/ru/{components => ui}/dropdown.blade.php (97%) rename resources/views/pages/ru/{components => ui}/files.blade.php (100%) rename resources/views/pages/ru/{components => ui}/form.blade.php (100%) rename resources/views/pages/ru/{components => ui}/grid.blade.php (100%) rename resources/views/pages/ru/{components => ui}/icon.blade.php (100%) create mode 100644 resources/views/pages/ru/ui/index.blade.php rename resources/views/pages/ru/{components => ui}/link.blade.php (100%) rename resources/views/pages/ru/{components => ui}/loader.blade.php (100%) rename resources/views/pages/ru/{components => ui}/modal.blade.php (100%) rename resources/views/pages/ru/{components => ui}/offcanvas.blade.php (100%) rename resources/views/pages/ru/{components => ui}/paginations.blade.php (100%) rename resources/views/pages/ru/{components => ui}/popover.blade.php (96%) rename resources/views/pages/ru/{components => ui}/progress_bar.blade.php (93%) rename resources/views/pages/ru/{components => ui}/rating.blade.php (100%) rename resources/views/pages/ru/{components => ui}/shared/colors.blade.php (100%) rename resources/views/pages/ru/{components => ui}/shared/placement.blade.php (100%) rename resources/views/pages/ru/{components => ui}/shared/sizes.blade.php (100%) rename resources/views/pages/ru/{components => ui}/shared/themes-colors.blade.php (100%) rename resources/views/pages/ru/{components => ui}/shared/type.blade.php (100%) rename resources/views/pages/ru/{components => ui}/spinner.blade.php (95%) rename resources/views/pages/ru/{components => ui}/table.blade.php (100%) create mode 100644 resources/views/pages/ru/ui/tabs.blade.php rename resources/views/pages/ru/{components => ui}/thumbnail.blade.php (100%) rename resources/views/pages/ru/{components => ui}/title.blade.php (100%) rename resources/views/pages/ru/{components => ui}/toast.blade.php (96%) rename resources/views/pages/ru/{components => ui}/tooltip.blade.php (96%) diff --git a/config/menu.php b/config/menu.php index fd1d6c88..acc3ec3e 100644 --- a/config/menu.php +++ b/config/menu.php @@ -19,20 +19,30 @@ ['slug' => 'page-instance', 'label' => 'Make instance'], ], + 'Components:rectangle-group' => [ + ['slug' => 'components-index', 'label' => 'Basics'], + + // Decorations + 'Decorations:_divider_', + ['slug' => 'components-decorations_tabs', 'label' => 'Tabs'], + ['slug' => 'components-decorations_heading', 'label' => 'Heading'], + ['slug' => 'components-decorations_block', 'label' => 'Block'], + ['slug' => 'components-decorations_layout', 'label' => 'Layout'], + ['slug' => 'components-decorations_collapse', 'label' => 'Collapse'], + ['slug' => 'components-decorations_divider', 'label' => 'Divider'], + + // Metrics + 'Metrics:_divider_', + ['slug' => 'components-metrics_value', 'label' => 'Value'], + ['slug' => 'components-metrics_line_chart', 'label' => 'Line Chart'], + ['slug' => 'components-metrics_donut_chart', 'label' => 'Donut Chart'], + ], + 'Appearance:photo' => [ ['slug' => 'appearance-index', 'label' => 'Basics'], ['slug' => 'appearance-layout_builder', 'label' => 'LayoutBuilder'], ['slug' => 'appearance-assets', 'label' => 'AssetsManager'], ['slug' => 'appearance-icons', 'label' => 'Icons'], - - // Text - 'Decorations:_divider_', - ['slug' => 'appearance-decorations_tabs', 'label' => 'Tabs'], - ['slug' => 'appearance-decorations_heading', 'label' => 'Heading'], - ['slug' => 'appearance-decorations_block', 'label' => 'Block'], - ['slug' => 'appearance-decorations_layout', 'label' => 'Layout'], - ['slug' => 'appearance-decorations_collapse', 'label' => 'Collapse'], - ['slug' => 'appearance-decorations_divider', 'label' => 'Divider'], ], 'Models Resources:document-duplicate' => [ @@ -48,6 +58,10 @@ ['slug' => 'resources-metrics', 'label' => 'Metrics'], ['slug' => 'resources-events', 'label' => 'Events'], ['slug' => 'resources-authorization', 'label' => 'Authorization'], + +// ['slug' => 'resources-export', 'label' => 'Export'], +// ['slug' => 'resources-import', 'label' => 'Import'], + // ['slug' => 'resources-actions', 'label' => 'Actions'], // ['slug' => 'resources-active_actions', 'label' => 'Active actions'], // ['slug' => 'resources-item_actions', 'label' => 'Item actions'], @@ -61,22 +75,6 @@ ['slug' => 'menu', 'label' => 'Menu'], ], - 'Appearance:photo' => [ - ['slug' => 'appearance-index', 'label' => 'Basics'], - ['slug' => 'appearance-layout_builder', 'label' => 'LayoutBuilder'], - ['slug' => 'appearance-assets', 'label' => 'AssetsManager'], - ['slug' => 'appearance-icons', 'label' => 'Icons'], - - // Decorations - 'Decorations:_divider_', - ['slug' => 'appearance-decorations_tabs', 'label' => 'Tabs'], - ['slug' => 'appearance-decorations_heading', 'label' => 'Heading'], - ['slug' => 'appearance-decorations_block', 'label' => 'Block'], - ['slug' => 'appearance-decorations_layout', 'label' => 'Layout'], - ['slug' => 'appearance-decorations_collapse', 'label' => 'Collapse'], - ['slug' => 'appearance-decorations_divider', 'label' => 'Divider'], - ], - 'Fields:table-cells' => [ ['slug' => 'fields-index', 'label' => 'Basics'], // Text @@ -149,32 +147,8 @@ ['slug' => 'action_button', 'label' => 'ActionButton'], ], -// 'Decorations:rocket-launch' => [ -// ['slug' => 'decorations-index', 'label' => 'Basics'], -// ['slug' => 'decorations-tabs', 'label' => 'Tabs'], -// ['slug' => 'decorations-heading', 'label' => 'Heading'], -// ['slug' => 'decorations-block', 'label' => 'Block'], -// ['slug' => 'decorations-layout', 'label' => 'Layout', 'badge' => 'new'], -// ['slug' => 'decorations-button', 'label' => 'Button'], -// ['slug' => 'decorations-collapse', 'label' => 'Collapse'], -// ['slug' => 'decorations-divider', 'label' => 'Divider', 'badge' => 'new'], -// ], - -// 'Metrics:chart-bar' => [ -// ['slug' => 'metrics-index', 'label' => 'Basics'], -// ['slug' => 'metrics-value', 'label' => 'Value'], -// ['slug' => 'metrics-line_chart', 'label' => 'Line Chart'], -// ['slug' => 'metrics-donut_chart', 'label' => 'Donut Chart', 'badge' => 'new'], -// ], - -// 'Actions:hand-raised' => [ -// ['slug' => 'actions-index', 'label' => 'Basics'], -// ['slug' => 'actions-export', 'label' => 'Export'], -// ['slug' => 'actions-import', 'label' => 'Import'], -// ], - 'Advanced:moon' => [ - //['slug' => 'advanced-resource', 'label' => 'Resource'], + ['slug' => 'advanced-resource', 'label' => 'Resource'], ['slug' => 'advanced-controller', 'label' => 'Controllers'], ['slug' => 'advanced-form_builder', 'label' => 'FormBuilder'], ['slug' => 'advanced-table_builder', 'label' => 'TableBuilder'], @@ -192,35 +166,35 @@ ':_divider_', 'UI components:code-bracket-square' => [ - ['slug' => 'components-index', 'label' => 'Basics'], - ['slug' => 'components-alert', 'label' => 'Alert'], - ['slug' => 'components-badge', 'label' => 'Badge'], - ['slug' => 'components-boolean', 'label' => 'Boolean'], - ['slug' => 'components-box', 'label' => 'Box'], - ['slug' => 'components-breadcrumbs', 'label' => 'Breadcrumbs'], - ['slug' => 'components-card', 'label' => 'Card'], - ['slug' => 'components-collapse', 'label' => 'Collapse'], - ['slug' => 'components-divider', 'label' => 'Divider'], - ['slug' => 'components-dropdown', 'label' => 'Dropdown'], - ['slug' => 'components-icon', 'label' => 'Icon'], - ['slug' => 'components-files', 'label' => 'Files'], - ['slug' => 'components-form', 'label' => 'Form elements'], - ['slug' => 'components-grid', 'label' => 'Grid/Column'], - ['slug' => 'components-link', 'label' => 'Link'], - ['slug' => 'components-loader', 'label' => 'Loader'], - ['slug' => 'components-modal', 'label' => 'Modal'], - ['slug' => 'components-offcanvas', 'label' => 'Offcanvas'], - ['slug' => 'components-paginations', 'label' => 'Paginations'], - ['slug' => 'components-popover', 'label' => 'Popover'], - ['slug' => 'components-progress_bar', 'label' => 'Progress bar'], - ['slug' => 'components-rating', 'label' => 'Rating'], - ['slug' => 'components-spinner', 'label' => 'Spinner'], - ['slug' => 'components-table', 'label' => 'Table'], - ['slug' => 'components-tabs', 'label' => 'Tabs'], - ['slug' => 'components-thumbnail', 'label' => 'Thumbnail'], - ['slug' => 'components-title', 'label' => 'Title'], - ['slug' => 'components-toast', 'label' => 'Toast'], - ['slug' => 'components-tooltip', 'label' => 'Tooltip'], + ['slug' => 'ui-index', 'label' => 'Basics'], + ['slug' => 'ui-alert', 'label' => 'Alert'], + ['slug' => 'ui-badge', 'label' => 'Badge'], + ['slug' => 'ui-boolean', 'label' => 'Boolean'], + ['slug' => 'ui-box', 'label' => 'Box'], + ['slug' => 'ui-breadcrumbs', 'label' => 'Breadcrumbs'], + ['slug' => 'ui-card', 'label' => 'Card'], + ['slug' => 'ui-collapse', 'label' => 'Collapse'], + ['slug' => 'ui-divider', 'label' => 'Divider'], + ['slug' => 'ui-dropdown', 'label' => 'Dropdown'], + ['slug' => 'ui-icon', 'label' => 'Icon'], + ['slug' => 'ui-files', 'label' => 'Files'], + ['slug' => 'ui-form', 'label' => 'Form elements'], + ['slug' => 'ui-grid', 'label' => 'Grid/Column'], + ['slug' => 'ui-link', 'label' => 'Link'], + ['slug' => 'ui-loader', 'label' => 'Loader'], + ['slug' => 'ui-modal', 'label' => 'Modal'], + ['slug' => 'ui-offcanvas', 'label' => 'Offcanvas'], + ['slug' => 'ui-paginations', 'label' => 'Paginations'], + ['slug' => 'ui-popover', 'label' => 'Popover'], + ['slug' => 'ui-progress_bar', 'label' => 'Progress bar'], + ['slug' => 'ui-rating', 'label' => 'Rating'], + ['slug' => 'ui-spinner', 'label' => 'Spinner'], + ['slug' => 'ui-table', 'label' => 'Table'], + ['slug' => 'ui-tabs', 'label' => 'Tabs'], + ['slug' => 'ui-thumbnail', 'label' => 'Thumbnail'], + ['slug' => 'ui-title', 'label' => 'Title'], + ['slug' => 'ui-toast', 'label' => 'Toast'], + ['slug' => 'ui-tooltip', 'label' => 'Tooltip'], ], // ':_divider_', diff --git a/resources/views/pages/en/components/alert.blade.php b/resources/views/pages/en/components/alert.blade.php index a0180816..c5776a2f 100644 --- a/resources/views/pages/en/components/alert.blade.php +++ b/resources/views/pages/en/components/alert.blade.php @@ -24,7 +24,7 @@ You can change the notification type by specifying the component type -@include('pages.en.components.shared.type') +@include('pages.en.ui.shared.type') diff --git a/resources/views/pages/en/components/dropdown.blade.php b/resources/views/pages/en/components/dropdown.blade.php index 11970cf6..14ff98cb 100644 --- a/resources/views/pages/en/components/dropdown.blade.php +++ b/resources/views/pages/en/components/dropdown.blade.php @@ -30,7 +30,7 @@ Placement -@include('pages.en.components.shared.placement') +@include('pages.en.ui.shared.placement') diff --git a/resources/views/pages/en/components/popover.blade.php b/resources/views/pages/en/components/popover.blade.php index 2877159f..0c1f77db 100644 --- a/resources/views/pages/en/components/popover.blade.php +++ b/resources/views/pages/en/components/popover.blade.php @@ -10,7 +10,7 @@ Using the moonshine::popover component, you can create a popup window -@include('pages.ru.components.shared.placement') +@include('pages.ru.ui.shared.placement') diff --git a/resources/views/pages/en/components/progress_bar.blade.php b/resources/views/pages/en/components/progress_bar.blade.php index cc1a4fc7..f1712f78 100644 --- a/resources/views/pages/en/components/progress_bar.blade.php +++ b/resources/views/pages/en/components/progress_bar.blade.php @@ -11,7 +11,7 @@ The moonshine::progress-bar component allows you to create a progress bar -@include('pages.en.components.shared.colors') +@include('pages.en.ui.shared.colors') @@ -31,7 +31,7 @@ To create a radial progress indicator, you need to pass the radial parameter to the component with the value TRUE -@include('pages.en.components.shared.sizes') +@include('pages.en.ui.shared.sizes') diff --git a/resources/views/pages/en/components/spinner.blade.php b/resources/views/pages/en/components/spinner.blade.php index e4575072..3210707b 100644 --- a/resources/views/pages/en/components/spinner.blade.php +++ b/resources/views/pages/en/components/spinner.blade.php @@ -24,7 +24,7 @@ Size -@include('pages.en.components.shared.sizes') +@include('pages.en.ui.shared.sizes') @@ -38,7 +38,7 @@ Color -@include('pages.en.components.shared.colors') +@include('pages.en.ui.shared.colors') diff --git a/resources/views/pages/en/components/toast.blade.php b/resources/views/pages/en/components/toast.blade.php index d7797dcb..ec100899 100644 --- a/resources/views/pages/en/components/toast.blade.php +++ b/resources/views/pages/en/components/toast.blade.php @@ -12,7 +12,7 @@ -@include('pages.en.components.shared.type') +@include('pages.en.ui.shared.type') diff --git a/resources/views/pages/en/components/tooltip.blade.php b/resources/views/pages/en/components/tooltip.blade.php index cbdf8312..8effd619 100644 --- a/resources/views/pages/en/components/tooltip.blade.php +++ b/resources/views/pages/en/components/tooltip.blade.php @@ -11,7 +11,7 @@ Using the moonshine::tooltip component, you can create handy tooltips -@include('pages.ru.components.shared.placement') +@include('pages.ru.ui.shared.placement') diff --git a/resources/views/pages/en/resources/table_styles.blade.php b/resources/views/pages/en/resources/table_styles.blade.php index 28655c0e..95543335 100644 --- a/resources/views/pages/en/resources/table_styles.blade.php +++ b/resources/views/pages/en/resources/table_styles.blade.php @@ -35,7 +35,7 @@ public function tdClass(Model $item, int $index, int $cell): string } -@include('pages.en.components.shared.colors') +@include('pages.en.ui.shared.colors') diff --git a/resources/views/pages/ru/decorations/block.blade.php b/resources/views/pages/ru/components/block.blade.php similarity index 100% rename from resources/views/pages/ru/decorations/block.blade.php rename to resources/views/pages/ru/components/block.blade.php diff --git a/resources/views/pages/ru/decorations/button.blade.php b/resources/views/pages/ru/components/button.blade.php similarity index 100% rename from resources/views/pages/ru/decorations/button.blade.php rename to resources/views/pages/ru/components/button.blade.php diff --git a/resources/views/pages/ru/components/collapse.blade.php b/resources/views/pages/ru/components/collapse.blade.php index f67800ee..c1a8470f 100644 --- a/resources/views/pages/ru/components/collapse.blade.php +++ b/resources/views/pages/ru/components/collapse.blade.php @@ -1,58 +1,38 @@ - - -Основы - - - Компонент moonshine::collapse позволяет сворачивать контент. - - - - - - - - @include("examples/components/collapse") - - - - -Отобразить развернутым + - Если параметр show имеет значение TRUE, - то по умолчанию блок будет отображаться развернутым. + Декоратор Collapse позволяет сворачивать fields и blocks с сохранением состояния. - - - - - - @include("examples/components/collapse-show") - - - - -Сохранение состояния - - - Если параметр persist имеет значение TRUE, то будет сохраняться состояние блока. - - - - - - - - @include("examples/components/collapse-persist") - - - + +use MoonShine\Decorations\Collapse; // [tl! focus] +use MoonShine\Decorations\Block; + +//... +public function fields(): array +{ + return [ + Block::make([ + Collapse::make('Title/Slug', [ // [tl! focus] + Text::make('Title') + ->fieldContainer(false), + + Text::make('Slug') + ->fieldContainer(false), + ]) // [tl! focus] + ->show() // отобразить развернутым (дополнительная опция) [tl! focus] + ]); + ]; +} +//... + + + + diff --git a/resources/views/pages/ru/components/divider.blade.php b/resources/views/pages/ru/components/divider.blade.php index 3698f838..d6713788 100644 --- a/resources/views/pages/ru/components/divider.blade.php +++ b/resources/views/pages/ru/components/divider.blade.php @@ -1,54 +1,82 @@ - + Основы - Компонент moonshine::divider позволяет создать стилизованный разделитель контента. + Для разделения на зоны можно воспользоваться декорацией Divider. - + +use MoonShine\Decorations\Divider; - - - - @include("examples/components/divider") - - - +//... +public function fields(): array +{ + return [ + //... + Divider::make(), // [tl! focus] + //... + ]; +} +//... + -Текстовый разделитель + + + +Label - В качестве разделителя можно использовать текст. Для этого необходимо указать текст в параметре label. + В качестве разделителя можно использовать текст, для этого его необходимо передать методу make() в качестве аргумента. - + +use MoonShine\Decorations\Divider; + +//... +public function fields(): array +{ + return [ + //... + Divider::make('Divider'), // [tl! focus] + //... + ]; +} +//... + - - - - @include("examples/components/divider-label") - - - + + - Параметр centered позволяет разместить текст по центру. + Метод centered() позволяет отцентрировать текст. - + +use MoonShine\Decorations\Divider; + +//... +public function fields(): array +{ + return [ + //... + Divider::make('Divider') + ->centered(), // [tl! focus] + //... + ]; +} +//... + - - - - @include("examples/components/divider-label-center") - - - + + diff --git a/resources/views/pages/ru/metrics/donut_chart.blade.php b/resources/views/pages/ru/components/donut_chart.blade.php similarity index 100% rename from resources/views/pages/ru/metrics/donut_chart.blade.php rename to resources/views/pages/ru/components/donut_chart.blade.php diff --git a/resources/views/pages/ru/decorations/heading.blade.php b/resources/views/pages/ru/components/heading.blade.php similarity index 100% rename from resources/views/pages/ru/decorations/heading.blade.php rename to resources/views/pages/ru/components/heading.blade.php diff --git a/resources/views/pages/ru/components/index.blade.php b/resources/views/pages/ru/components/index.blade.php index a18687a3..a04b7f70 100644 --- a/resources/views/pages/ru/components/index.blade.php +++ b/resources/views/pages/ru/components/index.blade.php @@ -1,19 +1,7 @@ - + - Для создания интерфейса админ-панели MoonShine используется множество UI компонентов.
- Вы можете воспользоваться этими компонентами для построения своих шаблонов, - кастомных полей, фильтров, декораций или страниц.
- Использование компонентов ускоряет разработку и позволяет сохранить единую стилистику проекта. + Блоки для отображения статистики.
- - Если вы планируете использовать компоненты за пределами админ-панели, - то необходимо ваш шаблон добавить директиву с ассетами MoonShine. - - - - @@moonShineAssets - -
diff --git a/resources/views/pages/ru/decorations/layout.blade.php b/resources/views/pages/ru/components/layout.blade.php similarity index 100% rename from resources/views/pages/ru/decorations/layout.blade.php rename to resources/views/pages/ru/components/layout.blade.php diff --git a/resources/views/pages/ru/metrics/line_chart.blade.php b/resources/views/pages/ru/components/line_chart.blade.php similarity index 100% rename from resources/views/pages/ru/metrics/line_chart.blade.php rename to resources/views/pages/ru/components/line_chart.blade.php diff --git a/resources/views/pages/ru/metrics/value.blade.php b/resources/views/pages/ru/components/metrics_value.blade.php similarity index 57% rename from resources/views/pages/ru/metrics/value.blade.php rename to resources/views/pages/ru/components/metrics_value.blade.php index eed90e43..e25dc6ff 100644 --- a/resources/views/pages/ru/metrics/value.blade.php +++ b/resources/views/pages/ru/components/metrics_value.blade.php @@ -1,33 +1,55 @@ - + + +Make - Предназначено для отображения простого значения. Например, сколько всего в таблице определенных записей. + Метрика ValueMetric предназначена для отображения какого-либо значения. + Например, сколько всего в таблице записей.
+ Создать ValueMetric можно используя статический метод make().
-namespace MoonShine\Resources; +make(Closure|string $label) + -use MoonShine\Metrics\ValueMetric; + + Метод value() позволяет указать значение для метрики. + -class PostResource extends Resource -{ - //... + +value(int|string|float|Closure $value) + - public function metrics(): array // [tl! focus:start] - { - return [ - ValueMetric::make('Завершенных заказов') - ->value(Orders::completed()->count()) - ]; - } // [tl! focus:end] + +use MoonShine\Metrics\ValueMetric; // [tl! focus] - //... +//... + +public function components(): array +{ + return [ + ValueMetric::make('Completed orders') + ->value(Orders::completed()->count()) // [tl! focus:-1] + ]; } + +//... +Прогресс + Также есть возможность отображения в виде прогресса достижения цели. @@ -57,6 +79,8 @@ public function metrics(): array // [tl! focus:start] +Формат + Выводимое значение можно отформатировать и добавить префикс и суффикс. diff --git a/resources/views/pages/ru/components/tabs.blade.php b/resources/views/pages/ru/components/tabs.blade.php index 0254b333..83dad1bd 100644 --- a/resources/views/pages/ru/components/tabs.blade.php +++ b/resources/views/pages/ru/components/tabs.blade.php @@ -1,40 +1,42 @@ - - -Основы - - - Для создания вкладок можно воспользоваться компонентом moonshine::tabs. - - - - - - - - @include("examples/components/tabs") - - - - -Активная вкладка + - Указать активную вкладку по умолчанию, можно задав active. + На форму для удобства можно добавить вкладки и сгруппировать поля. - - - - - - @include("examples/components/tabs-active") - - - + +use MoonShine\Decorations\Block; +use MoonShine\Decorations\Tabs; +use MoonShine\Decorations\Tab; +use MoonShine\Fields\Text; + +//... +public function fields(): array +{ + return [ + Block::make('Основное', [ + Tabs::make([ + Tab::make('Seo', [ + Text::make('Seo title') + ->fieldContainer(false), + //... + ]), + Tab::make('Categories', [ + //... + ]) + ]) + ]), + ]; +} +//... + + + + diff --git a/resources/views/pages/ru/decorations/collapse.blade.php b/resources/views/pages/ru/decorations/collapse.blade.php deleted file mode 100644 index c1a8470f..00000000 --- a/resources/views/pages/ru/decorations/collapse.blade.php +++ /dev/null @@ -1,38 +0,0 @@ - - - - Декоратор Collapse позволяет сворачивать fields и blocks с сохранением состояния. - - - -use MoonShine\Decorations\Collapse; // [tl! focus] -use MoonShine\Decorations\Block; - -//... -public function fields(): array -{ - return [ - Block::make([ - Collapse::make('Title/Slug', [ // [tl! focus] - Text::make('Title') - ->fieldContainer(false), - - Text::make('Slug') - ->fieldContainer(false), - ]) // [tl! focus] - ->show() // отобразить развернутым (дополнительная опция) [tl! focus] - ]); - ]; -} -//... - - - - - - diff --git a/resources/views/pages/ru/decorations/divider.blade.php b/resources/views/pages/ru/decorations/divider.blade.php deleted file mode 100644 index d6713788..00000000 --- a/resources/views/pages/ru/decorations/divider.blade.php +++ /dev/null @@ -1,82 +0,0 @@ - - -Основы - - - Для разделения на зоны можно воспользоваться декорацией Divider. - - - -use MoonShine\Decorations\Divider; - -//... -public function fields(): array -{ - return [ - //... - Divider::make(), // [tl! focus] - //... - ]; -} -//... - - - - - -Label - - - В качестве разделителя можно использовать текст, для этого его необходимо передать методу make() в качестве аргумента. - - - -use MoonShine\Decorations\Divider; - -//... -public function fields(): array -{ - return [ - //... - Divider::make('Divider'), // [tl! focus] - //... - ]; -} -//... - - - - - - - Метод centered() позволяет отцентрировать текст. - - - -use MoonShine\Decorations\Divider; - -//... -public function fields(): array -{ - return [ - //... - Divider::make('Divider') - ->centered(), // [tl! focus] - //... - ]; -} -//... - - - - - - diff --git a/resources/views/pages/ru/decorations/index.blade.php b/resources/views/pages/ru/decorations/index.blade.php deleted file mode 100644 index 0bc2b4c7..00000000 --- a/resources/views/pages/ru/decorations/index.blade.php +++ /dev/null @@ -1,15 +0,0 @@ - - - Декорации задаются в методах ресурса fields или filters. - - - - Служат для улучшения внешнего вида полей и повышения качества интерфейса. - - - diff --git a/resources/views/pages/ru/decorations/tabs.blade.php b/resources/views/pages/ru/decorations/tabs.blade.php deleted file mode 100644 index 83dad1bd..00000000 --- a/resources/views/pages/ru/decorations/tabs.blade.php +++ /dev/null @@ -1,42 +0,0 @@ - - - - На форму для удобства можно добавить вкладки и сгруппировать поля. - - - -use MoonShine\Decorations\Block; -use MoonShine\Decorations\Tabs; -use MoonShine\Decorations\Tab; -use MoonShine\Fields\Text; - -//... -public function fields(): array -{ - return [ - Block::make('Основное', [ - Tabs::make([ - Tab::make('Seo', [ - Text::make('Seo title') - ->fieldContainer(false), - //... - ]), - Tab::make('Categories', [ - //... - ]) - ]) - ]), - ]; -} -//... - - - - - - diff --git a/resources/views/pages/ru/fields/enum.blade.php b/resources/views/pages/ru/fields/enum.blade.php index 1f2e3cb3..ddaf3ca8 100644 --- a/resources/views/pages/ru/fields/enum.blade.php +++ b/resources/views/pages/ru/fields/enum.blade.php @@ -74,7 +74,7 @@ public function toString(): ?string то в preview поле отобразиться в виде значка определенного цвета. -@include('pages.ru.components.shared.colors') +@include('pages.ru.ui.shared.colors') namespace App\Enums; diff --git a/resources/views/pages/ru/fields/index.blade.php b/resources/views/pages/ru/fields/index.blade.php index 9d4b4e2c..9346735e 100644 --- a/resources/views/pages/ru/fields/index.blade.php +++ b/resources/views/pages/ru/fields/index.blade.php @@ -320,7 +320,7 @@ public function fields(): array badge(string|Closure|null $color = null) -@include('pages.ru.components.shared.colors') +@include('pages.ru.ui.shared.colors') //... diff --git a/resources/views/pages/ru/metrics/index.blade.php b/resources/views/pages/ru/metrics/index.blade.php deleted file mode 100644 index c1c25d89..00000000 --- a/resources/views/pages/ru/metrics/index.blade.php +++ /dev/null @@ -1,16 +0,0 @@ - - - - Блоки для отображения статистики. - - - - Можно вывести на главной странице панели управления - и в каждом отдельном ресурсе. - - - - Метрикам также доступны методы декораций - Layout (columnSpan). - - diff --git a/resources/views/pages/ru/components/alert.blade.php b/resources/views/pages/ru/ui/alert.blade.php similarity index 98% rename from resources/views/pages/ru/components/alert.blade.php rename to resources/views/pages/ru/ui/alert.blade.php index 01e16ef4..f9359642 100644 --- a/resources/views/pages/ru/components/alert.blade.php +++ b/resources/views/pages/ru/ui/alert.blade.php @@ -24,7 +24,7 @@ Изменить тип уведомления можно указав у компонента type. -@include('pages.ru.components.shared.type') +@include('pages.ru.ui.shared.type') diff --git a/resources/views/pages/ru/components/badge.blade.php b/resources/views/pages/ru/ui/badge.blade.php similarity index 100% rename from resources/views/pages/ru/components/badge.blade.php rename to resources/views/pages/ru/ui/badge.blade.php diff --git a/resources/views/pages/ru/components/boolean.blade.php b/resources/views/pages/ru/ui/boolean.blade.php similarity index 100% rename from resources/views/pages/ru/components/boolean.blade.php rename to resources/views/pages/ru/ui/boolean.blade.php diff --git a/resources/views/pages/ru/components/box.blade.php b/resources/views/pages/ru/ui/box.blade.php similarity index 100% rename from resources/views/pages/ru/components/box.blade.php rename to resources/views/pages/ru/ui/box.blade.php diff --git a/resources/views/pages/ru/components/breadcrumbs.blade.php b/resources/views/pages/ru/ui/breadcrumbs.blade.php similarity index 100% rename from resources/views/pages/ru/components/breadcrumbs.blade.php rename to resources/views/pages/ru/ui/breadcrumbs.blade.php diff --git a/resources/views/pages/ru/components/card.blade.php b/resources/views/pages/ru/ui/card.blade.php similarity index 100% rename from resources/views/pages/ru/components/card.blade.php rename to resources/views/pages/ru/ui/card.blade.php diff --git a/resources/views/pages/ru/ui/collapse.blade.php b/resources/views/pages/ru/ui/collapse.blade.php new file mode 100644 index 00000000..f67800ee --- /dev/null +++ b/resources/views/pages/ru/ui/collapse.blade.php @@ -0,0 +1,58 @@ + + +Основы + + + Компонент moonshine::collapse позволяет сворачивать контент. + + + + + + + + @include("examples/components/collapse") + + + + +Отобразить развернутым + + + Если параметр show имеет значение TRUE, + то по умолчанию блок будет отображаться развернутым. + + + + + + + + @include("examples/components/collapse-show") + + + + +Сохранение состояния + + + Если параметр persist имеет значение TRUE, то будет сохраняться состояние блока. + + + + + + + + @include("examples/components/collapse-persist") + + + + + diff --git a/resources/views/pages/ru/ui/divider.blade.php b/resources/views/pages/ru/ui/divider.blade.php new file mode 100644 index 00000000..3698f838 --- /dev/null +++ b/resources/views/pages/ru/ui/divider.blade.php @@ -0,0 +1,54 @@ + + +Основы + + + Компонент moonshine::divider позволяет создать стилизованный разделитель контента. + + + + + + + + @include("examples/components/divider") + + + + +Текстовый разделитель + + + В качестве разделителя можно использовать текст. Для этого необходимо указать текст в параметре label. + + + + + + + + @include("examples/components/divider-label") + + + + + + Параметр centered позволяет разместить текст по центру. + + + + + + + + @include("examples/components/divider-label-center") + + + + + diff --git a/resources/views/pages/ru/components/dropdown.blade.php b/resources/views/pages/ru/ui/dropdown.blade.php similarity index 97% rename from resources/views/pages/ru/components/dropdown.blade.php rename to resources/views/pages/ru/ui/dropdown.blade.php index 3b5d94ba..c40b8930 100644 --- a/resources/views/pages/ru/components/dropdown.blade.php +++ b/resources/views/pages/ru/ui/dropdown.blade.php @@ -30,7 +30,7 @@ Расположение -@include('pages.ru.components.shared.placement') +@include('pages.ru.ui.shared.placement') diff --git a/resources/views/pages/ru/components/files.blade.php b/resources/views/pages/ru/ui/files.blade.php similarity index 100% rename from resources/views/pages/ru/components/files.blade.php rename to resources/views/pages/ru/ui/files.blade.php diff --git a/resources/views/pages/ru/components/form.blade.php b/resources/views/pages/ru/ui/form.blade.php similarity index 100% rename from resources/views/pages/ru/components/form.blade.php rename to resources/views/pages/ru/ui/form.blade.php diff --git a/resources/views/pages/ru/components/grid.blade.php b/resources/views/pages/ru/ui/grid.blade.php similarity index 100% rename from resources/views/pages/ru/components/grid.blade.php rename to resources/views/pages/ru/ui/grid.blade.php diff --git a/resources/views/pages/ru/components/icon.blade.php b/resources/views/pages/ru/ui/icon.blade.php similarity index 100% rename from resources/views/pages/ru/components/icon.blade.php rename to resources/views/pages/ru/ui/icon.blade.php diff --git a/resources/views/pages/ru/ui/index.blade.php b/resources/views/pages/ru/ui/index.blade.php new file mode 100644 index 00000000..a18687a3 --- /dev/null +++ b/resources/views/pages/ru/ui/index.blade.php @@ -0,0 +1,19 @@ + + + + Для создания интерфейса админ-панели MoonShine используется множество UI компонентов.
+ Вы можете воспользоваться этими компонентами для построения своих шаблонов, + кастомных полей, фильтров, декораций или страниц.
+ Использование компонентов ускоряет разработку и позволяет сохранить единую стилистику проекта. +
+ + + Если вы планируете использовать компоненты за пределами админ-панели, + то необходимо ваш шаблон добавить директиву с ассетами MoonShine. + + + + @@moonShineAssets + + +
diff --git a/resources/views/pages/ru/components/link.blade.php b/resources/views/pages/ru/ui/link.blade.php similarity index 100% rename from resources/views/pages/ru/components/link.blade.php rename to resources/views/pages/ru/ui/link.blade.php diff --git a/resources/views/pages/ru/components/loader.blade.php b/resources/views/pages/ru/ui/loader.blade.php similarity index 100% rename from resources/views/pages/ru/components/loader.blade.php rename to resources/views/pages/ru/ui/loader.blade.php diff --git a/resources/views/pages/ru/components/modal.blade.php b/resources/views/pages/ru/ui/modal.blade.php similarity index 100% rename from resources/views/pages/ru/components/modal.blade.php rename to resources/views/pages/ru/ui/modal.blade.php diff --git a/resources/views/pages/ru/components/offcanvas.blade.php b/resources/views/pages/ru/ui/offcanvas.blade.php similarity index 100% rename from resources/views/pages/ru/components/offcanvas.blade.php rename to resources/views/pages/ru/ui/offcanvas.blade.php diff --git a/resources/views/pages/ru/components/paginations.blade.php b/resources/views/pages/ru/ui/paginations.blade.php similarity index 100% rename from resources/views/pages/ru/components/paginations.blade.php rename to resources/views/pages/ru/ui/paginations.blade.php diff --git a/resources/views/pages/ru/components/popover.blade.php b/resources/views/pages/ru/ui/popover.blade.php similarity index 96% rename from resources/views/pages/ru/components/popover.blade.php rename to resources/views/pages/ru/ui/popover.blade.php index 2fc247a4..b9edec0f 100644 --- a/resources/views/pages/ru/components/popover.blade.php +++ b/resources/views/pages/ru/ui/popover.blade.php @@ -10,7 +10,7 @@ C помощью компонента moonshine::popover можно создать всплывающее окно. -@include('pages.ru.components.shared.placement') +@include('pages.ru.ui.shared.placement') diff --git a/resources/views/pages/ru/components/progress_bar.blade.php b/resources/views/pages/ru/ui/progress_bar.blade.php similarity index 93% rename from resources/views/pages/ru/components/progress_bar.blade.php rename to resources/views/pages/ru/ui/progress_bar.blade.php index 514a5e60..f631d55e 100644 --- a/resources/views/pages/ru/components/progress_bar.blade.php +++ b/resources/views/pages/ru/ui/progress_bar.blade.php @@ -11,7 +11,7 @@ Компонент moonshine::progress-bar позволяет создавать индикатор прогресса. -@include('pages.ru.components.shared.themes-colors') +@include('pages.ru.ui.shared.themes-colors') @@ -29,7 +29,7 @@ Для создания радиального индикатора прогресса необходимо компоненту передать параметр radial со значением TRUE. -@include('pages.ru.components.shared.sizes') +@include('pages.ru.ui.shared.sizes') diff --git a/resources/views/pages/ru/components/rating.blade.php b/resources/views/pages/ru/ui/rating.blade.php similarity index 100% rename from resources/views/pages/ru/components/rating.blade.php rename to resources/views/pages/ru/ui/rating.blade.php diff --git a/resources/views/pages/ru/components/shared/colors.blade.php b/resources/views/pages/ru/ui/shared/colors.blade.php similarity index 100% rename from resources/views/pages/ru/components/shared/colors.blade.php rename to resources/views/pages/ru/ui/shared/colors.blade.php diff --git a/resources/views/pages/ru/components/shared/placement.blade.php b/resources/views/pages/ru/ui/shared/placement.blade.php similarity index 100% rename from resources/views/pages/ru/components/shared/placement.blade.php rename to resources/views/pages/ru/ui/shared/placement.blade.php diff --git a/resources/views/pages/ru/components/shared/sizes.blade.php b/resources/views/pages/ru/ui/shared/sizes.blade.php similarity index 100% rename from resources/views/pages/ru/components/shared/sizes.blade.php rename to resources/views/pages/ru/ui/shared/sizes.blade.php diff --git a/resources/views/pages/ru/components/shared/themes-colors.blade.php b/resources/views/pages/ru/ui/shared/themes-colors.blade.php similarity index 100% rename from resources/views/pages/ru/components/shared/themes-colors.blade.php rename to resources/views/pages/ru/ui/shared/themes-colors.blade.php diff --git a/resources/views/pages/ru/components/shared/type.blade.php b/resources/views/pages/ru/ui/shared/type.blade.php similarity index 100% rename from resources/views/pages/ru/components/shared/type.blade.php rename to resources/views/pages/ru/ui/shared/type.blade.php diff --git a/resources/views/pages/ru/components/spinner.blade.php b/resources/views/pages/ru/ui/spinner.blade.php similarity index 95% rename from resources/views/pages/ru/components/spinner.blade.php rename to resources/views/pages/ru/ui/spinner.blade.php index 90a2f550..eb2956a4 100644 --- a/resources/views/pages/ru/components/spinner.blade.php +++ b/resources/views/pages/ru/ui/spinner.blade.php @@ -24,7 +24,7 @@ Размер -@include('pages.ru.components.shared.sizes') +@include('pages.ru.ui.shared.sizes') @@ -38,7 +38,7 @@ Цвет -@include('pages.ru.components.shared.themes-colors') +@include('pages.ru.ui.shared.themes-colors') diff --git a/resources/views/pages/ru/components/table.blade.php b/resources/views/pages/ru/ui/table.blade.php similarity index 100% rename from resources/views/pages/ru/components/table.blade.php rename to resources/views/pages/ru/ui/table.blade.php diff --git a/resources/views/pages/ru/ui/tabs.blade.php b/resources/views/pages/ru/ui/tabs.blade.php new file mode 100644 index 00000000..0254b333 --- /dev/null +++ b/resources/views/pages/ru/ui/tabs.blade.php @@ -0,0 +1,40 @@ + + +Основы + + + Для создания вкладок можно воспользоваться компонентом moonshine::tabs. + + + + + + + + @include("examples/components/tabs") + + + + +Активная вкладка + + + Указать активную вкладку по умолчанию, можно задав active. + + + + + + + + @include("examples/components/tabs-active") + + + + + diff --git a/resources/views/pages/ru/components/thumbnail.blade.php b/resources/views/pages/ru/ui/thumbnail.blade.php similarity index 100% rename from resources/views/pages/ru/components/thumbnail.blade.php rename to resources/views/pages/ru/ui/thumbnail.blade.php diff --git a/resources/views/pages/ru/components/title.blade.php b/resources/views/pages/ru/ui/title.blade.php similarity index 100% rename from resources/views/pages/ru/components/title.blade.php rename to resources/views/pages/ru/ui/title.blade.php diff --git a/resources/views/pages/ru/components/toast.blade.php b/resources/views/pages/ru/ui/toast.blade.php similarity index 96% rename from resources/views/pages/ru/components/toast.blade.php rename to resources/views/pages/ru/ui/toast.blade.php index f9b85b0b..a88c419d 100644 --- a/resources/views/pages/ru/components/toast.blade.php +++ b/resources/views/pages/ru/ui/toast.blade.php @@ -12,7 +12,7 @@ -@include('pages.ru.components.shared.type') +@include('pages.ru.ui.shared.type') diff --git a/resources/views/pages/ru/components/tooltip.blade.php b/resources/views/pages/ru/ui/tooltip.blade.php similarity index 96% rename from resources/views/pages/ru/components/tooltip.blade.php rename to resources/views/pages/ru/ui/tooltip.blade.php index 75ec3c5f..7a19b466 100644 --- a/resources/views/pages/ru/components/tooltip.blade.php +++ b/resources/views/pages/ru/ui/tooltip.blade.php @@ -11,7 +11,7 @@ C помощью компонента moonshine::tooltip можно создавать удобные подсказки. -@include('pages.ru.components.shared.placement') +@include('pages.ru.ui.shared.placement') From 20fa013ef34c8272672054c2e619cfbaf89296a6 Mon Sep 17 00:00:00 2001 From: Alexander Nikushkin Date: Sun, 29 Oct 2023 11:41:25 +0500 Subject: [PATCH 2/7] feat(menu): title for pages --- app/Providers/MoonShineServiceProvider.php | 4 ++-- config/menu.php | 18 +++++++++--------- resources/views/pages/ru/menu.blade.php | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/Providers/MoonShineServiceProvider.php b/app/Providers/MoonShineServiceProvider.php index 3783a0a3..bbaa885a 100644 --- a/app/Providers/MoonShineServiceProvider.php +++ b/app/Providers/MoonShineServiceProvider.php @@ -35,7 +35,7 @@ protected function menu(): array foreach ($items as $item) { if (!is_string($item)) { $pages[] = DocSection::make( - $item['label'], + $item['title'] ?? $item['label'], $item['slug'], ); } @@ -63,7 +63,7 @@ protected function menu(): array $inner[] = MenuDivider::make($titleDivider); } else { $page = DocSection::make( - $item['label'], + $item['title'] ?? $item['label'], $item['slug'], )->setResource($resources[$slug]); diff --git a/config/menu.php b/config/menu.php index acc3ec3e..abda8107 100644 --- a/config/menu.php +++ b/config/menu.php @@ -24,18 +24,18 @@ // Decorations 'Decorations:_divider_', - ['slug' => 'components-decorations_tabs', 'label' => 'Tabs'], - ['slug' => 'components-decorations_heading', 'label' => 'Heading'], - ['slug' => 'components-decorations_block', 'label' => 'Block'], - ['slug' => 'components-decorations_layout', 'label' => 'Layout'], - ['slug' => 'components-decorations_collapse', 'label' => 'Collapse'], - ['slug' => 'components-decorations_divider', 'label' => 'Divider'], + ['slug' => 'components-decorations_tabs', 'label' => 'Tabs', 'title' => 'Decoration Tabs'], + ['slug' => 'components-decorations_heading', 'label' => 'Heading', 'title' => 'Decoration Heading'], + ['slug' => 'components-decorations_block', 'label' => 'Block', 'title' => 'Decoration Block'], + ['slug' => 'components-decorations_layout', 'label' => 'Layout', 'title' => 'Decoration Layout'], + ['slug' => 'components-decorations_collapse', 'label' => 'Collapse', 'title' => 'Decoration Collapse'], + ['slug' => 'components-decorations_divider', 'label' => 'Divider', 'title' => 'Decoration Divider'], // Metrics 'Metrics:_divider_', - ['slug' => 'components-metrics_value', 'label' => 'Value'], - ['slug' => 'components-metrics_line_chart', 'label' => 'Line Chart'], - ['slug' => 'components-metrics_donut_chart', 'label' => 'Donut Chart'], + ['slug' => 'components-metrics_value', 'label' => 'Value', 'title' => 'Metric Value'], + ['slug' => 'components-metrics_line_chart', 'label' => 'Line Chart', 'title' => 'Metric Line Chart'], + ['slug' => 'components-metrics_donut_chart', 'label' => 'Donut Chart', 'title' => 'Metric Donut Chart'], ], 'Appearance:photo' => [ diff --git a/resources/views/pages/ru/menu.blade.php b/resources/views/pages/ru/menu.blade.php index 49cdf273..7287a249 100644 --- a/resources/views/pages/ru/menu.blade.php +++ b/resources/views/pages/ru/menu.blade.php @@ -264,7 +264,7 @@ protected function menu(): array Иконка - У пункта меню и у группы можно задать иконку. Это можно реализовать несколькоми методами. + У пункта меню и у группы можно задать иконку. Это можно реализовать несколькими методами. From 126cfef0d882ef391844298b8058a503ceb291f1 Mon Sep 17 00:00:00 2001 From: Alexander Nikushkin Date: Sun, 29 Oct 2023 13:27:59 +0500 Subject: [PATCH 3/7] docs(components): ValueMetric --- config/menu.php | 18 +-- public/screenshots/metrics_value.png | Bin 8196 -> 0 bytes public/screenshots/metrics_value_dark.png | Bin 6827 -> 0 bytes public/screenshots/metrics_value_format.png | Bin 10228 -> 0 bytes .../screenshots/metrics_value_format_dark.png | Bin 9022 -> 0 bytes public/screenshots/metrics_value_progress.png | Bin 9223 -> 0 bytes .../metrics_value_progress_dark.png | Bin 7861 -> 0 bytes public/screenshots/value_metric.png | Bin 0 -> 5470 bytes .../screenshots/value_metric_column_span.png | Bin 0 -> 8675 bytes .../value_metric_column_span_dark.png | Bin 0 -> 6733 bytes public/screenshots/value_metric_dark.png | Bin 0 -> 3032 bytes public/screenshots/value_metric_format.png | Bin 0 -> 6375 bytes .../screenshots/value_metric_format_dark.png | Bin 0 -> 4892 bytes public/screenshots/value_metric_icon.png | Bin 0 -> 5332 bytes public/screenshots/value_metric_icon_dark.png | Bin 0 -> 3858 bytes public/screenshots/value_metric_progress.png | Bin 0 -> 5735 bytes .../value_metric_progress_dark.png | Bin 0 -> 4228 bytes .../ru/components/metric_value.blade.php | 129 ++++++++++++++++++ .../ru/components/metrics_value.blade.php | 113 --------------- .../shared/metric_column_span.blade.php | 42 ++++++ .../components/shared/metric_icon.blade.php | 29 ++++ 21 files changed, 209 insertions(+), 122 deletions(-) delete mode 100644 public/screenshots/metrics_value.png delete mode 100644 public/screenshots/metrics_value_dark.png delete mode 100644 public/screenshots/metrics_value_format.png delete mode 100644 public/screenshots/metrics_value_format_dark.png delete mode 100644 public/screenshots/metrics_value_progress.png delete mode 100644 public/screenshots/metrics_value_progress_dark.png create mode 100644 public/screenshots/value_metric.png create mode 100644 public/screenshots/value_metric_column_span.png create mode 100644 public/screenshots/value_metric_column_span_dark.png create mode 100644 public/screenshots/value_metric_dark.png create mode 100644 public/screenshots/value_metric_format.png create mode 100644 public/screenshots/value_metric_format_dark.png create mode 100644 public/screenshots/value_metric_icon.png create mode 100644 public/screenshots/value_metric_icon_dark.png create mode 100644 public/screenshots/value_metric_progress.png create mode 100644 public/screenshots/value_metric_progress_dark.png create mode 100644 resources/views/pages/ru/components/metric_value.blade.php delete mode 100644 resources/views/pages/ru/components/metrics_value.blade.php create mode 100644 resources/views/pages/ru/components/shared/metric_column_span.blade.php create mode 100644 resources/views/pages/ru/components/shared/metric_icon.blade.php diff --git a/config/menu.php b/config/menu.php index abda8107..934c2a4c 100644 --- a/config/menu.php +++ b/config/menu.php @@ -24,18 +24,18 @@ // Decorations 'Decorations:_divider_', - ['slug' => 'components-decorations_tabs', 'label' => 'Tabs', 'title' => 'Decoration Tabs'], - ['slug' => 'components-decorations_heading', 'label' => 'Heading', 'title' => 'Decoration Heading'], - ['slug' => 'components-decorations_block', 'label' => 'Block', 'title' => 'Decoration Block'], - ['slug' => 'components-decorations_layout', 'label' => 'Layout', 'title' => 'Decoration Layout'], - ['slug' => 'components-decorations_collapse', 'label' => 'Collapse', 'title' => 'Decoration Collapse'], - ['slug' => 'components-decorations_divider', 'label' => 'Divider', 'title' => 'Decoration Divider'], + ['slug' => 'components-decoration_tabs', 'label' => 'Tabs', 'title' => 'Decoration Tabs'], + ['slug' => 'components-decoration_heading', 'label' => 'Heading', 'title' => 'Decoration Heading'], + ['slug' => 'components-decoration_block', 'label' => 'Block', 'title' => 'Decoration Block'], + ['slug' => 'components-decoration_layout', 'label' => 'Layout', 'title' => 'Decoration Layout'], + ['slug' => 'components-decoration_collapse', 'label' => 'Collapse', 'title' => 'Decoration Collapse'], + ['slug' => 'components-decoration_divider', 'label' => 'Divider', 'title' => 'Decoration Divider'], // Metrics 'Metrics:_divider_', - ['slug' => 'components-metrics_value', 'label' => 'Value', 'title' => 'Metric Value'], - ['slug' => 'components-metrics_line_chart', 'label' => 'Line Chart', 'title' => 'Metric Line Chart'], - ['slug' => 'components-metrics_donut_chart', 'label' => 'Donut Chart', 'title' => 'Metric Donut Chart'], + ['slug' => 'components-metric_value', 'label' => 'Value', 'title' => 'Metric Value'], + ['slug' => 'components-metric_line_chart', 'label' => 'Line Chart', 'title' => 'Metric Line Chart'], + ['slug' => 'components-metric_donut_chart', 'label' => 'Donut Chart', 'title' => 'Metric Donut Chart'], ], 'Appearance:photo' => [ diff --git a/public/screenshots/metrics_value.png b/public/screenshots/metrics_value.png deleted file mode 100644 index 40107668decf3013f3f212485e0e6568f81b7469..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 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 b&q|m)ozmi8)2|i%pWejK!r=CgKb`n5#ILbg diff --git a/public/screenshots/metrics_value_dark.png b/public/screenshots/metrics_value_dark.png deleted file mode 100644 index cea10e7c2b786927a8bc6a7dd2ddf9a109e863cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6827 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 diff --git a/public/screenshots/metrics_value_progress.png b/public/screenshots/metrics_value_progress.png deleted file mode 100644 index 11a5c19ec4e394f4cef332d2e9c57e9ceafe2eda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9223 zcmd6N2UL?;w|3OQGJ<|HB7#a0EGUMABoK&{837d;dXp9mDf9%BP!gIWf+MJig-ElY zNGAf)2~ikCnn)L<_hRS)LjB(W{f7ieMtVMX=bN1PLpM9SF?9Ex+G}J#Y z^zFfKK_HNj&IK)F5NN9g@ce1#R^U7IU;8P*uU+mJEP>y<_wj$WfTChVfd>;O(@WG# zdOxACBsX~sj%1IQ_jYp!q(LB64R3c0)&)=r4;3rz*q$YObV$Yub>1~fgw&y!JrCA2owoXfPb<2Wn??}~TB6R8wHR^h8G5G6gmui}5I*3Ip!G=-||33#-*w?CDpn9|(w z5Mw-rU(zX-zD>3<6a)rs&I2Kh7p zCW`lV`U_G1%vVu&lqMOEp_0g^B$DfI*fIRgHz`d`K30^aWG$SCIFc9TB!BOlYw%ha zDqc+*2897Af`ef&Qw0^2A`%5tl!GdwpwJCbJpi3J3>EWVgb{pUgbE6Z{5N3|&WS+# zTTvVqMIe#gFu>V4xnUge5O<=(x-~sLln#+X#SpQ09W6C!z*TuCCmc!%iNo1rRIp&2 z5>5$>Kp=2nd$=+jj8j13u}X><6&x1%+j=b$)`O2L{`!p+!;!Fnj;{xT!YN?!1OyHW z#=sS^fFc9|Y_EVpfZ-S%R0#%$VKGRh-?SN!oq#OIxc*Tq-zyxT5eZea$K$a$FhUuF z1S=vCaIn1+Oc|^Ihr^LrI1Z_VQI?ka-L59dl|jsnyJu44EprY5bh zIe3YWR#%UWK_m{(^@6CD3znTAi+KlJ~gcv3*#fJ=P-M$IHUVsBiii&W>&2d8~ zZ@lXzEhivqlnqA^2*B3*n)Nx$Kg_8BZt(expQoq`P80xnv`xk_!C%>Ya&?kgPfZjC zyRi!_AES7j^yaYBpPcbOi{^$}FGoBOum1qt4KWIdK=s0q@jp5MLH;MX0r@NcDHzZH z?7f0L2BDyWfq}6|tP)sJ1z`_XCSa9;S7ihM1UODv1qkV1cn^c2pa>M~YbN~ z;QtTzgC!9?@#H@s%pF6<0Cg2lrl?61$Rsx@jJvz56Lvk*Af80rX1V&BoKjSh)bCXE zmvO`4$xeSj!XK@CbwTQX(ca(U4v$fS60lG#7zW3vfT4H<6s)YM1n{{s9-)F%u!j>A z0S@~A=A8a^KmUyB|9U_FR+0W!^9aIkfi@@(@?Y6+<6Ub59Ow9OTW>8;f5vnFG_!zS z0|ivBzo}(NB|H=ZQ@{X42c`hVsQ{HxS6sZ7|l?`u5|F^Y_pBC$3 z_(Ny-+Yr!h@*ltUxxmZUP8m-G*oX}D!J>_M@gR_>m5$brrrvFwjvd~@9*b|LBHcy= z?jEEM*K2=c+P!z@sb98+BnW4C{d(VIHbct$)FzY~wBOuP5u6>HNJF!?g5Ef3$D=`@Q2`K$yA^bm zz6F$c00e5>y*~65m@$Na_(S}eA6Os|f9Maw{Gm-@{`yT}{?HGs%D}fWLLdiCQ~fTw zPNHDxUG^!Bb0Fo=NJ^;lt||J6@##``Wm87Ofcs?NwyRmO>2m%x%xIdS_<&W$bP@yO z7dBnjM^=dyv;|$oB5EcVR|to2#k*qZtul;s(eE%4B?2H>&-WEI^C;o$qTpAV%~kr0 zE~s=n%p)WJUm*9mT|d=wdA82HZ&FjaFe=68B~`AP)9bJeB>Q7=Ekx)(H3^SCZ1j?@ zlYjI{RQmP8SV1)Cs&P3}^~v#ks9>2<&ed2ti>hgapN3Ium|Ev)rwBSnLEY6D(R1cG zEhENV&USEGM$j#giVG{=Blu-Acd<%MNDrTv&C!uPd;#tI%iI$ViRc)@07g&gniFubM`{%rH5a{B=sBnC-!lxdx@M-nbe)>po zvZ%kyLOmit6^L)l_1CvfCo~*0Vf5<`J~io__o(D%deV6Vc6tQn=#;|p1rR766%}zZ zi&5G>KOkF`&NN{%;!YJc#bH?~yAcZ)8=D9(&Hv2Tni1 z6yj6k`>;_LiJ-hKLO(y4q6GMG=3dkY*~&$!+S>@g4>xWDHE&vtm_m^ix+eFV@vfgE z8RSn4O!}46w^fCQ^050#$2@Mj)g@S!&nf89;(%4jFX&){j)mr8ffRVogDKB~@|;>KS^XxRrJ-8zKet=d$J!lwZ-$Y(%Yd5 zZDLcn`*nUU)DX|$gvCttPWEg(i_%|x@+NXVz4I+;c=w((+EHGtF}r<;^SImZGCx(U zm`*-}%QN#d?GF!5*SIcScvO1-`9RPa)s_1akE6VGYn?e=ZSzglfmJ6E1#|TWhuB44 z={7Sj>DwNER+Fn2Q%di7g`5K~Twd!A5|-oyBDyZgH12kOC4HpKMVP zEtGJyv;O39qfrkubw<`<8L$N*S?(G|VZ=az%T5hWi>p`;7+Q+kM+teZ+L@v)s?zVIFKQENai;msv z({SK08lFd(9}0+OA;2SA$V*lGato@eRDb3NGYMT|5q7diG`OsJ>}_!Ajpl;kcr^+^ z!shs~vHcG6GO6QtSSO#YeO?lISTv26Nau8P_3iowI4a{Y{y{Gt60-KBu53HgxihBq zL~-B3Ig5azwa>;~h;uAJz1duZ<{4W#6QpX?vVTN`%ac}_9PagZ0X%s(O6dE=j$W&g zkc`tFE1%q$B0hnxD&GLOprt73KS&n|-&Lzv=%G8;*+t$f$ZVjHr^~OTU&wEpRhw}T zw?hAP+A@0!;KnucYDqh$JyJBJ#rjT7{q(yDZ;H*zk-5cE)MMuW7vCBeHsle_y>$xt zK7gyX=(y2J+{N{HT=Xe?|?^w7>E-4Iq{OvjX2`_Hjnw{fbD}>my4{$ zK#3Ob#ZM;N`6k$O%=^82X%E3?9RbMoPW^6xKgZ%H4;cg7jJ?A(Uf?_c4n)74j$fdR zFLDP$c0PJB)?|*w+J>u=_>rctTnCDGg$o4(VyBAGA=$t5rTOiyRKH&F-ovHjhX^Nr zBHg05D&dYp^z^J48Ey{fN{rpPUFBy5@80M=?B#0j&63XmFPe_MUn<}S*OO2Aq3eZW zlkqpwTYIAv{J>hT7VByMTS57~GF+wqkq@4t*9*mFc}YC5E(fsWdXZVzw_#_!#%wAE z5^*^yhgQ`*AZKyHZJ}&v9!dQ4)Vf8VCI3Z4T-^z16(Ilz=(bKi{i$ zPHXZspD}*s-ix-Ht;wt~Si3dvWS-ChS}{*>b19V_tpoQ$*V5f!Xe#SI*laQ*EQo<#S!^DkUZTU_;L>DOp*R z??;<><&7r_spE!Uz^TjrHR62|5h=DB%gN;@+9f3<-kE#@U_zi-w_(RGSFDY0^J?Tjqv_>gwZeT{lb1R)gi0pxQydV?jP{ZE()#oIxHR zx+M;f{A@FqX1{F55zPSB8Tp)HJ#kg)0(0MSzg)UoZhGvRf`>83YDhT0q&Hsfof^Vu zJJXs}v`U)qxZ>Lh97W3Vm|12~(Xvi$@$6J;ewwvXz(8375KduVC;GWT83WbA%XRk% zdWQ@GdXmh+(Nq0E%dmfx8?`jh(kBrkdt$tp6TCFR;%HT&`09+uJi5DkmLz0!n^ua`9L754FEc>3yBFk9m-K(%=Aq#D^Bl((`vJ8?(JfzExS7 zT<{_0_bk4l?pM99w%GkCnv|z6Apk(OF(qWoW7cuh#Ki6~Jm6W3g!0pg1_S+_=%3b> ziZy^JUg8=`B^b)CcwR@Tl;9bH)U;=njRBT=RDefJ|y*C*OE^qt4~t5?N$Dgzz}Qp z%deUQ6?{0ALg$-$q)FW1I=W4{DIEpH2_-UDzJ%@akZv!3M`X0Nf zw!S?A_a(%;UKj;Rx9lpS@%l+QpK?{U0RdBKlskc(j~ue&O?GAJURd{N|5+}of_ih= zcVZUVsn@okyDQgo*0F66Y(4NRfC+P^gyeyJGuhcb7CBNeX^p7{jvcP_^RZJV{OZ0LR;~u8d~uAGdxtec;1B(G zPS_+HL&!RJtaHkL#@W%vbCMAa9?s?ybp!1SdBY#q zbo%=T!7J)XwL#)CG9@(h);E@>kW#~9>%ys-Ai2*u&h-T}nSA)?d-JPBSC;U8^21(J zv}CKEu)zopyX@Tgx%xsOd#j;*AuUiGud6G+e z#r-%dylqRKV{J)h+8R-$4-1*PH$-ATX9I)?u>3_jVQ$t-L(-F0YhH6uB;T=o+z&n! z;8XkP2r-v3GOxob^!ijhHZR0J>Qc}N%XrHZx2Crfm!i;5CfGXGx#R6)ROPl@r?zK$ zaGFj3GCt+r!6s&GMEJ2M1MaATCoRV_jLuF%y@oHe#o^aFUVF@|G+|T9%RPxLMSb}- zIFa^f@@3xML%!+(EY#5KXtRHff%QRTYD1pCIQylJOF&1)37B-ML+%{c`N=*T2=7-( zq$|(~b`HhqpErTCZMhVEqJKDPKPa&!(vYdg9$%!lwiT8O-rPAaoPVKrs&Z-OsMWpO z7F|yci0?n*Fqi-8zOT)6he7?TGv|aNLM|LZ(@5#%oKYVmho!hrj}nb6?0U&4d?Lzy zArW!zB4zl(;9-oL(ON;q!7C0lXO^&-&|9r+R~o)PB$Bnash|^Jk}OIIToU?WYkUHJd`_L z;MXt3Y(cJcGYbnyX=Bq)>b?N`88>7F&zy{PfCYaP>a40v;n$5`x4-8?MPMhR< z-VQCy@gXdh!+yP0{F05(`M?kx4m4Pkc`NG4D>HuZCB~*AP>ocfJ#7g)%N-`C$4v58 za>EKrR#Um`FE-i488?~j`*-O~Mrevntg3m9#6I8AlKP#b=oUMFpAV0Ewpk%br=Jz{ z-W$Jpd-P;8?Ed>-CT~@{s?5A(+vM2SyzBDsBJD66Z)|&!b`KFb)4vq{DC6Ze(1+J_ z0rYTanniTP?aw)msvNs4QXb)l`@tUD4shCL%8RtSx}d&qma;^+<8?-ZS#Pv;qP@N> zg9ir3c}EL=C4Yjb+o5a?HiQ z^R?fnH;=!EMkWfouo*x3PhF`aGIVs|}0WVuznWcg5k3A>$iJ?I3#Psv96 znC$UK3`L(gZzp!(kXe7+?5!^&6Mp_HW_~GUWkst!zLB-b<>lMuAD%5jy3{3N7)9`z zvA`Q9wgD0e0K%2*FLX&)Dd=aSr;WC!+A}YUR*tg*PFu75`Y8SKFXuv`oA{rhS$h1XB2uc^9h>8?&{RIpwJyD&um+ zUY|MfyN-DLfW9B+zRQj^yBkV3f0j#K!w*e2jgby140l-C%@31_liFp3k)vbT&K-pO zf$p@>@9T!pYq(+jfgO;Gvo39ga5k~+RVR%T#a8GG4KJ0CR9X8>xV`V%Hp1r&pRQC$ zM2An`-ABV09_R5BCd}{yedhFvz zcvP-NShyOzD|_HuHPiaM;A;qqdXy8`x+X^FmFXR9RI8x- zEwtM6+R+_ta)X6oGx6urqLHIrS)r8kR6gR=DSJcqZuO`v z+}H<}u?;Wy{2q>%f4TYk@vDA#)_$4bc_-$Vn<0Xot0LY8W;U)=^EN(_yf?JbXxj-EnOI5xIDbE6$ppBNc>+V*7{lC7h zchW#p^Vf~>`X$SMuX>T(dTPxV2KwvY?UBav38w@ore-W*+lGG0$l_k?bA8?!5Gdx@ z3vnm0R{07BwQ9uFEZ%uE{!s&Ce1`X2y0k=9!XFB{`hC9-t5t3I_I#nzuruh9avrdUEh_NeOp1oJ>13mdU$Nf z0J$JWKPh4qDxAcy%IDu`RM^!(jx_iYiV$KYy}fbLC8Y~0TR>aMGt&(XSvBERBZzrg zMfbqHa9y)TlRGU*&AJMG@zz4{WpZUTgSfwX(mUq6o*s#?{-%mrLC^=Q@3%8so%Ibj`9SJl4zt@swCy_X74`%Ly1tVZuF-t!zPG|&|JGdfNVpL7}mC*R%L@@T>NF}7J+geU!tK09?Q;&N33}i+N#=uq_h@%{o^N(wfX1E58{^> z81$xP?COx=VP{MxZkCMVyseTgC6vONQrwq~(`>|G-a0yItjh&{cRco{E;(KL`Ba{6 zdDjqjzWG(U*xNR3&`z;@8rnrzB_i>AbOq;tuh~iOR>n`30k}!>g~ime;N)y{scfHu ze5ENQ-hHGfJ-YBMqO9HDaSxh&hbFwog^ZZJwv;3y`Q^>Z!)Wp)x3F6~heo!7j!2(C z8lbBO;@hVZFiCj~swP-Aa<<~)RhqKw$tRi$xnfrEM~IZuy9cV6=;k@iGQmd}&#G7D z@>v-3rd0HyU~-&Zd@!rxWARJc@JU|R@O!AX8SNeDhbH)~)EHl0c@Nc!ByY|!6FSC9 zwuUUtDb^4ppWr0JTdX8W4?LnVyhh!VHfkidv#&j`wVq*BkBT64gxbj7?JI)S?!jvA zi_5Ez65a1a?F2php@m!hMK!ky&(@Nx`f$^(i4%(z;2Q7t^s_wlotcZGmdcA1-_iYf zH=HjY%!;skWD_~b?O)>9oQM_mx#Fvxc$dCnkot3ttWC5mJSh^w zep#*+l(q6NP;yAiP;K=Gc);FF57V=ho?vIrZu0eCGYgWL4C7ZLA8kgTeRdJyUJG11 zcP{As^{Gw>DA6^a*BSGr=vwIr>I>2>DS%#kfO~4^rJjsk z<5(Kb&0>E!Z=*pucAcWH8qqZ^*Qlc#FL;C*-Pu z2vfm7tO~L2xe^e__IXSPxmPj^-ZJCorl=ebkvX5xz+5pAo5N?V-<*v{zwKjSBs?os zpH;kxkCsepn*X`9`Ox8;+d!35Wyrh7UDTfSyxx;){i^b#k#}Cl#}EtIrWD6Ff@AYc z(GdB)FJB%CD6Z6zFW&)rV6!E@TeL7JAa-zyT0=S9%9`EKIz95^+sfP5 zoW?#)I0#k`>jODs_&j! z;7lG-_aj4t#^(=Za#8YD*LQu05Op diff --git a/public/screenshots/metrics_value_progress_dark.png b/public/screenshots/metrics_value_progress_dark.png deleted file mode 100644 index 9f9d57762d39ecc7ad3949bca8d14e2337fe286c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7861 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 literal 0 HcmV?d00001 diff --git a/public/screenshots/value_metric_column_span_dark.png b/public/screenshots/value_metric_column_span_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..5f868c02bbdc969a76e2d5d0b61120a7ad849a9c GIT binary patch literal 6733 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 cR^(9haBA3D_%e&|q58%E7sQ>@~ literal 0 HcmV?d00001 diff --git a/public/screenshots/value_metric_dark.png b/public/screenshots/value_metric_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..42385b2cc81cfb005c48c20438017b6dabcd8e79 GIT binary patch literal 3032 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 literal 0 HcmV?d00001 diff --git a/public/screenshots/value_metric_icon.png b/public/screenshots/value_metric_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b640d8e7c40feb77d62aa051b4a8078e4802b9e5 GIT binary patch literal 5332 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 TL(&-ROal7%jJ3-(9sc+iIZtb( literal 0 HcmV?d00001 diff --git a/public/screenshots/value_metric_icon_dark.png b/public/screenshots/value_metric_icon_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..fab07169a91c3472993074e93b3511c95e923d27 GIT binary patch literal 3858 zcmcInc{r5o`+tU%l9WQ$X`zlS60(ymGWKQ0He@+sEa5PW5tUAdlHFKB%D#<#9~_Dp zWQk!Ag~Bk7WyX@_JAKd9b^ZQ0*YBU-`MuZmzR!EV&;7pd=lqq; z>1*Gz2zt3PwTQNu7i{xAOd`L5>CI@!2q%PUF}Xl14LK|0la?V&nz4NmuUMn1qbiRF z+#0-u5Y?%;=W(W_e!`=;WkIntKTJC;^=d-{jQdKrFgo+_1ORrkkpS$QNP+MN z|3|eO>NJ~*ey)VssBUH;fl=gSVPDdz1K{jjL;%5VFoz9Dr!JTrl}MyHjk16gtM^RY zjhIpdWzz@(B9tR_f<}m387tdAq^5;s=^|2xY3fV)BjCuz+wo_tXnxoj0Aw|OKt7Jc zbg!=6xA=Xwi5a|N(eIpO)@3|ri~3>IStD9h4ibdF(v$gN(2cvMQUT;x#>}HRJjw2V zDE^c6&vKCgLeq}e6%DLcMt<*F#wn0;d4rNPbFDdZlHR(hMy#2u4MJznHVFY~)K?NE zW3EpLo{_Lx%op)xw)sMd%}y@mmMsXVat(BEp|z$62h)4aV11#)x5)}> zM?rY1OgYk*+TK(+MaR3tR*mk!U0`Limmz>P^C8U)it5ut*){x>mCiY!To+pxCt3_v zQd7jOf042_=IA6Tsd0kv8D0e5JTlrU8L8*-hc6GT1SgS*E6JC-BB$_knqdeX(;Xj{ z?^Tm;klCXdLilvY!xt+Iz@InDksYFfR>@^o>$>C9MOWyUeZ^dR?oWC`4%>I{JpBov zGHifmfN?k|a&qwOo;D8|iT5!Nx#MKe?E9{D3_~~ci1}O7oo2(A;C86=`>rN7YJ#6P zA-%3h0c{yqa=}>LaHSHzk+tddBIXFV5R^9}J{|^*2I~1bDT} zqvrKKQsCa(Y7EzRA5R6gN&0CZ>tsV9f9Y|9xXkkz^BxMb{P$k~JcIl{t*w8G)&F%tpGV;PY@aHjRTK%E%e#xy!q=wUN|(ET zL1SM65Xd01JtK@lg!+W-Z)`42Y#AM@eQ4dRwb@waCka4>fd&{}nm3Yc@@b^n;tf|q zMm%n=VsVwVoolz4z!B+E-_Z}O!7$OLR zYo8$i)>Dm<3xJyJ@G1p9$eSR4;FS-gqOqO;m|rhN683LfJ_v+j@8(U|d^ES$%0h$cDt+^3XODpL8>PrD<5syoSL6r6X5dmIInp*mAMU^m4n=nUH8h6bcA*L0XWF_xg%!)n` z$Elf6e)9}#UxP4%dTvXC_FbL2rGcca)dCS!<(L8yV}Y>XqEZ{oQEJmE;CNB840D_| z)o$Ffs~^hs;IBoTMQUT9K&D5+@)!AupC0`>v%uLWNkLlXq&V+Zti1P zWBH+MuYmM`GIyZEOvF8>(UX`( zhIe%jMaF0oin%NFn=orze`+6Pw3w)Z{2Ocu($tp)ckmmrv1PmGJNiXNbI?rTaF;P5 zc!w}Cx?bgDSM^l#+SJxTmqRhmJ9KB3;ptN<0beV!d5m8+?F~*JWG5feoTtRx>@*7JW8{yICgHIQ-M?^*_1KO(+n{Fhu**vMBX2Hl4?lex~?9EL&H1u0% z{==<_{e_LMnUL=#L~k9N1O3a^)CQ{z+h)+5(gZ5}fcF!?Gok$boN7s7sib~1GX@@+(t5XU`k77JZ*a@D&jSn znmxb9KUdM)JL%r?dN-p`k$wGR2J&J<(TdUn>QfbY!UGR?@%(dl$S8o*jN4{Iaa_8p zT%@?5G$-33v#h5eQOOD|IBBxAkfSaLPWyfRXdq_xsnMqhZjdfyfH0Tj$hp6+@aC0b z&ulcYpoA&_Bf2BLuH6Y*FRs`M# zqT}gvf&)o zh+%mZ4AR>?7z`94Da6K{CuZ8j%Q{~C6HxRHB?;azLKd#`E5--Mz?zeHKERj&ceo-g zDoVVBqL|ZjPNPv~y#cNnM|6;qdlUb}GUG7>)stv2BA(w2w?QDL+;H%kzIi-}LF9L< zHB^zmcKvDZSjG)@_uU;fTAs>h=UxfpEd z+81(VU-T>`S5HvH(bVn|JJ|S8fYI5-Z^iE+ruS`A?JlW``%Jmnue##l9!6ThL?q4r zWL)M1Vmwe|#9%b8%UZ{42|FVbQI;#!g!qDM zoHg#`B_Hc02#uFpKZq*1JhV66ehl>99A0vbQygA@)v8-@sbUPNpsYWYlaoBj)>@jq?fpUv^GFoK`J^kooUj+@29^EzmJ>ATJ_hSWi<5||bR;nG(tSo1MDt}5qJTU_QbU0ZD6f~Wo!VQ&A!0r9sq%sqE<{JnlC z6S#8mVJs}dmY{1S)U&!t$t~<_dpEb)v%{I5%J15TXwHwb8t5J-0Om4!UM?5X&3PLb}4hF*lP%#iLazSUyRdBD%|Mbvr zPwJ6p`2u~qA6*|+#5JA%@n*X08?9Y}BC8il(*ZBa$NhXz9YHsZP`-Jo_B5DLK~u*H zTlLeMzl#g3r7uk$ycoU}`Lz)XFd^4WfA8@AXamLmB5IS!%p2uX+89~)eRKy25w zAv1v(ov{&A;)xXTv_&4E06Xs79!^ozKGI`NR!Z|SAm3H6s1Z>Kx#yqf}skLK!}3$ z-fOTxgd_x{cbMxp>sxE)@2r{mac`1!&pmne-p?-2i8IvKU}m_=00029mZrK908m50 z?_KAp!Fz&i=Q#L5Nh`?3OGV1#D>2D~OQHJ6TGGSg8;5f&yW^-?Rqc|x z*x1<8y`mf>6+gc{aYRC0T}}%V6&ow0g}!ic7(!&{=g)!Q)zsC~i(#>`E@^Paix>6M zy!iOvY5h+ZPwU`)E!EYxa1Z=-24?jg^Nf|MUd6_u-*D3#D!%vcE1#Cg7rT|-Pw=Gx zz|&p<#grS%&&JKrV_Sy#nYsN&;sEfOLF>ht)+TB*Ui`?Yc(4A_jN9=H0Nl0Wf1aXi z?D)&X72WKfMJ$$(MR}lX*a6_Z4TSX)qt=5cV)=X6!NyyN9Kp%$I1+pXD^N33SE((@ zVLB!Oa|*2_v3t8y0bdZQ=9)4d@&xV4w=kLEbZ-wuuesXUnLu|&0H}QNO)ZV@XSG;h zQAL^;vD;LX9qo1u#{3zlrVNBDL$|SK#q=a!qEl~5U(Rmw00G8ZHpM~nHiXv^*K6X0 z-jY#6q~0XHe9~=!I}ZT1v}sKAF(lJQM#kRN%$e@CTCCUoOZDO00Puwg!dVX6Kf6w_ z6cxw8>_>d<>BYF>{@b1y0ql%Kua>YUF_Sy~o7=I{zkz6Nvztlz_s*_cA;ePQ@1$RO zQ2}@3{z8m%Xn{G3_ur_4=@-I$vb}xsF93k{U!#WbqTX6|f_Psd=(V{E_wk~BBB74> z+C0rZhNwpUa{wU7*PZfIQ)L-^&H>;-ey6{Mfi_$UCr?Dt1`rnarko>>dEJPII_lr7 zjXLsnk@S^sI6UwC`X+v5bH+>UcqY|@E#h%T6-KbVe1A}q|J_){&e!*01yN_GFmYtxdC z4Jcj&mfspY=yEW4M^#TZs*! z$no90qaMnxEoG3GIZXtFa+?4`=}>7?eZEe6RLSS(64C-QDza<{>++^PP-VoYg`^G7 z6?*EES*H6p(>LiJ400Q=1j`w2rfbxNo@U$j3p|VwTG>L)OJp`LFpFID&EJVWUj2$n z%J-OU>=V6XyqtM^%LZnquc;d*a);3Vr`=n&jmI0cpIzkBvuwPnIabu5gLXR|jiYU} zHI#F#m(L&Ux-6ROI=lXG7eCT+dN{;VCc6gZUOBbZ!O^)zY`A2?UwI)|Ch2S7ba%K? zTs-sghfWpO_YGmN!@gS^yziFBPywgd?Oz`fxaz`#`Db#NZ!MW7Ec6>UQ#I;Op)7?R ztZ3(-@!q+ThRk-Ydbu5;-SIJSwj+B#fi1xOk1E{&Qgbj^R^}+qw9_p;f=4e*#G~D} zxi_k$7n9)SXhlo@u}-^kYN*4XryOtxdPrF=Rw)d-me*i;IF_}^DYiN>K$y@Fun)sN z&Vsv-J^D&N7_}0ZyY=yR1f$&jiLU`-fC{ATnfT08&|szwS$k) z;N|=V!DkQc(yf3^o1sJYphB_ctou+QeD9hx74Qtkg*giVLjRz_9ESYOl{aVpORm7d zDxw<+rsFfMAqfDuN&o-1_@w~`LF#KXald6fDNnv-v-`n+Wu}OwIP95P$jPl##w>AM&=L&*Wc=9lvck;4I|suBMKF||rrq#HT#NuqXqdVN zxxnT`N0cyMya{@cVciccliinYpjzfG7e10uz;c3LJ2m5Nv>(Uh`p5u)A=}X$s)n_U zd|4~KcG`nQBfQ2Lsj`9OIrbdXpa$-Gu6v?)LbDBqzaJlcE&ctQC#jF%iwoLdIrx#7 zi#9pd1%S8ldv!30=M&0nVdiBn1QIipw>gM>K5X%c!BLsq$EOi~I=08962B&6l1+EF z!1W$S)2I)!OIK9twzDD*H=PfgF^I!TujD?bI+l}zfP*gXrk%^G#-9WCf^l}^P;geb zaV^4MjK|<;<-{i7U}*hE!2BA<@agzW;=!;mGQ1LnLhbQ^EHR7$k*GcL+x&V@!wfZR zJVkwvODPa_LNiF6)uh<-JaUlb` zQuLRWq!idYSZjhJBcmDPHZ;@oJL3D3gMp$>1OHlhR3~25y^W8tWjx>K5VL{_P_x0QlkLR{t3QKL{mSVx1(x1_AM%*#^|N}tof1MzuaeCzlW}!o|`+XODTqouIa>v|hS9;lC zfz$~k({Xk|XkaK=drDs+6!y!nR+0uZWnBwhY!ZR!RArZ3#s{snRW&P`I~iADp~clM zhIzQsYW*_{^HIIz^;41$PKg<<_{ME|;_lOGQPAsT6_Ez&_)} z5K2d-wvZg>9$-{1#|c_<-4;pxMA&)bs^ckKABtb1c`z8}IrV9p*E6;wydk~a z=}?x1sQDJRM6@3aUemXFgIgJ$jMgVB`|j*O!Q^1qdp@Mh%8r$B(EgrUx7blBmE4s- z?csksfu-r}3qdR!yE?nyzyywGzRH3v7MkB_gl{)Y#u#L6Dh>zgt7;X(Ht4R1e{T+} zI*_DGR_I|e8dz$}fQ@jL(*ke*fK!5{2ak-`*LogqsHbZiacu^xpqqmxjZzLF4}XO5fa^&XU@HL3d0h(c2W}EcXiWj6Zu4n;<35QkGZm z__tWAy=%(ob}AdNk;q8PwimbS-p$xd9q5kho;KaMLjqE7naKxM@l~un z;v{?=FT2!eiam7qw>chlF`b=!P3>oEXoSX?sV@x7TYTF^L@3xkU(;e1A{Zbei(2E}$C@NFLXH-Q?Buk1iymqbYG0dOGh50^Xa!+Go_R0DN0(oUM zwR^I9ozY3$LX0YXwgd|{niKHveT`NbkA>Ck<0@GMB@RoTr*G9OyWT5%(wZ8Gd+4{= zk>bNB)NiF2KrFQvlmN|!@5qf5tk-1*96xBsTQvB0t{!(PabIWs+$vY`LGXqw4n3bQ zf*2FqCd>)-?K`ZOOSEr_25A=f%|y!kE~1^K=9hb^fgd_YLlSoV&P`=fmZRJDGtG`j zNh_@0_e_P*?d`Z<8oNBV3#C{F9%Fn69ailuYz5^BUSUCh)XOT8e!3j(qdUo7Yz2zB zy@@%s#W$~f%6}bN^$X7C#pQlm*=-~3k~J*=oGyT=DD&9$neO8p8oMw9_Zy;|97+{(SN{b@mpOe@6P7B1fMHt!7ye8cF=Ntq12k7c1hjG(J>9qwtBV|Rg zAg6p#;ruZ`Ge9Ji3#u{mHZCvvzS!frhgKzG4Fbg$D%5)Pu0*JRcz(MFsqz`PVr1O=1k}K7XkGFGjKV2y~jhoL3D0-_8Fet5QP8ieaw%9n#~d zK!x0jZ5=AGOecXd@?vj*7`_4zDn3Dq@tvP91!`XBR&H1P`!V0olu%9e6>Dqe4rSsh}>cv@28N=Q_-RNYY zv9#9A3C%}-T@8=w!+pT1rX@vA^E!l;#BbNS!~V4lyKh>$i!m{0@SgslK0>eY>uYt6 zZ+G_DwugVzRmg=j z`nV{_y;i%dkksl{FQQJATMwJgRH}1HRDaaU@aZ_U8k%9a zTpw-3t;|khi*_rCp1~MWmu7kdI_HtTzPvo3-!6!73kVY9O8-!7@qh&Y&HqD7DbPU3*BjYjvlEKmy)|RWL|^;aPcpUpH7-rphod+V$uU9r)oms52yAgi zys+^g;cO3hy1{+HBXXAuE8bVf`rhLH3(y8mZ_`MpYF8bMFKk=r8Tgh9tQfErCFeYl_GW!|anFp8s z%q50mrxil_Xn-+*Gkm;3cV0Nk(R`q){Aq=1kW4+y8Z-7zJ*@tw*YteVc065VjV7cr zK>0PNJL*)G8rb9HbgG+AioEE(XOfQkOpvfMGdqVxESQ8O_Xy)_@kbpG>Fe*_3!~Qc znjO8)a&dzr4Y*c3Y}P zRJVcjli!XTAyy*AMuLAp-7+Gz_0oHjnY~97Qx0DGTei>&kR0!;e=A>RF5jn8_^1Hc zQfSm%PG%|_^N-wj8EmP`yaDOt@I#F(CJc5Nt?CtnP_7IU57Uf$%1NBElz zJ~O?#t=0fxN|?jvq<1DU_?|Mc(?Usa$L5(w_rf%1-QSe#G-`wEGgdgvxS=D#*Q^68 z=CQpmlq?XwQPn(68JJojmC^O?`XdFtiHyXe3m0oh>d#Cr0-(T-v@9+KNzV7=v*ZG|Le9v{(xSQsNoF|1&0suITjjmY& zz+n01lqt4-3f3769N6S>tP0tsZ5s zl7At1w?#hu*pv6l`y?5a%qsU3vf((d03yOIvZBS;Uf3 zWp~qx;X7ENXL0>J{likC0?_6^XixXss@onXRP=>E-QH-9yyJq(xEGukqL)V^QR5;H zQUIXMvybAL>I@D;K$JO+A6$_R-~g|92y9@8oy-boPrO+`fIgE&D<1(s&d`6&*6lwrUs8ti@Z5wRd(k9 zxRdj#O^(TwsJj1qhy0)c3-~76dV=dTE718vzPs88Z;Dm`KuTGB;n#CB1%LHc#4;snKghcfmYdym*-1QuJ6_?h^GeM=cU>F4KYu`=#_;z3{Gteq z-kVlMvl+jq5s#RNb72qevwQ_KM@7kXQ7296is zs8y)Qd=#?XiCwawXuo@Fj@$ZJjJ1jM-l2DqGveLNC@!?v(q3Gy1u}>RckNObb$m4x zTTeGfE{BKNuvQ zU}{^ZtqpX~#}T3#vADLP{Pm%pT3Z(t&TXiu9Z)W}p153P?z*_Ex+$&ezKj_wnTs54 zdzU~rEI`yQejShD+4Xj0EFT=ldV6ODZ#F@{_a`^HGCB>QwZSTvPxJE%I81zL>X7|T zNgxm#|d?41K(R?_y9EsV~|c==Xn>-vKFX2NM`W(##FX(h)r z`N_p$2qD^gXJM~Am@b6YwSit3+h=s{Bc_94A?NX1Zw|+*x|(%RebJR!SpT%^qWNU`%L&c7|zQw9L< zIfJ`Z6P>rWQBg>nDBU1AZxHUN7Wfp$6I;;Xnqm^9pVG&`EGDOkdM>*@V(^}IL6*%7 zJ(TLzq-*V=tG(?!n#TvOpjM`Fd>)s|d5zQdVkClUTxJT{-21t?_RGIrWC34mz3_fL zU(0z#v)7!t5NQU)v0w3qbtkri(HPPKPO@tGWTrE(=>p(kJ2l4n>vZmZj=%)l_CWzH7X- zf;o{OYc!a5OVi`U4?cnUarK6#%2BlI`b@j@xOHZS|0MYcGv#tHq1ZdW=-Xde)a1*r zZ*EX8cd=@n?AUf?7My2FrL@BIpV>u*BX1yVw1X*TZn{D^fT51Ga3!()aCeqKe+ z`pFDA;tnL!vCaWP+RKPIqHn1sS7u)UpQv`uu$$M``1n)$6kxn-8NubJkmU5kxbv)F z5;nQv(arJ}2N7q$Y)!4jZ(~j7bgjuTjp9Ct{k~=mV^$7Y7Z-V5BwOj>FG9Ox_%5m2 zKQ8k&xw38z*IK%z5aE_)R~x>GefWKX!nOcY<2t)<0_m2^^kDED0}c#OXiN7u0OgJg&`GcoSr`cklm)Qx_8siJCJ2Thl=k&ZMYGG1koaj)B zhTF|PTLxii+xRz9&k;xpMty%_a4=wtI979e$)<`jxhAYkxbgdRWfY>UQal^|7NM(o zVAka7MGleioljqz5&pM@t?}tB=Vg5bUqtgINST$V*s~>>s_)-A1|B7FHnD+f<^NgT zzqEpJ^hrhgq%J2bfLY&a3w-$F`On4as29-wyjt<#p7@n`=UZ+sYOBA9_T=tWJ}w>H z`woYm20Q=a9%Zm83J2v3mV>SV<|Nq$>IJ? zeMOl@>nw&F6=|9482_p(l6n7+MyIpc8w42QSQ&y)&d1eKGFZwNteM`h{zjLAcCEF? zxb;Cbj8!n!EoyJdq|QHtA3o>(a?#n?oa*;yhH87&rihBI-UCmE@PWkXvMi>iDaL7& z`zJI1kTxMnT&-Ncn=)tiK95hnKA@ZMu_Fk3OxFRN-rM zkR%K7+0cFXW!}2x)`SO`grqk;c_%8JF6*vu`}W&am@Is_{)`pA@ZQH1P4~u{Bv0&7 z(^|QLm%h@a9UEro2oN zYM+lrQ&H_3BR_jp7oSzkwDsrqIF*u8@91aHl&kIm>kkBH6Fr=#MqvE!TKJ?FGCZ+k zR;-;@^??#oe5Ao?j$EYX-8=4|%lDp2skgRLb%Lb51ZLM`Fwe0@=8KPc#fw}W?ys5J zr1C$lL&$~2*Gu=41r{eEnR9J9by@PV<#bFt3Fd|!gV9TFD3UI9&+QQJ!BWcG?k8Zm zt>6m6be%DFP;G!eJMib{)%>=d>CDa)b+^C!v?{+O#mieiJziv~EO>i*X5&JD$JkD4 zkfDg=^XNgG8llJtqhfMKsP2`ckL3my!CeeXNr6e}k2=bOyKI-1F;yEI2$fm^L)PO- zMro(I#GJz;VUtSv6_c@sJ`c>zsp}uA*}0a0gcIo>8f)M+MHx^1uZxoIQ5)5W(*v}6 zlR(nvkk~;DD;Wa^_aA%NWkQW!{^dPo$2Bb!JR8sEQk4dJPsFQ_Nb;rA%G^Bf1Y9+l zv;V)J8$>w9Z17&)j1U}=aEnXs)i$8-<9?>H*-~M3@)+aHn1?hRO0T!4^8p8SlOPY3i*mFebgEGg$hL4X7dN*};7WYW0ij89A z)XDCi8*~7+mN6fhvB>xU*S;bAfc4wqtT56G&uP9M96V*XF!c+XO3e+2rdKR%J!FZ} z?TsPRPf?6nz@;m{hmmCiWnSHdA6%j=xq z)qS!_zln4S{xZbn<)mQ3rqy9hvEEq#64LJ6DL_QdSum35>PnqI4UdAmwyErK*SRUv z>n`}*aIFeQV93D&yp6;pc!J)=Vy(0?Os!#-RspRyTdZF2=?^xzPbFH*AL7Mujqge;*nDXbkMqIM&;Hau0ur% zmuuMjjqGP^u3Awk3$wk?}Ts#}Ub}k~i(9=u`k=g8mGZ zaay8aj(oq~izU-naFH2~+e7m3_R+2YS_`egU~5$cJ%i>x56yK+K4k9UoO>{l$WH1KnYS<@9r>|s9) zY=YL{Q^Wd>Gc;D!gSY&GyhXZ?LK5V YDt(>%4Wt>$9NmHOb@OYL`gb4y3%msDz5oCK literal 0 HcmV?d00001 diff --git a/resources/views/pages/ru/components/metric_value.blade.php b/resources/views/pages/ru/components/metric_value.blade.php new file mode 100644 index 00000000..4956a5e4 --- /dev/null +++ b/resources/views/pages/ru/components/metric_value.blade.php @@ -0,0 +1,129 @@ + + +Make + + + Метрика ValueMetric предназначена для отображения какого-либо значения. + Например, сколько всего записей в таблице. + + + + Создать ValueMetric можно воспользовавшись статическим методом make(). + + + +make(Closure|string $label) + + + + Метод value() позволяет указать значение для метрики. + + + +value(int|string|float|Closure $value) + + + +use MoonShine\Metrics\ValueMetric; // [tl! focus] + +//... + +public function components(): array +{ + return [ + ValueMetric::make('Completed orders') + ->value(Order::completed()->count()) // [tl! focus:-1] + ]; +} + +//... + + + + + +Прогресс + + + Метод progress() позволяет отобразить индикатор прогресса достижения цели в метрике. + + + +progress(int|float|Closure $target) + + + +use MoonShine\Metrics\ValueMetric; + +//... + +public function components(): array +{ + return [ + ValueMetric::make('Open tasks') + ->value(Task::opened()->count()) + ->progress(Task::count()) // [tl! focus] + ]; +} + +//... + + + + При использовании индикатора прогресса, методу value() необходимо передать числовое значение + или замыкание, которое вернет число. + + + + + +Формат значения + + + Метод valueFormat() позволяет отформатировать значение метрики и добавить префикс и суффикс. + + + +valueFormat(string|Closure $value) + + + +use MoonShine\Metrics\ValueMetric; + +//... + +public function components(): array +{ + return [ + ValueMetric::make('Profit') + ->value(Order::completed()->sum('price')) + ->valueFormat('Today ${value}') // [tl! focus:-1] + ]; +} + +//... + + + + + +Icon + +@include('pages.ru.components.shared.metric_icon', ['metric' => 'ValueMetric']) + +Ширина блока + +@include('pages.ru.components.shared.metric_column_span', ['metric' => 'ValueMetric']) + + diff --git a/resources/views/pages/ru/components/metrics_value.blade.php b/resources/views/pages/ru/components/metrics_value.blade.php deleted file mode 100644 index e25dc6ff..00000000 --- a/resources/views/pages/ru/components/metrics_value.blade.php +++ /dev/null @@ -1,113 +0,0 @@ - - -Make - - - Метрика ValueMetric предназначена для отображения какого-либо значения. - Например, сколько всего в таблице записей.
- Создать ValueMetric можно используя статический метод make(). -
- - -make(Closure|string $label) - - - - Метод value() позволяет указать значение для метрики. - - - -value(int|string|float|Closure $value) - - - -use MoonShine\Metrics\ValueMetric; // [tl! focus] - -//... - -public function components(): array -{ - return [ - ValueMetric::make('Completed orders') - ->value(Orders::completed()->count()) // [tl! focus:-1] - ]; -} - -//... - - - - - -Прогресс - - - Также есть возможность отображения в виде прогресса достижения цели. - - - -namespace MoonShine\Resources; - -use MoonShine\Metrics\ValueMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - ValueMetric::make('Open tasks') - ->value(Task::opened()->count()) - ->progress(200) // Конечная цель - ]; - } // [tl! focus:end] - - //... -} - - - - - -Формат - - -Выводимое значение можно отформатировать и добавить префикс и суффикс. - - - -namespace MoonShine\Resources; - -use MoonShine\Metrics\ValueMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - ValueMetric::make('Profit') - ->value(Orders::completed()->sum('price')) - ->valueFormat('Today ${value}') - ]; - } // [tl! focus:end] - - //... -} - - - - - -
diff --git a/resources/views/pages/ru/components/shared/metric_column_span.blade.php b/resources/views/pages/ru/components/shared/metric_column_span.blade.php new file mode 100644 index 00000000..4df82b02 --- /dev/null +++ b/resources/views/pages/ru/components/shared/metric_column_span.blade.php @@ -0,0 +1,42 @@ + + Метод columnSpan() позволяет задать ширину блока в Grid сетке. + + + +columnSpan( + int $columnSpan, + int $adaptiveColumnSpan = 12 +) + + + +use MoonShine\Decorations\Grid; +use MoonShine\Metrics\ValueMetric; + +//... + +public function components(): array +{ + return [ + Grid::make([ // [tl! focus] + ValueMetric::make('Articles') + ->value(Article::count()) + ->columnSpan(6), // [tl! focus] + ValueMetric::make('Comments') + ->value(Comment::count()) + ->columnSpan(6) // [tl! focus] + ]) // [tl! focus] + ]; +} + +//... + + + + За более подробной информацией обратитесь к разделу + Декорация Layout. + + + + + diff --git a/resources/views/pages/ru/components/shared/metric_icon.blade.php b/resources/views/pages/ru/components/shared/metric_icon.blade.php new file mode 100644 index 00000000..a800f4ff --- /dev/null +++ b/resources/views/pages/ru/components/shared/metric_icon.blade.php @@ -0,0 +1,29 @@ + + Метод icon() позволяет добавить иконку к метрике. + + + +use MoonShine\Metrics\ValueMetric; + +//... + +public function components(): array +{ + return [ + ValueMetric::make('Orders') + ->value(Order::count()) + ->icon('heroicons.shopping-bag') // [tl! focus] + ]; +} + +//... + + + + За более подробной информацией обратитесь к разделу + Icons. + + + + + From fedf4152bee57bbe44b1b2f5c628b710e26b7168 Mon Sep 17 00:00:00 2001 From: Alexander Nikushkin Date: Sun, 29 Oct 2023 23:57:19 +0500 Subject: [PATCH 4/7] docs(components): LineChartMetric --- ...s_line_chart.png => line_chart_metric.png} | Bin .../line_chart_metric_column_span.png | Bin 0 -> 18306 bytes .../line_chart_metric_column_span_dark.png | Bin 0 -> 17408 bytes ...rt_dark.png => line_chart_metric_dark.png} | Bin .../pages/ru/components/line_chart.blade.php | 99 ------------- .../ru/components/metric_line_chart.blade.php | 131 ++++++++++++++++++ .../shared/metric_column_span.blade.php | 24 +++- 7 files changed, 152 insertions(+), 102 deletions(-) rename public/screenshots/{metrics_line_chart.png => line_chart_metric.png} (100%) create mode 100644 public/screenshots/line_chart_metric_column_span.png create mode 100644 public/screenshots/line_chart_metric_column_span_dark.png rename public/screenshots/{metrics_line_chart_dark.png => line_chart_metric_dark.png} (100%) delete mode 100644 resources/views/pages/ru/components/line_chart.blade.php create mode 100644 resources/views/pages/ru/components/metric_line_chart.blade.php diff --git a/public/screenshots/metrics_line_chart.png b/public/screenshots/line_chart_metric.png similarity index 100% rename from public/screenshots/metrics_line_chart.png rename to public/screenshots/line_chart_metric.png diff --git a/public/screenshots/line_chart_metric_column_span.png b/public/screenshots/line_chart_metric_column_span.png new file mode 100644 index 0000000000000000000000000000000000000000..fb10940fc16b8d2800e6937356829138d14602a1 GIT binary patch literal 18306 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 literal 0 HcmV?d00001 diff --git a/public/screenshots/line_chart_metric_column_span_dark.png b/public/screenshots/line_chart_metric_column_span_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..19baa246ca3ec8e5afe9dc4f4debc0ccf5e882fb GIT binary patch literal 17408 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 V)woxZ7()64c^PHtEJ=em{|}|z$w~kK literal 0 HcmV?d00001 diff --git a/public/screenshots/metrics_line_chart_dark.png b/public/screenshots/line_chart_metric_dark.png similarity index 100% rename from public/screenshots/metrics_line_chart_dark.png rename to public/screenshots/line_chart_metric_dark.png diff --git a/resources/views/pages/ru/components/line_chart.blade.php b/resources/views/pages/ru/components/line_chart.blade.php deleted file mode 100644 index ccbbe738..00000000 --- a/resources/views/pages/ru/components/line_chart.blade.php +++ /dev/null @@ -1,99 +0,0 @@ - - - - Позволяет создавать линейный график для метрик. - - - -namespace MoonShine\Resources; - -use MoonShine\Metrics\LineChartMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - LineChartMetric::make('Orders') - ->line([ - 'Profit' => Order::query() - ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date') - ->groupBy('date') - ->pluck('sum','date') - ->toArray() - ]) - ->line([ - 'Avg' => Order::query() - ->selectRaw('AVG(price) as avg, DATE_FORMAT(created_at, "%d.%m.%Y") as date') - ->groupBy('date') - ->pluck('avg','date') - ->toArray() - ], '#EC4176'), - ]; - } // [tl! focus:end] - - //... -} - - - - или используя один метод line: - - - -namespace MoonShine\Resources; - -use MoonShine\Metrics\LineChartMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - LineChartMetric::make('Orders') - ->line([ - 'Profit' => Order::query() - ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date') - ->groupBy('date') - ->pluck('sum','date') - ->toArray(), - 'Avg' => Order::query() - ->selectRaw('AVG(price) as avg, DATE_FORMAT(created_at, "%d.%m.%Y") as date') - ->groupBy('date') - ->pluck('avg','date') - ->toArray() - ],[ - 'red', 'blue' - ]) - ]; - } // [tl! focus:end] - - //... -} - - - - - - - По умолчанию у графика LineChart ключи сортируются по возрастанию. - Эту особенность можно отключить, используя метод withoutSortKeys(). - - - -LineChartMetric::make('Orders') - ->line([ - 'Profit' => Order::query() - ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date') - ->groupBy('date') - ->pluck('sum','date') - ->toArray() - ]) - ->withoutSortKeys(), // [tl! focus] - - - diff --git a/resources/views/pages/ru/components/metric_line_chart.blade.php b/resources/views/pages/ru/components/metric_line_chart.blade.php new file mode 100644 index 00000000..458090ad --- /dev/null +++ b/resources/views/pages/ru/components/metric_line_chart.blade.php @@ -0,0 +1,131 @@ + + +Make + + + Метрика LineChartMetric предназначена для отображения линейных графиков. + + + + Создать LineChartMetric можно воспользовавшись статическим методом make(). + + + +make(Closure|string $label) + + + + Метод line() позволяет добавить линию значений в метрику. + В ValueMetric можно добавить несколько линий. + + + +line( + array|Closure $line, + string|array|Closure $color = '#7843E9' +) + + + + $line - значения для построения графика,
+ $color - цвет линии. +
+ + +use MoonShine\Metrics\LineChartMetric; // [tl! focus] + +//... + +public function components(): array +{ + return [ + LineChartMetric::make('Orders') // [tl! focus:start] + ->line([ + 'Profit' => Order::query() + ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date') + ->groupBy('date') + ->pluck('sum','date') + ->toArray() + ]) + ->line([ + 'Avg' => Order::query() + ->selectRaw('AVG(price) as avg, DATE_FORMAT(created_at, "%d.%m.%Y") as date') + ->groupBy('date') + ->pluck('avg','date') + ->toArray() + ], '#EC4176') // [tl! focus:end] + ]; +} + +//... + + + + Можно задать несколько линий через один метод line. + + + +use MoonShine\Metrics\LineChartMetric; // [tl! focus] + +//... + +public function components(): array +{ + return [ + LineChartMetric::make('Orders') // [tl! focus:start] + ->line([ + 'Profit' => Order::query() + ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date') + ->groupBy('date') + ->pluck('sum','date') + ->toArray(), + 'Avg' => Order::query() + ->selectRaw('AVG(price) as avg, DATE_FORMAT(created_at, "%d.%m.%Y") as date') + ->groupBy('date') + ->pluck('avg','date') + ->toArray() + ],[ + 'red', 'blue' + ]) // [tl! focus:end] + ]; +} + +//... + + + + + +Сортировка ключей + + + По умолчанию у графика LineChart ключи сортируются по возрастанию. + Эту особенность можно отключить, используя метод withoutSortKeys(). + + + +LineChartMetric::make('Orders') + ->line([ + 'Profit' => Order::query() + ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date') + ->groupBy('date') + ->pluck('sum','date') + ->toArray() + ]) + ->withoutSortKeys(), // [tl! focus] + + +Ширина блока + +@include('pages.ru.components.shared.metric_column_span', ['metric' => 'LineChartMetric']) + +
diff --git a/resources/views/pages/ru/components/shared/metric_column_span.blade.php b/resources/views/pages/ru/components/shared/metric_column_span.blade.php index 4df82b02..a21db583 100644 --- a/resources/views/pages/ru/components/shared/metric_column_span.blade.php +++ b/resources/views/pages/ru/components/shared/metric_column_span.blade.php @@ -11,7 +11,7 @@ use MoonShine\Decorations\Grid; -use MoonShine\Metrics\ValueMetric; +use MoonShine\Metrics\{{ $metric }}; //... @@ -19,11 +19,29 @@ public function components(): array { return [ Grid::make([ // [tl! focus] - ValueMetric::make('Articles') + {{ $metric }}::make('Articles') +@if( $metric === 'ValueMetric') ->value(Article::count()) +@elseif( $metric === 'LineChartMetric') + ->line([ + 'Count' => [ + now()->format('Y-m-d') => 3, + now()->addDay()->format('Y-m-d') => 5 + ] + ]) +@endif ->columnSpan(6), // [tl! focus] - ValueMetric::make('Comments') + {{ $metric }}::make('Comments') +@if( $metric === 'ValueMetric') ->value(Comment::count()) +@elseif( $metric === 'LineChartMetric') + ->line([ + 'Count' => [ + now()->format('Y-m-d') => 53, + now()->addDay()->format('Y-m-d') => 22 + ] + ]) +@endif ->columnSpan(6) // [tl! focus] ]) // [tl! focus] ]; From 604d7953b407ccf856b66500c14be871010e7841 Mon Sep 17 00:00:00 2001 From: Alexander Nikushkin Date: Mon, 30 Oct 2023 11:48:39 +0500 Subject: [PATCH 5/7] docs(components): DonutChartMetric --- ...donut_chart.png => donut_chart_metric.png} | Bin .../donut_chart_metric_column_span.png | Bin 0 -> 24593 bytes .../donut_chart_metric_column_span_dark.png | Bin 0 -> 23734 bytes ...t_dark.png => donut_chart_metric_dark.png} | Bin .../pages/ru/components/donut_chart.blade.php | 31 ---------- .../views/pages/ru/components/index.blade.php | 6 +- .../components/metric_donut_chart.blade.php | 57 ++++++++++++++++++ .../shared/metric_column_span.blade.php | 33 ++++++++-- .../views/pages/ru/configuration.blade.php | 2 +- 9 files changed, 90 insertions(+), 39 deletions(-) rename public/screenshots/{metrics_donut_chart.png => donut_chart_metric.png} (100%) create mode 100644 public/screenshots/donut_chart_metric_column_span.png create mode 100644 public/screenshots/donut_chart_metric_column_span_dark.png rename public/screenshots/{metrics_donut_chart_dark.png => donut_chart_metric_dark.png} (100%) delete mode 100644 resources/views/pages/ru/components/donut_chart.blade.php create mode 100644 resources/views/pages/ru/components/metric_donut_chart.blade.php diff --git a/public/screenshots/metrics_donut_chart.png b/public/screenshots/donut_chart_metric.png similarity index 100% rename from public/screenshots/metrics_donut_chart.png rename to public/screenshots/donut_chart_metric.png diff --git a/public/screenshots/donut_chart_metric_column_span.png b/public/screenshots/donut_chart_metric_column_span.png new file mode 100644 index 0000000000000000000000000000000000000000..c7c6b6ede818faf93f60ff1ee62a2e41532140ee GIT binary patch literal 24593 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 D0E->@ literal 0 HcmV?d00001 diff --git a/public/screenshots/donut_chart_metric_column_span_dark.png b/public/screenshots/donut_chart_metric_column_span_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..94be84546cb6a4d07001af8a08d03113d31a9268 GIT binary patch literal 23734 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 r!dhE& - - - Позволяет создавать Donut график для метрик. - - - -namespace MoonShine\Resources; - -use MoonShine\Metrics\DonutChartMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - DonutChartMetric::make('Подписчики') - ->values(['CutCode' => 10000, 'Apple' => 9999]), - ]; - } // [tl! focus:end] - - //... -} - - - - - -
diff --git a/resources/views/pages/ru/components/index.blade.php b/resources/views/pages/ru/components/index.blade.php index a04b7f70..cdb23c09 100644 --- a/resources/views/pages/ru/components/index.blade.php +++ b/resources/views/pages/ru/components/index.blade.php @@ -1,7 +1,11 @@ - Блоки для отображения статистики. + + +php artisan moonshine:component + + diff --git a/resources/views/pages/ru/components/metric_donut_chart.blade.php b/resources/views/pages/ru/components/metric_donut_chart.blade.php new file mode 100644 index 00000000..3db58f1b --- /dev/null +++ b/resources/views/pages/ru/components/metric_donut_chart.blade.php @@ -0,0 +1,57 @@ + + + +Make + + + Метрика DonutChartMetric предназначена для создания Donut графиков. + + + + Создать DonutChartMetric можно воспользовавшись статическим методом make(). + + + +make(Closure|string $label) + + + + Метод values() позволяет указать значение для метрики. + + + +values(array|Closure $values) + + + +use MoonShine\Metrics\DonutChartMetric; // [tl! focus] + +//... + +public function components(): array +{ + return [ + DonutChartMetric::make('Subscribers') // [tl! focus] + ->values(['CutCode' => 10000, 'Apple' => 9999]) // [tl! focus] + ]; +} + +//... + + + + + +Ширина блока + +@include('pages.ru.components.shared.metric_column_span', ['metric' => 'DonutChartMetric']) + + diff --git a/resources/views/pages/ru/components/shared/metric_column_span.blade.php b/resources/views/pages/ru/components/shared/metric_column_span.blade.php index a21db583..60b5d610 100644 --- a/resources/views/pages/ru/components/shared/metric_column_span.blade.php +++ b/resources/views/pages/ru/components/shared/metric_column_span.blade.php @@ -10,6 +10,7 @@ +use App\Models\Article; use MoonShine\Decorations\Grid; use MoonShine\Metrics\{{ $metric }}; @@ -19,26 +20,46 @@ public function components(): array { return [ Grid::make([ // [tl! focus] - {{ $metric }}::make('Articles') + {{ $metric }}::make({{ $metric === 'DonutChartMetric' ? 'Subscribers' : 'Articles' }}) @if( $metric === 'ValueMetric') ->value(Article::count()) +@elseif( $metric === 'DonutChartMetric') + ->values(['CutCode' => 10000, 'Apple' => 9999]) @elseif( $metric === 'LineChartMetric') ->line([ 'Count' => [ - now()->format('Y-m-d') => 3, - now()->addDay()->format('Y-m-d') => 5 + now()->subDays()->format('Y-m-d') => + Article::whereDate( + 'created_at', + now()->subDays()->format('Y-m-d') + )->count(), + now()->format('Y-m-d') => + Article::whereDate( + 'created_at', + now()->subDays()->format('Y-m-d') + )->count() ] ]) @endif ->columnSpan(6), // [tl! focus] - {{ $metric }}::make('Comments') + {{ $metric }}::make( {{ $metric === 'DonutChartMetric' ? 'Tasks' : 'Comments' }}) @if( $metric === 'ValueMetric') ->value(Comment::count()) +@elseif( $metric === 'DonutChartMetric') + ->values(['New' => 234, 'Done' => 421]) @elseif( $metric === 'LineChartMetric') ->line([ 'Count' => [ - now()->format('Y-m-d') => 53, - now()->addDay()->format('Y-m-d') => 22 + now()->subDays()->format('Y-m-d') => + Comment::whereDate( + 'created_at', + now()->subDays()->format('Y-m-d') + )->count(), + now()->format('Y-m-d') => + Comment::whereDate( + 'created_at', + now()->subDays()->format('Y-m-d') + )->count() ] ]) @endif diff --git a/resources/views/pages/ru/configuration.blade.php b/resources/views/pages/ru/configuration.blade.php index e6428cca..4470a83e 100644 --- a/resources/views/pages/ru/configuration.blade.php +++ b/resources/views/pages/ru/configuration.blade.php @@ -57,7 +57,7 @@ 'disk' => 'public', // [tl! focus] 'forms' => [ // [tl! focus] - # форма аунтификации + # форма аутентификации 'login' => LoginForm::class // [tl! focus] ], // [tl! focus] From 94a8013c7839c76c4fa73b42efdc4613c1bea06c Mon Sep 17 00:00:00 2001 From: Alexander Nikushkin Date: Mon, 30 Oct 2023 12:18:02 +0500 Subject: [PATCH 6/7] docs: remove en --- .../views/pages/en/actions/export.blade.php | 51 -- .../views/pages/en/actions/import.blade.php | 53 -- .../views/pages/en/actions/index.blade.php | 10 - .../views/pages/en/advanced/assets.blade.php | 30 -- .../en/advanced/authentication.blade.php | 133 ----- .../pages/en/advanced/authorization.blade.php | 92 ---- .../pages/en/advanced/dashboard.blade.php | 115 ---- .../pages/en/advanced/development.blade.php | 122 ----- .../views/pages/en/advanced/events.blade.php | 57 -- .../pages/en/advanced/localization.blade.php | 8 - .../views/pages/en/advanced/menu.blade.php | 252 --------- .../pages/en/advanced/notifications.blade.php | 25 - .../views/pages/en/advanced/pages.blade.php | 150 ------ .../views/pages/en/advanced/routes.blade.php | 68 --- .../pages/en/advanced/socialite.blade.php | 36 -- .../views/pages/en/components/alert.blade.php | 58 -- .../views/pages/en/components/badge.blade.php | 22 - .../pages/en/components/boolean.blade.php | 27 - .../views/pages/en/components/box.blade.php | 50 -- .../pages/en/components/breadcrumbs.blade.php | 17 - .../views/pages/en/components/card.blade.php | 40 -- .../pages/en/components/collapse.blade.php | 57 -- .../pages/en/components/divider.blade.php | 54 -- .../pages/en/components/dropdown.blade.php | 46 -- .../views/pages/en/components/files.blade.php | 41 -- .../views/pages/en/components/form.blade.php | 269 ---------- .../views/pages/en/components/grid.blade.php | 27 - .../views/pages/en/components/icon.blade.php | 77 --- .../views/pages/en/components/index.blade.php | 15 - .../views/pages/en/components/link.blade.php | 58 -- .../pages/en/components/loader.blade.php | 17 - .../views/pages/en/components/modal.blade.php | 28 - .../pages/en/components/offcanvas.blade.php | 17 - .../pages/en/components/paginations.blade.php | 41 -- .../pages/en/components/popover.blade.php | 37 -- .../en/components/progress_bar.blade.php | 44 -- .../pages/en/components/rating.blade.php | 17 - .../en/components/shared/colors.blade.php | 13 - .../en/components/shared/placement.blade.php | 10 - .../en/components/shared/sizes.blade.php | 10 - .../pages/en/components/shared/type.blade.php | 10 - .../pages/en/components/spinner.blade.php | 67 --- .../views/pages/en/components/table.blade.php | 103 ---- .../views/pages/en/components/tabs.blade.php | 40 -- .../pages/en/components/thumbnail.blade.php | 46 -- .../views/pages/en/components/title.blade.php | 17 - .../views/pages/en/components/toast.blade.php | 39 -- .../pages/en/components/tooltip.blade.php | 38 -- resources/views/pages/en/concept.blade.php | 31 -- .../views/pages/en/configuration.blade.php | 102 ---- .../views/pages/en/contribution.blade.php | 162 ------ .../pages/en/decorations/block.blade.php | 47 -- .../pages/en/decorations/button.blade.php | 27 - .../pages/en/decorations/collapse.blade.php | 33 -- .../pages/en/decorations/divider.blade.php | 82 --- .../pages/en/decorations/heading.blade.php | 28 - .../pages/en/decorations/index.blade.php | 10 - .../pages/en/decorations/layout.blade.php | 94 ---- .../views/pages/en/decorations/tabs.blade.php | 36 -- .../pages/en/fields/belongs_to.blade.php | 140 ----- .../pages/en/fields/belongs_to_many.blade.php | 167 ------ .../views/pages/en/fields/checkbox.blade.php | 25 - .../views/pages/en/fields/code.blade.php | 31 -- .../views/pages/en/fields/color.blade.php | 31 -- .../views/pages/en/fields/date.blade.php | 51 -- .../views/pages/en/fields/email.blade.php | 17 - .../views/pages/en/fields/enum.blade.php | 30 -- .../views/pages/en/fields/file.blade.php | 217 -------- .../views/pages/en/fields/has_many.blade.php | 70 --- .../en/fields/has_many_through.blade.php | 13 - .../views/pages/en/fields/has_one.blade.php | 51 -- .../pages/en/fields/has_one_through.blade.php | 13 - resources/views/pages/en/fields/id.blade.php | 42 -- .../views/pages/en/fields/image.blade.php | 42 -- .../views/pages/en/fields/index.blade.php | 502 ------------------ .../views/pages/en/fields/json.blade.php | 90 ---- .../pages/en/fields/morph_many.blade.php | 13 - .../views/pages/en/fields/morph_one.blade.php | 16 - .../views/pages/en/fields/morph_to.blade.php | 35 -- .../pages/en/fields/morph_to_many.blade.php | 16 - .../views/pages/en/fields/no_input.blade.php | 106 ---- .../views/pages/en/fields/number.blade.php | 48 -- .../views/pages/en/fields/password.blade.php | 33 -- .../views/pages/en/fields/phone.blade.php | 19 - .../views/pages/en/fields/select.blade.php | 105 ---- .../en/fields/shared/async_search.blade.php | 90 ---- .../en/fields/shared/values_query.blade.php | 18 - .../views/pages/en/fields/slide.blade.php | 39 -- .../views/pages/en/fields/slug.blade.php | 28 - .../en/fields/spatie/medialibrary.blade.php | 88 --- .../en/fields/spatie/translatable.blade.php | 99 ---- .../pages/en/fields/stack_fields.blade.php | 37 -- .../views/pages/en/fields/switch.blade.php | 58 -- .../views/pages/en/fields/text.blade.php | 83 --- .../views/pages/en/fields/textarea.blade.php | 22 - resources/views/pages/en/fields/url.blade.php | 17 - .../views/pages/en/fields/wysiwyg.blade.php | 209 -------- .../pages/en/filters/belongs_to.blade.php | 27 - .../en/filters/belongs_to_many.blade.php | 25 - .../views/pages/en/filters/date.blade.php | 25 - .../pages/en/filters/date_range.blade.php | 25 - .../views/pages/en/filters/has_one.blade.php | 26 - .../views/pages/en/filters/index.blade.php | 100 ---- .../views/pages/en/filters/is_empty.blade.php | 32 -- .../views/pages/en/filters/select.blade.php | 29 - .../views/pages/en/filters/slide.blade.php | 29 - .../views/pages/en/filters/switch.blade.php | 25 - .../views/pages/en/filters/text.blade.php | 25 - resources/views/pages/en/home.blade.php | 28 - .../views/pages/en/icons/heroicons.blade.php | 37 -- .../views/pages/en/icons/index.blade.php | 31 -- .../views/pages/en/installation.blade.php | 99 ---- .../pages/en/metrics/donut_chart.blade.php | 31 -- .../views/pages/en/metrics/index.blade.php | 16 - .../pages/en/metrics/line_chart.blade.php | 99 ---- .../views/pages/en/metrics/value.blade.php | 89 ---- resources/views/pages/en/packages.blade.php | 3 - resources/views/pages/en/releases.blade.php | 272 ---------- .../pages/en/resources/actions.blade.php | 54 -- .../en/resources/active_actions.blade.php | 55 -- .../pages/en/resources/bulk_actions.blade.php | 48 -- .../pages/en/resources/components.blade.php | 133 ----- .../views/pages/en/resources/fields.blade.php | 49 -- .../pages/en/resources/filters.blade.php | 55 -- .../pages/en/resources/form_actions.blade.php | 45 -- .../views/pages/en/resources/index.blade.php | 370 ------------- .../pages/en/resources/item_actions.blade.php | 72 --- .../pages/en/resources/metrics.blade.php | 33 -- .../views/pages/en/resources/query.blade.php | 93 ---- .../pages/en/resources/query_tags.blade.php | 44 -- .../views/pages/en/resources/search.blade.php | 79 --- .../shared/actions_confirm.blade.php | 78 --- .../resources/shared/actions_view.blade.php | 59 -- .../pages/en/resources/singleton.blade.php | 52 -- .../pages/en/resources/table_styles.blade.php | 81 --- .../pages/en/resources/validation.blade.php | 103 ---- .../views/pages/en/upgrade_guide.blade.php | 38 -- 137 files changed, 8631 deletions(-) delete mode 100644 resources/views/pages/en/actions/export.blade.php delete mode 100644 resources/views/pages/en/actions/import.blade.php delete mode 100644 resources/views/pages/en/actions/index.blade.php delete mode 100644 resources/views/pages/en/advanced/assets.blade.php delete mode 100644 resources/views/pages/en/advanced/authentication.blade.php delete mode 100644 resources/views/pages/en/advanced/authorization.blade.php delete mode 100644 resources/views/pages/en/advanced/dashboard.blade.php delete mode 100644 resources/views/pages/en/advanced/development.blade.php delete mode 100644 resources/views/pages/en/advanced/events.blade.php delete mode 100644 resources/views/pages/en/advanced/localization.blade.php delete mode 100644 resources/views/pages/en/advanced/menu.blade.php delete mode 100644 resources/views/pages/en/advanced/notifications.blade.php delete mode 100644 resources/views/pages/en/advanced/pages.blade.php delete mode 100644 resources/views/pages/en/advanced/routes.blade.php delete mode 100644 resources/views/pages/en/advanced/socialite.blade.php delete mode 100644 resources/views/pages/en/components/alert.blade.php delete mode 100644 resources/views/pages/en/components/badge.blade.php delete mode 100644 resources/views/pages/en/components/boolean.blade.php delete mode 100644 resources/views/pages/en/components/box.blade.php delete mode 100644 resources/views/pages/en/components/breadcrumbs.blade.php delete mode 100644 resources/views/pages/en/components/card.blade.php delete mode 100644 resources/views/pages/en/components/collapse.blade.php delete mode 100644 resources/views/pages/en/components/divider.blade.php delete mode 100644 resources/views/pages/en/components/dropdown.blade.php delete mode 100644 resources/views/pages/en/components/files.blade.php delete mode 100644 resources/views/pages/en/components/form.blade.php delete mode 100644 resources/views/pages/en/components/grid.blade.php delete mode 100644 resources/views/pages/en/components/icon.blade.php delete mode 100644 resources/views/pages/en/components/index.blade.php delete mode 100644 resources/views/pages/en/components/link.blade.php delete mode 100644 resources/views/pages/en/components/loader.blade.php delete mode 100644 resources/views/pages/en/components/modal.blade.php delete mode 100644 resources/views/pages/en/components/offcanvas.blade.php delete mode 100644 resources/views/pages/en/components/paginations.blade.php delete mode 100644 resources/views/pages/en/components/popover.blade.php delete mode 100644 resources/views/pages/en/components/progress_bar.blade.php delete mode 100644 resources/views/pages/en/components/rating.blade.php delete mode 100644 resources/views/pages/en/components/shared/colors.blade.php delete mode 100644 resources/views/pages/en/components/shared/placement.blade.php delete mode 100644 resources/views/pages/en/components/shared/sizes.blade.php delete mode 100644 resources/views/pages/en/components/shared/type.blade.php delete mode 100644 resources/views/pages/en/components/spinner.blade.php delete mode 100644 resources/views/pages/en/components/table.blade.php delete mode 100644 resources/views/pages/en/components/tabs.blade.php delete mode 100644 resources/views/pages/en/components/thumbnail.blade.php delete mode 100644 resources/views/pages/en/components/title.blade.php delete mode 100644 resources/views/pages/en/components/toast.blade.php delete mode 100644 resources/views/pages/en/components/tooltip.blade.php delete mode 100644 resources/views/pages/en/concept.blade.php delete mode 100644 resources/views/pages/en/configuration.blade.php delete mode 100644 resources/views/pages/en/contribution.blade.php delete mode 100644 resources/views/pages/en/decorations/block.blade.php delete mode 100644 resources/views/pages/en/decorations/button.blade.php delete mode 100644 resources/views/pages/en/decorations/collapse.blade.php delete mode 100644 resources/views/pages/en/decorations/divider.blade.php delete mode 100644 resources/views/pages/en/decorations/heading.blade.php delete mode 100644 resources/views/pages/en/decorations/index.blade.php delete mode 100644 resources/views/pages/en/decorations/layout.blade.php delete mode 100644 resources/views/pages/en/decorations/tabs.blade.php delete mode 100644 resources/views/pages/en/fields/belongs_to.blade.php delete mode 100644 resources/views/pages/en/fields/belongs_to_many.blade.php delete mode 100644 resources/views/pages/en/fields/checkbox.blade.php delete mode 100644 resources/views/pages/en/fields/code.blade.php delete mode 100644 resources/views/pages/en/fields/color.blade.php delete mode 100644 resources/views/pages/en/fields/date.blade.php delete mode 100644 resources/views/pages/en/fields/email.blade.php delete mode 100644 resources/views/pages/en/fields/enum.blade.php delete mode 100644 resources/views/pages/en/fields/file.blade.php delete mode 100644 resources/views/pages/en/fields/has_many.blade.php delete mode 100644 resources/views/pages/en/fields/has_many_through.blade.php delete mode 100644 resources/views/pages/en/fields/has_one.blade.php delete mode 100644 resources/views/pages/en/fields/has_one_through.blade.php delete mode 100644 resources/views/pages/en/fields/id.blade.php delete mode 100644 resources/views/pages/en/fields/image.blade.php delete mode 100644 resources/views/pages/en/fields/index.blade.php delete mode 100644 resources/views/pages/en/fields/json.blade.php delete mode 100644 resources/views/pages/en/fields/morph_many.blade.php delete mode 100644 resources/views/pages/en/fields/morph_one.blade.php delete mode 100644 resources/views/pages/en/fields/morph_to.blade.php delete mode 100644 resources/views/pages/en/fields/morph_to_many.blade.php delete mode 100644 resources/views/pages/en/fields/no_input.blade.php delete mode 100644 resources/views/pages/en/fields/number.blade.php delete mode 100644 resources/views/pages/en/fields/password.blade.php delete mode 100644 resources/views/pages/en/fields/phone.blade.php delete mode 100644 resources/views/pages/en/fields/select.blade.php delete mode 100644 resources/views/pages/en/fields/shared/async_search.blade.php delete mode 100644 resources/views/pages/en/fields/shared/values_query.blade.php delete mode 100644 resources/views/pages/en/fields/slide.blade.php delete mode 100644 resources/views/pages/en/fields/slug.blade.php delete mode 100644 resources/views/pages/en/fields/spatie/medialibrary.blade.php delete mode 100644 resources/views/pages/en/fields/spatie/translatable.blade.php delete mode 100644 resources/views/pages/en/fields/stack_fields.blade.php delete mode 100644 resources/views/pages/en/fields/switch.blade.php delete mode 100644 resources/views/pages/en/fields/text.blade.php delete mode 100644 resources/views/pages/en/fields/textarea.blade.php delete mode 100644 resources/views/pages/en/fields/url.blade.php delete mode 100644 resources/views/pages/en/fields/wysiwyg.blade.php delete mode 100644 resources/views/pages/en/filters/belongs_to.blade.php delete mode 100644 resources/views/pages/en/filters/belongs_to_many.blade.php delete mode 100644 resources/views/pages/en/filters/date.blade.php delete mode 100644 resources/views/pages/en/filters/date_range.blade.php delete mode 100644 resources/views/pages/en/filters/has_one.blade.php delete mode 100644 resources/views/pages/en/filters/index.blade.php delete mode 100644 resources/views/pages/en/filters/is_empty.blade.php delete mode 100644 resources/views/pages/en/filters/select.blade.php delete mode 100644 resources/views/pages/en/filters/slide.blade.php delete mode 100644 resources/views/pages/en/filters/switch.blade.php delete mode 100644 resources/views/pages/en/filters/text.blade.php delete mode 100644 resources/views/pages/en/home.blade.php delete mode 100644 resources/views/pages/en/icons/heroicons.blade.php delete mode 100644 resources/views/pages/en/icons/index.blade.php delete mode 100644 resources/views/pages/en/installation.blade.php delete mode 100644 resources/views/pages/en/metrics/donut_chart.blade.php delete mode 100644 resources/views/pages/en/metrics/index.blade.php delete mode 100644 resources/views/pages/en/metrics/line_chart.blade.php delete mode 100644 resources/views/pages/en/metrics/value.blade.php delete mode 100644 resources/views/pages/en/packages.blade.php delete mode 100644 resources/views/pages/en/releases.blade.php delete mode 100644 resources/views/pages/en/resources/actions.blade.php delete mode 100644 resources/views/pages/en/resources/active_actions.blade.php delete mode 100644 resources/views/pages/en/resources/bulk_actions.blade.php delete mode 100644 resources/views/pages/en/resources/components.blade.php delete mode 100644 resources/views/pages/en/resources/fields.blade.php delete mode 100644 resources/views/pages/en/resources/filters.blade.php delete mode 100644 resources/views/pages/en/resources/form_actions.blade.php delete mode 100644 resources/views/pages/en/resources/index.blade.php delete mode 100644 resources/views/pages/en/resources/item_actions.blade.php delete mode 100644 resources/views/pages/en/resources/metrics.blade.php delete mode 100644 resources/views/pages/en/resources/query.blade.php delete mode 100644 resources/views/pages/en/resources/query_tags.blade.php delete mode 100644 resources/views/pages/en/resources/search.blade.php delete mode 100644 resources/views/pages/en/resources/shared/actions_confirm.blade.php delete mode 100644 resources/views/pages/en/resources/shared/actions_view.blade.php delete mode 100644 resources/views/pages/en/resources/singleton.blade.php delete mode 100644 resources/views/pages/en/resources/table_styles.blade.php delete mode 100644 resources/views/pages/en/resources/validation.blade.php delete mode 100644 resources/views/pages/en/upgrade_guide.blade.php diff --git a/resources/views/pages/en/actions/export.blade.php b/resources/views/pages/en/actions/export.blade.php deleted file mode 100644 index c5441f0a..00000000 --- a/resources/views/pages/en/actions/export.blade.php +++ /dev/null @@ -1,51 +0,0 @@ - - - - Exports all data considering filters - - - -use MoonShine\Actions\ExportAction; - -//... -public function actions(): array -{ - return [ - ExportAction::make('Export') - // Optional methods - // If you want to run in the background - ->queue() - // Selecting a drive - ->disk('public') - // Selecting a save directory - ->dir('/exports') - // If you want to use csv format - ->csv() - // If you use csv - ->delimiter(',') - , - ]; -} -//... - - - - Only fields having a showOnExport flag will be exported - - - - -//... -public function fields(): array -{ - return [ - ID::make()->showOnExport(), - ]; -} -//... - - - - - - diff --git a/resources/views/pages/en/actions/import.blade.php b/resources/views/pages/en/actions/import.blade.php deleted file mode 100644 index 5506cd44..00000000 --- a/resources/views/pages/en/actions/import.blade.php +++ /dev/null @@ -1,53 +0,0 @@ - - - - Imports data - - - -use MoonShine\Actions\ImportAction; - -//... -public function actions(): array -{ - return [ - ImportAction::make('Import') - // Optional methods - // If you want to run in the background - ->queue() - // Selecting a drive - ->disk('public') - // Selecting a save directory - ->dir('/exports') - // Delete after importing - ->deleteAfter() - // If you use csv - ->delimiter(',') - , - ]; -} -//... - - - - Only those fields will be imported that are marked using the useOnImport - - - - -//... -public function fields(): array -{ - return [ - // Be sure to mark the identifier, otherwise all entries will be added and not edited - ID::make() - ->useOnImport(), - - Text::make('Title') - ->useOnImport(), - ]; -} -//... - - - diff --git a/resources/views/pages/en/actions/index.blade.php b/resources/views/pages/en/actions/index.blade.php deleted file mode 100644 index d38f10dd..00000000 --- a/resources/views/pages/en/actions/index.blade.php +++ /dev/null @@ -1,10 +0,0 @@ - - - The actions are set in the actions resource method. - - - - Could be used to append additional processes for the main page of the resource. - - - diff --git a/resources/views/pages/en/advanced/assets.blade.php b/resources/views/pages/en/advanced/assets.blade.php deleted file mode 100644 index abcce6ea..00000000 --- a/resources/views/pages/en/advanced/assets.blade.php +++ /dev/null @@ -1,30 +0,0 @@ - - - - MoonShine can include any of your css and js files by adding them to the - MoonShineServiceProvider - - - -use MoonShine\Utilities\AssetManager; - -class MoonShineServiceProvider extends ServiceProvider -{ - //... - public function boot(): void - { - //... - app(AssetManager::class)->add([ - '/css/style.css', - '/js/main.js', - ]); - //... - } - //... -} - - - - - - diff --git a/resources/views/pages/en/advanced/authentication.blade.php b/resources/views/pages/en/advanced/authentication.blade.php deleted file mode 100644 index 879bcd8d..00000000 --- a/resources/views/pages/en/advanced/authentication.blade.php +++ /dev/null @@ -1,133 +0,0 @@ - - -Basics - - - The Moonshine admin panel implements an authentication system that is enabled by default, - but if you need to allow access for all users, - you can disable it in the configuration file config/moonshine.php - - - -return [ - // ... - 'auth' => [ - 'enable' => true, // [tl! focus] - // ... - ], - // ... -]; - - - - - -Extending capabilities - - - If you use your own guard, provider, then they can be redefined in the configuration, - as well as the MoonshineUser model - - - -return [ - // ... - 'auth' => [ - // ... - 'guard' => 'moonshine', // [tl! focus:start] - 'guards' => [ - 'moonshine' => [ - 'driver' => 'session', - 'provider' => 'moonshine', - ], - ], - 'providers' => [ - 'moonshine' => [ - 'driver' => 'eloquent', - 'model' => MoonshineUser::class, - ], - ], // [tl! focus:end] - // ... - ], - // ... -]; - - - - If there is a need to add text under the login button (for example, add a registration button), - then this can easily be done through the configuration file - - - -return [ - // ... - 'auth' => [ - // ... - 'footer' => 'CutCode' // [tl! focus] - ], - // ... - ], - // ... -]; - - -Greetings - - - To change the welcome text on the authentication page, - you need to create a language file lang/vendor/moonshine/en/ui.php - - - -return [ - // ... - 'login' => [ // [tl! focus:start] - 'title' => 'Welcome to :moonshine_title!', - 'description' => 'Please sign-in to your account', - ], // [tl! focus:end] - // ... -]; - - -Profile - - - You can override the fields for the profile in the configuration file config/moonshine.php - - - -return [ - // ... - 'auth' => [ - 'enable' => true, - 'fields' => [ // [tl! focus:start] - 'username' => 'email', - 'password' => 'password', - 'name' => 'name', - 'avatar' => 'avatar' - ], // [tl! focus:end] - 'guard' => 'moonshine', - // ... - ], - // ... -]; - - - - If you don't want to use an avatar, - then specify 'avatar'=>'' or 'avatar'=>false. - - - - If you want to change the look of your profile page, - then create a file resources/views/vendor/moonshine/profile.blade.php - - - diff --git a/resources/views/pages/en/advanced/authorization.blade.php b/resources/views/pages/en/advanced/authorization.blade.php deleted file mode 100644 index 4a814012..00000000 --- a/resources/views/pages/en/advanced/authorization.blade.php +++ /dev/null @@ -1,92 +0,0 @@ - - - - We stick to the Laravel concept, so using the Laravel policy we can operate - access rights from the MoonShine admin panel - - - - MoonShine resource controllers check each method for permissions. - If difficulties arise, check the official Laravel documentation - - - - By default, permission checking is disabled for resources. To enable it, you must add the - $withPolicy property - - - - Available Policy methods: - - - - - -namespace App\Policies; - -use Illuminate\Auth\Access\HandlesAuthorization; -use MoonShine\Models\MoonshineUser; -use App\Models\Post; - -class PostPolicy -{ - use HandlesAuthorization; - - public function viewAny(MoonshineUser $user) - { - // - } - - public function view(MoonshineUser $user, Post $model) - { - // - } - - public function create(MoonshineUser $user) - { - // - } - - public function update(MoonshineUser $user, Post $model) - { - // - } - - public function delete(MoonshineUser $user, Post $model) - { - // - } - - public function massDelete(MoonshineUser $user) - { - // - } - - public function restore(MoonshineUser $user, Post $model) - { - // - } - - public function forceDelete(MoonshineUser $user, Post $model) - { - // - } -} - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; - -class PostResource extends Resource -{ -//... - -public static bool $withPolicy = true; // [tl! focus] - -//... -} - - - diff --git a/resources/views/pages/en/advanced/dashboard.blade.php b/resources/views/pages/en/advanced/dashboard.blade.php deleted file mode 100644 index 2d853b1f..00000000 --- a/resources/views/pages/en/advanced/dashboard.blade.php +++ /dev/null @@ -1,115 +0,0 @@ - - -Basics - - The home page of the admin panel can be customized through the class app/MoonShine/Dashboard.php. - - - - Currently you can display metrics in the control panel - - - - The required metrics are registered in the blocks method and placed in the DashboardBlock wrapper for a convenient arrangement of the panel - - - - Layout (columnSpan) - decorating methods are also available for the elements - - - -namespace App\MoonShine; - -use App\Models\User; -use MoonShine\Dashboard\DashboardBlock; -use MoonShine\Dashboard\DashboardScreen; -use MoonShine\Metrics\ValueMetric; - -class Dashboard extends DashboardScreen -{ - public function blocks(): array - { - return [ - DashboardBlock::make([ - ValueMetric::make('Users') - ->value(User::query()->count()) - ]) - ]; - } -} - - - - - -Block with resource records - - - Sometimes it is extremely convenient to add a table with records from a resource to the main page for quick access. - To do this, use ResourcePreview - - - -namespace App\MoonShine; - -use App\Models\Article; -use MoonShine\Dashboard\DashboardBlock; -use MoonShine\Dashboard\DashboardScreen; -use MoonShine\Dashboard\ResourcePreview; - -class Dashboard extends DashboardScreen -{ - public function blocks(): array - { - return [ - DashboardBlock::make([ - ResourcePreview::make( - new ArticleResource(), // Mandatory parameter with MoonShine resource - 'Latest articles' // Optional - block header - Article::query()->where('active', true)->limit(2) // Optional QueryBuilder - ) - ]) - ]; - } -} - - - - - -Text block - - - To display plain text - - - -namespace App\MoonShine; - -use MoonShine\Dashboard\DashboardBlock; -use MoonShine\Dashboard\DashboardScreen;Welcome -use MoonShine\Dashboard\TextBlock; - -class Dashboard extends DashboardScreen -{ - public function blocks(): array - { - return [ - DashboardBlock::make([ - TextBlock::make( - 'Welcome', - view('welcome')->render() - ) - ]) - ]; - } -} - - diff --git a/resources/views/pages/en/advanced/development.blade.php b/resources/views/pages/en/advanced/development.blade.php deleted file mode 100644 index deee2407..00000000 --- a/resources/views/pages/en/advanced/development.blade.php +++ /dev/null @@ -1,122 +0,0 @@ - - - - MoonShine provides opportunities to extend the basic functionality and write your own packages that improve the features. - In this section, we will provide a list of such packages, an example with creating your own field and action. - - - - If you can't figure out how your MoonShine package should look like, we've prepared a ready-made template for you. - - Package template - - - - - The following entities could be extended: - - - -Custom field - - - Here is a small example of creating your own field! - It is a visual editor based on the CKEditor js plugin - - - - First, let's create a class that extends the MoonShine fields - - - -namespace App\MoonShine\Fields; - -use MoonShine\Fields\Field; - -final class CKEditor extends Field -{ - protected static string $view = 'fields.ckeditor'; - - protected array $assets = [ - 'https://cdn.ckeditor.com/ckeditor5/35.3.0/super-build/ckeditor.js' - ]; -} - - - - Then, create a view with implementation - - - - - - That's it! - - -Custom Action - - - MoonShine comes with several built-in actions such as - Export и - Import - but you can also create your own custom actions. - - - - To do this, you need to create a class that extends the MoonShine action class and define the handle method. - - - -namespace App\MoonShine\Actions; - -use MoonShine\Actions\Action; - -class CustomAction extends Action -{ - public function handle(): mixed - { - // Code with the handler logic - } -} - - - - This is enough to display our custom action on the resource page. - However, let's take a look at what else we can define in our action class. - - - -class CustomAction extends Action -{ - protected static string $view = 'view.custom'; // Custom blade mapping - - protected bool $withQuery = true; // Whether to pass the entire current getQuery to the action's URL. - - protected bool $inDropdown = false; // Display the button outside the dropdown menu. - - protected ?string $icon = 'heroicons.outline.table-cells'; // Icon for the button. -} - - - - Next, register the action in the actions method of the resource where you want to display it. - - - -public function actions(): array -{ - return [ - CustomAction::make('Custom Action'), - ]; -} - - - - That's it! - - diff --git a/resources/views/pages/en/advanced/events.blade.php b/resources/views/pages/en/advanced/events.blade.php deleted file mode 100644 index dff96205..00000000 --- a/resources/views/pages/en/advanced/events.blade.php +++ /dev/null @@ -1,57 +0,0 @@ - - - - Since MoonShine is based on standard eloquent methods for adding, editing and deleting, you can easily use standard Laravel events: - - -https://laravel.com/docs/9.x/eloquent#events - - - - But sometimes you need to snap exactly to the events within the MoonShine resources! - To do this, you need to implement the events you want in the resource - - - -protected function beforeCreating(Model $item) -{ - // Event before adding an entry -} - -protected function afterCreated(Model $item) -{ - // Event after adding a record -} - -protected function beforeUpdating(Model $item) -{ - // Event before record update -} - -protected function afterUpdated(Model $item) -{ - // Event after record update -} - -protected function beforeDeleting(Model $item) -{ - // Event before record deletion -} - -protected function afterDeleted(Model $item) -{ - // Event after record deletion -} - -protected function beforeMassDeleting(array $ids) -{ - // Event before mass deletion of records -} - -protected function afterMassDeleted(array $ids) -{ - // Event after mass deletion of records -} - - - diff --git a/resources/views/pages/en/advanced/localization.blade.php b/resources/views/pages/en/advanced/localization.blade.php deleted file mode 100644 index 1cd127cb..00000000 --- a/resources/views/pages/en/advanced/localization.blade.php +++ /dev/null @@ -1,8 +0,0 @@ - - - - After installing MoonShine you will see a folder with MoonShine translations in the translations folder. - Here you can add new languages or modify the current ones. - - - diff --git a/resources/views/pages/en/advanced/menu.blade.php b/resources/views/pages/en/advanced/menu.blade.php deleted file mode 100644 index 5abb0970..00000000 --- a/resources/views/pages/en/advanced/menu.blade.php +++ /dev/null @@ -1,252 +0,0 @@ - - -Registration - - - We have already figured out how to register sections of the admin panel - to make them appear in the menu - - - -namespace App\Providers; - -use Illuminate\Support\ServiceProvider; -use MoonShine\Menu\MenuItem; // [tl! focus] -use MoonShine\MoonShine; // [tl! focus] -use MoonShine\Resources\MoonShineUserResource; -use MoonShine\Resources\MoonShineUserRoleResource; - -class MoonShineServiceProvider extends ServiceProvider -{ - //... - - public function boot() - { - app(MoonShine::class)->menu([ // [tl! focus:start] - MenuItem::make('Admins', new MoonShineUserResource()), - MenuItem::make('Roles', new MoonShineUserRoleResource()), - ]); // [tl! focus:end] - } -} - - - - But to make our interface convenient we can also group menu items - - - -namespace App\Providers; - -use Illuminate\Support\ServiceProvider; -use MoonShine\Menu\MenuItem; -use MoonShine\Menu\MenuGroup; // [tl! focus] -use MoonShine\MoonShine; -use MoonShine\Resources\MoonShineUserResource; -use MoonShine\Resources\MoonShineUserRoleResource; - -class MoonShineServiceProvider extends ServiceProvider -{ - //... - - public function boot() - { - app(MoonShine::class)->menu([ - MenuGroup::make('System', [ // [tl! focus] - MenuItem::make('Admins', new MoonShineUserResource()), - MenuItem::make('Roles', new MoonShineUserRoleResource()), - ]) // [tl! focus] - ]); - } -} - - - - You just need to add the resources as a second parameter to the MoonShine\Menu\MenuGroup class. - And the first parameter is the name of the group! - - - - - -Condition-based display - - - Displays menu based on the condition - - - -//... -app(MoonShine::class)->menu([ - MenuGroup::make('System', [ - MenuItem::make('Admins', new MoonShineUserResource()), - MenuItem::make('Roles', new MoonShineUserRoleResource()), - ])->canSee(function(Request $request) { // [tl! focus:start] - return $request->user('moonshine')?->id === 1; - }) // [tl! focus:end] -]); -//... - - -External link - - - Adding a custom link - - - -//... -app(MoonShine::class)->menu([ - MenuItem::make('Документация Laravel', 'https://laravel.com') // [tl! focus] -]); -//... - - - - Links can be passed through a function - - - -//... -app(MoonShine::class)->menu([ - MenuItem::make('Admins', function () { // [tl! focus:start] - return (new MoonShineUserResource())->route('index'); - }), - MenuItem::make('Home', fn() => route('home')) // [tl! focus:end] -]); -//... - - -Icon - - - You can also change the icon of the menu item - - - -//... -app(MoonShine::class)->menu([ - MenuGroup::make('Система', [ // [tl! focus:start] - MenuItem::make('Admins', new MoonShineUserResource())->icon('heroicons.hashtag'), - MenuItem::make('Roles', new MoonShineUserRoleResource())->icon('heroicons.hashtag'), - ])->icon('app') // [tl! focus:end] - // or - MenuGroup::make('Blog', [ // [tl! focus:start] - MenuItem::make('Comments', new CommentResource(), 'heroicons.chat-bubble-left') - ], 'heroicons.newspaper') // [tl! focus:end] -]); -//... - - - - For more information, see Icons - - -Tag - - - You can add a counter to the menu item - - - -//... -app(MoonShine::class)->menu([ - MenuItem::make('Comments', new CommentResource()) - ->badge(fn() => Comment::query()->count()), // [tl! focus] -]); -//... - - - - - -Translation - - - To translate menu items, you need to add the translation key as the name - and add the translatable() method - - - -//... -app(MoonShine::class)->menu([ - MenuItem::make('menu.Comments', new CommentResource()) - ->translatable() // [tl! focus] - // or - MenuItem::make('Comments', new CommentResource()) - ->translatable('menu') // [tl! focus] -]); -//... - - - -// lang/ru/menu.php - -return [ - 'Comments' => 'Комментарии', -]; - - - - To translate menu labels, you can use Laravel's translation tools - - - -//... -app(MoonShine::class)->menu([ - MenuItem::make('Comments', new CommentResource()) - ->badge(fn() => __('menu.badge.new')) // [tl! focus] -]); -//... - - -Divider - - - Menu items can be visually separated using MenuDivider - - - -use MoonShine\Menu\MenuDivider; // [tl! focus] - -//... -app(MoonShine::class)->menu([ - MenuItem::make('Categories', new CategoryResource()), - MenuDivider::make(), // [tl! focus] - MenuItem::make('Articles', new ArticleResource()), -]); -//... - - - - - - - You can use text as a separator, for this you need to pass it to the make() method - - - -use MoonShine\Menu\MenuDivider; // [tl! focus] - -//... -app(MoonShine::class)->menu([ - MenuItem::make('Categories', new CategoryResource()), - MenuDivider::make('Divider'), // [tl! focus] - MenuItem::make('Articles', new ArticleResource()), -]); -//... - - - - - - diff --git a/resources/views/pages/en/advanced/notifications.blade.php b/resources/views/pages/en/advanced/notifications.blade.php deleted file mode 100644 index 400286b1..00000000 --- a/resources/views/pages/en/advanced/notifications.blade.php +++ /dev/null @@ -1,25 +0,0 @@ - - - - If you need to add notifications to the MoonShine notification center, - you can use the class: MoonShine\Notifications\MoonShineNotification - - - -use MoonShine\Notifications\MoonShineNotification; - -MoonShineNotification::send( - message: 'Notification message', - // Optional button - button: ['link' => 'https://moonshine.cutcode.dev', 'label' => 'Click me'], - // Optional id administrators (by default for everyone) - ids: [1,2,3], - // Optional icon color (purple, pink, blue, green, yellow, red, gray) - color: 'green' -); - - - - - - diff --git a/resources/views/pages/en/advanced/pages.blade.php b/resources/views/pages/en/advanced/pages.blade.php deleted file mode 100644 index 02712e12..00000000 --- a/resources/views/pages/en/advanced/pages.blade.php +++ /dev/null @@ -1,150 +0,0 @@ - - -Basics - - - You can create your own blank pages based on the blade view - and UI components, - style in your own way, as well as organize some kind of logic. - - - -use Illuminate\Support\ServiceProvider; -use MoonShine\Menu\MenuItem; -use MoonShine\MoonShine; -use MoonShine\Resources\CustomPage; // [tl! focus] - -class MoonShineServiceProvider extends ServiceProvider -{ - public function boot(): void - { - app(MoonShine::class)->menu([ - MenuItem::make( - 'Page title', - CustomPage::make('Page title', 'slug', 'view', fn() => []) // [tl! focus] - ) - ]); - } -} - - - - The first argument - page title. - - - - The second argument - page slug to generate url. - - - - The third argument - your custom blade view, which could be found in the resources/views. - - - - The fourth argument - the data required for view. - - - - You can use blade components which have a handler class to add your own logic. - - -Without title - - - Sometimes it is not required to display the title on a custom page, so it can be hidden using the withoutTitle method. - - - -use Illuminate\Support\ServiceProvider; -use MoonShine\Menu\MenuItem; -use MoonShine\MoonShine; -use MoonShine\Resources\CustomPage; - -class MoonShineServiceProvider extends ServiceProvider -{ - public function boot(): void - { - app(MoonShine::class)->menu([ - MenuItem::make( - 'Page title', - CustomPage::make('Page title', 'slug', 'view', fn() => []) - ->withoutTitle() // [tl! focus] - ) - ]); - } -} - - -Layout - - - You can use custom layout, for this you need to specify the path to it in the corresponding method. - - - -use Illuminate\Support\ServiceProvider; -use MoonShine\Menu\MenuItem; -use MoonShine\MoonShine; -use MoonShine\Resources\CustomPage; - -class MoonShineServiceProvider extends ServiceProvider -{ - public function boot(): void - { - app(MoonShine::class)->menu([ - MenuItem::make( - 'Page title', - CustomPage::make('Page title', 'slug', 'view', fn() => []) - ->layout('path') // [tl! focus] - ) - ]); - } -} - -] -class CustomPage - - - Pages can be created through a class, just run the command: - - - - php artisan moonshine:page ExamplePage - - - - As a result, a ExamplePage class will be created, which will be the basis of the custom page. - It is located by default in the app/MoonShine/Pages directory. - - -When executing the command, you can immediately set an alias, title and blade view for your page. - - - php artisan moonshine:page ExamplePage --alias="example" --title="Example Page" --view="pages.example" - - -After creating a page, it can be added to the menu. - - -use Illuminate\Support\ServiceProvider; -use MoonShine\Pages\ExamplePage; // [tl! focus] - -class MoonShineServiceProvider extends ServiceProvider -{ - public function boot(): void - { - app(MoonShine::class)->menu([ - MenuItem::make('Example', new ExamplePage()) // [tl! focus] - ]); - } -} - - - diff --git a/resources/views/pages/en/advanced/routes.blade.php b/resources/views/pages/en/advanced/routes.blade.php deleted file mode 100644 index 348d4ffa..00000000 --- a/resources/views/pages/en/advanced/routes.blade.php +++ /dev/null @@ -1,68 +0,0 @@ - - -Resource routes - - - In MoonShine, the resource has many routes registered for various actions: - - - -$this->route('index'); // GET|HEAD - list of items -$this->route('create'); // GET|HEAD - create a new item -$this->route('store'); // POST - save a new item -$this->route('edit', $resourceItem); // GET|HEAD - edit an item -$this->route('update', $resourceItem); // PUT|PATCH - save an item -$this->route('destroy', $resourceItem); // DELETE - delete an item -$this->route('show', $resourceItem); // GET|HEAD - view an item -$this->route('query-tag', $queryTag); // GET|HEAD - filtered list of items by query filter / tag -$this->route('update-column', $resourceItem); // PUT - save an item`s field - - -Custom routes - - - Through the resolveRoutes() method, you can add or override default routes. - - - -namespace App\MoonShine\Resources; - -use App\Models\Post; -use MoonShine\Resources\Resource; - -class PostResource extends Resource -{ - public static string $model = Post::class; - - // ... - - public function resolveRoutes(): void // [tl! focus:start] - { - parent::resolveRoutes(); - - Route::prefix('resource')->group(function (): void { - Route::get("{$this->uriKey()}/restore/{resourceItem}", function (Post $item) { - $item->restore(); - - return redirect()->back(); - }); - }); - } // [tl! focus:end] - - // ... -} - - - - To access a route outside of a resource, use (new Resource())->route('index'). - - - diff --git a/resources/views/pages/en/advanced/socialite.blade.php b/resources/views/pages/en/advanced/socialite.blade.php deleted file mode 100644 index 1f7167d7..00000000 --- a/resources/views/pages/en/advanced/socialite.blade.php +++ /dev/null @@ -1,36 +0,0 @@ - - - - For convenience, you can link the account to social networks and simplify the authentication process - - - - The process is based on a Laravel package - Socialite - - -Socialite - - - Make sure you have it installed and configured - - - - Next, in the moonshine config config/moonshine.php install the available drivers (you should already have them set up) and the image for the button - - - -return [ - // - 'socialite' => [ - 'github' => '/images/github.png', - 'facebook' => '/images/facebook.svg' - ] - // -]; - - - - If you use your model for authentication, then you need to add the trait HasMoonShineSocialite to it - - - diff --git a/resources/views/pages/en/components/alert.blade.php b/resources/views/pages/en/components/alert.blade.php deleted file mode 100644 index c5776a2f..00000000 --- a/resources/views/pages/en/components/alert.blade.php +++ /dev/null @@ -1,58 +0,0 @@ - - -Basics - - - If you need a notification on the page, - you can use the moonshine::alert component - - - - -@include("examples/components/alert") - -Notification type - - - You can change the notification type by specifying the component type - - -@include('pages.en.ui.shared.type') - - - -@include("examples/components/alert-type") - -Icon - - - The notification has the ability to change the icon, for this you need to pass it to the icon parameter - - - - -@include("examples/components/alert-icon") - - - For more information, see Icons - - -Removing notifications - - - To remove notifications after some time, you must pass the parameter removable - with the value TRUE - - - - -@include("examples/components/alert-removable") - - diff --git a/resources/views/pages/en/components/badge.blade.php b/resources/views/pages/en/components/badge.blade.php deleted file mode 100644 index 034974d8..00000000 --- a/resources/views/pages/en/components/badge.blade.php +++ /dev/null @@ -1,22 +0,0 @@ - - - - If you need to place a badge on a custom page, - you can use the moonshine::badge component - - - - The following badges are available: - - - - - - - - @include("examples/components/badge") - - - - - diff --git a/resources/views/pages/en/components/boolean.blade.php b/resources/views/pages/en/components/boolean.blade.php deleted file mode 100644 index fc1cb2aa..00000000 --- a/resources/views/pages/en/components/boolean.blade.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - A simple moonshine::boolean component allows you to create an indicator TRUE / FALSE - - - - - - - - @include("examples/components/boolean") - - - - - - - - - - @include("examples/components/boolean-false") - - - - - diff --git a/resources/views/pages/en/components/box.blade.php b/resources/views/pages/en/components/box.blade.php deleted file mode 100644 index 16c70d44..00000000 --- a/resources/views/pages/en/components/box.blade.php +++ /dev/null @@ -1,50 +0,0 @@ - -Basics - - - To highlight content, you can use the moonshine::box component - - - - - - - @include("examples/components/box") - - - -Title - - - The title parameter sets the title of the block - - - - - - - @include("examples/components/box-title") - - - -Dark style - - - You can set a dark style for a block by specifying the dark parameter with the value TRUE - - - - - - - @include("examples/components/box-dark") - - - - diff --git a/resources/views/pages/en/components/breadcrumbs.blade.php b/resources/views/pages/en/components/breadcrumbs.blade.php deleted file mode 100644 index a39f5f98..00000000 --- a/resources/views/pages/en/components/breadcrumbs.blade.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - The moonshine::breadcrumbs component is used to create breadcrumbs - - - - - - - - @include("examples/components/breadcrumbs") - - - - - diff --git a/resources/views/pages/en/components/card.blade.php b/resources/views/pages/en/components/card.blade.php deleted file mode 100644 index 51e3ba68..00000000 --- a/resources/views/pages/en/components/card.blade.php +++ /dev/null @@ -1,40 +0,0 @@ - - -Basics - - - To create cards in the admin panel, use the moonshine::card component - - - - - - -
- @include("examples/components/card") -
-
-
- -Overlay view - - - The overlay view is available for the card - - - - - - -
- @include("examples/components/card-overlay") -
-
-
- -
diff --git a/resources/views/pages/en/components/collapse.blade.php b/resources/views/pages/en/components/collapse.blade.php deleted file mode 100644 index 64ef72f8..00000000 --- a/resources/views/pages/en/components/collapse.blade.php +++ /dev/null @@ -1,57 +0,0 @@ - - -Basics - - - The moonshine::collapse component allows you to collapse content - - - - - - - - @include("examples/components/collapse") - - - - -Show expanded - - - If the show parameter is set to TRUE, then by default the block will be displayed expanded - - - - - - - - @include("examples/components/collapse-show") - - - - -Save state - - - If the persist parameter is set to TRUE, then the state of the block will be saved - - - - - - - - @include("examples/components/collapse-persist") - - - - - diff --git a/resources/views/pages/en/components/divider.blade.php b/resources/views/pages/en/components/divider.blade.php deleted file mode 100644 index df427e91..00000000 --- a/resources/views/pages/en/components/divider.blade.php +++ /dev/null @@ -1,54 +0,0 @@ - - -Basics - - - The moonshine::divider component allows you to create a stylized content divider - - - - - - - - @include("examples/components/divider") - - - - -Text divider - - - You can use text as a separator, for this you need to specify the text in the label parameter - - - - - - - - @include("examples/components/divider-label") - - - - - - The centered parameter allows you to center the text - - - - - - - - @include("examples/components/divider-label-center") - - - - - diff --git a/resources/views/pages/en/components/dropdown.blade.php b/resources/views/pages/en/components/dropdown.blade.php deleted file mode 100644 index 14ff98cb..00000000 --- a/resources/views/pages/en/components/dropdown.blade.php +++ /dev/null @@ -1,46 +0,0 @@ - -Basics - - - Using the moonshine::dropdown component, you can create dropdown blocks - - - - -@include("examples/components/dropdown") - -Title - - - -@include("examples/components/dropdown-title") - -Footer - - - -@include("examples/components/dropdown-footer") - -Placement - -@include('pages.en.ui.shared.placement') - - - -@include("examples/components/dropdown-placement") - - - - For additional location options, see the official documentation - tippy.js - - - - diff --git a/resources/views/pages/en/components/files.blade.php b/resources/views/pages/en/components/files.blade.php deleted file mode 100644 index a7edbc9d..00000000 --- a/resources/views/pages/en/components/files.blade.php +++ /dev/null @@ -1,41 +0,0 @@ - - -Basics - - - To display a list of files, you can use the moonshine::files component. - - - - - - - - @include("examples/components/files") - - - - -No download - - - To disable the ability to download files, the component must - pass the download parameter with the value FALSE. - - - - - - - - @include("examples/components/files-no-download") - - - - - diff --git a/resources/views/pages/en/components/form.blade.php b/resources/views/pages/en/components/form.blade.php deleted file mode 100644 index 1b3d2ae3..00000000 --- a/resources/views/pages/en/components/form.blade.php +++ /dev/null @@ -1,269 +0,0 @@ - - - - Form components are a wrapper for similar html elements, they can be passed all the necessary attributes. - - -Label - - - - - - - @include("examples/components/form/label") - - - - - - If the field is required, then you can pass the required attribute to style the element - - - - - - - - @include("examples/components/form/label-required") - - - - -Input - - - - - - - @include("examples/components/form/input") - - - - -Checkbox - - - - - - - @include("examples/components/form/checkbox") - - - - -Radio - - - - - - - @include("examples/components/form/radio") - - - - -Color select - - - - - - - @include("examples/components/form/color") - - - - -Button - - - - - - - @include("examples/components/form/button") - - - - -Hint - - - - - - - @include("examples/components/form/hint") - - - - -File - - - - - - - @include("examples/components/form/file") - - - - - - Using the component, you can display previously uploaded files. - - - - - - - - @include("examples/components/form/file-files") - - - - - - - Additionally, hidden fields will be created with the values passed in the files[] array. - - - - - You can pass additional parameters to the component: - - - download - download downloaded file
- removable - removal from the list of downloaded files
- imageable - display image previews -
- - - - - - - @include("examples/components/form/file-full") - - - - -Range - - - - - - - @include("examples/components/form/range") - - - - -Select - - - - - or via slot:options - - - - - - - - @include("examples/components/form/select") - - - - - - You can combine values into groups. - - - - - - - - @include("examples/components/form/select-groups") - - - - - - You can pass additional parameters to the component: - - - searchable - search by values
- nullable - can be NULL -
- - - - - - - @include("examples/components/form/select-full") - - - - - - For asynchronous loading of values, you need to specify the url in the asyncRoute attribute, - which will return data in json format - - - - -Switcher - - - - - - - @include("examples/components/form/switcher") - - - - - - onValue - value when active
- offValue - value when inactive -
- -Textarea - - - - - - - @include("examples/components/form/textarea") - - - - -
diff --git a/resources/views/pages/en/components/grid.blade.php b/resources/views/pages/en/components/grid.blade.php deleted file mode 100644 index 7ced2e4c..00000000 --- a/resources/views/pages/en/components/grid.blade.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - You can use moonshine::grid to arrange elements on the page - and moonshine::column components. - - - - The grid consists of 12 columns. - - - - - - - - @include("examples/components/grid") - - - - - - adaptiveColSpan - the number of columns that occupy the block when the screen size is up to 1280 pixels.
- colSpan - the number of columns that occupy a block with a screen size of 1280px. -
- -
diff --git a/resources/views/pages/en/components/icon.blade.php b/resources/views/pages/en/components/icon.blade.php deleted file mode 100644 index aaa4b6ff..00000000 --- a/resources/views/pages/en/components/icon.blade.php +++ /dev/null @@ -1,77 +0,0 @@ - - -Basics - - - To insert icons into your custom elements, - you can use the moonshine::icon component - - - - - - @include("examples/components/icon") - - - - All available icons - - -Size - - - Using the size parameter, you can set the size of the icon. - - - - - - @include("examples/components/icon-size") - - - - The value of the size parameter corresponds to the sizes in tailwindcss - - -Color - - - Using the color parameter, you can set the color of the icon - - - - - - @include("examples/components/icon-color") - - - - Several colors are available by default, but you can expand them using your own - color classes tailwindcss - - -Customization - - - An arbitrary style for icons can be set via the class parameter - - - - - - @include("examples/components/icon-class") - - - - Build MoonShine contains a limited list of tailwindcss classes, - use custom styles - - - diff --git a/resources/views/pages/en/components/index.blade.php b/resources/views/pages/en/components/index.blade.php deleted file mode 100644 index 26fa1212..00000000 --- a/resources/views/pages/en/components/index.blade.php +++ /dev/null @@ -1,15 +0,0 @@ - - - - A lot of UI components are used to create the MoonShine admin panel interface. - - - - You can use these components to build your own templates, custom fields, filters, decorations or pages. - - - - The use of components speeds up development and allows you to maintain a single style of the project. - - - diff --git a/resources/views/pages/en/components/link.blade.php b/resources/views/pages/en/components/link.blade.php deleted file mode 100644 index 5817019a..00000000 --- a/resources/views/pages/en/components/link.blade.php +++ /dev/null @@ -1,58 +0,0 @@ - - -Basics - - - To create a stylized link, you can use the moonshine::link-button - or moonshine::link-native components - - - - - - - - @include("examples/components/link") - - - - -Filled - - - The filled parameter is responsible for filling - - - - - - - - @include("examples/components/link-filled") - - - - -Icon - - - You can pass the parameter icon - - - - - - - - @include("examples/components/link-icon") - - - - - diff --git a/resources/views/pages/en/components/loader.blade.php b/resources/views/pages/en/components/loader.blade.php deleted file mode 100644 index 26d856f8..00000000 --- a/resources/views/pages/en/components/loader.blade.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - The moonshine::loader component allows you to create a stylized loading indicator - - - - - - - - @include("examples/components/loader") - - - - - diff --git a/resources/views/pages/en/components/modal.blade.php b/resources/views/pages/en/components/modal.blade.php deleted file mode 100644 index 948c19d2..00000000 --- a/resources/views/pages/en/components/modal.blade.php +++ /dev/null @@ -1,28 +0,0 @@ - - -Basics - - - The moonshine::modal component is used to create modal windows. - - - - -@include("examples/components/modal") - -Wide - - - The wide parameter allows modal windows to take up the entire width. - - - - -@include("examples/components/modal-wide") - - diff --git a/resources/views/pages/en/components/offcanvas.blade.php b/resources/views/pages/en/components/offcanvas.blade.php deleted file mode 100644 index 044a0658..00000000 --- a/resources/views/pages/en/components/offcanvas.blade.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - The moonshine::offcanvas component allows you to create sidebars. - - - - - - - - @include("examples/components/offcanvas") - - - - - diff --git a/resources/views/pages/en/components/paginations.blade.php b/resources/views/pages/en/components/paginations.blade.php deleted file mode 100644 index 566b6fd8..00000000 --- a/resources/views/pages/en/components/paginations.blade.php +++ /dev/null @@ -1,41 +0,0 @@ - - -Basics - - - The moonshine::pagination component allows you to create a stylized page-by-page pagination.
- To do this, add a component to the pagination blade view. -
- - - - - - - @include("examples/components/pagination-mock") - - - - -Simple pagination - - - The simple parameter with the value TRUE allows you to display the pagination in a simplified way. - - - - - - - - @include("examples/components/pagination-mock", ['simple' => true]) - - - - -
diff --git a/resources/views/pages/en/components/popover.blade.php b/resources/views/pages/en/components/popover.blade.php deleted file mode 100644 index 0c1f77db..00000000 --- a/resources/views/pages/en/components/popover.blade.php +++ /dev/null @@ -1,37 +0,0 @@ - -Basics - - - Using the moonshine::popover component, you can create a popup window - - -@include('pages.ru.ui.shared.placement') - - - - - - - @include("examples/components/popover") - - - - -Without use component - - - - - - - @include("examples/components/popover-without") - - - - - diff --git a/resources/views/pages/en/components/progress_bar.blade.php b/resources/views/pages/en/components/progress_bar.blade.php deleted file mode 100644 index f1712f78..00000000 --- a/resources/views/pages/en/components/progress_bar.blade.php +++ /dev/null @@ -1,44 +0,0 @@ - - -Basics - - - The moonshine::progress-bar component allows you to create a progress bar - - -@include('pages.en.ui.shared.colors') - - - - - - - @include("examples/components/progress_bar") - - - - -Radial - - - - - To create a radial progress indicator, you need to pass the radial parameter to the component with the value TRUE - - -@include('pages.en.ui.shared.sizes') - - - - - @include("examples/components/progress_bar-radial") - - - - - diff --git a/resources/views/pages/en/components/rating.blade.php b/resources/views/pages/en/components/rating.blade.php deleted file mode 100644 index b2af1e2c..00000000 --- a/resources/views/pages/en/components/rating.blade.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - The moonshine::rating component allows you to create stylized ratings - - - - - - - - @include("examples/components/rating") - - - - - diff --git a/resources/views/pages/en/components/shared/colors.blade.php b/resources/views/pages/en/components/shared/colors.blade.php deleted file mode 100644 index 16ae6346..00000000 --- a/resources/views/pages/en/components/shared/colors.blade.php +++ /dev/null @@ -1,13 +0,0 @@ - - Available colors: - - - - Purple - Pink - Blue - Green - Yellow - Red - Gray - diff --git a/resources/views/pages/en/components/shared/placement.blade.php b/resources/views/pages/en/components/shared/placement.blade.php deleted file mode 100644 index a2f91c4a..00000000 --- a/resources/views/pages/en/components/shared/placement.blade.php +++ /dev/null @@ -1,10 +0,0 @@ - - Available placement: - - - - bottom - top - left - right - diff --git a/resources/views/pages/en/components/shared/sizes.blade.php b/resources/views/pages/en/components/shared/sizes.blade.php deleted file mode 100644 index 38a524eb..00000000 --- a/resources/views/pages/en/components/shared/sizes.blade.php +++ /dev/null @@ -1,10 +0,0 @@ - - Available sizes: - - - - sm - md - lg - xl - diff --git a/resources/views/pages/en/components/shared/type.blade.php b/resources/views/pages/en/components/shared/type.blade.php deleted file mode 100644 index b23f124f..00000000 --- a/resources/views/pages/en/components/shared/type.blade.php +++ /dev/null @@ -1,10 +0,0 @@ - - Available types: - - - - success - info - warning - error - diff --git a/resources/views/pages/en/components/spinner.blade.php b/resources/views/pages/en/components/spinner.blade.php deleted file mode 100644 index 3210707b..00000000 --- a/resources/views/pages/en/components/spinner.blade.php +++ /dev/null @@ -1,67 +0,0 @@ - -Basics - - - Using the moonshine::spinner component, you can create loading indicators - - - - - - - - @include("examples/components/spinner") - - - - -Size - -@include('pages.en.ui.shared.sizes') - - - - - - - @include("examples/components/spinner-size") - - - - -Color - -@include('pages.en.ui.shared.colors') - - - - - - - @include("examples/components/spinner-color") - - - - -Position - - - The absolute="true" parameter sets the absolute position of the loading indicator - - - - - - The fixed="true" parameter specifies a fixed positioning of the loading indicator - - - - - diff --git a/resources/views/pages/en/components/table.blade.php b/resources/views/pages/en/components/table.blade.php deleted file mode 100644 index 940f8fbb..00000000 --- a/resources/views/pages/en/components/table.blade.php +++ /dev/null @@ -1,103 +0,0 @@ - - -Basics - - - Styled tables can be created using the moonshine::table component - - - - - - - - @include("examples/components/table") - - - - -Crud mode - - - The crudMode parameter allows you to additionally style tables - - - - - - - @include("examples/components/table-crud") - - - -Not found - - - The notfound parameter allows you to display a message if there are no table elements - - - - - - - - @include("examples/components/table-notfound") - - - - -Slots - - - The table can be formed using slots - - - - - - - - @include("examples/components/table-slots") - - - - -Styles - - - To style the table, there are predefined classes that can be used for tr / td - - - - Available classes: - - - - bgc-purple - bgc-pink - bgc-blue - bgc-green - bgc-yellow - bgc-red - bgc-gray - - - - - - - - @include("examples/components/table-slots-color") - - - - - diff --git a/resources/views/pages/en/components/tabs.blade.php b/resources/views/pages/en/components/tabs.blade.php deleted file mode 100644 index dbd63d88..00000000 --- a/resources/views/pages/en/components/tabs.blade.php +++ /dev/null @@ -1,40 +0,0 @@ - - -Basics - - - To create tabs, you can use the moonshine::tabs component - - - - - - - - @include("examples/components/tabs") - - - - -Active tab - - - You can specify the default active tab by setting the activeTab. - - - - - - - - @include("examples/components/tabs-active") - - - - - diff --git a/resources/views/pages/en/components/thumbnail.blade.php b/resources/views/pages/en/components/thumbnail.blade.php deleted file mode 100644 index ae6a3443..00000000 --- a/resources/views/pages/en/components/thumbnail.blade.php +++ /dev/null @@ -1,46 +0,0 @@ - - -Basics - - - To create thumbnails, you can use the moonshine::thumbnails component - - - - - - - - @include("examples/components/thumbnails") - - - - - - You can also specify the attribute alt - - - - -Group of images - - - Component can be passed an array of images - - - - - - - - @include("examples/components/thumbnails-multiple") - - - - - diff --git a/resources/views/pages/en/components/title.blade.php b/resources/views/pages/en/components/title.blade.php deleted file mode 100644 index 5300ded3..00000000 --- a/resources/views/pages/en/components/title.blade.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - If you want to place a stylized title, you can use the moonshine::title component - - - - - - - - @include("examples/components/title") - - - - - diff --git a/resources/views/pages/en/components/toast.blade.php b/resources/views/pages/en/components/toast.blade.php deleted file mode 100644 index ec100899..00000000 --- a/resources/views/pages/en/components/toast.blade.php +++ /dev/null @@ -1,39 +0,0 @@ - -Basics - - - Using the moonshine::toast component, you can create notifications - - - - -@include('pages.en.ui.shared.type') - - - -
- @include("examples/components/toast-default") - @include("examples/components/toast-success") - @include("examples/components/toast-info") - @include("examples/components/toast-warning") - @include("examples/components/toast-error") -
- -Without use component - - - You can create a notification using the MoonShineUi::toast() method - - - -use MoonShine\MoonShineUI; - -MoonShineUi::toast('Toast content', 'error'); - - -
diff --git a/resources/views/pages/en/components/tooltip.blade.php b/resources/views/pages/en/components/tooltip.blade.php deleted file mode 100644 index 8effd619..00000000 --- a/resources/views/pages/en/components/tooltip.blade.php +++ /dev/null @@ -1,38 +0,0 @@ - - -Basics - - - Using the moonshine::tooltip component, you can create handy tooltips - - -@include('pages.ru.ui.shared.placement') - - - - - - - @include("examples/components/tooltip") - - - - -Without use component - - - - - - - @include("examples/components/tooltip-without") - - - - - diff --git a/resources/views/pages/en/concept.blade.php b/resources/views/pages/en/concept.blade.php deleted file mode 100644 index 444c0419..00000000 --- a/resources/views/pages/en/concept.blade.php +++ /dev/null @@ -1,31 +0,0 @@ - - - The idea of the Moonshine project is to create a versatile and customizable admin panel for Laravel projects. - Almost all serious projects require an admin panel, and it takes a lot of time to create it. - So I've got an idea to make my own admin panel, but it's a huge job - and in a few years I managed to create a working version for the most common tasks. However, there are some serious drawbacks. - - - - Recently I saw the initiative in my CutCode community for Laravel to create their own open-source project, - and I’ve decided this was the proper approach to make a good admin panel together - by joining resources for a common target. - - - - Everyone will benefit from the interaction - you will be able to use a quality product that will always evolve. - - - - An active and vibrant community is the heart of the project. Therefore, the most active users will be encouraged. - What kind of incentive? The very first idea about the incentive is to create a system of donations. - Donated money is distributed among the main participants of the developer team. - Project MoonShine participates in the "Free License Programs" support program provided by JetBrains - - active developers receive a license for products from JetBrains. - - - - My goal is to make the project a place where developers will want to come back. - We can make a functional and comfortable machine together only! Together we will do more than one at a time! - - diff --git a/resources/views/pages/en/configuration.blade.php b/resources/views/pages/en/configuration.blade.php deleted file mode 100644 index ec0a18e1..00000000 --- a/resources/views/pages/en/configuration.blade.php +++ /dev/null @@ -1,102 +0,0 @@ - - - -use MoonShine\Exceptions\MoonShineNotFoundException; -use MoonShine\Models\MoonshineUser; - -return [ - # The directory where the resources are located - 'dir' => 'app/MoonShine', - # If you change the directory, you must also change the namespace according to psr-4 - 'namespace' => 'App\MoonShine', - - # Admin panel header - 'title' => env('MOONSHINE_TITLE', 'MoonShine'), - # You can change the logo by specifying the path (example - /images/logo.svg) - 'logo' => env('MOONSHINE_LOGO', '/images/logo.svg'), - 'logo_small' => env('MOONSHINE_LOGO_SMALL', '/images/logo-icon.svg'), - - 'route' => [ - # Which url will be available for the control panel (as a rule admin) - # If the value is left empty, the panel will be accessible from / - 'prefix' => env('MOONSHINE_ROUTE_PREFIX', 'moonshine'), - # Starting route in admin panel - 'index_route' => env('MOONSHINE_INDEX_ROUTE', 'moonshine.index'), - # Groups of middlewares in the panel - 'middleware' => ['moonshine'], - # Slug of the url formation for custom pages - 'custom_page_slug' => 'custom_page', - # You can change 404 error exception (for ModelNotFound you need to implement it yourself) - 'notFoundHandler' => MoonShineNotFoundException::class - ], - - # If you want to replace MoonshineUser with your own model, you can disable default migrations - 'use_migrations' => true, - # On/Off notifications - 'use_notifications' => true, - - 'auth' => [ - # On/Off authentication. If false, the panel will be available to all - 'enable' => true, - # If you use your own guard, provider - 'guard' => 'moonshine', - 'guards' => [ - 'moonshine' => [ - 'driver' => 'session', - 'provider' => 'moonshine', - ], - ], - 'providers' => [ - 'moonshine' => [ - 'driver' => 'eloquent', - 'model' => MoonshineUser::class, - ], - ], - # Text under the sign in button. As an example, you can add a sign-in button - 'footer' => '' - ], - # Possible translations - 'locales' => [ - 'en', 'ru' - ], - # Additional middlewares - 'middlewares' => [], - 'tinymce' => [ - # File manager root, see the Fields section for details - 'file_manager' => false, // or 'laravel-filemanager' prefix for lfm - 'token' => env('MOONSHINE_TINYMCE_TOKEN', ''), - 'version' => env('MOONSHINE_TINYMCE_VERSION', '6') - ], - # Authenticate via social networks and socialite, list the drivers and specify the logo - 'socialite' => [ - // 'driver' => 'path_to_image_for_button' - ], - # Template customization - 'header' => null, // blade path - 'footer' => [ - 'copyright' => 'Made with ❤️ by CutCode', - 'nav' => [ - 'https://github.com/moonshine/moonshine/blob/1.x/LICENSE.md' => 'License', - 'https://moonshine.cutcode.dev' => 'Documentation', - 'https://github.com/moonshine/moonshine' => 'GitHub', - ], - ] -]; - - - - For basic use it is enough to edit the parameters below - - - -return [ - // .. - 'title' => env('MOONSHINE_TITLE', 'MoonShine'), // [tl! focus] - 'logo' => env('MOONSHINE_LOGO', ''), // [tl! focus] - - 'route' => [ - 'prefix' => env('MOONSHINE_ROUTE_PREFIX', 'moonshine'), // [tl! focus] - ], - // .. - - diff --git a/resources/views/pages/en/contribution.blade.php b/resources/views/pages/en/contribution.blade.php deleted file mode 100644 index 8fb42a67..00000000 --- a/resources/views/pages/en/contribution.blade.php +++ /dev/null @@ -1,162 +0,0 @@ - - -What can you do to help? - - - Our community needs active users. You can help in many ways - - - - -We are using a technology stack - - - -Where do we start? - - - The product is working already, fully functional and testable. - But working doesn't mean great, so the goal is to make the project better. - - -Pull requests - - - You can suggest new features or improvements to MoonShine! Bugs and errors - all this could be documented and sent for improvement. - I'm also glad to meet new open source project development specialists - - -Where shall we discuss development? - - - For active participants in the project created a separate chat in telegram. If you are ready to participate in the development, - then join - MoonShine. - - - -If you found a mistake - - - 1. You have enough experience to offer a solution. - I would be very happy to receive your PR with a description of the error and a way to fix it. -
- 2. If you don't know how to solve the problem, create GitHub issues, and we will fix the problem soon. - -
* It is important that your pr passed all the tests of the platform and had a detailed description, - so that all participants of the development process understand what exactly happened.
-
- -Main branch - - - At the moment, the main branch is 1.5.x - - -Coding style - - - MoonShine adheres to the PSR-12 standard and PSR-4 autoload standard. - - -Developer's guide - -1 Make project dir and clone demo project - - - git clone git@github.com:moonshine-software/demo-project.git . - - -2 Add packages directory and execute the command below - - - cd packages && git clone git@github.com:moonshine-software/moonshine.git && cd moonshine && composer install && npm install - - -3 Go back to the project directory and remove moonshine/moonshine dependency from the composer.json - - - "moonshine/moonshine": "^1.50", - - -3 Add MoonShine from the packages directory to autoload section in the composer.json - - -"autoload": { - "psr-4": { - "App\\": "app/", - "Database\\Factories\\": "database/factories/", - "Database\\Seeders\\": "database/seeders/", - "MoonShine\\": "packages/moonshine/src" - } -}, - - -4 Add MoonShineServiceProvider to config/app.php - - -use App\Providers\MoonShineServiceProvider; -// Import vendor provider -use MoonShine\Providers\MoonShineServiceProvider as MSProvider; - -// .. - -/* -* Package Service Providers... -*/ -// Add vendor provider -MSProvider::class, - -// .. - - -5 Create .env from .env.example (don't forget to create a database) and complete the install below - - -composer require lee-to/laravel-package-command && composer require rap2hpoutre/fast-excel && composer install && npm install - - - -php artisan key:generate -php artisan storage:link -php artisan migrate --seed -php artisan moonshine:user -php artisan serve - - -# Make something great - -How to make a pull request? - - -Any questions? - - - My name is Danil! Email me at thecutcode@gmail.com - - -
diff --git a/resources/views/pages/en/decorations/block.blade.php b/resources/views/pages/en/decorations/block.blade.php deleted file mode 100644 index c55ea5a8..00000000 --- a/resources/views/pages/en/decorations/block.blade.php +++ /dev/null @@ -1,47 +0,0 @@ - - - - Substrate with header for form features - - - -use MoonShine\Decorations\Block; // [tl! focus] - -//... -public function fields(): array -{ - return [ - Block::make('Block title', [ // [tl! focus] - Text::make('Name', 'first_name'), - ]), // [tl! focus] - ]; -} -//... - - - - - - - If you don't need a header - - - -use MoonShine\Decorations\Block; // [tl! focus] - -//... -public function fields(): array -{ - return [ - Block::make([ // [tl! focus] - Text::make('Name', 'first_name'), - ]), // [tl! focus] - ]; -} -//... - - - - - - diff --git a/resources/views/pages/en/decorations/button.blade.php b/resources/views/pages/en/decorations/button.blade.php deleted file mode 100644 index 7be16367..00000000 --- a/resources/views/pages/en/decorations/button.blade.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - To add a button with a link to a form - - - -use MoonShine\Decorations\Button; - -//... -public function fields(): array -{ - return [ - Button::make( - 'Link to article', - $this->getItem() ? route('articles.show', $this->getItem()) : '/', - true - )->icon('clip'), - ]; -} -//... - - - - - - diff --git a/resources/views/pages/en/decorations/collapse.blade.php b/resources/views/pages/en/decorations/collapse.blade.php deleted file mode 100644 index eb3bb6a3..00000000 --- a/resources/views/pages/en/decorations/collapse.blade.php +++ /dev/null @@ -1,33 +0,0 @@ - - - - The Collapse decorator allows you to minimize fields and blocks while keeping their state - - - -use MoonShine\Decorations\Collapse; // [tl! focus] -use MoonShine\Decorations\Block; - -//... -public function fields(): array -{ - return [ - Block::make([ - Collapse::make('Title/Slug', [ // [tl! focus] - Text::make('Title') - ->fieldContainer(false), - - Text::make('Slug') - ->fieldContainer(false), - ]) // [tl! focus] - ->show() // Display expanded (optional) [tl! focus] - ]); - ]; -} -//... - - - - - - diff --git a/resources/views/pages/en/decorations/divider.blade.php b/resources/views/pages/en/decorations/divider.blade.php deleted file mode 100644 index 3c591871..00000000 --- a/resources/views/pages/en/decorations/divider.blade.php +++ /dev/null @@ -1,82 +0,0 @@ - - -Basics - - - To divide into areas, you can use the Divider decorator - - - -use MoonShine\Decorations\Divider; - -//... -public function fields(): array -{ - return [ - //... - Divider::make(), // [tl! focus] - //... - ]; -} -//... - - - - - -Label - - - You can use text as a separator, for this you need to pass it to the make() method - - - -use MoonShine\Decorations\Divider; - -//... -public function fields(): array -{ - return [ - //... - Divider::make('Divider'), // [tl! focus] - //... - ]; -} -//... - - - - - - - The centered() method allows you to center the text - - - -use MoonShine\Decorations\Divider; - -//... -public function fields(): array -{ - return [ - //... - Divider::make('Divider') - ->centered(), // [tl! focus] - //... - ]; -} -//... - - - - - - diff --git a/resources/views/pages/en/decorations/heading.blade.php b/resources/views/pages/en/decorations/heading.blade.php deleted file mode 100644 index 8e7734c3..00000000 --- a/resources/views/pages/en/decorations/heading.blade.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - You can add headers to separate areas of the form - - - -use MoonShine\Decorations\Heading; - -//... -public function fields(): array -{ - return [ - Heading::make('Title/Slug'), - - Text::make('Title') - ->fieldContainer(false), - Text::make('Slug') - ->fieldContainer(false), - ]; -} -//... - - - - - - diff --git a/resources/views/pages/en/decorations/index.blade.php b/resources/views/pages/en/decorations/index.blade.php deleted file mode 100644 index d1fb9a5e..00000000 --- a/resources/views/pages/en/decorations/index.blade.php +++ /dev/null @@ -1,10 +0,0 @@ - - - Decorations are set in the fields or filters resource methods. - - - - Improve the appearance of the fields and the quality of the interface - - - diff --git a/resources/views/pages/en/decorations/layout.blade.php b/resources/views/pages/en/decorations/layout.blade.php deleted file mode 100644 index f647d6cd..00000000 --- a/resources/views/pages/en/decorations/layout.blade.php +++ /dev/null @@ -1,94 +0,0 @@ - - - Sometimes it is necessary to divide the form into several blocks for convenience, by default they go under each other, but with the help of scenery Layout you can easily change the display - - -Flex - - - Changing the positioning of the fields in the line - - - -use MoonShine\Decorations\Flex; - - //... - public function fields(): array -{ - return [ - Flex::make([ - Text::make('Title'), - Text::make('Slug'), - ]) - // Additional options - ->withoutSpace() // Eliminate indentation - ->justifyAlign('start') // Based on tailwind classes justify-[param] - ->itemsAlign('start') // Based on tailwind classes items-[param] - ]; -} -//... - - - - - - - -Grid/Column - - - Grid with speakers - - - -use MoonShine\Decorations\Grid; -use MoonShine\Decorations\Column; - -//... -public function fields(): array -{ - return [ - Grid::make([ - Column::make([ - Block::make('Main information', [ - // Fields here - ]) - ])->columnSpan(6), // 6 out of 12 is half of the screen - - Column::make([ - Block::make('Contact information', [ - // Fields here - ]) - ])->columnSpan(6), // 6 out of 12 is half of the screen - ]) - ]; -} -//... - - - - The result is two columns with blocks - - - - - - diff --git a/resources/views/pages/en/decorations/tabs.blade.php b/resources/views/pages/en/decorations/tabs.blade.php deleted file mode 100644 index 27f9f80b..00000000 --- a/resources/views/pages/en/decorations/tabs.blade.php +++ /dev/null @@ -1,36 +0,0 @@ - - - You can add tabs and group fields in the form for convenience - - - -use MoonShine\Decorations\Block; -use MoonShine\Decorations\Tabs; -use MoonShine\Decorations\Tab; -use MoonShine\Fields\Text; - -//... -public function fields(): array -{ - return [ - Block::make('Main', [ - Tabs::make([ - Tab::make('Seo', [ - Text::make('Seo title') - ->fieldContainer(false), - //... - ]), - Tab::make('Categories', [ - //... - ]) - ]) - ]), - ]; -} -//... - - - - - - diff --git a/resources/views/pages/en/fields/belongs_to.blade.php b/resources/views/pages/en/fields/belongs_to.blade.php deleted file mode 100644 index 7b2c10c7..00000000 --- a/resources/views/pages/en/fields/belongs_to.blade.php +++ /dev/null @@ -1,140 +0,0 @@ - - - - Select - - -Basics - -Field for relationships in Laravel, BelongsTo type. Displayed as select. - - -use MoonShine\Fields\BelongsTo; // [tl! focus] - -//... -public function fields(): array -{ - return [ - // indicating the relationship - BelongsTo::make('Country', 'country', 'name') // [tl! focus] - // or you can field - BelongsTo::make('Country', 'country_id', 'name') // [tl! focus] - ]; -} -//... - - -The third argument with the "name" value is a field in the linked "countries" table to display the values. - - - - -You can also pass a resource with a field to display as a third parameter - - -use MoonShine\Fields\BelongsTo; -use App\MoonShine\Resources\CountryResource; // [tl! focus] - -//... -public function fields(): array -{ - return [ - BelongsTo::make('Country', 'country', new CountryResource()) // [tl! focus] - ]; -} -//... - - - -namespace App\MoonShine\Resources; - -use MoonShine\Resources\Resource; -use App\Models\Country; - -class CountryResource extends Resource -{ - //... - - public string $titleField = 'name'; // [tl! focus] - - //... -} - - -If you need a more complex value to display, you can pass a function to the third argument - - -use MoonShine\Fields\BelongsTo; - -//... -public function fields(): array -{ - return [ - BelongsTo::make( - 'Country', - 'country', - fn($item) => "$item->id.) $item->name" // [tl! focus] - ) - ]; -} -//... - - -Searching values - - - If you need to search among values, then you need to add the searchable() method. - - - -use MoonShine\Fields\BelongsTo; -use App\MoonShine\Resources\CountryResource; - -//... -public function fields(): array -{ - return [ - BelongsTo::make('Country', 'country', new CountryResource()) - ->searchable() // [tl! focus] - ]; -} -//... - - -@include('pages.en.fields.shared.async_search', ['field' => 'BelongsTo']) - -@include('pages.en.fields.shared.values_query', ['field' => 'BelongsTo']) - -Empty value - - - If you need the default value Null - - - -use MoonShine\Fields\BelongsTo; - -//... -public function fields(): array -{ - return [ - BelongsTo::make('Country', 'country') - ->nullable() // [tl! focus] - ]; -} -//... - - - - Don't forget to specify in the database table that the field can be Null. - - - diff --git a/resources/views/pages/en/fields/belongs_to_many.blade.php b/resources/views/pages/en/fields/belongs_to_many.blade.php deleted file mode 100644 index 6f88956e..00000000 --- a/resources/views/pages/en/fields/belongs_to_many.blade.php +++ /dev/null @@ -1,167 +0,0 @@ - - - - Select - - -Basics - -Field for relationships in Laravel, BelongsToMany type. - -Displayed as a group of checkboxes, you can also transform into select multiple. - - -use MoonShine\Fields\BelongsToMany; // [tl! focus] - -//... -public function fields(): array -{ - return [ - BelongsToMany::make('Categories', 'categories', 'name') // [tl! focus] - ]; -} -//... - - - - - -Pivot - -To implement pivot fields, use the fields() method. - - -use MoonShine\Fields\BelongsToMany; - -//... -public function fields(): array -{ - return [ - BelongsToMany::make('Contacts', 'contacts', 'name') - ->fields([ - Text::make('Contact', 'text'), - ]) // [tl! focus:-2] - ]; -} -//... - - - - - -@include('pages.en.fields.shared.async_search', ['field' => 'BelongsToMany']) - - - Requests must be customized via the asyncSearch() method, - don't use valuesQuery()! - - - - -Select - -To transform the display into select, use the select() method. - - -use MoonShine\Fields\BelongsToMany; - -//... -public function fields(): array -{ - return [ - BelongsToMany::make('Categories', 'categories', 'name') - ->select() // [tl! focus] - ]; -} -//... - - - - - -@include('pages.en.fields.shared.values_query', ['field' => 'BelongsToMany']) - -Tree - - - Sometimes it makes sense to display checkboxes with a hierarchy, example for categories that have nesting, - there is a tree() method for this. - - -use MoonShine\Fields\BelongsToMany; - -//... -public function fields(): array -{ - return [ - BelongsToMany::make('Categories', 'categories', 'name') - ->tree('parent_id') // Contact field // [tl! focus] - ]; -} -//... - - -onlyCount - - - If you want to display only the number of selected values on the index page, - then you should use the onlyCount() method. - - - -use MoonShine\Fields\BelongsToMany; - -//... -public function fields(): array -{ - return [ - BelongsToMany::make('Categories', 'categories', 'name') - ->onlyCount() // [tl! focus] - ]; -} -//... - - -inLine - - - By default, the index page will display the field as a table, - but if you want to display it in a line, you can use the inLine() method. - - - Optional parameters can be passed to the method: -
    -
  • separator - separator between elements
  • -
  • badge - display elements as badge
  • -
-
- - -use MoonShine\Fields\BelongsToMany; - -//... -public function fields(): array -{ - return [ - BelongsToMany::make('Categories', 'categories', 'name') - ->inLine(separator: ' ', badge: true) // [tl! focus] - ]; -} -//... - - - - - -
diff --git a/resources/views/pages/en/fields/checkbox.blade.php b/resources/views/pages/en/fields/checkbox.blade.php deleted file mode 100644 index 60234387..00000000 --- a/resources/views/pages/en/fields/checkbox.blade.php +++ /dev/null @@ -1,25 +0,0 @@ - - - - The Checkbox field includes all the basic methods - - - -use MoonShine\Fields\Checkbox; - -//... - -public function fields(): array -{ - return [ - Checkbox::make('Label', 'table_field') - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/fields/code.blade.php b/resources/views/pages/en/fields/code.blade.php deleted file mode 100644 index ee01b9e8..00000000 --- a/resources/views/pages/en/fields/code.blade.php +++ /dev/null @@ -1,31 +0,0 @@ - - - - Textarea - - -Code Editor - - -use MoonShine\Fields\Code; - -//... -public function fields(): array -{ - return [ - Code::make('Code', 'code') - ->language('js') - ->lineNumbers() - ]; -} - -//... - - - - - - - - - diff --git a/resources/views/pages/en/fields/color.blade.php b/resources/views/pages/en/fields/color.blade.php deleted file mode 100644 index 2b3873ac..00000000 --- a/resources/views/pages/en/fields/color.blade.php +++ /dev/null @@ -1,31 +0,0 @@ - - - - Text - - - - Everything is the same as "Text field", the only difference is input type = color - - - -use MoonShine\Fields\Color; - -//... -public function fields(): array -{ - return [ - Color::make('Color') - ]; -} - -//... - - - - - - - - - diff --git a/resources/views/pages/en/fields/date.blade.php b/resources/views/pages/en/fields/date.blade.php deleted file mode 100644 index 1e7e4e90..00000000 --- a/resources/views/pages/en/fields/date.blade.php +++ /dev/null @@ -1,51 +0,0 @@ - - - - Text - - - - Input has date type and additional method - format - - - -use MoonShine\Fields\Date; - -//... -public function fields(): array -{ - return [ - Date::make('Creation date', 'created_at') - ->format('d.m.Y') // Date display format on the main resource - ]; -} - -//... - - - - - - - Use the withTime method to display not only the date but also the time in the field - - - -use MoonShine\Fields\Date; - -//... -public function fields(): array -{ - return [ - Date::make('Date and time of creation', 'created_at') - ->withTime() - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/fields/email.blade.php b/resources/views/pages/en/fields/email.blade.php deleted file mode 100644 index 65d71219..00000000 --- a/resources/views/pages/en/fields/email.blade.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - Text - - - - Everything is the same as "Text field", the only difference is input type = email - - - -use MoonShine\Fields\Email; - -Email::make('E-mail', 'email') - - - diff --git a/resources/views/pages/en/fields/enum.blade.php b/resources/views/pages/en/fields/enum.blade.php deleted file mode 100644 index c06586fe..00000000 --- a/resources/views/pages/en/fields/enum.blade.php +++ /dev/null @@ -1,30 +0,0 @@ - - - - Select - - - - Works the same as the Select field but accepts Enum - - - - Model attribute requires EnumCast - - - -use MoonShine\Fields\Enum; - -//... - -public function fields(): array -{ - return [ - Enum::make('Status', 'status_id')->attach(EnumStatus::class) - ]; -} - -//... - - - diff --git a/resources/views/pages/en/fields/file.blade.php b/resources/views/pages/en/fields/file.blade.php deleted file mode 100644 index 418e8b33..00000000 --- a/resources/views/pages/en/fields/file.blade.php +++ /dev/null @@ -1,217 +0,0 @@ - - - - Before using the file field, - make sure that a symbolic link is set to the storage directory - - - - php artisan storage:link - - - -use MoonShine\Fields\File; - -//... -public function fields(): array -{ - return [ - //... - // [tl! focus:start] - File::make('File', 'file') - ->dir('/') // The directory where the files will be stored in storage (by default /) - ->disk('public') // Filesystems disk - ->allowedExtensions(['jpg', 'gif', 'png']) // Allowable extensions - // [tl! focus:end] - //... - ]; -} -//... - - - - - - - To correctly generate the file URL, you must define the environment variable APP_URL in this way, - to match your app's URL. - - - - When using the local driver, the return value of url is not URL encoded. - For this reason, we recommend always storing your files using names that will create valid URLs. - - -Multiple - - - The multiple() method is used to upload multiple files - - - -use MoonShine\Fields\File; - -//... -public function fields(): array -{ - return [ - //... - File::make('File', 'file') - ->multiple(), // [tl! focus] - //... - ]; -} -//... - - - - The field in the database must be of text or json type.
- You also need to add cast for eloquent model - json or array or collection. -
- -Removing files - - - To be able to delete files, you must use the removable() method - - - -use MoonShine\Fields\File; - -//... -public function fields(): array -{ - return [ - //... - File::make('File', 'file') - ->removable(), // [tl! focus] - //... - ]; -} -//... - - - - The disableDeleteFiles() method will allow you to delete only the record in the database, - but not delete the file itself - - - -use MoonShine\Fields\File; - -//... -public function fields(): array -{ - return [ - //... - File::make('File', 'file') - ->removable() - ->disableDeleteFiles(), // [tl! focus] - //... - ]; -} -//... - - - - The enableDeleteDir() method deletes the directory specified in the dir() method if it is empty - - - -use MoonShine\Fields\File; - -//... -public function fields(): array -{ - return [ - //... - File::make('File', 'file') - ->dir('/images/') - ->removable() - ->enableDeleteDir(), // [tl! focus] - //... - ]; -} -//... - - -Disabling download - - - If you want to protect the file from download, you must use the disableDownload() method - - - -use MoonShine\Fields\File; - -//... -public function fields(): array -{ - return [ - //... - File::make('File', 'file') - ->disableDownload(), // [tl! focus] - //... - ]; -} -//... - - -Original filename - - - If you want to keep the original filename received from the client, use the keepOriginalFileName() method - - - -use MoonShine\Fields\File; - -//... -public function fields(): array -{ - return [ - //... - File::make('File', 'file') - ->keepOriginalFileName(), // [tl! focus] - //... - ]; -} -//... - - -Custom file name - - - If you need to save a custom file name, use the method customName('file_name')) - - - -use MoonShine\Fields\File; -use Illuminate\Http\UploadedFile; -use Illuminate\Support\Str; - -//... -public function fields(): array -{ - return [ - //... - File::make('File', 'file') - ->customName(fn(UploadedFile $file) => Str::random(10) . '.' . $file->extension()), // [tl! focus] - //... - ]; -} -//... - - -
diff --git a/resources/views/pages/en/fields/has_many.blade.php b/resources/views/pages/en/fields/has_many.blade.php deleted file mode 100644 index 8f97279d..00000000 --- a/resources/views/pages/en/fields/has_many.blade.php +++ /dev/null @@ -1,70 +0,0 @@ - - -Field for relationships in Laravel, hasMany type - - -use MoonShine\Fields\HasMany; - -//... -public function fields(): array -{ - return [ - HasMany::make('Comments') - ->fields([ - ID::make(), - BelongsTo::make('Article'), - BelongsTo::make('User'), - Text::make('Text')->required(), - ]) - ->removable() - ]; -} -//... - - - - ID in the fields method is required - - - - It often happens that there are a lot of fields for relations and they look small in the table, and this is inconvenient. - In many cases, you have to move this relation to a separate resource, however if you must leave it within the current resource, - but display the fields completely, - you can use the fullPage() method, and the fields will get a standard shape - - - - - - - Anyway, the table and fullPage modes are more suitable for relations with primitive fields, such modes - do not support Json, HasOne, HasMany fields and many others. - But you can switch the field to ResourceMode to render a list of related records, or a related form - as a standalone resource. - To do this, you need to specify the resourceMode() method for the field and in this case you shouldn't specify the field set - in the fields() method, but the resource associated with the fields will be required - - - -use MoonShine\Fields\HasMany; - -//... -public function fields(): array -{ - return [ - HasMany::make('Rates', 'prices', new PriceResource()) - ->resourceMode() - ]; -} -//... - - - - Pay attention that the presence of a resource in this mode is a mandatory criterion. - However, it can be omitted if it does not violate the naming convention. As a result of which, it will be found automatically. - - - - - - diff --git a/resources/views/pages/en/fields/has_many_through.blade.php b/resources/views/pages/en/fields/has_many_through.blade.php deleted file mode 100644 index 207b00c9..00000000 --- a/resources/views/pages/en/fields/has_many_through.blade.php +++ /dev/null @@ -1,13 +0,0 @@ - - - - HasMany - - -Field for relationships in Laravel, hasManyThrough type - -Same as MoonShine\Fields\HasMany only for hasManyThrough relationships - -MoonShine\Fields\hasManyThrough - - diff --git a/resources/views/pages/en/fields/has_one.blade.php b/resources/views/pages/en/fields/has_one.blade.php deleted file mode 100644 index c6edd1a2..00000000 --- a/resources/views/pages/en/fields/has_one.blade.php +++ /dev/null @@ -1,51 +0,0 @@ - - - - HasMany - - -Field for relationships in Laravel, hasOne type - -Creates a new record in the linked table and binds it to the current record - -In case of relationship the record is edited - - -use MoonShine\Fields\HasOne; - -//... -public function fields(): array -{ - return [ - HasOne::make('City', 'city', 'name') - ->fields([ - ID::make(), - Text::make('Value', 'name'), - ]) - ]; -} -//... - - - - ID in the fields method is required - - - - It often happens that there are a lot of fields for relations and they look small in the table, and this is inconvenient. - In many cases, you have to move this relation to a separate resource, however if you must leave it within the current resource, - but display the fields completely, you can use - the fullPage() method, and the fields will get a standard shape - - - - - - - - - - resourceMode is also available, details in the HasMany field - - - diff --git a/resources/views/pages/en/fields/has_one_through.blade.php b/resources/views/pages/en/fields/has_one_through.blade.php deleted file mode 100644 index 9021819a..00000000 --- a/resources/views/pages/en/fields/has_one_through.blade.php +++ /dev/null @@ -1,13 +0,0 @@ - - - - HasOne - - -Field for relationships in Laravel, hasOneThrough type - -Same as MoonShine\Fields\HasOne but for hasOneThrough relationships - -MoonShine\Fields\HasOne - - diff --git a/resources/views/pages/en/fields/id.blade.php b/resources/views/pages/en/fields/id.blade.php deleted file mode 100644 index 7e18db11..00000000 --- a/resources/views/pages/en/fields/id.blade.php +++ /dev/null @@ -1,42 +0,0 @@ - - - - Text - - - - It is almost always present and will be hidden by default on the add/edit page. - If the primary key has a name other than id you have to specify its name as the first argument of the make method. - - - -use MoonShine\Fields\ID; // [tl! focus] - -//... - -public function fields(): array -{ - return [ - ID::make() // [tl! focus] - ]; -} - -//... - - - -use MoonShine\Fields\ID; // [tl! focus] - -//... - -public function fields(): array -{ - return [ - ID::make('primary_key') // [tl! focus] - ]; -} - -//... - - - diff --git a/resources/views/pages/en/fields/image.blade.php b/resources/views/pages/en/fields/image.blade.php deleted file mode 100644 index ede3759e..00000000 --- a/resources/views/pages/en/fields/image.blade.php +++ /dev/null @@ -1,42 +0,0 @@ - - - - File - - - - Everything is the same as File, only the display changes - - - -use MoonShine\Fields\Image; - -//... -public function fields(): array -{ - return [ - //... [tl! focus:start] - Image::make('Thumbnail', 'thumbnail') - ->dir('/') // The directory where the files will be stored in storage (by default /) - ->disk('public') // Filesystems disk - ->allowedExtensions(['jpg', 'gif', 'png']) // Allowable extensions - //... [tl! focus:end] - ]; -} -//... - - - - - - - To correctly generate the file URL, you must define the environment variable APP_URL in this way, - to match your app's URL. - - - - When using the local driver, the return value of url is not URL encoded. - For this reason, we recommend always storing your files using names that will create valid URLs. - - - diff --git a/resources/views/pages/en/fields/index.blade.php b/resources/views/pages/en/fields/index.blade.php deleted file mode 100644 index 62f6f57b..00000000 --- a/resources/views/pages/en/fields/index.blade.php +++ /dev/null @@ -1,502 +0,0 @@ - - - - Fields is one of the most important sections along with resources. - We have already discussed the process of Fields registration in the Resource section, - but let's figure out how to customize them to your needs! The fluent interface is used for convenience - - -Make - - - First of all, let's understand how the make method works when creating an instance of a field - - - -Text::make(string $label = null, string $column = null, ResourceContract|string|null $resource = null) - - - - $label - Label, field header
- $column - A field in the database (e.g. name) or a relation (e.g. countries)
- $resource - If $field is a relation, then in this parameter you need to specify a field - in the linked table that will be displayed in the view -
- - - $resource can also be a Resource class. In this case, if the - $titleField property is specified, the field of the relation will be defined through it - - - -//... -class MoonShineUserResource extends Resource -{ -public static string $model = MoonshineUser::class; - -public static string $title = 'Administrators'; - -public string $titleField = 'name'; // [tl! focus] -//... - - -Displaying - - - The fields are displayed at the page (the main page of the resource) and at the create/edit page. - To exclude the field from the main page or the page with the form, you can use - hideOnIndex/hideOnForm/hideOnDetail methods and showOnIndex/showOnForm/showOnDetail reverse methods. - To exclude it from the edit or add page only - - use hideOnCreate/hideOnUpdate/showOnCreate/showOnUpdate - - - -//... - -public function fields(): array -{ - return [ - Block::make('Block title', [ - ID::make(), - Text::make('Title', 'title') - // [tl! focus:start] - ->hideOnIndex() - ->hideOnForm() - // [tl! focus:end] - , - ]) - ]; -} - -//... - - -Conditional display - - - This method also accepts bool, or Closure - - - -//... - -public function fields(): array -{ - return [ - Block::make('Block title', [ - ID::make(), - Text::make('Title', 'title') - // [tl! focus:start] - ->hideOnIndex(auth()->check()) - // [tl! focus:end] - , - ]) - ]; -} - -//... - - -Attributes - - - As the form renders the html element, you can use basic html attributes as well. - Such as disabled, autocomplete, readonly, multiple etc. - - - -//... - -public function fields(): array -{ - return [ - Block::make('Block title', [ - Text::make('Title', 'title') - ->disabled() // [tl! focus] - ->hidden() // [tl! focus] - ->readonly(), // [tl! focus] - ]; - ]) - } - -//... - - -Arbitrary attributes - - -//... - -public function fields(): array -{ - return [ - Block::make('Block title', [ - Password::make('Password', 'password') - ->customAttributes(['autocomplete' => 'off']) // [tl! focus] - ]) - ]; -} - -//... - - -Required field - - - To make the field mandatory, you must use the required method - - - -//... - -public function fields(): array -{ - return [ - Block::make('Block title', [ - Text::make('Title', 'title') - ->required() // [tl! focus] - ]) - ]; -} - -//... - - -Dynamic value - - -//... - -public function fields(): array -{ - return [ - Block::make('Block title', [ - Text::make('Name', 'first_name', fn($item) => $item->first_name . ' ' . $item->last_name) - - // Example if you want to separate the logic for the main and for editing - Text::make('Price', resource: function ($item) { - if(request()->routeIs('*.index')) { - return $item->price; - } - - return $item->exists ? $item->price->raw() : 0; - }), - ]) - ]; -} - -//... - - -Hint - - - You can add a hint with a description to the field by calling the hint - - - -//... - -public function fields(): array -{ - return [ - Number::make('Rating') - ->hint('From 0 to 5') // [tl! focus] - ->min(0) - ->max(5) - ->stars() - ]; -} - -//... - - - - - -Link - - - You can add a link to the field (e.g. with instructions) - addLink(string $name, string $link, bool $blank = false) - - - -//... - -public function fields(): array -{ - return [ - Text::make('Title', 'title') - ->addLink('YouTube', 'https://youtube.com') // [tl! focus] - // or with the anonymous function - ->addLink('Test', function() { - if(!$this->getItem()) { - return route('admin.brands.index'); - } - - return route('admin.brands.edit', $this->getItem()->brand_id); - }), - ]; -} - -//... - - - - - -Nullable - - - If you want to save NULL nullable() by default - - -Sorting - - - To be able to sort the field on the main page of the resource, you must add the sortable method - - - -//... - -public function fields(): array -{ - return [ - Text::make('Title', 'title') - ->sortable() // [tl! focus] - ]; -} - -//... - - -Hide label - - - The fieldContainer method hides Label fields to save space, - especially useful in conjunction with the Flex decoration - - - -//... - -public function fields(): array -{ - return [ - Text::make('Title', 'title') - ->fieldContainer(false) // [tl! focus] - ]; -} - -//... - - -Default value - - - Use the default method if you want to specify a default value for the field - - - -//... - -public function fields(): array -{ - return [ - Text::make('Title', 'title') - ->default('-') // [tl! focus] - ]; -} - -//... - - -Display condition - - - There may be a need to display a field only if the value of another field - in the form has a certain value (For example: display the phone only if there is a check mark for it). - For these purposes, the showWhen($column, $operator, $value) method is used - - - - Available operators: - - - - = - < - > - <= - >= - != - in - not in - - - - If the operator is not specified, then = will be used - - - -//... - -public function fields(): array -{ - return [ - Phone::make('Phone', 'phone') - ->showWhen('has_phone','=', 1) // [tl! focus] - // или - Phone::make('Phone', 'phone') - ->showWhen('has_phone', 1) // [tl! focus] - ]; -} - -//... - - - - If the statement is in or not in, - then in $value you need to pass an array - - - -//... - -public function fields(): array -{ - return [ - Select::make('List', 'list')->multiple()->options([ - 'value 1' => 'Option Label 1', - 'value 2' => 'Option Label 2', - 'value 3' => 'Option Label 3', - ]), - - Text::make('Name', 'name') - ->showWhen('list', 'not in', ['value 1', 'value 3']), // [tl! focus] - - Textarea::make('Content', 'content') - ->showWhen('list', 'in', ['value 2', 'value 3']) // [tl! focus] - ]; -} - -//... - - -Ability to save - - -//... - -public function fields(): array -{ - return [ - Text::make('Title', 'title') - ->canSave(false) // [tl! focus] - // or - ->canSave(fn() => false) // [tl! focus] - ]; -} - -//... - - -Events - - - When writing your own Fields, you may need to interact with events before and after saving. - To do this, you have to implement the relevant methods in your custom field - - - -public function beforeSave(Model $item): void -{ - // -} - -public function afterSave(Model $item): void -{ - // -} - - -Change view - - - Sometimes it makes sense to change the view using a fluent interface - (For example, if you use filters or fields outside of MoonShine) - - - -Text::make('Title') - ->customView('fields.my-custom-input'), - - -Methods by condition - - - The when method implements the fluent interface - and will execute a callback when the first argument, passed to the method is true. - - - -Text::make('Slug') - ->when(isset($this->getItem()->id), fn(Text $field) => $field->locked()), - - - - The field instance will be passed to the callback function. - - - - The second callback can be passed to the when method, it will be executed, - when the first argument passed to the method has a false value. - - - -Text::make('Slug') - ->when( - isset($this->getItem()->id), - fn(Text $field) => $field->locked(), - fn(Text $field) => $field->hidden() - ), - - - - The unless method is the reverse of the when method and will execute the first callback, - when the first argument has a false value, otherwise the second callback will be executed if it was passed to the method. - - - -Text::make('Slug') - ->unless( - auth('moonshine')->user()->moonshine_user_role_id === 1, - fn(Text $field) => $field->readonly()->hideOnCreate(), - fn(Text $field) => $field->locked() - ), - - -
diff --git a/resources/views/pages/en/fields/json.blade.php b/resources/views/pages/en/fields/json.blade.php deleted file mode 100644 index aceb7dec..00000000 --- a/resources/views/pages/en/fields/json.blade.php +++ /dev/null @@ -1,90 +0,0 @@ - - - - In the database, the field must be of type text or json. Also cast eloquent array or json or collection models. - - -Key/Value - - - The easiest way is to use the keyValue method, in which case the database will have a simple json [{key: value}] - - - -use MoonShine\Fields\Json; - -//... -public function fields(): array -{ - return [ - Json::make('Product Options', 'options') // [tl! focus] - ->keyValue('Characteristic', 'Value') // First argument Key label, second argument Value label [tl! focus] - ]; -} -//... - - - - - -With a set of fields - - - For more advanced use, use the fields method and pass the required set of fields in a similar way to how the resource works - - - -use MoonShine\Fields\Json; - -//... -public function fields(): array -{ - return [ - Json::make('Product Options', 'options') // [tl! focus:start] - ->fields([ - Text::make('Title', 'title'), - Text::make('Value', 'value') - ]) // [tl! focus:end] - ]; -} -//... - - - - json [{title: 'value', value: 'value'}] - - - - - -Deleting - - -Json::make('Product Options', 'options') - ->keyValue('Characteristics', 'Value') - ->removable() // [tl! focus] - - - - - -Value only - - - Sometimes you only need to store the values in the database - for this you can use the onlyValue() method. - - - -Json::make('Product Options', 'options') - ->onlyValue() // [tl! focus] - - - diff --git a/resources/views/pages/en/fields/morph_many.blade.php b/resources/views/pages/en/fields/morph_many.blade.php deleted file mode 100644 index 21ce53a1..00000000 --- a/resources/views/pages/en/fields/morph_many.blade.php +++ /dev/null @@ -1,13 +0,0 @@ - - - - HasMany - - -Field for relationships in Laravel, morphMany type - -Same as MoonShine\Fields\HasMany only for morphMany relations - -MoonShine\Fields\MorphMany - - diff --git a/resources/views/pages/en/fields/morph_one.blade.php b/resources/views/pages/en/fields/morph_one.blade.php deleted file mode 100644 index 396b62f7..00000000 --- a/resources/views/pages/en/fields/morph_one.blade.php +++ /dev/null @@ -1,16 +0,0 @@ - - - - HasOne - - -Field for relationships in Laravel, morphOne type - -Same as MoonShine\Fields\HasOne but for MorphOne relations - -MoonShine\Fields\MorphOne - - - - - diff --git a/resources/views/pages/en/fields/morph_to.blade.php b/resources/views/pages/en/fields/morph_to.blade.php deleted file mode 100644 index 353bf7b6..00000000 --- a/resources/views/pages/en/fields/morph_to.blade.php +++ /dev/null @@ -1,35 +0,0 @@ - - - - BelongsTo - - -Relationship field in Laravel like MorphTo - -Same as MoonShine\Fields\BelongsTo but for MorphTo relationships - - -use MoonShine\Fields\MorphTo; - -//... - -public function fields(): array -{ - return [ - MorphTo::make('Commentable')->types([ - Article::class => 'title' - ]), - ]; -} -//... - - - - Required types method specifying the classes available.
- The key is a reference to the model, and the value is the field to display. -
- - - - -
diff --git a/resources/views/pages/en/fields/morph_to_many.blade.php b/resources/views/pages/en/fields/morph_to_many.blade.php deleted file mode 100644 index 1c42d29a..00000000 --- a/resources/views/pages/en/fields/morph_to_many.blade.php +++ /dev/null @@ -1,16 +0,0 @@ - - - - BelongsToMany - - -Field for relationships in Laravel, MorphToMany type - -Same as MoonShine\Fields\BelongsToMany only for MorphToMany relationships - -MoonShine\Fields\MorphToMany - - - - - diff --git a/resources/views/pages/en/fields/no_input.blade.php b/resources/views/pages/en/fields/no_input.blade.php deleted file mode 100644 index 124903e2..00000000 --- a/resources/views/pages/en/fields/no_input.blade.php +++ /dev/null @@ -1,106 +0,0 @@ - - - - The field is not for data input/amendment! - - -Basic application - - - With this default field, you can display text data from any field in the model, - or generate text based on the model. - - - -//... -use MoonShine\Fields\NoInput; - -public function fields(): array -{ - return [ - NoInput::make('No input field', 'no_input', static fn() => fake()->realText()), - ]; -} - -//... - - - - - -Badge - - - Displays a label, could be used for order status, as an example! - We use the badge method with a color parameter, - which can be either a string or a closure with the current element in the parameter - - - -//... -use MoonShine\Fields\NoInput; - -public function fields(): array -{ - return [ - NoInput::make('Status')->badge(fn($item) => $item->status_id === 1 ? 'green' : 'gray'), - ]; -} - -//... - - -Boolean - - - Display a label (green or red) for boolean values. - Using the hideTrue and hideFalse options you can hide the label for values input - - - -//... -use MoonShine\Fields\NoInput; - -public function fields(): array -{ - return [ - NoInput::make('Active')->boolean(hideTrue: false, hideFalse: false), - ]; -} - -//... - - -Link - - - Displays a link. - We can show the value and specify the link using the parameter (string or closure with the current element) - - - -//... -use MoonShine\Fields\NoInput; - -public function fields(): array -{ - return [ - NoInput::make('Link')->link('https://cutcode.dev', blank: false), - NoInput::make('Link')->link(fn($item) => $item->link, blank: true), - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/fields/number.blade.php b/resources/views/pages/en/fields/number.blade.php deleted file mode 100644 index 79d0ab8a..00000000 --- a/resources/views/pages/en/fields/number.blade.php +++ /dev/null @@ -1,48 +0,0 @@ - - - - Text - - - - Input with the number type and additional methods: stars, min, max - - - -use MoonShine\Fields\Number; - -//... -public function fields(): array -{ - return [ - Number::make('Rating', 'rating') - ->min(1) - ->max(5) - ]; -} - -//... - - - - To display a numerical value as stars (e.g. for rating), you need the stars method - - - -use MoonShine\Fields\Number; - -//... -public function fields(): array -{ - return [ - Number::make('Rating', 'rating') - ->stars() // [tl! focus] - ->min(1) - ->max(5) - ]; -} - -//... - - - diff --git a/resources/views/pages/en/fields/password.blade.php b/resources/views/pages/en/fields/password.blade.php deleted file mode 100644 index e3590c87..00000000 --- a/resources/views/pages/en/fields/password.blade.php +++ /dev/null @@ -1,33 +0,0 @@ - - - - Text - - - - Everything is the same as the "Text field", the only difference is input type = password - - - - And usually it could be accompanied with the password confirmation field - - - -use MoonShine\Fields\Password; -use MoonShine\Fields\PasswordRepeat; - -//... - -public function fields(): array -{ - return [ - Password::make('Password', 'password')->hideOnIndex(), // [tl! focus] - PasswordRepeat::make('Repeat password', 'password_repeat')->hideOnIndex(), // [tl! focus] - ]; -} - -//... - - - - diff --git a/resources/views/pages/en/fields/phone.blade.php b/resources/views/pages/en/fields/phone.blade.php deleted file mode 100644 index 4715c10d..00000000 --- a/resources/views/pages/en/fields/phone.blade.php +++ /dev/null @@ -1,19 +0,0 @@ - - - - Text - - - - Everything is the same as the "Text field", the only difference is input type = tel - - - -use MoonShine\Fields\Phone; - -Phone::make('Phone', 'tel') - - -To mask the telephone number, use the mask('7 999 999-99-99') method - - diff --git a/resources/views/pages/en/fields/select.blade.php b/resources/views/pages/en/fields/select.blade.php deleted file mode 100644 index 47e73726..00000000 --- a/resources/views/pages/en/fields/select.blade.php +++ /dev/null @@ -1,105 +0,0 @@ - - - - The text field includes all the basic methods and additional methods for select fields - - - -use MoonShine\Fields\Select; - -//... - -public function fields(): array -{ - return [ - Select::make('Country', 'country_id') - ->options([ - 'value 1' => 'Option Label 2', - 'value 2' => 'Option Label 2' - ]) - ]; -} - -//... - - - - - -Nullable - - - If you need to save NULL, then you need to add a nullable method - - - - Select::make('Country', 'country_id') - ->nullable() // [tl! focus] - - - - - -Groups - - - You can combine values into groups - - - -Select::make('City')->options([ - 'Italy' => [ - 1 => 'Rome', - 2 => 'Milan' - ], - 'France' => [ - 3 => 'Paris', - 4 => 'Marseille' - ], -]), - - - - - -Multiple select - - - To select multiple values, you need the multiple method - - - -Select::make('Country', 'country_id') - ->multiple() // [tl! focus] - - - - The field in the database must be of the text or json type.
- You also need to add a cast for the eloquent model - json or array or collection. -
- - - - -Search - - - If you want to add a search among values, you need to add the searchable method - - - - Select::make('Country', 'country_id') - ->searchable() // [tl! focus] - - - - - -
diff --git a/resources/views/pages/en/fields/shared/async_search.blade.php b/resources/views/pages/en/fields/shared/async_search.blade.php deleted file mode 100644 index 9172f369..00000000 --- a/resources/views/pages/en/fields/shared/async_search.blade.php +++ /dev/null @@ -1,90 +0,0 @@ -Async search - - - Async search for values is provided by the asyncSearch() method. - - - -use MoonShine\Fields\{{ $field }}; // [tl! focus] - -//... -public function fields(): array -{ - return [ - {{ $field }}::make('Contacts') // [tl! focus] - ->asyncSearch(){!!$field === 'BelongsToMany' ? "->fields([Text::make('Contact', 'text')])" : ""!!} // [tl! focus] - ]; -} -//... - - - - The search will be performed on the resource relation field titleField. The default is titleField=id. - - - - You can pass parameters to the asyncSearch() method: - - - -
    -
  • title - search field
  • -
  • count - amount of items in output
  • -
  • asyncSearchQuery() - callback function for filtering values
  • -
  • asyncSearchValueCallback() - callback function for output customization.
  • -
-
- - -use Illuminate\Contracts\Database\Eloquent\Builder; // [tl! focus] -use MoonShine\Fields\{{ $field }}; // [tl! focus] - -//... -public function fields(): array -{ - return [ - {{ $field }}::make('Contacts')->asyncSearch( - 'title', - 10, - asyncSearchQuery: function (Builder $query) { - return $query->where('id', '!=', 2); - }, - asyncSearchValueCallback: function ($contact) { - return $contact->id . ' | ' . $contact->title; - } - ){!!$field === 'BelongsToMany' ? "->fields([Text::make('Contact', 'text')])" : ""!!} // [tl! focus:-9] - ]; -} -//... - - - - When building a query in asyncSearchQuery(), you can use the current form values. - To do this, you need to pass Request to the callback functions. - - - -use Illuminate\Contracts\Database\Eloquent\Builder; // [tl! focus] -use Illuminate\Http\Request; // [tl! focus] -use MoonShine\Fields\{{ $field }}; -use MoonShine\Fields\Select; - -//... -public function fields(): array -{ - return [ - Select::make('Country', 'country_id'), // [tl! focus] - {{ $field }}::make('City')->asyncSearch( - 'title', - asyncSearchQuery: function (Builder $query, Request $request): Builder { - return $query->where('country_id', $request->get('country_id')); - } // [tl! focus:-2] - ) - ]; -} -//... - - - - Relations that use async search in their fields are recommended to be used in ResourceMode. - diff --git a/resources/views/pages/en/fields/shared/values_query.blade.php b/resources/views/pages/en/fields/shared/values_query.blade.php deleted file mode 100644 index 71793e18..00000000 --- a/resources/views/pages/en/fields/shared/values_query.blade.php +++ /dev/null @@ -1,18 +0,0 @@ -Values query - -To filter values, use the valuesQuery method - - -use Illuminate\Contracts\Database\Eloquent\Builder; // [tl! focus] -use MoonShine\Fields\{{ $field }}; - -//... -public function fields(): array -{ - return [ - {{ $field }}::make('Categories', 'categories', 'name') - ->valuesQuery(fn(Builder $query) => $query->where('active', true)) // [tl! focus] - ]; -} -//... - diff --git a/resources/views/pages/en/fields/slide.blade.php b/resources/views/pages/en/fields/slide.blade.php deleted file mode 100644 index 526907b2..00000000 --- a/resources/views/pages/en/fields/slide.blade.php +++ /dev/null @@ -1,39 +0,0 @@ - - - - Text - - - - Has the same methods as the "Number" field, plus additional methods: step, - fromField, toField - - - - Since the range has two values, you have to specify these two fields in the database by means of - fromField and toField methods - - - -use MoonShine\Fields\SlideField; - -//... -public function fields(): array -{ - return [ - SlideField::make('Age') - ->fromField('age_from') // Field in the table for the value "From" - ->toField('age_to') // Field in the table for the value "Before" - ->min(0) - ->max(60) - ->step(1) // Slider pitch - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/fields/slug.blade.php b/resources/views/pages/en/fields/slug.blade.php deleted file mode 100644 index 901cbaa5..00000000 --- a/resources/views/pages/en/fields/slug.blade.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - Text - - - - Using this field you can generate a slug based on the selected field and keep it unique too - - - -//... -use MoonShine\Fields\Slug; - -public function fields(): array -{ - return [ - Slug::make('Slug')->from('title')->separator('-')->unique(), - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/fields/spatie/medialibrary.blade.php b/resources/views/pages/en/fields/spatie/medialibrary.blade.php deleted file mode 100644 index a45e33af..00000000 --- a/resources/views/pages/en/fields/spatie/medialibrary.blade.php +++ /dev/null @@ -1,88 +0,0 @@ - - - - Image - - - - This field belongs to a separate package, you have to complete the installation before using it - - - - composer require visual-ideas/moonshine-spatie-medialibrary - - - - The field is purposed for work with the - Laravel-medialibrary - package made by - Spatie - - - - Before using the Spatie\MediaLibrary field, make sure that: - - - - - - In the model: - - -use Spatie\MediaLibrary\HasMedia; -use Spatie\MediaLibrary\InteractsWithMedia; - -class ModelClass extends Model implements HasMedia - //... - use InteractsWithMedia; - - //... - public function registerMediaCollections(): void - { - $this->addMediaCollection('cover'); - } - //... - - - - In the MoonShine-resource: - - - use VI\MoonShineSpatieMediaLibrary\Fields\MediaLibrary; - //... - MediaLibrary::make('Cover', 'cover'), - //... - - - - By default, the field works in a single image mode - - -use Spatie\MediaLibrary\HasMedia; -use Spatie\MediaLibrary\InteractsWithMedia; - -class ModelClass extends Model implements HasMedia -//... -use InteractsWithMedia; -//... -public function registerMediaCollections(): void -{ - $this->addMediaCollection('cover')->singleFile(); -} -//... - - - If you want to use a field to load multiple images, add the ->multiple() method when declaring the field - - -//... -MediaLibrary::make('Gallery', 'gallery')->multiple(), -//... - - - - diff --git a/resources/views/pages/en/fields/spatie/translatable.blade.php b/resources/views/pages/en/fields/spatie/translatable.blade.php deleted file mode 100644 index 537d2344..00000000 --- a/resources/views/pages/en/fields/spatie/translatable.blade.php +++ /dev/null @@ -1,99 +0,0 @@ - - - - Json - - - - This field belongs to a separate package, you have to complete the installation before using it - - - - composer require visual-ideas/moonshine-spatie-translatable - - - - The field is purposed for work with the - Laravel-translatable - package made by - Spatie - - - - Before using the Spatie\Translatable field, make sure that: - - - - - -use VI\MoonShineSpatieTranslatable\Fields\Translatable; -//... -Translatable::make('Title', 'name') -//... - - -Mandatory translations - - - The ->requiredLanguages(array $languages) method is used to specify the languages required by the validator for creating/saving a record. - - - - It is recommended to pass the config('app.fallback_locale') value to this method - - - - -use VI\MoonShineSpatieTranslatable\Fields\Translatable; -//... -Translatable::make('Title', 'name') - ->requiredLanguages([config('app.fallback_locale'), 'ru']) -//... - - -Recommended translations - - - If you specify this array, the language codes in the forms for adding/modifying a specific translation will be placed at the beginning of the list of all possible languages. - - - -use VI\MoonShineSpatieTranslatable\Fields\Translatable; -//... -Translatable::make('Title', 'name') - ->priorityLanguages([config('app.fallback_locale'), config('app.locale'), 'de', 'fr', 'uk']) -//... - - -Deleting - - - You can delete specific translations from out of the entered ones - - - -Translatable::make('Field', 'field') - ->removable() // [tl! focus] - - - - If you leave the translation text blank, it will be deleted! - - - - If there are two translations into the same language, the translation that comes first will be deleted (replaced)! - - - - - - diff --git a/resources/views/pages/en/fields/stack_fields.blade.php b/resources/views/pages/en/fields/stack_fields.blade.php deleted file mode 100644 index 3f022046..00000000 --- a/resources/views/pages/en/fields/stack_fields.blade.php +++ /dev/null @@ -1,37 +0,0 @@ - - - - The StackFields field allows you to group fields when displayed on the index page. - - - - The fields() method needs to pass an array of fields for grouping. - - - - The withLabels() method can be used to display labels on the index page - - - -use MoonShine\Fields\BelongsTo; -use MoonShine\Fields\StackFields; // [tl! focus] -use MoonShine\Fields\Text; -//... - -public function fields(): array -{ - return [ - StackFields::make('Title')->fields([ // [tl! focus] - Text::make('Title'), - BelongsTo::make('Author', resource: 'name'), - ]) // [tl! focus] - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/fields/switch.blade.php b/resources/views/pages/en/fields/switch.blade.php deleted file mode 100644 index ce3a5861..00000000 --- a/resources/views/pages/en/fields/switch.blade.php +++ /dev/null @@ -1,58 +0,0 @@ - - - - Checkbox - - - -use MoonShine\Fields\SwitchBoolean; - -//... -public function fields(): array -{ - return [ - SwitchBoolean::make('Publish', 'active') - ]; -} - -//... - - - -use MoonShine\Fields\SwitchBoolean; - -//... -public function fields(): array -{ - return [ - SwitchBoolean::make('Publish', 'active') - ->onValue(1) // Active value of a form element - ->offValue(0) // Inactive value of a form element - ]; -} - -//... - - - - -use MoonShine\Fields\SwitchBoolean; - -//... -public function fields(): array -{ - return [ - SwitchBoolean::make('Publish', 'active') - ->autoUpdate(false) // The option to change on the main page is disabled - ->autoUpdate(true) // The option to change on the home page is enabled - ->autoUpdate(fn() => true) - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/fields/text.blade.php b/resources/views/pages/en/fields/text.blade.php deleted file mode 100644 index b2497164..00000000 --- a/resources/views/pages/en/fields/text.blade.php +++ /dev/null @@ -1,83 +0,0 @@ - - - - The text field includes all the basic methods - - - -use MoonShine\Fields\Text; // [tl! focus] - -//... - -public function fields(): array -{ - return [ - Text::make('Title', 'title') // [tl! focus] - ]; -} - -//... - - - - - -Mask - - - Use the mask method if you want to add a mask to the field - - - -//... - -public function fields(): array -{ - return [ - Text::make('Title', 'title') - ->mask('7 (999) 999-99-99') // [tl! focus] - ]; -} - -//... - - - - - -Extensions - - -//... - -public function fields(): array -{ - return [ - Text::make('Title', 'title') - // Copy input value to clipboard - ->copy() - // Disable/enable input - ->locked() - // Expansion - ->expansion('kg') - // Switch type password/text - ->eye() - ]; -} - -//... - - - - - - - The copy method uses the Clipboard API which is only available for HTTPS or localhost - - - diff --git a/resources/views/pages/en/fields/textarea.blade.php b/resources/views/pages/en/fields/textarea.blade.php deleted file mode 100644 index 0ce86b06..00000000 --- a/resources/views/pages/en/fields/textarea.blade.php +++ /dev/null @@ -1,22 +0,0 @@ - - - - The Textarea field includes all the basic methods - - - -use MoonShine\Fields\Textarea; - -//... - -public function fields(): array -{ - return [ - Textarea::make('Label', 'table_field') - ]; -} - -//... - - - diff --git a/resources/views/pages/en/fields/url.blade.php b/resources/views/pages/en/fields/url.blade.php deleted file mode 100644 index 19e08df1..00000000 --- a/resources/views/pages/en/fields/url.blade.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - Text - - - - Everything is the same as the "Text field", the only difference is input type = url - - - -use MoonShine\Fields\Url; - -Url::make('Url', 'url') - - - diff --git a/resources/views/pages/en/fields/wysiwyg.blade.php b/resources/views/pages/en/fields/wysiwyg.blade.php deleted file mode 100644 index 50b32541..00000000 --- a/resources/views/pages/en/fields/wysiwyg.blade.php +++ /dev/null @@ -1,209 +0,0 @@ - - - - Textarea - - -TinyMce - - -use MoonShine\Fields\TinyMce; // [tl! focus] - -//... -public function fields(): array -{ - return [ - TinyMce::make('Description', 'description'), // [tl! focus] - - // More advanced settings - - TinyMce::make('Text') // [tl! focus] - // Override the plugin set - ->plugins('anchor') // [tl! focus] - // Adding plugins to the base set - ->addPlugins('code codesample') // [tl! focus] - // Override the set toolbar - ->toolbar('undo redo | blocks fontfamily fontsize') // [tl! focus] - // Adding a toolbar to the base set - ->addToolbar('code codesample') // [tl! focus] - // To change the author name for a plugin tinycomments - ->commentAuthor('Danil Shutsky') // [tl! focus] - // Tags - ->mergeTags([ - ['value' => 'tag', 'title' => 'Title'] - ]) // [tl! focus:-2] - // Override the current locale - ->locale('en'), // [tl! focus] - ]; -} -//... - - - - Translation files are placed in the public/vendor/moonshine/libs/tinymce/langs directory - - - - - - - Sign up at Tiny.Cloud and get a token. Then add it to config/moonshine.php config - - - -//... -'tinymce' => [ - 'token' => 'YOUR_TOKEN' // [tl! focus] -] -//... - - -Laravel File manager -Laravel FileManager - - - If you want to use the file manager in tinymce, you need to install the Laravel FileManager package - - -Installing - - -composer require unisharp/laravel-filemanager - -php artisan vendor:publish --tag=lfm_config -php artisan vendor:publish --tag=lfm_public - - - - Be sure to set the 'use_package_routes' flag in the lfm config to false, otherwise the route caching will cause an error - - - -return [ - // ... - 'use_package_routes' => false, // [tl! focus] - // ... -]; - - - -Add routes to the app/Providers/RouteServiceProvider.php - - -// .. -Route::middleware('web') -->group(base_path('routes/web.php')); - -Route::group(['prefix' => 'laravel-filemanager', 'middleware' => ['moonshine', 'auth.moonshine']], function () { - UniSharp\LaravelFilemanager\Lfm::routes(); -}); // [tl! focus:-2] - -// .. - - - - The file manager route must be in the moonshine middleware group, not in the web! - - - - To allow access only to users authorized in the admin panel - middleware auth.moonshine must be used - - -Add the prefix to config/moonshine.php - - -//... -'tinymce' => [ - 'file_manager' => 'laravel-filemanager', // [tl! focus] - // ... -] -//... - - -Trix - - - This field belongs to a separate package, complete the installation before use - - - -composer require moonshine/trix - - - -use MoonShine\Fields\Trix; // [tl! focus] - -//... -public function fields(): array -{ - return [ - Trix::make('Description', 'description'), // [tl! focus] - ]; -} -//... - - - - - -CKEditor - - - The field is placed in a separate package, before use it is necessary to perform the installation - - - -composer require moonshine/ckeditor - - - -use MoonShine\CKEditor\Fields\CKEditor; // [tl! focus] - -//... -public function fields(): array -{ - return [ - CKEditor::make('Description', 'description'), // [tl! focus] - ]; -} -//... - - - - - -Quill - - - The field is placed in a separate package, before use it is necessary to perform the installation - - - - composer require moonshine/quill - - - -use MoonShine\Quill\Fields\Quill; // [tl! focus] - -//... -public function fields(): array -{ - return [ - Quill::make('Description', 'description'), // [tl! focus] - ]; -} -//... - - - - - - diff --git a/resources/views/pages/en/filters/belongs_to.blade.php b/resources/views/pages/en/filters/belongs_to.blade.php deleted file mode 100644 index 8e5ad172..00000000 --- a/resources/views/pages/en/filters/belongs_to.blade.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - BelongsTo - - - -use MoonShine\Filters\BelongsToFilter; - -//... - -public function filters(): array -{ - return [ - BelongsToFilter::make('Author', resource: 'name') - ->nullable() - ->canSee(fn() => auth('moonshine')->user()->moonshine_user_role_id === 1), - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/filters/belongs_to_many.blade.php b/resources/views/pages/en/filters/belongs_to_many.blade.php deleted file mode 100644 index 4e2d1d22..00000000 --- a/resources/views/pages/en/filters/belongs_to_many.blade.php +++ /dev/null @@ -1,25 +0,0 @@ - - - - BelongsToMany - - - -use MoonShine\Filters\BelongsToManyFilter; - -//... - -public function filters(): array -{ - return [ - BelongsToManyFilter::make('Categories') - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/filters/date.blade.php b/resources/views/pages/en/filters/date.blade.php deleted file mode 100644 index e5cd68e9..00000000 --- a/resources/views/pages/en/filters/date.blade.php +++ /dev/null @@ -1,25 +0,0 @@ - - - - Date - - - -use MoonShine\Filters\DateFilter; - -//... - -public function filters(): array -{ - return [ - DateFilter::make('Created at') - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/filters/date_range.blade.php b/resources/views/pages/en/filters/date_range.blade.php deleted file mode 100644 index 8dfba5a5..00000000 --- a/resources/views/pages/en/filters/date_range.blade.php +++ /dev/null @@ -1,25 +0,0 @@ - - - - Date - - - -use MoonShine\Filters\DateRangeFilter; - -//... - -public function filters(): array -{ - return [ - DateRangeFilter::make('Created at') - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/filters/has_one.blade.php b/resources/views/pages/en/filters/has_one.blade.php deleted file mode 100644 index 7057730c..00000000 --- a/resources/views/pages/en/filters/has_one.blade.php +++ /dev/null @@ -1,26 +0,0 @@ - - - - HasOne - - - -use MoonShine\Filters\HasOneFilter; - -//... - -public function filters(): array -{ - return [ - HasOne::make('Phone', resource: 'number') - ->nullable() - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/filters/index.blade.php b/resources/views/pages/en/filters/index.blade.php deleted file mode 100644 index d16eb115..00000000 --- a/resources/views/pages/en/filters/index.blade.php +++ /dev/null @@ -1,100 +0,0 @@ - - -Adding a filter - - - Fields - - - - Filters are shown on the main page of the resource to filter data. - They implement from the corresponding fields, so all methods of these fields are available here as well. - - - - Filters work in exactly the same way as fields, except that they are declared in the - filters resource method - - - -use MoonShine\Filters\BelongsToFilter; -use MoonShine\Filters\BelongsToManyFilter; -use MoonShine\Filters\DateRangeFilter; -use MoonShine\Filters\SlideFilter; -use MoonShine\Filters\SwitchBooleanFilter; -use MoonShine\Filters\TextFilter; - -//... - -public function filters(): array -{ - return [ - TextFilter::make('Title'), - - BelongsToFilter::make('Author', resource: 'name') - ->nullable() - ->canSee(fn() => auth('moonshine')->user()->moonshine_user_role_id === 1), - - TextFilter::make('Slug'), - - BelongsToManyFilter::make('Categories') - ->select(), - - DateRangeFilter::make('Created at'), - - SlideFilter::make('Age') - ->fromField('age_from') - ->toField('age_to') - ->min(0) - ->max(60), - - SwitchBooleanFilter::make('Active') - ]; -} - -//... - - - - - -Custom query - - - Using the customQuery method, you can create a custom query for the filter - - - -use MoonShine\Filters\DateRangeFilter; -use MoonShine\Filters\TextFilter; - -//... - -public function filters(): array -{ - return [ - TextFilter::make('Title') - ->customQuery(fn(Builder $query, $value) => $query->where('title', 'LIKE', "%${value}%")), // [tl! focus] - - DateRangeFilter::make('Created at') - ->customQuery(function (Builder $query, $values) { - return $query - ->when($values['from'] ?? null, function ($query, $fromDate) { - $query->whereDate('created_at', '>=', Carbon::parse($fromDate)); - }) - ->when($values['to'] ?? null, function ($query, $toDate) { - $query->whereDate('created_at', '<=', Carbon::parse($toDate)); - }); - }), // [tl! focus] - ]; -} - -//... - - - diff --git a/resources/views/pages/en/filters/is_empty.blade.php b/resources/views/pages/en/filters/is_empty.blade.php deleted file mode 100644 index bdb8ce14..00000000 --- a/resources/views/pages/en/filters/is_empty.blade.php +++ /dev/null @@ -1,32 +0,0 @@ - - - - SwitchBooleanFilter - - -Enables displaying only rows with empty (not empty for IsNotEmptyFilter) field values - -Empty values are the following: - - - -use MoonShine\Filters\IsEmptyFilter; -use MoonShine\Filters\IsNotEmptyFilter; - -//... - -public function filters(): array -{ - return [ - IsEmptyFilter::make('Url'), - IsNotEmptyFilter::make('Active') - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/filters/select.blade.php b/resources/views/pages/en/filters/select.blade.php deleted file mode 100644 index 23858932..00000000 --- a/resources/views/pages/en/filters/select.blade.php +++ /dev/null @@ -1,29 +0,0 @@ - - - - Select - - - -use MoonShine\Filters\SelectFilter; - -//... - -public function filters(): array -{ - return [ - SelectFilter::make('Country', 'country_id') - ->options([ - 'value 1' => 'Option Label 1', - 'value 2' => 'Option Label 2' - ]) - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/filters/slide.blade.php b/resources/views/pages/en/filters/slide.blade.php deleted file mode 100644 index 4714e0d5..00000000 --- a/resources/views/pages/en/filters/slide.blade.php +++ /dev/null @@ -1,29 +0,0 @@ - - - - Slide - - - -use MoonShine\Filters\SlideFilter; - -//... - -public function filters(): array -{ - return [ - SlideFilter::make('Age') - ->fromField('age_from') - ->toField('age_to') - ->min(0) - ->max(60) - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/filters/switch.blade.php b/resources/views/pages/en/filters/switch.blade.php deleted file mode 100644 index 58d08f00..00000000 --- a/resources/views/pages/en/filters/switch.blade.php +++ /dev/null @@ -1,25 +0,0 @@ - - - - Switch - - - -use MoonShine\Filters\SwitchBooleanFilter; - -//... - -public function filters(): array -{ - return [ - SwitchBooleanFilter::make('Active') - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/filters/text.blade.php b/resources/views/pages/en/filters/text.blade.php deleted file mode 100644 index e2118f48..00000000 --- a/resources/views/pages/en/filters/text.blade.php +++ /dev/null @@ -1,25 +0,0 @@ - - - - Text - - - -use MoonShine\Filters\TextFilter; - -//... - -public function filters(): array -{ - return [ - TextFilter::make('Title') - ]; -} - -//... - - - - - - diff --git a/resources/views/pages/en/home.blade.php b/resources/views/pages/en/home.blade.php deleted file mode 100644 index 76898a1e..00000000 --- a/resources/views/pages/en/home.blade.php +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Hello Laravel user! - - - Welcome to the open-source project dedicated to the "MoonShine" admin panel. - - - I've been working on it for several years and have used it on dozens of small projects constantly tweaking it. - - - What does moonshine mean? It's not exactly "moonlight" - my idea is the "moonshine" concept. - The term means the independent production of a drink in illegal conditions under the cover of the night :) - So I developed this admin panel at night in my free time under the moonlight ;) - - - Everything is already ready for use in your projects, - documentation has been created describing the installation, configuration and features. - - - I invite interested users to use and develop Moonshine together. - - - - - diff --git a/resources/views/pages/en/icons/heroicons.blade.php b/resources/views/pages/en/icons/heroicons.blade.php deleted file mode 100644 index de8eba9e..00000000 --- a/resources/views/pages/en/icons/heroicons.blade.php +++ /dev/null @@ -1,37 +0,0 @@ - - - - In addition to the standard icons, you can find preinstalled - icons from the Heroicons collection - (Solid set is the default one, plus Outline) in the resources/views/vendor/moonshine/shared/icons/heroicons folder. - You can use them wherever you use the icon() method - - -Solid - - - ->icon('heroicons.academic-cap') // [tl! focus] - - - - -Outline - - - ->icon('heroicons.outline.academic-cap') // [tl! focus] - - - - - diff --git a/resources/views/pages/en/icons/index.blade.php b/resources/views/pages/en/icons/index.blade.php deleted file mode 100644 index 25d4c877..00000000 --- a/resources/views/pages/en/icons/index.blade.php +++ /dev/null @@ -1,31 +0,0 @@ - - - - For all entities that have the icon() method, - you can use one of the proposed icon sets or create your own set - - -System icons - - - ->icon('add') // [tl! focus] - - - - -Custom icons - - - You can also create a blade file with your custom icon. To do this you have to create a blade file in - resources/views/vendor/moonshine/shared/icons (e.g. - my-icon.blade.php) containing the icon image inside (e.g. svg code) - and then specify the icon('my-icon') - - - diff --git a/resources/views/pages/en/installation.blade.php b/resources/views/pages/en/installation.blade.php deleted file mode 100644 index 7c6c690e..00000000 --- a/resources/views/pages/en/installation.blade.php +++ /dev/null @@ -1,99 +0,0 @@ - - -Requirements - - - To use MoonShine, the following requirements must be met prior to installation: - - - -Composer - - - composer require moonshine/moonshine:2.0.0.alpha.1 - - -Installation - - - php artisan moonshine:install - - - - This command will add config/moonshine.php with the basic settings. - More about the config file - - - - A directory containing the admin panel and resources will also be added - app/MoonShine. - More about Resources - - - - It will also add MoonShineServiceProvider App\Providers\MoonShineServiceProvider where you need to register resources. - More about Resources - - - - Create an Administrator - - - - php artisan moonshine:user - - - - Resource registration and menu configuration - - - - To register new resources in the MoonShine and configure a menu, we need app/Providers/MoonShineServiceProvider.php - - - -namespace App\Providers; - -use Illuminate\Support\ServiceProvider; -use MoonShine\MoonShine; -use MoonShine\Menu\MenuItem; -use MoonShine\Resources\MoonShineUserResource; - -class MoonShineServiceProvider extends ServiceProvider -{ - public function boot(): void - { - // [tl! focus:start] - app(MoonShine::class)->menu([ - MenuItem::make('Admins', new MoonShineUserResource()), - ]); - // [tl! focus:end] - } -} - - - - In this example, we have added a menu item with panel admins. - More about Menu - - - - Great! Now you can create and register sections of the future admin panel and proceed with the real work! - But don't forget to read the documentation all the way through! - - - - By default, the admin panel is accessed by url /moonshine. You can change the url in - config file. - - - diff --git a/resources/views/pages/en/metrics/donut_chart.blade.php b/resources/views/pages/en/metrics/donut_chart.blade.php deleted file mode 100644 index 4c9034e6..00000000 --- a/resources/views/pages/en/metrics/donut_chart.blade.php +++ /dev/null @@ -1,31 +0,0 @@ - - - - Provides the ability to create a donut chart for metric - - - -namespace MoonShine\Resources; - -use MoonShine\Metrics\DonutChartMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - DonutChartMetric::make('Subscribers') - ->values(['CutCode' => 10000, 'Apple' => 9999]), - ]; - } // [tl! focus:end] - - //... -} - - - - - - diff --git a/resources/views/pages/en/metrics/index.blade.php b/resources/views/pages/en/metrics/index.blade.php deleted file mode 100644 index 33a266ea..00000000 --- a/resources/views/pages/en/metrics/index.blade.php +++ /dev/null @@ -1,16 +0,0 @@ - - - - These blocks are intended for displaying statistics - - - - You can show them on the admin panel home page - and in every individual resource as well - - - - Metrics are also provided with - Layout (columnSpan) decorator features - - diff --git a/resources/views/pages/en/metrics/line_chart.blade.php b/resources/views/pages/en/metrics/line_chart.blade.php deleted file mode 100644 index 0872fb56..00000000 --- a/resources/views/pages/en/metrics/line_chart.blade.php +++ /dev/null @@ -1,99 +0,0 @@ - - - - Provides the ability to create a line chart for metric - - - -namespace MoonShine\Resources; - -use MoonShine\Metrics\LineChartMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - LineChartMetric::make('Orders') - ->line([ - 'Profit' => Order::query() - ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date') - ->groupBy('date') - ->pluck('sum','date') - ->toArray() - ]) - ->line([ - 'Avg' => Order::query() - ->selectRaw('AVG(price) as avg, DATE_FORMAT(created_at, "%d.%m.%Y") as date') - ->groupBy('date') - ->pluck('avg','date') - ->toArray() - ], '#EC4176'), - ]; - } // [tl! focus:end] - - //... -} - - - - or using one line method - - - -namespace MoonShine\Resources; - -use MoonShine\Metrics\LineChartMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - LineChartMetric::make('Orders') - ->line([ - 'Profit' => Order::query() - ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date') - ->groupBy('date') - ->pluck('sum','date') - ->toArray(), - 'Avg' => Order::query() - ->selectRaw('AVG(price) as avg, DATE_FORMAT(created_at, "%d.%m.%Y") as date') - ->groupBy('date') - ->pluck('avg','date') - ->toArray() - ],[ - 'red', 'blue' - ]) - ]; - } // [tl! focus:end] - - //... -} - - - - - - - By default, LineChart graphics sort keys in ascending order. - This feature can be used with the usual withoutSortKeys() method. - - - -LineChartMetric::make('Orders') - ->line([ - 'Profit' => Order::query() - ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date') - ->groupBy('date') - ->pluck('sum','date') - ->toArray() - ]) - ->withoutSortKeys(), // [tl! focus] - - - diff --git a/resources/views/pages/en/metrics/value.blade.php b/resources/views/pages/en/metrics/value.blade.php deleted file mode 100644 index ce30ff2d..00000000 --- a/resources/views/pages/en/metrics/value.blade.php +++ /dev/null @@ -1,89 +0,0 @@ - - - - Displays a simple value, such as how many specific records a table contains - - - -namespace MoonShine\Resources; - -use MoonShine\Metrics\ValueMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - ValueMetric::make('Completed orders') - ->value(Orders::completed()->count()) - ]; - } // [tl! focus:end] - - //... -} - - - - - - - You can also display a value as a goal progress indicator - - - -namespace MoonShine\Resources; - -use MoonShine\Metrics\ValueMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - ValueMetric::make('Open orders left') - ->value(Orders::completed()->count()) - ->progress(200) // Ultimate goal - ]; - } // [tl! focus:end] - - //... -} - - - - - - - You can add formatting, prefix, and suffix to the output value - - - -namespace MoonShine\Resources; - -use MoonShine\Metrics\ValueMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - ValueMetric::make('Revenue') - ->value(Orders::completed()->sum('price')) - ->valueFormat('for today {value} rub.') - ]; - } // [tl! focus:end] - - //... -} - - - - - - diff --git a/resources/views/pages/en/packages.blade.php b/resources/views/pages/en/packages.blade.php deleted file mode 100644 index ca325aff..00000000 --- a/resources/views/pages/en/packages.blade.php +++ /dev/null @@ -1,3 +0,0 @@ - - @include('packages') - diff --git a/resources/views/pages/en/releases.blade.php b/resources/views/pages/en/releases.blade.php deleted file mode 100644 index e57a14e4..00000000 --- a/resources/views/pages/en/releases.blade.php +++ /dev/null @@ -1,272 +0,0 @@ - -
    -
  • - v1.50.0 - -
    -
    Changes
    -
      -
    • New unique design
    • -
    • A new approach to grid customization (Grid, Grid Column, Flex)
    • -
    • An option to disable authentication
    • -
    • Changing localization
    • -
    • Improvements for the decorator interface
    • -
    • Component approach for blade
    • -
    • Text Dashboard block
    • -
    • Improvements for custom pages
    • -
    • New onlySelected mode for BelongsToMany
    • -
    • Laravel file manager is excluded from the package
    • -
    • and much more ...
    • -
    -
    -
  • - -
  • - v1.27.0 - -
    -
    Changes
    -
      -
    • MorphTo,MorphToMany fields
    • -
    • Detail page
    • -
    -
    -
  • -
  • - v1.26.0 - -
    -
    Changes
    -
      -
    • Collapse decoration
    • -
    • Design fixes
    • -
    -
    -
  • -
  • - v1.25.0 - -
    -
    Changes
    -
      -
    • Resource query tags
    • -
    • NoInput field
    • -
    • Fields fullWidth method
    • -
    • Form components
    • -
    • User permissions
    • -
    • Resource show action
    • -
    -
    -
  • -
  • - v1.24.0 - -
    -
    Changes
    -
      -
    • FormActions
    • -
    • FieldContainer
    • -
    -
    -
  • -
  • - v1.23.0 - -
    -
    Changes
    -
      -
    • New decoration added - Block, Flex, Button
    • -
    • Changed structure Tabs
    • -
    -
    -
  • -
  • - v1.22.0 - -
    -
    Changes
    -
      -
    • Added Dashboard block - ResourcePreview
    • -
    • Fixed select mode for BelongsToMany
    • -
    -
    -
  • -
  • - v1.21.0 - -
    -
    Changes
    -
      -
    • ResourceMode for HasOne/HasMany fields
    • -
    • Precognition
    • -
    • Enabling adding and editing content in modal windows
    • -
    -
    -
  • -
  • - v1.20.0 - -
    -
    Changes
    -
      -
    • Added notifications
    • -
    • Import
    • -
    • Import and Export Queues
    • -
    • Storage disk and directory for import and export
    • -
    • Arbitrary Views
    • -
    • AddLink method with empty parameter
    • -
    • phpoffice/phpspreadsheet package was replaced with a lightweight and efficient rap2hpoutre/fast-excel
    • -
    -
    -
  • -
  • - v1.19.0 - -
    -
    Changes
    -
      -
    • Login via social networks based on the Socialite login
    • -
    • withTime method for the Date field
    • -
    • History of changes in resources made by user (to keep track of the author and subject of amendments)
    • -
    • Fulltext search
    • -
    -
    -
  • -
  • - v1.18.0 - -
    -
    Changes
    -
      -
    • canSee method for fields and filters
    • -
    • ValuesQuery method for Relationship fields
    • -
    • Fix attributes for Json(KeyValue)
    • -
    -
    -
  • -
  • - v1.17.0 - -
    -
    Changes
    -
      -
    • Subheader for resources
    • -
    -
    -
  • -
  • - v1.16.0 -
  • -
  • - v1.15.0 - -
    -
    Changes
    -
      -
    • New CKEditor field
    • -
    • New Quill field
    • -
    • New Translatable field to work with Laravel-translatable made by - Spatie
    • -
    • Labels for menu items
    • -
    • onlyCount method for the BelongsToMany field
    • -
    • ShowOnUpdateForm/showOnCreateForm methods for fields
    • -
    • The autoUpdate method for the "Switch" field that enables/disables the option to change the field on the main page
    • -
    • The addLink method for adding a hint link to a field
    • -
    • Custom bulk actions
    • -
    • Custom styles for rows and cells of the table for displaying data
    • -
    • Profile page
    • -
    • Custom pages
    • -
    -
    -
  • -
  • - v1.14.0 -
  • -
  • - v1.13.0 - -
    -
    Changes
    -
      -
    • New MediaLibrary field to work with Laravel-medialibrary made by - Spatie
    • -
    -
    -
  • -
  • - v1.12.0 - -
    -
    Changes
    -
      -
    • BeforeSave and afterSave events for fields
    • -
    -
    -
  • -
  • - v1.11.0 - -
  • -
  • - v1.10.0 - -
    -
    Changes
    -
      -
    • New parameter: config/moonshine.php
    • -
    -
    -
  • - -
  • - v1.9.0 -
  • - -
  • - v1.8.0 -
  • - -
  • - v1.7.0 -
  • - -
  • - v1.6.0 -
  • - -
  • - v1.5.0 -
    -
    Changes
    -
      -
    • Simplified installation. Everything is wrapped in the artisan moonshine:install command
    • -
    • New config/moonshine.php
    • -
    • App/MoonShine/Controllers directory removed
    • -
    • Changing the resource base class: MoonShine\Resources\BaseResource -> MoonShine\Resources\Resource
    • -
    • Dashboard.php added to the main app/MoonShine directory to customize the admin panel
    • -
    -
    -
  • - -
  • - v1.4.0 -
  • - -
  • - v1.3.0 -
  • - -
  • - v1.2.0 -
  • - -
  • - v1.1.0 -
  • - -
  • - v1.0.0 -
  • -
-
-
diff --git a/resources/views/pages/en/resources/actions.blade.php b/resources/views/pages/en/resources/actions.blade.php deleted file mode 100644 index 8477bff3..00000000 --- a/resources/views/pages/en/resources/actions.blade.php +++ /dev/null @@ -1,54 +0,0 @@ - - -Basics - - - Often it is necessary to do something with the list of the section and "Actions" serve for this purpose. - At the moment, there is only one Action class in MoonShine, which is responsible for exporting data, - but actions could be extended and you can easily write your own. - - - - You can simply return all the necessary actions in the actions method which returns an array. - And we will talk about actions structure in the "Actions" section. - - - - If the method is absent or returns an empty array, then the actions will not be displayed - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; -use MoonShine\Actions\ExportAction; // [tl! focus] - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - //... - - public function actions(): array // [tl! focus:start] - { - return [ - ExportAction::make('Export') - ]; - } // [tl! focus:end] - - //... -} - - - - - -@include('pages.en.resources.shared.actions_view', ['action' => 'ExportAction']) - - diff --git a/resources/views/pages/en/resources/active_actions.blade.php b/resources/views/pages/en/resources/active_actions.blade.php deleted file mode 100644 index 514fe339..00000000 --- a/resources/views/pages/en/resources/active_actions.blade.php +++ /dev/null @@ -1,55 +0,0 @@ - - - - Quite often you need to create a resource with the disabled delete - or add or edit section. And we are not talking about authorization here, but about the global exclusion of these sections. - This could be done very easy by using the activeActions property in the resource - - - -namespace MoonShine\Resources; - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - - public static array $activeActions = ['create', 'show', 'edit', 'delete']; // [tl! focus] - //... -} - - -Just eliminate the needless one - - - public static array $activeActions = ['create']; // [tl! focus] - - -You can also use the getActiveActions() method and set your own logic for the available sections - - -namespace MoonShine\Resources; - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - - public static array $activeActions = ['create', 'show', 'edit']; // [tl! focus] - - //... - - public function getActiveActions(): array // [tl! focus:start] - { - if (auth()->id() === $this->getItem()?->author_id) { - return array_merge(static::$activeActions, ['delete']); - } - - return static::$activeActions; - } // [tl! focus:end] -} - - - diff --git a/resources/views/pages/en/resources/bulk_actions.blade.php b/resources/views/pages/en/resources/bulk_actions.blade.php deleted file mode 100644 index 3289cd5a..00000000 --- a/resources/views/pages/en/resources/bulk_actions.blade.php +++ /dev/null @@ -1,48 +0,0 @@ - - - - By default, the table in the MoonShine panel contains only 1 mass action for the elements - deletion. - But you can also add your own custom bulk actions - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; -use MoonShine\BulkActions\BulkAction; // [tl! focus] - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - //... - - public function bulkActions(): array // [tl! focus:start] - { - return [ - BulkAction::make('Deactivation', function (Model $item) { - $item->update(['active' => false]); - }, 'Deactivated')->icon('app') - ]; - } // [tl! focus:end] - - //... -} - - -

- The first argument is the name of the action. - The second argument is a callback with the current element parameter. - The third argument is the message that will be displayed after the execution of the action. -

- -@include('pages.en.resources.shared.actions_view', ['action' => 'BulkAction']) -@include('pages.en.resources.shared.actions_confirm', ['action' => 'BulkAction']) - -
diff --git a/resources/views/pages/en/resources/components.blade.php b/resources/views/pages/en/resources/components.blade.php deleted file mode 100644 index fc312ccd..00000000 --- a/resources/views/pages/en/resources/components.blade.php +++ /dev/null @@ -1,133 +0,0 @@ - - -Basics - - - You can add your own components based on the MoonShine\IndexComponent, MoonShine\FormComponent - or MoonShine\DetailComponent abstract classes to extend the functionality, - they will be displayed below the main form or below detailed information respectively - - - - All custom components must be registered in the components() method - - - -namespace MoonShine\Resources; - -class ArticleResource extends Resource -{ - //... - - public function components(): array // [tl! focus:2] - { - return [ - // ... - ]; - } // [tl! focus:-1] - - //... -} - - -Permissions - - - Example of adding a PermissionFormComponent component - - - -namespace MoonShine\Resources; - -use MoonShine\FormComponents\PermissionFormComponent; // [tl! focus] -use MoonShine\Models\MoonshineUserRole; -use MoonShine\Resources\Resource; - -class MoonShineUserResource extends Resource -{ - //... - - public function components(): array - { - return [ - PermissionFormComponent::make('Permissions') // [tl! focus] - ->canSee(fn() => auth()->user()->moonshine_user_role_id === MoonshineUserRole::DEFAULT_ROLE_ID) - ]; - } - - //... -} - - - - - - - If you use your model for authentication, - then you need to add the MoonShine\Traits\Models\HasMoonShinePermissions trait to it - - - - If you use your resource with admin output, - you need to add the MoonShine\Traits\Resource\WithUserPermissions trait to the resource - - -Change log - - - To display the log of edits in the admin panel based on the user you must add - the MoonShine\Traits\Models\HasMoonShineChangeLog trait to the model being used in the resource - - - -namespace App\Models; - -use Illuminate\Database\Eloquent\Model; -use MoonShine\Traits\Models\HasMoonShineChangeLog; // [tl! focus] - -class Article extends Model -{ - use HasMoonShineChangeLog; // [tl! focus] - - //... -} - - - - And also add a component in the ChangeLogFormComponent resource - - - -namespace MoonShine\Resources; - -use MoonShine\FormComponents\ChangeLogFormComponent; // [tl! focus] -use MoonShine\Models\MoonshineUserRole; -use MoonShine\Resources\Resource; - -class ArticleResource extends Resource -{ - // ... - public function components(): array - { - return [ - ChangeLogFormComponent::make('Change log') // [tl! focus] - ->canSee(fn() => auth()->user()->moonshine_user_role_id === MoonshineUserRole::DEFAULT_ROLE_ID), - ]; - } - // ... -} - - - - - - diff --git a/resources/views/pages/en/resources/fields.blade.php b/resources/views/pages/en/resources/fields.blade.php deleted file mode 100644 index 93169f67..00000000 --- a/resources/views/pages/en/resources/fields.blade.php +++ /dev/null @@ -1,49 +0,0 @@ - - - - Fields in most cases refer to table fields from the database. Within CRUD they will be displayed - with a list on the main page of the section (resource) and on the page for creating and editing records. - There are many types of fields in the MoonShine admin panel to cover all possible requirements! - They also cover all possible relationships in Laravel and are named in the same way as relationship methods for convenience: - BelongsTo, BelongsToMany, HasOne, HasMany, - HasOneThrough, HasManyThrough, MorphOne, MorphMany - - - - Adding new fields is extremely easy! You can simply return all the required fields in the fields method which returns an array. - And we will talk about fields structure in the "Fields" section. - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; -use MoonShine\Fields\ID; // [tl! focus] -use MoonShine\Fields\Text; // [tl! focus] -use MoonShine\Decorations\Block; - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - //... - - public function fields(): array // [tl! focus:start] - { - return [ - Block::make('Block title', [ - ID::make(), - Text::make('header', 'title'), - ]) - ]; - } // [tl! focus:end] - - //... -} - - - - - - diff --git a/resources/views/pages/en/resources/filters.blade.php b/resources/views/pages/en/resources/filters.blade.php deleted file mode 100644 index 0472dbe7..00000000 --- a/resources/views/pages/en/resources/filters.blade.php +++ /dev/null @@ -1,55 +0,0 @@ - - - - Filters are not much different from fields and inherit their properties and methods! - They are displayed on the main page of the section to filter the list of data. - - - - Adding new filters is easy! You can simply return all the necessary filters in the filters method which returns an array. - And we will talk about filters structure in the "Filters" section. - - - - If the method is absent or returns an empty array, then the filters will not be displayed - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; -use MoonShine\Filters\TextFilter; // [tl! focus] - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - //... - - // [tl! focus:start] - public function filters(): array - { - return [ - TextFilter::make('header', 'title') - ]; - } - - // Don't forget to connect filters to the resource - public function actions(): array - { - return [ - FiltersAction::make(trans('moonshine::ui.filters')), - ]; - } - - // [tl! focus:end] - - //... -} - - - - - - diff --git a/resources/views/pages/en/resources/form_actions.blade.php b/resources/views/pages/en/resources/form_actions.blade.php deleted file mode 100644 index 1faf37e1..00000000 --- a/resources/views/pages/en/resources/form_actions.blade.php +++ /dev/null @@ -1,45 +0,0 @@ - - - - By default, forms in the MoonShine panel contain only 1 action - saving. - But you can add your own custom actions - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; -use MoonShine\FormActions\FormAction; // [tl! focus] - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - //... - - public function formActions(): array // [tl! focus:start] - { - return [ - FormAction::make('Delete', function (Model $item) { - $item->delete(); - }, 'Removed')->icon('delete') - ]; - } // [tl! focus:end] - - //... -} - - - - - -@include('pages.en.resources.shared.actions_view', ['action' => 'FormAction']) -@include('pages.en.resources.shared.actions_confirm', ['action' => 'FormAction']) - - diff --git a/resources/views/pages/en/resources/index.blade.php b/resources/views/pages/en/resources/index.blade.php deleted file mode 100644 index 4220fcee..00000000 --- a/resources/views/pages/en/resources/index.blade.php +++ /dev/null @@ -1,370 +0,0 @@ - - -Basics - - - What is an administrative panel? Basically, these are partitions based on data from the database, based on eloquent models. - - - - MoonShine is based on standard Laravel resource controllers and resource routes - - - php artisan make:controller Controller --resource - - - - Route::resources('resources', Controller::class); - - - But system will generate and declare them independently. - - - - Therefore, the MoonShine resources (admin panel sections) are based on the eloquent model. - - -Creating a section in the admin panel - - - php artisan moonshine:resource Post - - - - This will create a Resource class that will be the basis of the new section in the panel. - By default, it is located in the app/MoonShine/Resources/PostResource directory. - And it will be automatically bound to the app/Models/Post model. - The section title will keep the Posts name - - - - You can change the model binding and section title along with the command - - - php artisan moonshine:resource Post --model=CustomPost --title="Articles" - - - - php artisan moonshine:resource Post --model="App\Models\CustomPost" --title="Articles" - - - -Main properties of the section - - The main parameters of the resource that could be changed in order to customize its work - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; // Model [tl! focus] - - public static string $title = 'Articles'; // Section name [tl! focus] - - public static string $subTitle = 'Article Management'; // Text under section heading [tl! focus] - - public static array $with = ['category']; // Eager load [tl! focus] - - public static bool $withPolicy = false; // Authorization [tl! focus] - - public static string $orderField = 'id'; // Default sort field [tl! focus] - - public static string $orderType = 'DESC'; // Default sort type [tl! focus] - - public static int $itemsPerPage = 25; // Number of items per page [tl! focus] - - //... -} - - - - - -Declaring a partition in the system - - - New resources are added to the system in the service provider using the singleton class - MoonShine\MoonShine. - - - -namespace App\Providers; - -use App\MoonShine\Resources\PostResource; // [tl! focus] - -class MoonShineServiceProvider extends ServiceProvider -{ - //... - - public function boot() - { - app(MoonShine::class)->resources([ - new PostResource(), - ]) // [tl! focus: -2] - } - - - - To add a resource link to the navigation menu, the resource can be registered using the menu() method. - - - -namespace App\Providers; - -use App\MoonShine\Resources\PostResource; // [tl! focus] -use Illuminate\Support\ServiceProvider; -use MoonShine\Menu\MenuItem; // [tl! focus] -use MoonShine\MoonShine; // [tl! focus] -use MoonShine\Resources\MoonShineUserResource; -use MoonShine\Resources\MoonShineUserRoleResource; - -class MoonShineServiceProvider extends ServiceProvider -{ - //... - - public function boot() - { - app(MoonShine::class)->menu([ // [tl! focus] - MenuItem::make('Admins', new MoonShineUserResource()), - MenuItem::make('Roles', new MoonShineUserRoleResource()), - MenuItem::make('Posts', new PostResource()), // [tl! focus] - ]); // [tl! focus] - } -} - - - - - - - For advanced settings, see Digging Deeper > Menu. - - -Current item/model - - - In the resource you have access to the current element and model via the relevant methods. - - - - $this->getItem(); - - - - $this->getModel(); - - - - If the element does not yet exist (action create), then the getItem() method will return NULL. - - -Modal windows - - - Ability to add, edit and view entries directly on the list page in a modal window. - - - -namespace App\MoonShine\Resources; - -use App\Models\Post; - -use MoonShine\Resources\Resource; - -class PostResource extends Resource -{ - public static string $model = Post::class; - - public static string $title = 'Posts'; - - protected bool $createInModal = true; // [tl! focus] - - protected bool $editInModal = true; // [tl! focus] - - protected bool $showInModal = true; // [tl! focus] - - // ... - - -Route after save - - - After saving the resource, you can specify which route to go to: - the list page, the detail page, or the edit page. - - -Default index - - -namespace App\MoonShine\Resources; - -use App\Models\Post; -use MoonShine\Resources\Resource; - -class PostResource extends Resource -{ - public static string $model = Post::class; - - protected string $routeAfterSave = 'index'; // index, show, edit [tl! focus] - - // ... -} - - -Simple pagination - - - If you don't plan to display the total number of pages, use Simple Pagination. - This will avoid additional queries on the total number of records in the database. - - - -namespace App\MoonShine\Resources; - -use App\Models\Post; -use MoonShine\Resources\Resource; - -class PostResource extends Resource -{ - public static string $model = Post::class; - - public static bool $simplePaginate = true; // [tl! focus] - - // ... -} - - - - - -Disable pagination - - - If you do not plan to use pagination, then you can turn it off. - - - -namespace App\MoonShine\Resources; - -use App\Models\Post; -use MoonShine\Resources\Resource; - -class PostResource extends Resource -{ - public static string $model = Post::class; - - protected bool $usePagination = false; // [tl! focus] - - // ... -} - - -Customization of views - - - You can customize the display of the list and form through - the properties itemsView, formView and detailView. - - - -namespace App\MoonShine\Resources; - -use App\Models\Post; -use MoonShine\Resources\Resource; - -class PostResource extends Resource -{ - public static string $model = Post::class; - - protected string $itemsView = 'moonshine::crud.shared.table'; // [tl! focus] - - protected string $formView = 'moonshine::crud.shared.form'; // [tl! focus] - - protected string $detailView = 'moonshine::crud.shared.detail-card'; // [tl! focus] - - // ... -} - - - - Or by overriding the appropriate methods - - - -namespace App\MoonShine\Resources; - -use App\Models\Post; -use MoonShine\Resources\Resource; - -class PostResource extends Resource -{ - public static string $model = Post::class; - - public function itemsView(): string - { - return $this->itemsView; - } // [tl! focus:-3] - - public function formView(): string - { - return $this->formView; - } // [tl! focus:-3] - - public function detailView(): string - { - return $this->detailView; - } // [tl! focus:-3] - - // ... -} - - -Precognition - - - Precognition in Laravel allows you to create a "live" check for your application - without having to duplicate validation rules. - - - - In Moonshine, you can use precognition when sending requests to your resource. - To do this, set the precognition property to true. - - - -namespace App\MoonShine\Resources; - -use App\Models\Post; -use MoonShine\Resources\Resource; - -class PostResource extends Resource -{ - public static string $model = Post::class; - - protected bool $precognition = true; // [tl! focus] - - // ... -} - - - diff --git a/resources/views/pages/en/resources/item_actions.blade.php b/resources/views/pages/en/resources/item_actions.blade.php deleted file mode 100644 index 1ad60045..00000000 --- a/resources/views/pages/en/resources/item_actions.blade.php +++ /dev/null @@ -1,72 +0,0 @@ - - -Registration - - - By default, the table in the MoonShine panel contains only 2 actions for items - edit and delete. - But you can also add your own custom actions - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; -use MoonShine\ItemActions\ItemAction; // [tl! focus] - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - //... - - public function itemActions(): array // [tl! focus:start] - { - return [ - ItemAction::make('Deactivating', function (Model $item) { - $item->update(['active' => false]); - }, 'Deactivated')->icon('app') - ]; - } // [tl! focus:end] - - //... -} - - -

- The first argument is the name of the action. - The second argument is the callback with the current item parameter. - The third argument - the message that will be displayed after the action is executed -

- -Display condition - - - Display action by condition - - - -... -public function itemActions(): array -{ - return [ - ItemAction::make('Restore', function (Model $item) { - $item->restore(); - }, 'Retrieved') - ->canSee(fn(Model $item) => $item->trashed()) // [tl! focus] - ]; -} -... - - -@include('pages.en.resources.shared.actions_view', ['action' => 'ItemAction']) -@include('pages.en.resources.shared.actions_confirm', ['action' => 'ItemAction']) - -
diff --git a/resources/views/pages/en/resources/metrics.blade.php b/resources/views/pages/en/resources/metrics.blade.php deleted file mode 100644 index 0de98cb5..00000000 --- a/resources/views/pages/en/resources/metrics.blade.php +++ /dev/null @@ -1,33 +0,0 @@ - - - - Same as the control panel you can - display metrics in every resource - - - -namespace MoonShine\Resources; - - -use MoonShine\Metrics\ValueMetric; - -class PostResource extends Resource -{ - //... - - public function metrics(): array // [tl! focus:start] - { - return [ - ValueMetric::make('Completed orders') - ->value(Orders::completed()->count()) - ]; - } // [tl! focus:end] - - //... -} - - - - - - diff --git a/resources/views/pages/en/resources/query.blade.php b/resources/views/pages/en/resources/query.blade.php deleted file mode 100644 index e4d062da..00000000 --- a/resources/views/pages/en/resources/query.blade.php +++ /dev/null @@ -1,93 +0,0 @@ - - -Filter - - - Quite often you have to filter the output with a list of records from the very start. - - - - In general, you can easily override the query builder in the resource. - - - -namespace MoonShine\Resources; - -use Illuminate\Contracts\Database\Eloquent\Builder; // [tl! focus] - -class PostResource extends Resource -{ - //... - public function query(): Builder // [tl! focus:start] - { - return parent::query() - ->where('active', true); - } // [tl! focus:end] - //... -} - - -Order - - - By overriding the performOrder() method, you can customize the sorting of elements. - - - -namespace MoonShine\Resources; - -use Illuminate\Contracts\Database\Eloquent\Builder; // [tl! focus] - -class PostResource extends Resource -{ - //... - public function performOrder(Builder $query, string $column, string $direction): Builder // [tl! focus:start] - { - return $query->orderBy( - $column, - $direction - ); - } // [tl! focus:end] - //... -} - - -Scopes - - - Laravel has a handy scopes functionality that could be used within the MoonShine admin panel. - - - - At first, you need to create the scopes required. - - - -php artisan make:scope ActiveUserScope - - - -namespace MoonShine\Resources; - -use App\Models\Scopes\ActiveUserScope; // [tl! focus] - -class PostResource extends Resource -{ - //... - public function scopes(): array // [tl! focus:start] - { - return [ - new ActiveUserScope() - ]; - } // [tl! focus:end] - //... -} - - - diff --git a/resources/views/pages/en/resources/query_tags.blade.php b/resources/views/pages/en/resources/query_tags.blade.php deleted file mode 100644 index ae18b55e..00000000 --- a/resources/views/pages/en/resources/query_tags.blade.php +++ /dev/null @@ -1,44 +0,0 @@ - - - - Sometimes you may need to create a set of filters (collection of results) - and display it in the listing. Tags have been created for these cases. - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; -use MoonShine\QueryTags\QueryTag; // [tl! focus] -use Illuminate\Contracts\Database\Eloquent\Builder; - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - //... - - public function queryTags(): array // [tl! focus:start] - { - return [ - QueryTag::make( - 'Post with author', // Tag Title - fn(Builder $query) => $query->whereNotNull('author_id') // Query builder - ), - - QueryTag::make( - 'Post without an author', - fn(Builder $query) => $query->whereNull('author_id') - )->icon('users') - ]; - } // [tl! focus:end] - - //... -} - - - - - - diff --git a/resources/views/pages/en/resources/search.blade.php b/resources/views/pages/en/resources/search.blade.php deleted file mode 100644 index c46ce92e..00000000 --- a/resources/views/pages/en/resources/search.blade.php +++ /dev/null @@ -1,79 +0,0 @@ - - -Основы - - - Everything is simple here! For a full-text search, you need to specify which fields will be included into the search. - To do this, you need to list them in the return array in the search() method - - - - If the method is missing or returns an empty array, the search string will not be displayed - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; - -class PostResource extends Resource -{ - //... - - public function search(): array // [tl! focus:start] - { - return ['id', 'title']; - } // [tl! focus:end] - - //... -} - - - - If a fulltext search is required, you must use the MoonShine\Attributes\SearchUsingFullText - - - - namespace MoonShine\Resources; - - use MoonShine\Attributes\SearchUsingFullText; // [tl! focus] - - class PostResource extends Resource - { - //... - - #[SearchUsingFullText(['title', 'text'])] // [tl! focus] - public function search(): array - { - return ['id']; - } - - //... - } - - - - Don't forget to add the fulltext index - - - - - -Global search - - - To organize a global search, you can use the package - Algolias search for MoonShine - - - - This package uses the Algolia search engine, which takes context and query type into account, - possible typos, synonyms and word forms, entering a query in different languages and much more. - - - diff --git a/resources/views/pages/en/resources/shared/actions_confirm.blade.php b/resources/views/pages/en/resources/shared/actions_confirm.blade.php deleted file mode 100644 index 45b14f46..00000000 --- a/resources/views/pages/en/resources/shared/actions_confirm.blade.php +++ /dev/null @@ -1,78 +0,0 @@ -Confirm the action - - - To confirm the action, you must use the withConfirm method - - - -use MoonShine\{!! ($action === 'ExportAction' || $action === 'ImportAction') ? 'Action' : $action !!}s\{{ $action }}; - -//... -public function {!! ($action === 'ExportAction' || $action === 'ImportAction') ? 'action' : str($action)->camel() !!}s(): array -{ - return [ - @if ( $action === 'ExportAction' || $action === 'ImportAction') - {!! $action !!}::make('{!! str($action)->replace('Action', '') !!}') - @else - {{ $action }}::make('Deactivation', function (Model $item) { - $item->update(['active' => false]); - }, 'Deactivated') - @endif - ->withConfirm() // [tl! focus] - ]; -} -//... - - - - - - - The withConfirm() method can be passed the title and text for the modal window, as well as the title - for confirmation button - - - -use MoonShine\{!! ($action === 'ExportAction' || $action === 'ImportAction') ? 'Action' : $action !!}s\{{ $action }}; - -//... -public function {!! ($action === 'ExportAction' || $action === 'ImportAction') ? 'action' : str($action)->camel() !!}s(): array -{ - return [ - @if ( $action === 'ExportAction' || $action === 'ImportAction') - {!! $action !!}::make('{!! str($action)->replace('Action', '') !!}') - @else - {{ $action }}::make('Deactivation', function (Model $item) { - $item->update(['active' => false]); - }, 'Deactivated') - @endif - ->withConfirm('Title', 'Modal content', 'Accept') // [tl! focus] - ]; -} -//... - - - - The errorMessage() method allows you to set the text of the error message - - - -use MoonShine\{!! ($action === 'ExportAction' || $action === 'ImportAction') ? 'Action' : $action !!}s\{{ $action }}; - -//... -public function {!! ($action === 'ExportAction' || $action === 'ImportAction') ? 'action' : str($action)->camel() !!}s(): array -{ - return [ - @if ( $action === 'ExportAction' || $action === 'ImportAction') - {!! $action !!}::make('{!! str($action)->replace('Action', '') !!}') - @else - {{ $action }}::make('Deactivation', function (Model $item) { - $item->update(['active' => false]); - }, 'Deactivated') - @endif - ->withConfirm('Title', 'Modal content', 'Accept') - ->errorMessage('Fail') // [tl! focus] - ]; -} -//... - diff --git a/resources/views/pages/en/resources/shared/actions_view.blade.php b/resources/views/pages/en/resources/shared/actions_view.blade.php deleted file mode 100644 index ef2448da..00000000 --- a/resources/views/pages/en/resources/shared/actions_view.blade.php +++ /dev/null @@ -1,59 +0,0 @@ -Display method - - - To display actions as a dropdown list, you can use the showInDropdown method - - - -use MoonShine\{!! ($action === 'ExportAction' || $action === 'ImportAction') ? 'Action' : $action !!}s\{{ $action }}; - -//... -public function {!! ($action === 'ExportAction' || $action === 'ImportAction') ? 'action' : str($action)->camel() !!}s(): array -{ - return [ - @if ( $action === 'ExportAction' || $action === 'ImportAction') - {!! $action !!}::make('{!! str($action)->replace('Action', '') !!}') - @else - {{ $action }}::make('Deactivation', function (Model $item) { - $item->update(['active' => false]); - }, 'Deactivated') - @endif - ->showInDropdown() // [tl! focus] - ]; -} -//... - - - - This display method is used by default - - - - - - - To display actions as a horizontal list, you can use the showInLine method - - - -use MoonShine\{!! ($action === 'ExportAction' || $action === 'ImportAction') ? 'Action' : $action !!}s\{{ $action }}; - -//... -public function {!! ($action === 'ExportAction' || $action === 'ImportAction') ? 'action' : str($action)->camel() !!}s(): array -{ - return [ - @if ( $action === 'ExportAction' || $action === 'ImportAction') - {!! $action !!}::make('{!! str($action)->replace('Action', '') !!}') - @else - {{ $action }}::make('Deactivation', function (Model $item) { - $item->update(['active' => false]); - }, 'Deactivated') - @endif - ->showInLine() // [tl! focus] - ]; -} -//... - - - - diff --git a/resources/views/pages/en/resources/singleton.blade.php b/resources/views/pages/en/resources/singleton.blade.php deleted file mode 100644 index 5dc97dd1..00000000 --- a/resources/views/pages/en/resources/singleton.blade.php +++ /dev/null @@ -1,52 +0,0 @@ - - - - A resource for one entry without the ability to list, add and delete! Perfect for resources with settings. - Implements singletonResource in Laravel routing. - - - - To use it, you need to implement the getId method specifying the id of the record in the database. - - - -// ... - -class SettingResource extends SingletonResource -{ - public static string $model = Setting::class; - - public static string $title = 'Settings'; - - public function getId(): int|string - { - return 1; - } -// ... - - - - You can create SingletonResource using the artisan command - - - - php artisan moonshine:resource Setting --singleton - - - - or - - - - php artisan moonshine:resource Setting --s - - - - with id - - - - php artisan moonshine:resource Setting --s --id=1 - - - diff --git a/resources/views/pages/en/resources/table_styles.blade.php b/resources/views/pages/en/resources/table_styles.blade.php deleted file mode 100644 index 95543335..00000000 --- a/resources/views/pages/en/resources/table_styles.blade.php +++ /dev/null @@ -1,81 +0,0 @@ - - - - Using resources you can customize the color for tr and td for tables with data - - - -namespace MoonShine\Resources; - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - //... - - public function trClass(Model $item, int $index): string // [tl! focus:start] - { - if($item->id === 1 || $index === 2) { - return 'green'; - } - - return parent::trClass($item, $index); - } - - public function tdClass(Model $item, int $index, int $cell): string - { - if($cell === 6) { - return 'red'; - } - - return parent::tdClass($item, $index, $cell); - } // [tl! focus:end] - //... -} - - -@include('pages.en.ui.shared.colors') - - - - - - You can also add custom styles - - - -namespace MoonShine\Resources; - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - //... - - public function trStyles(Model $item, int $index): string // [tl! focus:start] - { - if ($item->id === 1 || $index === 2) { - return 'background: rgba(128, 152, 253, .5);'; - } - - return parent::trStyles($item, $index); - } - - public function tdStyles(Model $item, int $index, int $cell): string - { - if ($cell === 3) { - return 'background: rgba(128, 253, 163, .5); text-align:center;'; - } - - return parent::tdStyles($item, $index, $cell); - } // [tl! focus:end] - //... -} - - - - - - diff --git a/resources/views/pages/en/resources/validation.blade.php b/resources/views/pages/en/resources/validation.blade.php deleted file mode 100644 index 3a669777..00000000 --- a/resources/views/pages/en/resources/validation.blade.php +++ /dev/null @@ -1,103 +0,0 @@ - - -Basics - - - Validation is as simple as in the FormRequests classes provided by Laravel. - - - - You can simply add rules to the rules() method of the resource in the usual way. - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - - public static string $title = 'Articles'; - //... - - public function rules($item): array // [tl! focus:start] - { - return [ - 'title' => ['required', 'string', 'min:5'] - ]; - } // [tl! focus:end] - - //... -} - - - - - -Messages - - - Using the validationMessages() method, you can create your own validation error messages - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - //... - - public function validationMessages(): array // [tl! focus:start] - { - return [ - 'email.required' => 'Required email' - ]; - } // [tl! focus:end] - - //... -} - - -Preparing Input For Validation - - - If you need to prepare or sanitize any data from the request before you apply your validation rules, - you may use the prepareForValidation() method. - - - -namespace MoonShine\Resources; - -use MoonShine\Models\MoonshineUser; - -class PostResource extends Resource -{ - public static string $model = App\Models\Post::class; - //... - - public function prepareForValidation(): void // [tl! focus:start] - { - request()?->merge([ - 'email' => request() - ?->string('email') - ->lower() - ->value() - ]); - } // [tl! focus:end] - - //... -} - - - diff --git a/resources/views/pages/en/upgrade_guide.blade.php b/resources/views/pages/en/upgrade_guide.blade.php deleted file mode 100644 index ebb06fda..00000000 --- a/resources/views/pages/en/upgrade_guide.blade.php +++ /dev/null @@ -1,38 +0,0 @@ - - - - Upgrading To 1.50 From 1.0 - - - - registerResources is outdated and will be removed in 2.0 version - - - -app(MoonShine::class)->registerResources([ - MenuItem::make('Admins', new MoonShineUserResource()), -]); - - - - We recommend to use the menu method - - - -app(MoonShine::class)->menu([ - MenuItem::make('Admins', new MoonShineUserResource()), -]); - - - - The fullWidth field method is outdated and will be removed - - - - To create a display grid in a form, you should use the Grid/Column decorations - - - - Laravel filemanager is excluded from the base package, it should be installed separately - - From 2dc21d0cb7917f842cfc3411ba4d1c8a64376f33 Mon Sep 17 00:00:00 2001 From: Alexander Nikushkin Date: Mon, 30 Oct 2023 14:30:44 +0500 Subject: [PATCH 7/7] docs(components): basics --- config/menu.php | 4 +- ...bs.blade.php => decoration_tabs.blade.php} | 11 ++- .../views/pages/ru/components/index.blade.php | 93 ++++++++++++++++++- .../components/metric_donut_chart.blade.php | 1 - 4 files changed, 102 insertions(+), 7 deletions(-) rename resources/views/pages/ru/components/{tabs.blade.php => decoration_tabs.blade.php} (71%) diff --git a/config/menu.php b/config/menu.php index 934c2a4c..ad634b66 100644 --- a/config/menu.php +++ b/config/menu.php @@ -33,9 +33,9 @@ // Metrics 'Metrics:_divider_', - ['slug' => 'components-metric_value', 'label' => 'Value', 'title' => 'Metric Value'], - ['slug' => 'components-metric_line_chart', 'label' => 'Line Chart', 'title' => 'Metric Line Chart'], ['slug' => 'components-metric_donut_chart', 'label' => 'Donut Chart', 'title' => 'Metric Donut Chart'], + ['slug' => 'components-metric_line_chart', 'label' => 'Line Chart', 'title' => 'Metric Line Chart'], + ['slug' => 'components-metric_value', 'label' => 'Value', 'title' => 'Metric Value'], ], 'Appearance:photo' => [ diff --git a/resources/views/pages/ru/components/tabs.blade.php b/resources/views/pages/ru/components/decoration_tabs.blade.php similarity index 71% rename from resources/views/pages/ru/components/tabs.blade.php rename to resources/views/pages/ru/components/decoration_tabs.blade.php index 83dad1bd..7f24b6ee 100644 --- a/resources/views/pages/ru/components/tabs.blade.php +++ b/resources/views/pages/ru/components/decoration_tabs.blade.php @@ -1,12 +1,17 @@ [ + ['url' => '#make', 'label' => 'Make'], + ['url' => '#active-tab', 'label' => 'Активная вкладка'], + ] ]" > +Make + - На форму для удобства можно добавить вкладки и сгруппировать поля. + Компонент Tabs позволяет создавать вкладки. diff --git a/resources/views/pages/ru/components/index.blade.php b/resources/views/pages/ru/components/index.blade.php index cdb23c09..3aae7092 100644 --- a/resources/views/pages/ru/components/index.blade.php +++ b/resources/views/pages/ru/components/index.blade.php @@ -1,11 +1,102 @@ - + + +Основы + + + Компоненты в MoonShine являются основой для построения интерфейса.
+ В админ-панели уже реализовано множество компонентов, которые можно разделить на несколько групп: + Layouts, Decorations и Metrics. +
+ + + Layouts - компоненты используются для создания основных блоков админ-панели: + Flash, Footer, Header, LayoutBlock, LayoutBuilder, Menu, Profile, Sidebar, TopBar. + + + + Decorations - компоненты используются для визуального оформления пользовательского интерфейса: + Block, Collapse, Divider, Flex, Fragment, Grid, Heading, LineBreak, Tabs, TextBlock. + + Metrics - компоненты используются для создания информационных блоков: + DonutChartMetric, + LineChartMetric, + ValueMetric. + + + Админ-панель MoonShine не ограничивает вас в использовании других компонентов, + которые могут быть реализованы с использованием + Livewire, + а так же Blade + компоненты. + + +MoonshineComponent + + + В MoonShine реализована консольная команда для создания MoonshineComponent, + в котором уже реализованы основные методы для использования в админ панели. php artisan moonshine:component + + В результате будет создан класс NameComponent, который является основой нового компонента.
+ Располагается он, по умолчанию, в директории app/MoonShine/Components.
+ А так же Blade файл для компонента в директории resources/views/admin/components. +
+ + + + + Метод make() предназначен для создания экземпляра компонента. + + + +use App\MoonShine\Components\NameComponent; // [tl! focus] + +//... + +public function components(): array +{ + return [ + NameComponent::make() // [tl! focus] + ]; +} + +//... + + + + Метод viewData() позволяет передать данные в шаблон компонента. + + + +namespace App\MoonShine\Components; // [tl! focus] + +//... + +final class Test extends MoonshineComponent +{ + protected function viewData(): array + { + return []; + } +} + +//... + +
diff --git a/resources/views/pages/ru/components/metric_donut_chart.blade.php b/resources/views/pages/ru/components/metric_donut_chart.blade.php index 3db58f1b..66520e27 100644 --- a/resources/views/pages/ru/components/metric_donut_chart.blade.php +++ b/resources/views/pages/ru/components/metric_donut_chart.blade.php @@ -8,7 +8,6 @@ ]" > - Make