This commit is contained in:
Dan Harrin
2021-02-07 23:39:16 +00:00
parent fba5f0c5e8
commit bb664b4ee7
43 changed files with 445 additions and 417 deletions
-7
View File
@@ -1,7 +0,0 @@
<?php
return [
'error' => 'Errors found. Please check all form tabs for errors and try again.',
];
+1 -1
View File
@@ -1,5 +1,5 @@
@props([
'type' => 'submit',
'type' => 'submit',
])
<button type="{{ $type }}" {{ $attributes->merge(['class' => 'btn']) }}>
@@ -1,7 +1,7 @@
@props([
'errorKey' => null,
'for' => null,
'help' => null,
'helpMessage' => null,
'hint' => null,
'label' => null,
'labelPrefix' => null,
@@ -39,9 +39,9 @@
<x-filament::error :field="$errorKey" />
@endif
@if ($help)
<x-filament::help>
@markdown($help)
</x-filament::help>
@if ($helpMessage)
<x-filament::help-message>
@markdown($helpMessage)
</x-filament::help-message>
@endif
</div>
@@ -1,10 +1,13 @@
@props([
'id',
])
<div
aria-labelledby="{{ $id }}"
role="tabpanel"
tabindex="0"
x-show="tab === '{{ $id }}'"
{{ $attributes->merge(['class' => 'p-4 md:p-6']) }}
x-show="tab === '{{ $id }}'"
tabindex="0"
role="tabpanel"
id="{{ $id }}-tab"
aria-labelledby="{{ $id }}"
>
{{ $slot }}
</div>
+9 -5
View File
@@ -1,11 +1,15 @@
@props([
'id',
])
<button type="button"
aria-controls="{{ $id }}-tab"
x-bind:aria-selected="tab === '{{ $id }}'"
x-on:click="tab = '{{ $id }}'"
role="tab"
x-bind:tabindex="tab === '{{ $id }}' ? 0 : -1"
class="text-sm leading-tight font-medium p-3 md:px-6 -mb-px border-r border-gray-200"
:class="{ 'bg-white': tab === '{{ $id }}' }"
:aria-selected="tab === '{{ $id }}'"
aria-controls="{{ $id }}-tab" id="{{ $id }}"
:tabindex="tab === '{{ $id }}' ? 0 : -1"
@click="tab = '{{ $id }}'"
x-bind:class="{ 'bg-white': tab === '{{ $id }}' }"
>
{{ $slot }}
</button>
+4 -4
View File
@@ -1,16 +1,16 @@
@props([
'defaultTabId',
'label',
'tab',
])
<x-filament::card
x-data="{ tab: '{{ $tab }}' }"
x-data="{ tab: '{{ $defaultTabId }}' }"
x-cloak
class="overflow-hidden"
>
<div class="-m-4 md:-m-6">
<div class="bg-gray-100 border-b border-gray-200 flex" class="tablist" role="tablist" aria-label="{{ $label }}">
{{ $tablist }}
<div aria-label="{{ $label }}" role="tablist" class="bg-gray-100 border-b border-gray-200 flex">
{{ $tabList }}
</div>
{{ $slot }}
+1 -1
View File
@@ -42,7 +42,7 @@
{{ $field->nameAttribute }}="{{ $field->name }}"
class="sr-only"
id="{{ $field->id }}"
{{ Filament\format_attributes($field->attributes) }}
{{ Filament\format_attributes($field->extraAttributes) }}
/>
<div x-show="isUploading" :aria-hidden="!isUploading" class="absolute bottom-0 -mb-3 w-48 max-w-full">
+2 -2
View File
@@ -1,7 +1,7 @@
<x-filament::field-group
:errorKey="$field->errorKey"
:for="$field->id"
:help="__($field->help)"
:help-message="__($field->helpMessage)"
:hint="__($field->hint)"
:label="__($field->label)"
:required="$field->required"
@@ -11,7 +11,7 @@
:autofocus="$field->autofocus"
:disabled="$field->disabled"
:error-key="$field->errorKey"
:extra-attributes="$field->attributes"
:extra-attributes="$field->extraAttributes"
:id="$field->id"
:name="$field->name"
:name-attribute="$field->nameAttribute"
+2 -2
View File
@@ -9,7 +9,7 @@
<x-filament::field-group
:errorKey="$field->errorKey"
:for="$field->id"
:help="__($field->help)"
:help-message="__($field->helpMessage)"
:hint="__($field->hint)"
:label="__($field->label)"
:required="$field->required"
@@ -26,7 +26,7 @@
:name="$field->name"
:name-attribute="$field->nameAttribute"
:error-key="$field->errorKey"
:extra-attributes="$field->attributes"
:extra-attributes="$field->extraAttributes"
x-ref="input"
/>
</div>
+4 -4
View File
@@ -13,7 +13,7 @@
<x-filament::field-group
:errorKey="$field->errorKey"
:for="$field->id"
:help="__($field->help)"
:help-message="__($field->helpMessage)"
:hint="__($field->hint)"
:label="__($field->label)"
:required="$field->required"
@@ -23,10 +23,10 @@
x-data
x-init="
FilePond.setOptions({
@isset($field->attributes['placeholder'])
labelIdle: '{{ $field->attributes['placeholder'] }}',
@isset($field->extraAttributes['placeholder'])
labelIdle: '{{ $field->extraAttributes['placeholder'] }}',
@endisset
allowMultiple: {{ isset($field->attributes['multiple']) ? 'true' : 'false' }},
allowMultiple: {{ isset($field->extraAttributes['multiple']) ? 'true' : 'false' }},
server: {
process:(fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
@this.upload('{{ $field->model }}', file, load, error, progress)
+2 -2
View File
@@ -24,7 +24,7 @@
<x-filament::field-group
:errorKey="$field->errorKey"
:for="$field->id"
:help="__($field->help)"
:help-message="__($field->helpMessage)"
:hint="__($field->hint)"
:label="__($field->label)"
:required="$field->required"
@@ -155,7 +155,7 @@
toolbar="trix-toolbar-{{ $field->id }}"
x-ref="trix"
class="block w-full rounded shadow-sm border-gray-400 focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50 bg-white border-gray-300 prose max-w-none"
{{ Filament\format_attributes($field->attributes) }}
{{ Filament\format_attributes($field->extraAttributes) }}
/>
@else
<div x-html="value" class="p-3 rounded shadow-sm border border-gray-400"></div>
@@ -5,7 +5,7 @@
<x-filament::field-group
:errorKey="$field->errorKey"
:for="$field->id"
:help="__($field->help)"
:help-message="__($field->helpMessage)"
:hint="__($field->hint)"
:label="__($field->label)"
:required="$field->required"
@@ -14,7 +14,7 @@
<x-filament::select
:id="$field->id"
:error-key="$field->errorKey"
:extra-attributes="$field->attributes"
:extra-attributes="$field->extraAttributes"
wire:change="{{ $field->addMethod }}($event.target.value)"
>
<option value="">{{ __($field->placeholder) }}</option>
+2 -2
View File
@@ -1,7 +1,7 @@
<x-filament::field-group
:errorKey="$field->errorKey"
:for="$field->id"
:help="__($field->help)"
:help-message="__($field->helpMessage)"
:hint="__($field->hint)"
:label="__($field->label)"
:required="$field->required"
@@ -11,7 +11,7 @@
:name="$field->name"
:name-attribute="$field->nameAttribute"
:error-key="$field->errorKey"
:extra-attributes="$field->attributes"
:extra-attributes="$field->extraAttributes"
:required="$field->required"
:placeholder="__($field->placeholder)"
:options="$field->options"
+5 -11
View File
@@ -1,21 +1,15 @@
<x-filament::tabs :label="__($field->label)" :tab="array_key_first($field->tabs)">
<x-slot name="tablist">
<x-filament::tabs :label="__($field->label)" :default-tab-id="Str::of(array_key_first($field->tabs))->kebab()">
<x-slot name="tabList">
@foreach (array_keys($field->tabs) as $label)
<x-filament::tab :id="$label">
<x-filament::tab :id="Str::of($label)->kebab()">
{{ __($label) }}
</x-filament::tab>
@endforeach
</x-slot>
@foreach($field->tabs as $label => $fields)
<x-filament::tab-panel :id="$label">
<x-filament::form :fields="$fields" />
<x-filament::tab-panel :id="Str::of($label)->kebab()">
<x-filament::form embedded :fields="$fields" />
</x-filament::tab-panel>
@endforeach
</x-filament::tabs>
@if (count($field->tabs) > 1 && $errors->any())
<p role="alert" class="text-red-700 font-medium text-sm leading-tight">
{{ __('filament::tabs.error') }}
</p>
@endif
+2 -2
View File
@@ -1,7 +1,7 @@
<x-filament::field-group
:errorKey="$field->errorKey"
:for="$field->id"
:help="__($field->help)"
:help-message="__($field->helpMessage)"
:hint="__($field->hint)"
:label="__($field->label)"
:required="$field->required"
@@ -11,7 +11,7 @@
:autofocus="$field->autofocus"
:disabled="$field->disabled"
:error-key="$field->errorKey"
:extra-attributes="$field->attributes"
:extra-attributes="$field->extraAttributes"
:id="$field->id"
:maxLength="$field->maxLength"
:minLength="$field->minLength"
+2 -2
View File
@@ -1,7 +1,7 @@
<x-filament::field-group
:errorKey="$field->errorKey"
:for="$field->id"
:help="__($field->help)"
:help-message="__($field->helpMessage)"
:hint="__($field->hint)"
:label="__($field->label)"
:required="$field->required"
@@ -11,7 +11,7 @@
:autofocus="$field->autofocus"
:disabled="$field->disabled"
:error-key="$field->errorKey"
:extra-attributes="$field->attributes"
:extra-attributes="$field->extraAttributes"
:id="$field->id"
:name="$field->name"
:name-attribute="$field->nameAttribute"
+57 -57
View File
@@ -16,30 +16,56 @@ abstract class Action extends Component
protected static $title;
public static function getModel()
{
$resource = static::getResource();
return $resource::$model;
}
public static function getResource()
{
return static::$resource;
}
public static function route($uri, $name)
{
return new ResourceRoute(static::class, $uri, $name);
}
protected static function getTitle()
{
if (static::$title) return static::$title;
return (string) Str::of(class_basename(static::class))
->kebab()
->replace('-', ' ')
->title();
}
public function reset(...$properties)
{
parent::reset(...$properties);
$defaults = $this->getPropertyDefaults();
if (count($properties) && is_array($properties[0])) $properties = $properties[0];
if (empty($properties)) $properties = array_keys($defaults);
$propertiesToFill = collect($properties)
->filter(fn ($property) => in_array($property, $defaults))
->mapWithKeys(fn ($property) => [$property => $defaults[$property]])
->toArray();
$this->fill($propertiesToFill);
}
protected function callFormHooks($event)
{
return $this->getForm()->callHook($this, $event);
}
protected function fillWithFormDefaults()
{
$this->fill($this->getPropertyDefaults());
}
protected function getPropertyDefaults()
{
return $this->getForm()->getDefaults();
}
protected function getFields()
{
$fields = static::$resource ? static::$resource::fields() : [];
if (method_exists($this, 'fields')) return array_merge($fields, $this->fields());
return $fields;
}
public function getForm()
{
$record = null;
@@ -52,16 +78,23 @@ abstract class Action extends Component
);
}
public static function getModel()
protected function getFields()
{
$resource = static::getResource();
$fields = static::$resource ? static::$resource::fields() : [];
return $resource::$model;
if (method_exists($this, 'fields')) return array_merge($fields, $this->fields());
return $fields;
}
public static function getResource()
protected function fillWithFormDefaults()
{
return static::$resource;
$this->fill($this->getPropertyDefaults());
}
protected function getPropertyDefaults()
{
return $this->getForm()->getDefaults();
}
protected function getRules()
@@ -77,16 +110,6 @@ abstract class Action extends Component
return $rules;
}
protected static function getTitle()
{
if (static::$title) return static::$title;
return (string) Str::of(class_basename(static::class))
->kebab()
->replace('-', ' ')
->title();
}
protected function getValidationAttributes()
{
$attributes = $this->getForm()->getValidationAttributes();
@@ -97,27 +120,4 @@ abstract class Action extends Component
return $attributes;
}
public function reset(...$properties)
{
parent::reset(...$properties);
$defaults = $this->getPropertyDefaults();
if (count($properties) && is_array($properties[0])) $properties = $properties[0];
if (empty($properties)) $properties = array_keys($defaults);
$propertiesToFill = collect($properties)
->filter(fn($property) => in_array($property, $defaults))
->mapWithKeys(fn($property) => [$property => $defaults[$property]])
->toArray();
$this->fill($propertiesToFill);
}
public static function route($uri, $name)
{
return new ResourceRoute(static::class, $uri, $name);
}
}
-1
View File
@@ -3,7 +3,6 @@
namespace Filament\Actions;
use Filament\Action;
use Filament\Traits\WithNotifications;
abstract class CreateAction extends Action
{
-2
View File
@@ -3,8 +3,6 @@
namespace Filament\Actions;
use Filament\Action;
use Filament\Traits\WithNotifications;
use Filament\View\Components\Form;
abstract class EditAction extends Action
{
+5 -5
View File
@@ -14,6 +14,11 @@ class Avatar extends InputField
public $user;
public static function make($name)
{
return static::make($name)->image();
}
public function avatar($avatar)
{
$this->avatar = $avatar;
@@ -28,11 +33,6 @@ class Avatar extends InputField
return $this;
}
public static function make($name)
{
return static::make($name)->image();
}
public function size($size)
{
$this->size = $size;
+13 -86
View File
@@ -10,25 +10,13 @@ class Field
{
use Tappable;
public $attributes = [];
protected $context;
public $fields = [];
public $help;
public $hidden = false;
public $hint;
public $hooks = [];
public $id;
public $label;
public $name;
protected $context;
protected $pendingExcludedContextModifications = [];
@@ -38,18 +26,6 @@ class Field
protected $view;
public function __construct($name = null)
{
if ($name !== null) $this->name($name);
}
public function attributes($attributes)
{
$this->attributes = $attributes;
return $this;
}
public function context($context)
{
$this->context = $context;
@@ -63,7 +39,7 @@ class Field
$this->pendingIncludedContextModifications = [];
collect($this->pendingExcludedContextModifications)
->filter(fn($callbacks, $context) => $context !== $this->context)
->filter(fn ($callbacks, $context) => $context !== $this->context)
->each(function ($callbacks) {
foreach ($callbacks as $callback) {
$callback($this);
@@ -89,7 +65,7 @@ class Field
if (! $callback) {
$this->hidden();
$callback = fn($field) => $field->visible();
$callback = fn ($field) => $field->visible();
}
if (! $this->context) {
@@ -111,6 +87,13 @@ class Field
return $this;
}
public function hidden()
{
$this->hidden = true;
return $this;
}
public function fields($fields)
{
$this->fields = $fields;
@@ -124,7 +107,7 @@ class Field
$defaults = [];
if ($this->name !== null && property_exists($this, 'default')) {
if (property_exists($this, 'name') && property_exists($this, 'default')) {
$defaults[$this->name] = $this->default;
}
@@ -176,7 +159,7 @@ class Field
$attributes = [];
if ($this->name !== null && $this->label !== null) {
if (property_exists($this, 'name') && property_exists($this, 'label')) {
$label = Str::of($this->label)->lower();
$attributes[$this->name] = $label;
@@ -187,62 +170,6 @@ class Field
return $attributes;
}
public function help($help)
{
$this->help = $help;
return $this;
}
public function hidden()
{
$this->hidden = true;
return $this;
}
public function hint($hint)
{
$this->hint = $hint;
return $this;
}
public function id($id)
{
$this->id = $id;
return $this;
}
public function label($label)
{
$this->label = $label;
return $this;
}
public function name($name)
{
$this->name = $name;
$this->id(
(string) Str::of($this->name)
->replace('.', '-')
->slug(),
);
$this->label(
(string) Str::of($this->name)
->afterLast('.')
->kebab()
->replace(['-', '_'], ' ')
->ucfirst(),
);
return $this;
}
public function only($contexts, $callback = null)
{
if (! is_array($contexts)) $contexts = [$contexts];
@@ -250,7 +177,7 @@ class Field
if (! $callback) {
$this->hidden();
$callback = fn($field) => $field->visible();
$callback = fn ($field) => $field->visible();
}
if (! $this->context) {
+4
View File
@@ -2,8 +2,12 @@
namespace Filament\Fields;
use Filament\Traits\FieldConcerns;
class Fieldset extends Field
{
use FieldConcerns\CanHaveLabel;
public $columns = 1;
public static function make($label = null)
+92 -39
View File
@@ -2,53 +2,58 @@
namespace Filament\Fields;
use Filament\Traits\FieldConcerns;
use Illuminate\Support\Str;
class InputField extends Field
{
use FieldConcerns\CanHaveId;
use FieldConcerns\CanHaveLabel;
public $default = '';
public $errorKey;
public $extraAttributes = [];
public $helpMessage;
public $hint;
public $name;
public $nameAttribute = 'wire:model.defer';
public $required = false;
public $rules = [];
public function addRules($rules)
public function __construct($name)
{
foreach ($rules as $field => $conditionsToAdd) {
if (! is_array($conditionsToAdd)) $conditionsToAdd = explode('|', $conditionsToAdd);
$this->rules[$field] = collect($this->rules[$field] ?? [])
->filter(function ($originalCondition) use ($conditionsToAdd) {
if (! is_string($originalCondition)) return true;
$conditionsToAdd = collect($conditionsToAdd);
if ($conditionsToAdd->contains($originalCondition)) return false;
if (! Str::of($originalCondition)->contains(':')) return true;
$originalConditionType = (string) Str::of($originalCondition)->before(':');
return ! $conditionsToAdd->contains(function ($conditionToAdd) use ($originalConditionType) {
return $originalConditionType === (string) Str::of($conditionToAdd)->before(':');
});
})
->push(...$conditionsToAdd)
->toArray();
}
return $this;
$this->name($name);
}
public function default($default)
public function name($name)
{
$this->default = $default;
$this->name = $name;
return $this;
$this->errorKey($this->name);
$this->id(
(string) Str::of($this->name)
->replace('.', '-')
->slug(),
);
$this->label(
(string) Str::of($this->name)
->afterLast('.')
->kebab()
->replace(['-', '_'], ' ')
->ucfirst(),
);
$this->rules(['nullable']);
}
public function errorKey($errorKey)
@@ -58,17 +63,44 @@ class InputField extends Field
return $this;
}
public function rules($conditions)
{
$this->rules = [$this->name => $conditions];
return $this;
}
public static function make($name)
{
return new static($name);
}
public function name($name)
public function default($default)
{
parent::name($name);
$this->default = $default;
$this->errorKey($this->name);
$this->rules(['nullable']);
return $this;
}
public function extraAttributes($attributes)
{
$this->extraAttributes = $attributes;
return $this;
}
public function helpMessage($message)
{
$this->helpMessage = $message;
return $this;
}
public function hint($hint)
{
$this->hint = $hint;
return $this;
}
public function nameAttribute($nameAttribute)
@@ -121,6 +153,34 @@ class InputField extends Field
return $this;
}
public function addRules($rules)
{
foreach ($rules as $field => $conditionsToAdd) {
if (! is_array($conditionsToAdd)) $conditionsToAdd = explode('|', $conditionsToAdd);
$this->rules[$field] = collect($this->rules[$field] ?? [])
->filter(function ($originalCondition) use ($conditionsToAdd) {
if (! is_string($originalCondition)) return true;
$conditionsToAdd = collect($conditionsToAdd);
if ($conditionsToAdd->contains($originalCondition)) return false;
if (! Str::of($originalCondition)->contains(':')) return true;
$originalConditionType = (string) Str::of($originalCondition)->before(':');
return ! $conditionsToAdd->contains(function ($conditionToAdd) use ($originalConditionType) {
return $originalConditionType === (string) Str::of($conditionToAdd)->before(':');
});
})
->push(...$conditionsToAdd)
->toArray();
}
return $this;
}
public function required()
{
$this->required = true;
@@ -131,13 +191,6 @@ class InputField extends Field
return $this;
}
public function rules($conditions)
{
$this->rules = [$this->name => $conditions];
return $this;
}
public function requiredWith($field)
{
$this->required = false;
+1 -1
View File
@@ -34,7 +34,7 @@ class RichEditor extends InputField
$this->toolbarButtons = array_merge($this->toolbarButtons, $buttonsToDisable);
$this->toolbarButtons = collect($this->toolbarButtons)
->filter(fn($button) => ! in_array($button, $buttonsToDisable))
->filter(fn ($button) => ! in_array($button, $buttonsToDisable))
->toArray();
return $this;
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace Filament\Fields;
use Filament\Traits\FieldConcerns;
use Illuminate\Support\Str;
class Tab extends Field
{
use FieldConcerns\CanHaveId;
use FieldConcerns\CanHaveLabel;
public static function make($label)
{
return (new static())
->label($label)
->id((string) Str::of($label)->slug());
}
}
+13 -12
View File
@@ -2,25 +2,26 @@
namespace Filament\Fields;
use Filament\Traits\FieldConcerns;
use Illuminate\Support\Str;
class Tabs extends Field
{
public $label;
use FieldConcerns\CanHaveId;
use FieldConcerns\CanHaveLabel;
public $tabs = [];
public function __construct($label)
public static function make($label = null)
{
$this->label = $label;
$tabs = (new static())->label($label);
if ($label) $tabs = $tabs->id((string) Str::of($label)->slug());
return $tabs;
}
public static function make(string $label)
public function tabs($tabs)
{
return new static($label);
}
public function tab(string $label, array $fields)
{
$this->tabs[$label] = $fields;
$this->fields($tabs);
return $this;
}
+7 -7
View File
@@ -25,17 +25,17 @@ class Text extends InputField
return $this;
}
public function password()
{
$this->type('password');
return $this;
}
public function type($type)
{
$this->type = $type;
return $this;
}
public function password()
{
$this->type('password');
return $this;
}
}
+38 -38
View File
@@ -13,34 +13,6 @@ class FilamentManager
public $styles;
protected function getAsset($key)
{
$manifest = json_decode(file_get_contents($this->distPath('mix-manifest.json')), true);
if (! isset($manifest[$key])) {
return;
}
return $manifest[$key];
}
protected function getPublicAsset($key)
{
$manifestFile = public_path('vendor/filament/mix-manifest.json');
if (! file_exists($manifestFile)) {
return;
}
$manifest = json_decode(file_get_contents($manifestFile), true);
if (! isset($manifest[$key])) {
return;
}
return $manifest[$key];
}
public function scripts()
{
if ($this->scripts) return $this->scripts;
@@ -68,6 +40,44 @@ class FilamentManager
');
}
protected function getAsset($key)
{
$manifest = json_decode(file_get_contents($this->distPath('mix-manifest.json')), true);
if (! isset($manifest[$key])) {
return;
}
return $manifest[$key];
}
public function distPath($path = '')
{
return $this->basePath('dist/' . ltrim($path, '/'));
}
public function basePath($path = '')
{
return __DIR__ . '/../' . ltrim($path, '/');
}
protected function getPublicAsset($key)
{
$manifestFile = public_path('vendor/filament/mix-manifest.json');
if (! file_exists($manifestFile)) {
return;
}
$manifest = json_decode(file_get_contents($manifestFile), true);
if (! isset($manifest[$key])) {
return;
}
return $manifest[$key];
}
public function storage()
{
if ($this->storage) return $this->storage;
@@ -108,14 +118,4 @@ class FilamentManager
<link rel=\"stylesheet\" href=\"" . route('filament.assets.css', $cssInfo) . "\">
");
}
public function basePath($path = '')
{
return __DIR__ . '/../' . ltrim($path, '/');
}
public function distPath($path = '')
{
return $this->basePath('dist/' . ltrim($path, '/'));
}
}
+8 -4
View File
@@ -4,9 +4,13 @@ namespace Filament;
use Filament\Commands\MakeUserCommand;
use Filament\Http\Middleware\AuthorizeResourceRoute;
use Filament\Models\FilamentUser;
use Filament\Providers\RouteServiceProvider;
use Filament\Providers\ServiceProvider;
use Filament\Traits\CanRegisterLivewireComponentDirectories;
use Filament\View\Components\Avatar;
use Filament\View\Components\Image;
use Filament\View\Components\Nav;
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Blade;
@@ -46,7 +50,7 @@ class FilamentServiceProvider extends ServiceProvider
$this->app['config']->set('auth.providers.filament_users', [
'driver' => 'eloquent',
'model' => \Filament\Models\FilamentUser::class,
'model' => FilamentUser::class,
]);
}
@@ -72,9 +76,9 @@ class FilamentServiceProvider extends ServiceProvider
protected function bootLoaders()
{
$this->loadViewComponentsAs('filament', [
'avatar' => \Filament\View\Components\Avatar::class,
'image' => \Filament\View\Components\Image::class,
'nav' => \Filament\View\Components\Nav::class,
'avatar' => Avatar::class,
'image' => Image::class,
'nav' => Nav::class,
]);
$this->loadViewsFrom(__DIR__ . '/../resources/views', 'filament');
-1
View File
@@ -6,7 +6,6 @@ use DanHarrin\LivewireRateLimiting\WithRateLimiting;
use Filament\Action;
use Filament\Fields;
use Illuminate\Support\Facades\Auth;
use Livewire\Component;
class Login extends Action
{
@@ -7,7 +7,6 @@ use Filament\Action;
use Filament\Fields;
use Filament\Traits\WithNotifications;
use Illuminate\Support\Facades\Password;
use Livewire\Component;
class RequestPassword extends Action
{
-1
View File
@@ -8,7 +8,6 @@ use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Livewire\Component;
class ResetPassword extends Action
{
+5 -5
View File
@@ -17,6 +17,11 @@ class EditAccount extends Action
public $record;
public function getForm()
{
return new Form($this->fields(), static::class, $this->record);
}
public function fields()
{
return [
@@ -50,11 +55,6 @@ class EditAccount extends Action
];
}
public function getForm()
{
return new Form($this->fields(), static::class, $this->record);
}
public function mount()
{
$this->record = Auth::guard('filament')->user();
+9 -9
View File
@@ -45,15 +45,6 @@ abstract class Resource
->replace('-', ' ');
}
public static function getSlug()
{
if (static::$slug) return static::$slug;
return (string) Str::of(class_basename(static::$model))
->plural()
->kebab();
}
public static function route($name = null, $parameters = [], $absolute = true)
{
if (! $name) $name = static::router()->getIndexRoute()->name;
@@ -66,6 +57,15 @@ abstract class Resource
return new ResourceRouter(static::class);
}
public static function getSlug()
{
if (static::$slug) return static::$slug;
return (string) Str::of(class_basename(static::$model))
->plural()
->kebab();
}
public static function routes()
{
return [];
+6 -6
View File
@@ -43,14 +43,14 @@ class ResourceAuthorizationManager
if (! $this->resource::router()->hasRoute($route)) return $this->type === 'deny';
return collect($this->authorizations)
->contains(function ($authorization) use ($route, $user) {
if (! $user->hasRole($authorization->role)) return false;
->contains(function ($authorization) use ($route, $user) {
if (! $user->hasRole($authorization->role)) return false;
if (in_array($route, $authorization->onlyRoutes)) return $this->type === 'allow';
if (in_array($route, $authorization->onlyRoutes)) return $this->type === 'allow';
if (in_array($route, $authorization->exceptRoutes)) return $this->type === 'deny';
if (in_array($route, $authorization->exceptRoutes)) return $this->type === 'deny';
return $this->type === 'deny';
}) || $this->type === 'deny';
return $this->type === 'deny';
}) || $this->type === 'deny';
}
}
+11 -11
View File
@@ -15,6 +15,17 @@ class ResourceRouter
$this->register($resource::routes());
}
public function register($routes)
{
if (! $routes) return;
if (! is_array($routes)) $routes = [$routes];
$this->routes = array_merge($this->routes, $routes);
return $this;
}
public function getIndexRoute()
{
return collect($this->routes)
@@ -26,15 +37,4 @@ class ResourceRouter
return collect($this->routes)
->contains(fn ($route) => $route->name === $name);
}
public function register($routes)
{
if (! $routes) return;
if (! is_array($routes)) $routes = [$routes];
$this->routes = array_merge($this->routes, $routes);
return $this;
}
}
@@ -6,17 +6,17 @@ trait CanBeAutocompleted
{
public $autocomplete;
public function autocomplete($autocomplete = 'on')
{
$this->autocomplete = $autocomplete;
return $this;
}
public function disableAutocomplete()
{
$this->autocomplete('off');
return $this;
}
public function autocomplete($autocomplete = 'on')
{
$this->autocomplete = $autocomplete;
return $this;
}
}
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace Filament\Traits\FieldConcerns;
trait CanHaveId
{
public $id;
public function id($id)
{
$this->id = $id;
return $this;
}
}
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace Filament\Traits\FieldConcerns;
trait CanHaveLabel
{
public $label;
public function label($label)
{
$this->label = $label;
return $this;
}
}
+29 -27
View File
@@ -2,36 +2,23 @@
namespace Filament\Traits;
use DateTime;
use Illuminate\Database\Connectors\ConnectionFactory;
use Illuminate\Support\Str;
use ReflectionClass;
trait Sushi
{
protected static $sushiConnection;
public function getRows()
{
return $this->rows;
}
public function getSchema()
{
return $this->schema ?? [];
}
public static function resolveConnection($connection = null)
{
return static::$sushiConnection;
}
public static function bootSushi()
{
$instance = (new static);
$cacheFileName = config('sushi.cache-prefix', 'sushi').'-'.Str::kebab(str_replace('\\', '', static::class)).'.sqlite';
$cacheFileName = config('sushi.cache-prefix', 'sushi') . '-' . Str::kebab(str_replace('\\', '', static::class)) . '.sqlite';
$cacheDirectory = realpath(config('sushi.cache-path', storage_path('framework/cache')));
$cachePath = $cacheDirectory.'/'.$cacheFileName;
$modelPath = (new \ReflectionClass(static::class))->getFileName();
$cachePath = $cacheDirectory . '/' . $cacheFileName;
$modelPath = (new ReflectionClass(static::class))->getFileName();
$states = [
'cache-file-found-and-up-to-date' => function () use ($cachePath) {
@@ -94,6 +81,11 @@ trait Sushi
static::insert($rows);
}
public function getRows()
{
return $this->rows;
}
public function createTable(string $tableName, $firstRow)
{
static::resolveConnection()->getSchemaBuilder()->create($tableName, function ($table) use ($firstRow) {
@@ -113,7 +105,7 @@ trait Sushi
case is_string($value):
$type = 'string';
break;
case is_object($value) && $value instanceof \DateTime:
case is_object($value) && $value instanceof DateTime:
$type = 'dateTime';
break;
default:
@@ -138,6 +130,24 @@ trait Sushi
});
}
public static function resolveConnection($connection = null)
{
return static::$sushiConnection;
}
public function getSchema()
{
return $this->schema ?? [];
}
public function usesTimestamps()
{
// Override the Laravel default value of $timestamps = true; Unless otherwise set.
return (new ReflectionClass($this))->getProperty('timestamps')->class === static::class
? parent::usesTimestamps()
: false;
}
public function createTableWithNoData(string $tableName)
{
static::resolveConnection()->getSchemaBuilder()->create($tableName, function ($table) {
@@ -161,12 +171,4 @@ trait Sushi
}
});
}
public function usesTimestamps()
{
// Override the Laravel default value of $timestamps = true; Unless otherwise set.
return (new \ReflectionClass($this))->getProperty('timestamps')->class === static::class
? parent::usesTimestamps()
: false;
}
}
+39 -39
View File
@@ -23,6 +23,32 @@ class Form extends Component
if ($record) $this->passRecordToFields($record);
}
public function passContextToFields($context = null)
{
if (! $context) return $this->fields;
return $this->fields = collect($this->fields)
->map(function ($field) use ($context) {
return $field
->context($context)
->fields($field->getForm()->passContextToFields($context));
})
->toArray();
}
public function passRecordToFields($record = null)
{
if (! $record) return $this->fields;
return $this->fields = collect($this->fields)
->map(function ($field) use ($record) {
return $field
->record($record)
->fields($field->getForm()->passRecordToFields($record));
})
->toArray();
}
public function callHooks($action, $event)
{
$hooks = $this->getHooks();
@@ -38,6 +64,19 @@ class Form extends Component
return $action;
}
public function getHooks()
{
$hooks = $this->hooks;
foreach ($this->fields as $field) {
foreach ($field->getHooks as $event => $callbacks) {
$hooks[$event] = array_merge($hooks[$event] ?? [], $callbacks);
}
}
return $hooks;
}
public function columns($columns)
{
$this->columns = $columns;
@@ -56,19 +95,6 @@ class Form extends Component
return $defaults;
}
public function getHooks()
{
$hooks = $this->hooks;
foreach ($this->fields as $field) {
foreach ($field->getHooks as $event => $callbacks) {
$hooks[$event] = array_merge($hooks[$event] ?? [], $callbacks);
}
}
return $hooks;
}
public function getRules()
{
$rules = $this->rules;
@@ -98,32 +124,6 @@ class Form extends Component
$this->hooks = $hooks;
}
public function passContextToFields($context = null)
{
if (! $context) return $this->fields;
return $this->fields = collect($this->fields)
->map(function ($field) use ($context) {
return $field
->context($context)
->fields($field->getForm()->passContextToFields($context));
})
->toArray();
}
public function passRecordToFields($record = null)
{
if (! $record) return $this->fields;
return $this->fields = collect($this->fields)
->map(function ($field) use ($record) {
return $field
->record($record)
->fields($field->getForm()->passRecordToFields($record));
})
->toArray();
}
public function rules($rules)
{
$this->rules = $rules;
+1 -1
View File
@@ -8,7 +8,7 @@ if (! function_exists('Filament\format_attributes')) {
function format_attributes($attributes = [])
{
return collect($attributes)
->map(fn($value, $key) => "{$key}={$value}")
->map(fn ($value, $key) => "{$key}={$value}")
->join(' ');
}
}