chore: styling

This commit is contained in:
danharrin
2021-03-13 19:01:11 +00:00
committed by GitHub Actions
parent d371681db4
commit b14584cb62
95 changed files with 1212 additions and 1029 deletions
+4 -4
View File
@@ -1,15 +1,15 @@
<?php
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Http\Middleware\EncryptCookies;
use Filament\Http\Middleware\RedirectIfAuthenticated;
use Filament\Http\Middleware\VerifyCsrfToken;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\AuthenticateSession;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Http\Middleware\RedirectIfAuthenticated;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
return [
+1 -1
View File
@@ -85,4 +85,4 @@ return [
'placeholder' => 'Nova Etiqueta',
],
];
];
+49 -29
View File
@@ -15,10 +15,10 @@ class Component
protected $configurationQueue = [];
protected $hidden = false;
protected $form;
protected $hidden = false;
protected $id;
protected $label;
@@ -67,7 +67,9 @@ class Component
public function except($contexts, $callback = null)
{
$this->configure(function () use ($contexts, $callback) {
if (! is_array($contexts)) $contexts = [$contexts];
if (! is_array($contexts)) {
$contexts = [$contexts];
}
if (! $callback) {
$this->hidden();
@@ -75,7 +77,9 @@ class Component
$callback = fn ($component) => $component->visible();
}
if (! $this->getContext() || in_array($this->getContext(), $contexts)) return $this;
if (! $this->getContext() || in_array($this->getContext(), $contexts)) {
return $this;
}
$callback($this);
});
@@ -98,15 +102,6 @@ class Component
return $this;
}
public function hidden()
{
$this->configure(function () {
$this->hidden = true;
});
return $this;
}
public function getColumnSpan()
{
return $this->columnSpan;
@@ -119,7 +114,9 @@ class Component
public function getDefaultValues()
{
if ($this->isHidden()) return [];
if ($this->isHidden()) {
return [];
}
$values = [];
@@ -176,7 +173,9 @@ class Component
return $this->rules[$field] ?? null;
}
if ($this->isHidden()) return [];
if ($this->isHidden()) {
return [];
}
$rules = $this instanceof Field ? $this->rules : [];
@@ -207,7 +206,9 @@ class Component
public function getValidationAttributes()
{
if ($this->isHidden()) return [];
if ($this->isHidden()) {
return [];
}
$attributes = [];
@@ -229,6 +230,15 @@ class Component
return $this->view;
}
public function hidden()
{
$this->configure(function () {
$this->hidden = true;
});
return $this;
}
public function id($id)
{
$this->configure(function () use ($id) {
@@ -255,7 +265,9 @@ class Component
public function only($contexts, $callback = null)
{
$this->configure(function () use ($callback, $contexts) {
if (! is_array($contexts)) $contexts = [$contexts];
if (! is_array($contexts)) {
$contexts = [$contexts];
}
if (! $callback) {
$this->hidden();
@@ -263,7 +275,9 @@ class Component
$callback = fn ($component) => $component->visible();
}
if (! in_array($this->getContext(), $contexts)) return $this;
if (! in_array($this->getContext(), $contexts)) {
return $this;
}
$callback($this);
});
@@ -278,6 +292,17 @@ class Component
return $this;
}
public function render()
{
if ($this->isHidden()) {
return;
}
$view = $this->getView() ?? 'forms::components.' . Str::of(class_basename(static::class))->kebab();
return view($view, ['formComponent' => $this]);
}
public function schema($schema)
{
$this->schema = collect(value($schema))
@@ -314,7 +339,9 @@ class Component
$callback = fn ($component) => $component->visible();
}
if ($this->getRecord() === null) return $this;
if ($this->getRecord() === null) {
return $this;
}
try {
$shouldExecuteCallback = $condition($this->getRecord());
@@ -330,20 +357,13 @@ class Component
return $this;
}
public function render()
{
if ($this->isHidden()) return;
$view = $this->getView() ?? 'forms::components.' . Str::of(class_basename(static::class))->kebab();
return view($view, ['formComponent' => $this]);
}
protected function transformConditions($conditions)
{
return collect($conditions)
->map(function ($condition) {
if (! is_string($condition)) return $condition;
if (! is_string($condition)) {
return $condition;
}
return (string) Str::of($condition)->replace('{{record}}', $this->getRecord() instanceof Model ? $this->getRecord()->getKey() : '');
})
@@ -6,15 +6,6 @@ trait CanBeAutocompleted
{
protected $autocomplete;
public function disableAutocomplete()
{
$this->configure(function () {
$this->autocomplete('off');
});
return $this;
}
public function autocomplete($autocomplete = 'on')
{
$this->configure(function () use ($autocomplete) {
@@ -24,6 +15,15 @@ trait CanBeAutocompleted
return $this;
}
public function disableAutocomplete()
{
$this->configure(function () {
$this->autocomplete('off');
});
return $this;
}
public function getAutocomplete()
{
return $this->autocomplete;
@@ -7,7 +7,9 @@ trait CanBeCompared
public function confirmed($confirmationFieldName = null)
{
$this->configure(function () use ($confirmationFieldName) {
if ($confirmationFieldName === null) $confirmationFieldName = "{$this->getName()}Confirmation";
if ($confirmationFieldName === null) {
$confirmationFieldName = "{$this->getName()}Confirmation";
}
$this->addRules([$confirmationFieldName => ["same:{$this->getName()}"]]);
});
@@ -8,7 +8,9 @@ trait CanBeUnique
{
$this->configure(function () use ($column, $exceptCurrentRecord, $table) {
$rule = "unique:$table,$column";
if ($exceptCurrentRecord) $rule .= ',{{record}}';
if ($exceptCurrentRecord) {
$rule .= ',{{record}}';
}
$this->addRules([$this->getName() => [$rule]]);
});
+2 -2
View File
@@ -13,10 +13,10 @@ class DatePicker extends Field
protected $format;
protected $hasTime = false;
protected $hasSeconds = true;
protected $hasTime = false;
protected $maxDate;
protected $minDate;
@@ -4,8 +4,6 @@ namespace Filament\Forms\Components;
class DateTimePicker extends DatePicker
{
protected $time = true;
protected $defaultDisplayFormat = 'F j, Y H:i:s';
protected $defaultDisplayFormatWithoutSeconds = 'F j, Y H:i';
@@ -13,6 +11,7 @@ class DateTimePicker extends DatePicker
protected $defaultFormat = 'Y-m-d H:i:s';
protected $defaultFormatWithoutSeconds = 'Y-m-d H:i';
protected $time = true;
protected $view = 'forms::components.date-time-picker';
+44 -42
View File
@@ -33,11 +33,6 @@ class Field extends Component
$this->setUp();
}
public static function make($name)
{
return new static($name);
}
public function addRules($rules)
{
$this->configure(function () use ($rules) {
@@ -93,6 +88,15 @@ class Field extends Component
return $this;
}
public function default($value)
{
$this->configure(function () use ($value) {
$this->defaultValue = $value;
});
return $this;
}
public function dependable()
{
$this->configure(function () {
@@ -120,15 +124,6 @@ class Field extends Component
return $this;
}
public function default($value)
{
$this->configure(function () use ($value) {
$this->defaultValue = $value;
});
return $this;
}
public function extraAttributes($attributes)
{
$this->configure(function () use ($attributes) {
@@ -138,24 +133,6 @@ class Field extends Component
return $this;
}
public function helpMessage($message)
{
$this->configure(function () use ($message) {
$this->helpMessage = $message;
});
return $this;
}
public function hint($hint)
{
$this->configure(function () use ($hint) {
$this->hint = $hint;
});
return $this;
}
public function getBindingAttribute()
{
return $this->bindingAttribute;
@@ -219,6 +196,24 @@ class Field extends Component
return $this->rules;
}
public function helpMessage($message)
{
$this->configure(function () use ($message) {
$this->helpMessage = $message;
});
return $this;
}
public function hint($hint)
{
$this->configure(function () use ($hint) {
$this->hint = $hint;
});
return $this;
}
public function isDisabled()
{
return $this->isDisabled;
@@ -229,6 +224,11 @@ class Field extends Component
return $this->isRequired;
}
public static function make($name)
{
return new static($name);
}
public function name($name)
{
$this->configure(function () use ($name) {
@@ -262,7 +262,9 @@ class Field extends Component
$field = $this->getName();
}
if (! is_array($conditionsToRemove)) $conditionsToRemove = explode('|', $conditionsToRemove);
if (! is_array($conditionsToRemove)) {
$conditionsToRemove = explode('|', $conditionsToRemove);
}
if (empty($conditionsToRemove)) {
unset($this->rules[$field]);
@@ -299,15 +301,6 @@ class Field extends Component
return $this;
}
public function rules($conditions)
{
$this->configure(function () use ($conditions) {
$this->addRules([$this->getName() => $conditions]);
});
return $this;
}
public function required()
{
$this->configure(function () {
@@ -332,6 +325,15 @@ class Field extends Component
return $this;
}
public function rules($conditions)
{
$this->configure(function () use ($conditions) {
$this->addRules([$this->getName() => $conditions]);
});
return $this;
}
public function validationAttribute($attribute)
{
$this->configure(function () use ($attribute) {
+7 -7
View File
@@ -6,13 +6,6 @@ class Fieldset extends Component
{
protected $columns = 2;
public static function make($label, $schema = [])
{
return (new static())
->label($label)
->schema($schema);
}
public function columns($columns)
{
$this->configure(function () use ($columns) {
@@ -31,4 +24,11 @@ class Fieldset extends Component
{
return parent::getSubform()->columns($this->columns);
}
public static function make($label, $schema = [])
{
return (new static())
->label($label)
->schema($schema);
}
}
+9 -7
View File
@@ -48,7 +48,9 @@ class FileUpload extends Field
public function acceptedFileTypes($types)
{
$this->configure(function () use ($types) {
if (! is_array($types)) $types = explode(',', $types);
if (! is_array($types)) {
$types = explode(',', $types);
}
$this->acceptedFileTypes = $types;
@@ -79,19 +81,19 @@ class FileUpload extends Field
return $this;
}
public function disk($name)
public function directory($directory)
{
$this->configure(function () use ($name) {
$this->diskName = $name;
$this->configure(function () use ($directory) {
$this->directory = $directory;
});
return $this;
}
public function directory($directory)
public function disk($name)
{
$this->configure(function () use ($directory) {
$this->directory = $directory;
$this->configure(function () use ($name) {
$this->diskName = $name;
});
return $this;
+5 -5
View File
@@ -6,11 +6,6 @@ class Grid extends Component
{
protected $columns = 2;
public static function make($schema = [])
{
return (new static())->schema($schema);
}
public function columns($columns)
{
$this->configure(function () use ($columns) {
@@ -29,4 +24,9 @@ class Grid extends Component
{
return parent::getSubform()->columns($this->columns);
}
public static function make($schema = [])
{
return (new static())->schema($schema);
}
}
+5 -5
View File
@@ -126,6 +126,11 @@ class KeyValue extends Field
return $this->valuePlaceholder;
}
public function isSortable()
{
return $this->isSortable;
}
public function keyLabel($label)
{
$this->configure(function () use ($label) {
@@ -144,11 +149,6 @@ class KeyValue extends Field
return $this;
}
public function isSortable()
{
return $this->isSortable;
}
public function sortable($sortable = true)
{
$this->configure(function () use ($sortable) {
+20 -14
View File
@@ -35,7 +35,9 @@ class RichEditor extends Field
$this->attachmentDisk(config('forms.default_filesystem_disk'));
$attachmentUploadUrl = config('forms.rich_editor.default_attachment_upload_url');
if ($attachmentUploadUrl) $this->enableAttachments($attachmentUploadUrl);
if ($attachmentUploadUrl) {
$this->enableAttachments($attachmentUploadUrl);
}
}
public function attachmentDirectory($directory)
@@ -68,7 +70,9 @@ class RichEditor extends Field
public function disableToolbarButtons($buttonsToDisable)
{
$this->configure(function () use ($buttonsToDisable) {
if (! is_array($buttonsToDisable)) $buttonsToDisable = [$buttonsToDisable];
if (! is_array($buttonsToDisable)) {
$buttonsToDisable = [$buttonsToDisable];
}
$this->toolbarButtons = collect($this->getToolbarButtons())
->filter(fn ($button) => ! in_array($button, $buttonsToDisable))
@@ -92,7 +96,9 @@ class RichEditor extends Field
public function enableToolbarButtons($buttonsToEnable)
{
$this->configure(function () use ($buttonsToEnable) {
if (! is_array($buttonsToEnable)) $buttonsToEnable = [$buttonsToEnable];
if (! is_array($buttonsToEnable)) {
$buttonsToEnable = [$buttonsToEnable];
}
$this->toolbarButtons = array_merge($this->getToolbarButtons(), $buttonsToEnable);
});
@@ -100,17 +106,6 @@ class RichEditor extends Field
return $this;
}
public function hasToolbarButton($button)
{
if (is_array($button)) {
$buttons = $button;
return (bool) count(array_intersect($buttons, $this->getToolbarButtons()));
}
return in_array($button, $this->getToolbarButtons());
}
public function getAttachmentDirectory()
{
return $this->attachmentDirectory;
@@ -131,6 +126,17 @@ class RichEditor extends Field
return $this->toolbarButtons;
}
public function hasToolbarButton($button)
{
if (is_array($button)) {
$buttons = $button;
return (bool) count(array_intersect($buttons, $this->getToolbarButtons()));
}
return in_array($button, $this->getToolbarButtons());
}
public function toolbarButtons($buttons)
{
$this->configure(function () use ($buttons) {
+13 -13
View File
@@ -10,14 +10,6 @@ class Section extends Component
protected $subheading;
public static function make($heading, $subheading = null, $schema = [])
{
return (new static())
->heading($heading)
->subheading($subheading)
->schema($schema);
}
public function columns($columns)
{
$this->configure(function () use ($columns) {
@@ -37,16 +29,16 @@ class Section extends Component
return $this->heading;
}
public function getSubheading()
{
return $this->subheading;
}
public function getSubform()
{
return parent::getSubform()->columns($this->columns);
}
public function getSubheading()
{
return $this->subheading;
}
public function heading($heading)
{
$this->configure(function () use ($heading) {
@@ -56,6 +48,14 @@ class Section extends Component
return $this;
}
public static function make($heading, $subheading = null, $schema = [])
{
return (new static())
->heading($heading)
->subheading($subheading)
->schema($schema);
}
public function subheading($subheading)
{
$this->configure(function () use ($subheading) {
+8 -8
View File
@@ -8,14 +8,6 @@ class Tab extends Component
{
protected $columns = 1;
public static function make($label, $schema = [])
{
return (new static())
->label($label)
->id(Str::slug($label))
->schema($schema);
}
public function columns($columns)
{
$this->configure(function () use ($columns) {
@@ -34,4 +26,12 @@ class Tab extends Component
{
return parent::getSubform()->columns($this->columns);
}
public static function make($label, $schema = [])
{
return (new static())
->label($label)
->id(Str::slug($label))
->schema($schema);
}
}
+5 -5
View File
@@ -6,11 +6,6 @@ use Illuminate\Support\Str;
class Tabs extends Component
{
public static function make($label = null)
{
return (new static())->label($label);
}
public function getTabsConfig()
{
return collect($this->getSchema())
@@ -27,6 +22,11 @@ class Tabs extends Component
return parent::id($id);
}
public static function make($label = null)
{
return (new static())->label($label);
}
public function tabs($tabs)
{
$this->schema($tabs);
+9 -9
View File
@@ -24,9 +24,11 @@ class Form
protected $validationAttributes = [];
public static function make()
public function columns($columns)
{
return new static();
$this->columns = $columns;
return $this;
}
public function context($context)
@@ -36,13 +38,6 @@ class Form
return $this;
}
public function columns($columns)
{
$this->columns = $columns;
return $this;
}
public function getColumns()
{
return $this->columns;
@@ -119,6 +114,11 @@ class Form
return $attributes;
}
public static function make()
{
return new static();
}
public function model($model)
{
$this->model = $model;
+15 -13
View File
@@ -41,6 +41,11 @@ class FormsServiceProvider extends ServiceProvider
});
}
protected function bootLivewireComponents()
{
$this->registerLivewireComponentDirectory(__DIR__ . '/Http/Livewire', 'Filament\\Forms\\Http\\Livewire', 'forms.');
}
protected function bootLoaders()
{
$this->loadViewsFrom(__DIR__ . '/../resources/views', 'forms');
@@ -48,11 +53,6 @@ class FormsServiceProvider extends ServiceProvider
$this->loadTranslationsFrom(__DIR__ . '/../resources/lang', 'forms');
}
protected function bootLivewireComponents()
{
$this->registerLivewireComponentDirectory(__DIR__ . '/Http/Livewire', 'Filament\\Forms\\Http\\Livewire', 'forms.');
}
protected function bootPublishing()
{
if (! $this->app->runningInConsole()) {
@@ -72,13 +72,6 @@ class FormsServiceProvider extends ServiceProvider
], 'forms-views');
}
protected function mergeConfigFrom($path, $key)
{
$config = $this->app['config']->get($key, []);
$this->app['config']->set($key, $this->mergeConfig(require $path, $config));
}
protected function mergeConfig(array $original, array $merging)
{
$array = array_merge($original, $merging);
@@ -102,11 +95,20 @@ class FormsServiceProvider extends ServiceProvider
return $array;
}
protected function mergeConfigFrom($path, $key)
{
$config = $this->app['config']->get($key, []);
$this->app['config']->set($key, $this->mergeConfig(require $path, $config));
}
protected function registerLivewireComponentDirectory($directory, $namespace, $aliasPrefix = '')
{
$filesystem = new Filesystem();
if (! $filesystem->isDirectory($directory)) return;
if (! $filesystem->isDirectory($directory)) {
return;
}
collect($filesystem->allFiles($directory))
->map(function (SplFileInfo $file) use ($namespace) {
+189 -167
View File
@@ -18,29 +18,6 @@ trait HasForm
public $temporaryUploadedFiles = [];
public static function getTemporaryUploadedFilePropertyName($fieldName)
{
return "temporaryUploadedFiles.{$fieldName}";
}
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 function clearTemporaryUploadedFile($name)
{
$this->syncInput(
@@ -50,145 +27,9 @@ trait HasForm
);
}
public function getTemporaryUploadedFile($name)
public function fillWithFormDefaults()
{
return $this->getPropertyValue(
static::getTemporaryUploadedFilePropertyName($name)
);
}
public function getUploadedFileUrl($name, $disk)
{
$path = $this->getPropertyValue($name);
if (! $path) return null;
$storage = Storage::disk($disk);
if (
$storage->getDriver()->getAdapter() instanceof AwsS3Adapter &&
$storage->getVisibility($path) === 'private'
) {
return $storage->temporaryUrl(
$path,
now()->addMinutes(5),
);
}
return $storage->url($path);
}
public function storeTemporaryUploadedFiles()
{
foreach ($this->getForm()->getFlatSchema() as $field) {
if (! $field instanceof FileUpload) continue;
$temporaryUploadedFile = $this->getTemporaryUploadedFile($field->getName());
if (! $temporaryUploadedFile) continue;
$storeMethod = $field->getVisibility() === 'public' ? 'storePublicly' : 'store';
$path = $temporaryUploadedFile->{$storeMethod}($field->getDirectory(), $field->getDiskName());
$this->syncInput($field->getName(), $path, false);
}
$this->resetTemporaryUploadedFiles();
}
public function resetTemporaryUploadedFiles()
{
$this->temporaryUploadedFiles = [];
}
public function removeUploadedFile($name)
{
$this->syncInput($name, null, false);
$this->clearTemporaryUploadedFile($name);
}
public function validate($rules = null, $messages = [], $attributes = [])
{
try {
return parent::validate($rules, $messages, $attributes);
} catch (ValidationException $exception) {
$fieldToFocus = collect($this->getForm()->getFlatSchema())
->first(function ($field) use ($exception) {
return ($field instanceof Field &&
array_key_exists($field->getName(), $exception->validator->failed())
);
});
if ($fieldToFocus) $this->focusTabbedField($fieldToFocus);
throw $exception;
}
}
public function validateOnly($field, $rules = null, $messages = [], $attributes = [])
{
try {
return parent::validateOnly($field, $rules, $messages, $attributes);
} catch (ValidationException $exception) {
$fieldToFocus = collect($this->getForm()->getFlatSchema())
->first(function ($field) use ($exception) {
return ($field instanceof Field &&
array_key_exists($field->getName(), $exception->validator->failed())
);
});
if ($fieldToFocus) $this->focusTabbedField($fieldToFocus);
throw $exception;
}
}
public function getSelectFieldOptionSearchResults($fieldName, $search = '')
{
$field = collect($this->getForm()->getFlatSchema())
->first(fn ($field) => $field instanceof Select && $field->getName() === $fieldName);
if (! $field) return [];
return $field->getOptionSearchResults($search);
}
public function validateTemporaryUploadedFiles()
{
$rules = collect($this->getRules())
->filter(function ($conditions, $field) {
return Str::of($field)->startsWith('temporaryUploadedFiles.');
})
->toArray();
if (! count($rules)) return;
try {
return parent::validate($rules);
} catch (ValidationException $exception) {
$fieldToFocus = collect($this->getForm()->getFlatSchema())
->first(function ($component) use ($exception) {
return (
$component instanceof Field &&
array_key_exists(
static::getTemporaryUploadedFilePropertyName($component->getName()),
$exception->validator->failed()
)
);
});
if ($fieldToFocus) $this->focusTabbedField($fieldToFocus);
$this->setErrorBag($exception->validator->errors());
foreach ($this->getErrorBag()->messages() as $field => $messages) {
$field = (string) Str::of($field)->after('temporaryUploadedFiles.');
foreach ($messages as $message) {
$this->addError($field, $message);
}
}
throw $exception;
}
$this->fill($this->getPropertyDefaults());
}
public function focusTabbedField($field)
@@ -216,17 +57,14 @@ trait HasForm
return $this->getForm()->getDefaultValues();
}
public function fillWithFormDefaults()
{
$this->fill($this->getPropertyDefaults());
}
public function getRules()
{
$rules = $this->getForm()->getRules();
foreach (parent::getRules() as $field => $conditions) {
if (! is_array($conditions)) $conditions = explode('|', $conditions);
if (! is_array($conditions)) {
$conditions = explode('|', $conditions);
}
$rules[$field] = array_merge($rules[$field] ?? [], $conditions);
}
@@ -234,6 +72,53 @@ trait HasForm
return $rules;
}
public function getSelectFieldOptionSearchResults($fieldName, $search = '')
{
$field = collect($this->getForm()->getFlatSchema())
->first(fn ($field) => $field instanceof Select && $field->getName() === $fieldName);
if (! $field) {
return [];
}
return $field->getOptionSearchResults($search);
}
public function getTemporaryUploadedFile($name)
{
return $this->getPropertyValue(
static::getTemporaryUploadedFilePropertyName($name)
);
}
public static function getTemporaryUploadedFilePropertyName($fieldName)
{
return "temporaryUploadedFiles.{$fieldName}";
}
public function getUploadedFileUrl($name, $disk)
{
$path = $this->getPropertyValue($name);
if (! $path) {
return null;
}
$storage = Storage::disk($disk);
if (
$storage->getDriver()->getAdapter() instanceof AwsS3Adapter &&
$storage->getVisibility($path) === 'private'
) {
return $storage->temporaryUrl(
$path,
now()->addMinutes(5),
);
}
return $storage->url($path);
}
public function getValidationAttributes()
{
$attributes = $this->getForm()->getValidationAttributes();
@@ -244,4 +129,141 @@ trait HasForm
return $attributes;
}
public function removeUploadedFile($name)
{
$this->syncInput($name, null, false);
$this->clearTemporaryUploadedFile($name);
}
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 function resetTemporaryUploadedFiles()
{
$this->temporaryUploadedFiles = [];
}
public function storeTemporaryUploadedFiles()
{
foreach ($this->getForm()->getFlatSchema() as $field) {
if (! $field instanceof FileUpload) {
continue;
}
$temporaryUploadedFile = $this->getTemporaryUploadedFile($field->getName());
if (! $temporaryUploadedFile) {
continue;
}
$storeMethod = $field->getVisibility() === 'public' ? 'storePublicly' : 'store';
$path = $temporaryUploadedFile->{$storeMethod}($field->getDirectory(), $field->getDiskName());
$this->syncInput($field->getName(), $path, false);
}
$this->resetTemporaryUploadedFiles();
}
public function validate($rules = null, $messages = [], $attributes = [])
{
try {
return parent::validate($rules, $messages, $attributes);
} catch (ValidationException $exception) {
$fieldToFocus = collect($this->getForm()->getFlatSchema())
->first(function ($field) use ($exception) {
return ($field instanceof Field &&
array_key_exists($field->getName(), $exception->validator->failed())
);
});
if ($fieldToFocus) {
$this->focusTabbedField($fieldToFocus);
}
throw $exception;
}
}
public function validateOnly($field, $rules = null, $messages = [], $attributes = [])
{
try {
return parent::validateOnly($field, $rules, $messages, $attributes);
} catch (ValidationException $exception) {
$fieldToFocus = collect($this->getForm()->getFlatSchema())
->first(function ($field) use ($exception) {
return ($field instanceof Field &&
array_key_exists($field->getName(), $exception->validator->failed())
);
});
if ($fieldToFocus) {
$this->focusTabbedField($fieldToFocus);
}
throw $exception;
}
}
public function validateTemporaryUploadedFiles()
{
$rules = collect($this->getRules())
->filter(function ($conditions, $field) {
return Str::of($field)->startsWith('temporaryUploadedFiles.');
})
->toArray();
if (! count($rules)) {
return;
}
try {
return parent::validate($rules);
} catch (ValidationException $exception) {
$fieldToFocus = collect($this->getForm()->getFlatSchema())
->first(function ($component) use ($exception) {
return (
$component instanceof Field &&
array_key_exists(
static::getTemporaryUploadedFilePropertyName($component->getName()),
$exception->validator->failed()
)
);
});
if ($fieldToFocus) {
$this->focusTabbedField($fieldToFocus);
}
$this->setErrorBag($exception->validator->errors());
foreach ($this->getErrorBag()->messages() as $field => $messages) {
$field = (string) Str::of($field)->after('temporaryUploadedFiles.');
foreach ($messages as $message) {
$this->addError($field, $message);
}
}
throw $exception;
}
}
}
@@ -17,4 +17,4 @@ return [
'results' => 'resultats.',
],
];
];
+1 -1
View File
@@ -54,4 +54,4 @@ return [
'placeholder' => 'Cerca',
],
];
];
+36 -26
View File
@@ -39,11 +39,6 @@ class Column
$this->setUp();
}
public static function make($name)
{
return new static($name);
}
protected function setUp()
{
//
@@ -73,7 +68,9 @@ class Column
public function except($contexts, $callback = null)
{
$this->configure(function () use ($callback, $contexts) {
if (! is_array($contexts)) $contexts = [$contexts];
if (! is_array($contexts)) {
$contexts = [$contexts];
}
if (! $callback) {
$this->hidden();
@@ -81,7 +78,9 @@ class Column
$callback = fn ($column) => $column->visible();
}
if (! $this->getContext() || in_array($this->getContext(), $contexts)) return $this;
if (! $this->getContext() || in_array($this->getContext(), $contexts)) {
return $this;
}
$callback($this);
});
@@ -170,6 +169,11 @@ class Column
return $this->isHidden;
}
public function isPrimary()
{
return $this->isPrimary;
}
public function isSearchable()
{
return $this->isSearchable && $this->getValueUsing === null;
@@ -180,11 +184,6 @@ class Column
return $this->isSortable && $this->getValueUsing === null;
}
public function isPrimary()
{
return $this->isPrimary;
}
public function label($label)
{
$this->configure(function () use ($label) {
@@ -194,6 +193,11 @@ class Column
return $this;
}
public static function make($name)
{
return new static($name);
}
public function name($name)
{
$this->configure(function () use ($name) {
@@ -206,7 +210,9 @@ class Column
public function only($contexts, $callback = null)
{
$this->configure(function () use ($callback, $contexts) {
if (! is_array($contexts)) $contexts = [$contexts];
if (! is_array($contexts)) {
$contexts = [$contexts];
}
if (! $callback) {
$this->hidden();
@@ -214,7 +220,9 @@ class Column
$callback = fn ($column) => $column->visible();
}
if (! in_array($this->getContext(), $contexts)) return $this;
if (! in_array($this->getContext(), $contexts)) {
return $this;
}
$callback($this);
});
@@ -231,6 +239,20 @@ class Column
return $this;
}
public function renderCell($record)
{
if ($this->isHidden()) {
return;
}
$view = $this->getView() ?? 'tables::cells.' . Str::of(class_basename(static::class))->kebab();
return view($view, array_merge($this->viewData, [
'column' => $this,
'record' => $record,
]));
}
public function searchable()
{
$this->configure(function () {
@@ -286,16 +308,4 @@ class Column
return $this;
}
public function renderCell($record)
{
if ($this->isHidden()) return;
$view = $this->getView() ?? 'tables::cells.' . Str::of(class_basename(static::class))->kebab();
return view($view, array_merge($this->viewData, [
'column' => $this,
'record' => $record,
]));
}
}
@@ -47,7 +47,9 @@ trait CanOpenUrl
{
$this->configure(function () use ($shouldOpenInNewTab, $url) {
$this->url = $url;
if ($shouldOpenInNewTab) $this->openUrlInNewTab();
if ($shouldOpenInNewTab) {
$this->openUrlInNewTab();
}
});
return $this;
+31 -21
View File
@@ -32,15 +32,6 @@ class Image extends Column
return $this;
}
public function height($height)
{
$this->configure(function () use ($height) {
$this->height = $height;
});
return $this;
}
public function getDisk()
{
return Storage::disk($this->getDiskName());
@@ -53,27 +44,24 @@ class Image extends Column
public function getHeight()
{
if ($this->height === null) return null;
if ($this->height === null) {
return null;
}
if (is_integer($this->height)) return "{$this->height}px";
if (is_integer($this->height)) {
return "{$this->height}px";
}
return $this->height;
}
public function getWidth()
{
if ($this->width === null) return null;
if (is_integer($this->width)) return "{$this->width}px";
return $this->width;
}
public function getPath($record)
{
$path = $this->getValue($record);
if (! $path) return null;
if (! $path) {
return null;
}
if (filter_var($path, FILTER_VALIDATE_URL) !== false) {
return $path;
@@ -94,6 +82,28 @@ class Image extends Column
return $storage->url($path);
}
public function getWidth()
{
if ($this->width === null) {
return null;
}
if (is_integer($this->width)) {
return "{$this->width}px";
}
return $this->width;
}
public function height($height)
{
$this->configure(function () use ($height) {
$this->height = $height;
});
return $this;
}
public function isRounded()
{
return $this->isRounded;
+14 -12
View File
@@ -18,7 +18,9 @@ class Text extends Column
{
$this->configure(function () use ($decimalSeparator, $symbol, $thousandsSeparator) {
$this->formatUsing = function ($value) use ($decimalSeparator, $symbol, $thousandsSeparator) {
if (! is_numeric($value)) return $this->getDefaultValue();
if (! is_numeric($value)) {
return $this->getDefaultValue();
}
return $symbol . number_format($value, 2, $decimalSeparator, $thousandsSeparator);
};
@@ -87,6 +89,17 @@ class Text extends Column
return $value;
}
public function limit($length = -1)
{
$this->configure(function () use ($length) {
$this->formatUsing = function ($value) use ($length) {
return Str::limit($value, $length);
};
});
return $this;
}
public function options($options)
{
$this->configure(function () use ($options) {
@@ -101,15 +114,4 @@ class Text extends Column
return $this;
}
public function limit($length = -1)
{
$this->configure(function () use ($length) {
$this->formatUsing = function ($value) use ($length) {
return Str::limit($value, $length);
};
});
return $this;
}
}
+26 -18
View File
@@ -37,11 +37,6 @@ class Filter
//
}
public static function make($name = null, $callback = null)
{
return new static($name, $callback);
}
public function apply($query)
{
$callback = $this->getCallback();
@@ -82,7 +77,9 @@ class Filter
public function except($contexts, $callback = null)
{
$this->configure(function () use ($callback, $contexts) {
if (! is_array($contexts)) $contexts = [$contexts];
if (! is_array($contexts)) {
$contexts = [$contexts];
}
if (! $callback) {
$this->hidden();
@@ -90,7 +87,9 @@ class Filter
$callback = fn ($filter) => $filter->visible();
}
if (! $this->getContext() || in_array($this->getContext(), $contexts)) return $this;
if (! $this->getContext() || in_array($this->getContext(), $contexts)) {
return $this;
}
$callback($this);
});
@@ -98,15 +97,6 @@ class Filter
return $this;
}
public function hidden()
{
$this->configure(function () {
$this->isHidden = true;
});
return $this;
}
public function getCallback()
{
return $this->callback;
@@ -139,6 +129,15 @@ class Filter
return $this->table;
}
public function hidden()
{
$this->configure(function () {
$this->isHidden = true;
});
return $this;
}
public function isHidden()
{
return $this->isHidden;
@@ -153,6 +152,11 @@ class Filter
return $this;
}
public static function make($name = null, $callback = null)
{
return new static($name, $callback);
}
public function name($name)
{
$this->configure(function () use ($name) {
@@ -163,7 +167,9 @@ class Filter
public function only($contexts, $callback = null)
{
$this->configure(function () use ($callback, $contexts) {
if (! is_array($contexts)) $contexts = [$contexts];
if (! is_array($contexts)) {
$contexts = [$contexts];
}
if (! $callback) {
$this->hidden();
@@ -171,7 +177,9 @@ class Filter
$callback = fn ($filter) => $filter->visible();
}
if (! in_array($this->getContext(), $contexts)) return $this;
if (! in_array($this->getContext(), $contexts)) {
return $this;
}
$callback($this);
});
+90 -82
View File
@@ -28,88 +28,6 @@ trait HasTable
$this->selected = [];
}
public function setPage($page)
{
$this->page = $page;
$this->selected = [];
}
public function sortBy($column)
{
if ($this->sortColumn === $column) {
switch ($this->sortDirection) {
case 'asc':
$this->sortDirection = 'desc';
break;
case 'desc':
$this->sortColumn = null;
$this->sortDirection = 'asc';
break;
}
return;
}
$this->sortColumn = $column;
$this->sortDirection = 'asc';
}
public function toggleSelectAll()
{
$records = $this->getRecords();
if (! $records->count()) return;
$keyName = $records->first()->getKeyName();
if ($records->count() !== count($this->selected)) {
$this->selected = $records->pluck($keyName)->all();
} else {
$this->selected = [];
}
}
public function toggleSelected($record)
{
if (! in_array($record, $this->selected)) {
$this->selected[] = $record;
} else {
$key = array_search($record, $this->selected);
unset($this->selected[$key]);
}
}
public function updatedFilter()
{
$this->selected = [];
if (! $this->getTable()->hasPagination()) return;
$this->resetPage();
}
public function updatedRecordsPerPage()
{
$this->selected = [];
if (! $this->getTable()->hasPagination()) return;
$this->resetPage();
}
public function updatedSearch()
{
$this->selected = [];
if (! $this->getTable()->hasPagination()) return;
$this->resetPage();
}
public function getRecords()
{
$query = static::getQuery();
@@ -177,4 +95,94 @@ trait HasTable
return $query->paginate($this->recordsPerPage);
}
public function setPage($page)
{
$this->page = $page;
$this->selected = [];
}
public function sortBy($column)
{
if ($this->sortColumn === $column) {
switch ($this->sortDirection) {
case 'asc':
$this->sortDirection = 'desc';
break;
case 'desc':
$this->sortColumn = null;
$this->sortDirection = 'asc';
break;
}
return;
}
$this->sortColumn = $column;
$this->sortDirection = 'asc';
}
public function toggleSelectAll()
{
$records = $this->getRecords();
if (! $records->count()) {
return;
}
$keyName = $records->first()->getKeyName();
if ($records->count() !== count($this->selected)) {
$this->selected = $records->pluck($keyName)->all();
} else {
$this->selected = [];
}
}
public function toggleSelected($record)
{
if (! in_array($record, $this->selected)) {
$this->selected[] = $record;
} else {
$key = array_search($record, $this->selected);
unset($this->selected[$key]);
}
}
public function updatedFilter()
{
$this->selected = [];
if (! $this->getTable()->hasPagination()) {
return;
}
$this->resetPage();
}
public function updatedRecordsPerPage()
{
$this->selected = [];
if (! $this->getTable()->hasPagination()) {
return;
}
$this->resetPage();
}
public function updatedSearch()
{
$this->selected = [];
if (! $this->getTable()->hasPagination()) {
return;
}
$this->resetPage();
}
}
+16 -14
View File
@@ -90,6 +90,22 @@ class Action
return $this;
}
public function render($record)
{
$when = $this->when;
if (! $when($record)) {
return;
}
$view = $this->getView() ?? 'tables::record-actions.' . Str::of(class_basename(static::class))->kebab();
return view($view, array_merge($this->getViewData(), [
'record' => $record,
'recordAction' => $this,
]));
}
public function table($table)
{
$this->table = $table;
@@ -127,18 +143,4 @@ class Action
return $this;
}
public function render($record)
{
$when = $this->when;
if (! $when($record)) return;
$view = $this->getView() ?? 'tables::record-actions.' . Str::of(class_basename(static::class))->kebab();
return view($view, array_merge($this->getViewData(), [
'record' => $record,
'recordAction' => $this,
]));
}
}
@@ -37,7 +37,9 @@ trait CanOpenUrl
{
$this->configure(function () use ($shouldOpenInNewTab, $url) {
$this->url = $url;
if ($shouldOpenInNewTab) $this->openUrlInNewTab();
if ($shouldOpenInNewTab) {
$this->openUrlInNewTab();
}
});
return $this;
+5 -5
View File
@@ -9,6 +9,11 @@ class Icon extends Action
protected $icon;
public function getIcon()
{
return $this->icon;
}
public function icon($icon)
{
$this->configure(function () use ($icon) {
@@ -17,9 +22,4 @@ class Icon extends Action
return $this;
}
public function getIcon()
{
return $this->icon;
}
}
+22 -22
View File
@@ -9,26 +9,13 @@ class Link extends Action
use Concerns\CanCallAction;
use Concerns\CanOpenUrl;
protected $label;
protected $icon;
public function label($label)
protected $label;
public function getIcon()
{
$this->configure(function () use ($label) {
$this->label = $label;
});
return $this;
}
public function icon($icon)
{
$this->configure(function () use ($icon) {
$this->icon = $icon;
});
return $this;
return $this->icon;
}
public function getLabel()
@@ -43,13 +30,26 @@ class Link extends Action
return $this->label;
}
public function getIcon()
{
return $this->icon;
}
public function hasIcon()
{
return $this->icon !== null;
}
public function icon($icon)
{
$this->configure(function () use ($icon) {
$this->icon = $icon;
});
return $this;
}
public function label($label)
{
$this->configure(function () use ($label) {
$this->label = $label;
});
return $this;
}
}
+5 -5
View File
@@ -28,11 +28,6 @@ class Table
protected $recordActions = [];
public static function make()
{
return new static();
}
public function columns($columns)
{
$this->columns = collect(value($columns))
@@ -181,6 +176,11 @@ class Table
->count();
}
public static function make()
{
return new static();
}
public function pagination($enabled)
{
$this->pagination = $enabled;
+1 -2
View File
@@ -6,7 +6,6 @@ use Filament\Commands;
class MakeColumnCommand extends Commands\MakeColumnCommand
{
protected $signature = 'filament:column {name} {--R|resource}';
protected $hidden = true;
protected $signature = 'filament:column {name} {--R|resource}';
}
+1 -2
View File
@@ -6,7 +6,6 @@ use Filament\Commands;
class MakeFieldCommand extends Commands\MakeFieldCommand
{
protected $signature = 'filament:field {name} {--R|resource}';
protected $hidden = true;
protected $signature = 'filament:field {name} {--R|resource}';
}
+1 -2
View File
@@ -4,7 +4,6 @@ namespace Filament\Commands\Aliases;
class MakeFilterCommand extends \Filament\Commands\MakeFilterCommand
{
protected $signature = 'filament:filter {name} {--R|resource}';
protected $hidden = true;
protected $signature = 'filament:filter {name} {--R|resource}';
}
@@ -6,7 +6,6 @@ use Filament\Commands;
class MakeFormComponentCommand extends Commands\MakeFormComponentCommand
{
protected $signature = 'filament:form-component {name} {--R|resource}';
protected $hidden = true;
protected $signature = 'filament:form-component {name} {--R|resource}';
}
+1 -2
View File
@@ -6,7 +6,6 @@ use Filament\Commands;
class MakePageCommand extends Commands\MakePageCommand
{
protected $signature = 'filament:page {name} {--R|resource=}';
protected $hidden = true;
protected $signature = 'filament:page {name} {--R|resource=}';
}
@@ -6,7 +6,6 @@ use Filament\Commands;
class MakeRelationManagerCommand extends Commands\MakeRelationManagerCommand
{
protected $signature = 'filament:relation-manager {resource} {relationship}';
protected $hidden = true;
protected $signature = 'filament:relation-manager {resource} {relationship}';
}
+1 -2
View File
@@ -6,7 +6,6 @@ use Filament\Commands;
class MakeResourceCommand extends Commands\MakeResourceCommand
{
protected $signature = 'filament:resource {name}';
protected $hidden = true;
protected $signature = 'filament:resource {name}';
}
+1 -2
View File
@@ -6,7 +6,6 @@ use Filament\Commands;
class MakeRoleCommand extends Commands\MakeRoleCommand
{
protected $signature = 'filament:role {name}';
protected $hidden = true;
protected $signature = 'filament:role {name}';
}
+1 -2
View File
@@ -4,7 +4,6 @@ namespace Filament\Commands\Aliases;
class MakeThemeCommand extends \Filament\Commands\MakeThemeCommand
{
protected $signature = 'filament:theme {name}';
protected $hidden = true;
protected $signature = 'filament:theme {name}';
}
+1 -2
View File
@@ -6,7 +6,6 @@ use Filament\Commands;
class MakeUserCommand extends Commands\MakeUserCommand
{
protected $signature = 'filament:user';
protected $hidden = true;
protected $signature = 'filament:user';
}
+1 -2
View File
@@ -6,7 +6,6 @@ use Filament\Commands;
class MakeWidgetCommand extends Commands\MakeWidgetCommand
{
protected $signature = 'filament:widget {name}';
protected $hidden = true;
protected $signature = 'filament:widget {name}';
}
+3 -1
View File
@@ -46,7 +46,9 @@ class MakeColumnCommand extends Command
if ($this->checkForCollision([
$path,
])) return;
])) {
return;
}
if (! $this->option('resource')) {
$this->copyStubToApp('Column', $path, [
+3 -1
View File
@@ -46,7 +46,9 @@ class MakeFieldCommand extends Command
if ($this->checkForCollision([
$path,
])) return;
])) {
return;
}
if (! $this->option('resource')) {
$this->copyStubToApp('Field', $path, [
+4 -2
View File
@@ -2,8 +2,8 @@
namespace Filament\Commands;
use Illuminate\Support\Str;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
class MakeFilterCommand extends Command
{
@@ -34,7 +34,9 @@ class MakeFilterCommand extends Command
if ($this->checkForCollision([
$path,
])) return;
])) {
return;
}
if (! $this->option('resource')) {
$this->copyStubToApp('Filter', $path, [
+3 -1
View File
@@ -46,7 +46,9 @@ class MakeFormComponentCommand extends Command
if ($this->checkForCollision([
$path,
])) return;
])) {
return;
}
if (! $this->option('resource')) {
$this->copyStubToApp('FormComponent', $path, [
+3 -1
View File
@@ -61,7 +61,9 @@ class MakePageCommand extends Command
if ($this->checkForCollision([
$path,
$viewPath,
])) return;
])) {
return;
}
if ($resource === null) {
$this->copyStubToApp('Page', $path, [
+3 -1
View File
@@ -35,7 +35,9 @@ class MakeRelationManagerCommand extends Command
if ($this->checkForCollision([
$path,
])) return;
])) {
return;
}
$this->copyStubToApp('RelationManager', $path, [
'namespace' => "App\\Filament\\Resources\\{$resource}\\RelationManagers",
+3 -1
View File
@@ -50,7 +50,9 @@ class MakeResourceCommand extends Command
$indexResourcePagePath,
$createResourcePagePath,
$editResourcePagePath,
])) return;
])) {
return;
}
$this->copyStubToApp('Resource', $resourcePath, [
'createResourcePageClass' => $createResourcePageClass,
+3 -1
View File
@@ -34,7 +34,9 @@ class MakeRoleCommand extends Command
if ($this->checkForCollision([
$path,
])) return;
])) {
return;
}
$this->copyStubToApp('Role', $path, [
'class' => $roleClass,
+3 -1
View File
@@ -22,7 +22,9 @@ class MakeThemeCommand extends Command
if ($this->checkForCollision([
$path,
])) return;
])) {
return;
}
$this->copyStubToApp('Theme', $path);
+9 -3
View File
@@ -42,9 +42,15 @@ class MakeUserCommand extends Command
$this->info("Success! {$user->email} may now log in at {$loginUrl}.");
if (Filament::auth()->getProvider()->getModel()::count() === 1 && $this->confirm('Would you like to show some love by starring the repo?', true)) {
if (PHP_OS_FAMILY === 'Darwin') exec('open https://github.com/laravel-filament/filament');
if (PHP_OS_FAMILY === 'Linux') exec('xdg-open https://github.com/laravel-filament/filament');
if (PHP_OS_FAMILY === 'Windows') exec('start https://github.com/laravel-filament/filament');
if (PHP_OS_FAMILY === 'Darwin') {
exec('open https://github.com/laravel-filament/filament');
}
if (PHP_OS_FAMILY === 'Linux') {
exec('xdg-open https://github.com/laravel-filament/filament');
}
if (PHP_OS_FAMILY === 'Windows') {
exec('start https://github.com/laravel-filament/filament');
}
$this->line('Thank you!');
}
+3 -1
View File
@@ -47,7 +47,9 @@ class MakeWidgetCommand extends Command
if ($this->checkForCollision([
$path,
$viewPath,
])) return;
])) {
return;
}
$this->copyStubToApp('Widget', $path, [
'class' => $widgetClass,
+27 -15
View File
@@ -20,16 +20,16 @@ class FilamentManager
public $roles = [];
public $styles = [];
public $scriptData = [];
public $scripts = [];
public $scriptData = [];
public $shouldRunMigrations = true;
public $styles = [];
public $widgets = [];
public $shouldRunMigrations = true;
public function auth()
{
return Auth::guard(config('filament.auth.guard', 'filament'));
@@ -46,7 +46,9 @@ class FilamentManager
{
$user = $this->auth()->user();
if ($user->isFilamentAdmin()) return true;
if ($user->isFilamentAdmin()) {
return true;
}
$targetClass = is_object($target) ? get_class($target) : $target;
@@ -59,14 +61,22 @@ class FilamentManager
][$mode];
foreach ($this->authorizations[$targetClass] as $authorization) {
if ($mode !== $authorization->mode) continue;
if ($mode !== $authorization->mode) {
continue;
}
if (! $user->hasFilamentRole($authorization->role)) continue;
if (! $user->hasFilamentRole($authorization->role)) {
continue;
}
if (in_array($action, $authorization->exceptActions)) continue;
if (in_array($action, $authorization->exceptActions)) {
continue;
}
if (in_array($action, $authorization->onlyActions)) {
if ($mode === 'allow') return true;
if ($mode === 'allow') {
return true;
}
if ($mode === 'deny') {
$fallback = false;
@@ -75,7 +85,9 @@ class FilamentManager
}
}
if (count($authorization->onlyActions)) continue;
if (count($authorization->onlyActions)) {
continue;
}
return [
'allow' => true,
@@ -115,11 +127,6 @@ class FilamentManager
return $this->roles;
}
public function getScripts()
{
return $this->scripts;
}
public function getScriptData()
{
return array_merge([
@@ -128,6 +135,11 @@ class FilamentManager
], $this->scriptData);
}
public function getScripts()
{
return $this->scripts;
}
public function getStyles()
{
return $this->styles;
+55 -54
View File
@@ -3,7 +3,6 @@
namespace Filament;
use BladeUI\Icons\Factory as BladeUIFactory;
use Filament\Commands;
use Filament\Models\User;
use Filament\Pages\Page;
use Filament\Providers\RouteServiceProvider;
@@ -100,6 +99,13 @@ class FilamentServiceProvider extends ServiceProvider
});
}
protected function bootLivewireComponents()
{
$this->registerLivewireComponentDirectory(__DIR__ . '/Http/Livewire', 'Filament\\Http\\Livewire', 'filament.core.');
$this->registerLivewireComponentDirectory(__DIR__ . '/Resources', 'Filament\\Resources', 'filament.core.resources.');
$this->registerLivewireComponentDirectory(app_path('Filament'), 'App\\Filament', 'filament.');
}
protected function bootLoaders()
{
$this->loadViewComponentsAs('filament', [
@@ -117,13 +123,6 @@ class FilamentServiceProvider extends ServiceProvider
$this->loadTranslationsFrom(__DIR__ . '/../resources/lang', 'filament');
}
protected function bootLivewireComponents()
{
$this->registerLivewireComponentDirectory(__DIR__ . '/Http/Livewire', 'Filament\\Http\\Livewire', 'filament.core.');
$this->registerLivewireComponentDirectory(__DIR__ . '/Resources', 'Filament\\Resources', 'filament.core.resources.');
$this->registerLivewireComponentDirectory(app_path('Filament'), 'App\\Filament', 'filament.');
}
protected function bootPublishing()
{
if (! $this->app->runningInConsole()) {
@@ -187,51 +186,6 @@ class FilamentServiceProvider extends ServiceProvider
});
}
protected function registerIcons()
{
$this->callAfterResolving(BladeUIFactory::class, function (BladeUIFactory $factory) {
$factory->add('filamenticons', [
'path' => __DIR__ . '/../resources/svg',
'prefix' => 'filamenticon',
]);
});
}
protected function registerProviders()
{
$this->app->register(RouteServiceProvider::class);
}
protected function mergeConfigFrom($path, $key)
{
$config = $this->app['config']->get($key, []);
$this->app['config']->set($key, $this->mergeConfig(require $path, $config));
}
protected function mergeConfig(array $original, array $merging)
{
$array = array_merge($original, $merging);
foreach ($original as $key => $value) {
if (! is_array($value)) {
continue;
}
if (! Arr::exists($merging, $key)) {
continue;
}
if (is_numeric($key)) {
continue;
}
$array[$key] = $this->mergeConfig($value, $merging[$key]);
}
return $array;
}
protected function discoverFilamentPages()
{
$filesystem = new Filesystem();
@@ -308,11 +262,53 @@ class FilamentServiceProvider extends ServiceProvider
->each(fn ($widget) => Filament::registerWidget($widget));
}
protected function mergeConfig(array $original, array $merging)
{
$array = array_merge($original, $merging);
foreach ($original as $key => $value) {
if (! is_array($value)) {
continue;
}
if (! Arr::exists($merging, $key)) {
continue;
}
if (is_numeric($key)) {
continue;
}
$array[$key] = $this->mergeConfig($value, $merging[$key]);
}
return $array;
}
protected function mergeConfigFrom($path, $key)
{
$config = $this->app['config']->get($key, []);
$this->app['config']->set($key, $this->mergeConfig(require $path, $config));
}
protected function registerIcons()
{
$this->callAfterResolving(BladeUIFactory::class, function (BladeUIFactory $factory) {
$factory->add('filamenticons', [
'path' => __DIR__ . '/../resources/svg',
'prefix' => 'filamenticon',
]);
});
}
protected function registerLivewireComponentDirectory($directory, $namespace, $aliasPrefix = '')
{
$filesystem = new Filesystem();
if (! $filesystem->isDirectory($directory)) return;
if (! $filesystem->isDirectory($directory)) {
return;
}
collect($filesystem->allFiles($directory))
->map(function (SplFileInfo $file) use ($namespace) {
@@ -335,4 +331,9 @@ class FilamentServiceProvider extends ServiceProvider
Livewire::component($alias, $class);
});
}
protected function registerProviders()
{
$this->app->register(RouteServiceProvider::class);
}
}
+6 -5
View File
@@ -17,10 +17,16 @@ class AssetController
return $this->pretendResponseIsFile(__DIR__ . '/../../../dist/js/filament.js.map', 'application/json; charset=utf-8');
default:
abort(404);
break;
}
}
protected function getHttpDate($timestamp)
{
return sprintf('%s GMT', gmdate('D, d M Y H:i:s', $timestamp));
}
protected function pretendResponseIsFile($path, $contentType)
{
abort_if(! file_exists($path), 404);
@@ -44,9 +50,4 @@ class AssetController
'Last-Modified' => $this->getHttpDate($lastModified),
]);
}
protected function getHttpDate($timestamp)
{
return sprintf('%s GMT', gmdate('D, d M Y H:i:s', $timestamp));
}
}
+3 -1
View File
@@ -9,5 +9,7 @@ use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
use AuthorizesRequests;
use DispatchesJobs;
use ValidatesRequests;
}
+8 -8
View File
@@ -43,6 +43,14 @@ class Login extends Component
]);
}
public function render()
{
return view('filament::auth.login')
->layout('filament::components.layouts.auth', [
'title' => 'filament::auth/login.title',
]);
}
public function submit()
{
try {
@@ -66,12 +74,4 @@ class Login extends Component
return redirect()->intended(route('filament.dashboard'));
}
public function render()
{
return view('filament::auth.login')
->layout('filament::components.layouts.auth', [
'title' => 'filament::auth/login.title',
]);
}
}
+5 -5
View File
@@ -9,15 +9,15 @@ class Logout extends Component
{
public $class;
public function render()
{
return view('filament::auth.logout');
}
public function submit()
{
Filament::auth()->logout();
return redirect()->route('filament.auth.login');
}
public function render()
{
return view('filament::auth.logout');
}
}
+6 -6
View File
@@ -33,6 +33,12 @@ class RequestPassword extends Component
]);
}
public function render()
{
return view('filament::.auth.request-password')
->layout('filament::components.layouts.auth', ['title' => 'filament::auth/request-password.title']);
}
public function submit()
{
try {
@@ -56,10 +62,4 @@ class RequestPassword extends Component
$this->dispatchBrowserEvent('notify', __("filament::auth/request-password.messages.{$requestStatus}"));
}
public function render()
{
return view('filament::.auth.request-password')
->layout('filament::components.layouts.auth', ['title' => 'filament::auth/request-password.title']);
}
}
+8 -8
View File
@@ -58,6 +58,14 @@ class ResetPassword extends Component
$this->token = $token;
}
public function render()
{
return view('filament::.auth.reset-password')
->layout('filament::components.layouts.auth', [
'title' => 'filament::auth/reset-password.title',
]);
}
public function submit()
{
$this->validate();
@@ -83,12 +91,4 @@ class ResetPassword extends Component
return redirect()->to(route('filament.dashboard'));
}
public function render()
{
return view('filament::.auth.reset-password')
->layout('filament::components.layouts.auth', [
'title' => 'filament::auth/reset-password.title',
]);
}
}
+7 -7
View File
@@ -12,17 +12,12 @@ class EditAccount extends Page
{
use HasForm;
public $record;
public static $title = 'filament::edit-account.title';
public static $view = 'filament::edit-account';
public $record;
public static function getResource()
{
return Filament::userResource();
}
public function getForm()
{
return static::getResource()::form(
@@ -34,6 +29,11 @@ class EditAccount extends Page
);
}
public static function getResource()
{
return Filament::userResource();
}
public function mount()
{
$this->record = Filament::auth()->user();
+18 -18
View File
@@ -4,6 +4,15 @@ namespace Filament\Models\Concerns;
trait IsFilamentUser
{
public function canAccessFilament()
{
$column = static::getFilamentUserColumn();
return $column !== null ?
$this->{$column} :
true;
}
public static function getFilamentAdminColumn()
{
if (property_exists(static::class, 'filamentAdminColumn')) {
@@ -13,6 +22,15 @@ trait IsFilamentUser
return null;
}
public function getFilamentAvatar()
{
$column = static::getFilamentAvatarColumn();
return $column !== null ?
$this->{$column} :
null;
}
public static function getFilamentAvatarColumn()
{
if (property_exists(static::class, 'filamentAvatarColumn')) {
@@ -40,15 +58,6 @@ trait IsFilamentUser
return null;
}
public function canAccessFilament()
{
$column = static::getFilamentUserColumn();
return $column !== null ?
$this->{$column} :
true;
}
public function hasFilamentRole($role)
{
$column = static::getFilamentRolesColumn();
@@ -58,15 +67,6 @@ trait IsFilamentUser
true;
}
public function getFilamentAvatar()
{
$column = static::getFilamentAvatarColumn();
return $column !== null ?
$this->{$column} :
null;
}
public function isFilamentAdmin()
{
$column = static::getFilamentAdminColumn();
+2 -2
View File
@@ -4,13 +4,13 @@ namespace Filament\Models\Contracts;
interface FilamentUser
{
public function canAccessFilament();
public static function getFilamentAdminColumn();
public static function getFilamentRolesColumn();
public static function getFilamentUserColumn();
public function canAccessFilament();
public function isFilamentAdmin();
}
+5 -5
View File
@@ -37,11 +37,6 @@ class User extends Authenticatable implements FilamentUser
protected $table = 'filament_users';
protected static function newFactory()
{
return UserFactory::new();
}
public function sendPasswordResetNotification($token)
{
$notification = new ResetPasswordNotification($token);
@@ -58,4 +53,9 @@ class User extends Authenticatable implements FilamentUser
$this->notify($notification);
}
protected static function newFactory()
{
return UserFactory::new();
}
}
+5 -5
View File
@@ -20,11 +20,6 @@ class NavigationItem
$this->url($url);
}
public static function make($label, $url)
{
return new static($label, $url);
}
public function activeRule($rule)
{
$this->activeRule = $rule;
@@ -46,6 +41,11 @@ class NavigationItem
return $this;
}
public static function make($label, $url)
{
return new static($label, $url);
}
public function sort($sort)
{
$this->sort = $sort;
+34 -26
View File
@@ -46,7 +46,9 @@ class Page extends Component
public static function getNavigationLabel()
{
if (static::$navigationLabel) return static::$navigationLabel;
if (static::$navigationLabel) {
return static::$navigationLabel;
}
return (string) Str::of(class_basename(static::class))
->kebab()
@@ -58,16 +60,29 @@ class Page extends Component
return static::$navigationSort;
}
public static function getPageTitle()
{
if (property_exists(static::class, 'pageTitle')) {
return static::$pageTitle;
}
return static::getTitle();
}
public static function getSlug()
{
if (static::$slug) return static::$slug;
if (static::$slug) {
return static::$slug;
}
return (string) Str::of(class_basename(static::class))->kebab();
}
public static function getTitle()
{
if (property_exists(static::class, 'title')) return static::$title;
if (property_exists(static::class, 'title')) {
return static::$title;
}
return (string) Str::of(class_basename(static::class))
->kebab()
@@ -75,11 +90,9 @@ class Page extends Component
->title();
}
public static function getPageTitle()
public function isAuthorized()
{
if (property_exists(static::class, 'pageTitle')) return static::$pageTitle;
return static::getTitle();
return Filament::can('view', static::class);
}
public static function navigationItems()
@@ -96,16 +109,6 @@ class Page extends Component
];
}
public static function route()
{
return Route::make(static::getSlug(), static::getSlug());
}
public function isAuthorized()
{
return Filament::can('view', static::class);
}
public function notify($message)
{
$this->dispatchBrowserEvent('notify', $message);
@@ -117,16 +120,9 @@ class Page extends Component
->layout(static::$layout, $this->getLayoutData());
}
protected function getViewData()
public static function route()
{
return array_merge($this->viewData(), [
'title' => static::getTitle(),
]);
}
protected function viewData()
{
return [];
return Route::make(static::getSlug(), static::getSlug());
}
protected function getLayoutData()
@@ -136,8 +132,20 @@ class Page extends Component
]);
}
protected function getViewData()
{
return array_merge($this->viewData(), [
'title' => static::getTitle(),
]);
}
protected function layoutData()
{
return [];
}
protected function viewData()
{
return [];
}
}
+5 -5
View File
@@ -97,16 +97,16 @@ abstract class PluginServiceProvider extends ServiceProvider
return $this->roles;
}
protected function scripts()
{
return $this->scripts;
}
protected function scriptData()
{
return [];
}
protected function scripts()
{
return $this->scripts;
}
protected function styles()
{
return $this->styles;
@@ -6,9 +6,8 @@ use Illuminate\Support\Str;
class BelongsToSelect extends Select
{
protected $getOptions;
protected $displayColumnName;
protected $getOptions;
protected $relationship;
@@ -67,7 +66,9 @@ class BelongsToSelect extends Select
$this->configure(function () {
$options = $this->getOptions();
if (! $options || ! $this->getModel()) return;
if (! $options || ! $this->getModel()) {
return;
}
$this->options = $options;
});
@@ -2,8 +2,6 @@
namespace Filament\Resources\Forms\Components;
use Filament\Resources\Forms\Components\Concerns;
class Checkbox extends \Filament\Forms\Components\Checkbox
{
use Concerns\InteractsWithResource;
@@ -2,8 +2,6 @@
namespace Filament\Resources\Forms\Components;
use Filament\Resources\Forms\Components\Concerns;
class DatePicker extends \Filament\Forms\Components\DatePicker
{
use Concerns\InteractsWithResource;
+9 -10
View File
@@ -6,7 +6,6 @@ use Filament\Filament;
use Filament\Forms\HasForm;
use Filament\Resources\Forms\Form;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Gate;
class CreateRecord extends Page
{
@@ -14,19 +13,12 @@ class CreateRecord extends Page
public static $createButtonLabel = 'filament::resources/pages/create-record.buttons.create.label';
public $record;
public static $showRoute = 'edit';
public static $view = 'filament::resources.pages.create-record';
public $record;
public static function getBreadcrumbs()
{
return [
static::getResource()::generateUrl() => (string) Str::title(static::getResource()::getPluralLabel()),
];
}
public function create()
{
$this->callHook('beforeValidate');
@@ -50,6 +42,13 @@ class CreateRecord extends Page
]));
}
public static function getBreadcrumbs()
{
return [
static::getResource()::generateUrl() => (string) Str::title(static::getResource()::getPluralLabel()),
];
}
public function getForm()
{
return static::getResource()::form(
+11 -11
View File
@@ -21,23 +21,16 @@ class EditRecord extends Page
public static $deleteModalHeading = 'filament::resources/pages/edit-record.modals.delete.heading';
public $indexRoute = 'index';
public $record;
public static $saveButtonLabel = 'filament::resources/pages/edit-record.buttons.save.label';
public static $savedMessage = 'filament::resources/pages/edit-record.messages.saved';
public static $view = 'filament::resources.pages.edit-record';
public $record;
public $indexRoute = 'index';
public static function getBreadcrumbs()
{
return [
static::getResource()::generateUrl() => (string) Str::title(static::getResource()::getPluralLabel()),
];
}
public function canDelete()
{
return Filament::can('delete', $this->record);
@@ -56,6 +49,13 @@ class EditRecord extends Page
$this->redirect($this->getResource()::generateUrl($this->indexRoute));
}
public static function getBreadcrumbs()
{
return [
static::getResource()::generateUrl() => (string) Str::title(static::getResource()::getPluralLabel()),
];
}
public function getForm()
{
return static::getResource()::form(
+20 -16
View File
@@ -3,8 +3,8 @@
namespace Filament\Resources\Pages;
use Filament\Filament;
use Filament\Resources\Tables\Table;
use Filament\Resources\Tables\RecordActions;
use Filament\Resources\Tables\Table;
use Filament\Tables\HasTable;
use Illuminate\Support\Str;
@@ -14,14 +14,12 @@ class ListRecords extends Page
public static $createButtonLabel = 'filament::resources/pages/list-records.buttons.create.label';
public $createRoute = 'create';
public static $editRecordActionLabel = 'filament::resources/pages/list-records.table.recordActions.edit.label';
public static $view = 'filament::resources.pages.list-records';
public $filterable = true;
public $createRoute = 'create';
public $pagination = true;
public $recordRoute = 'edit';
@@ -30,16 +28,7 @@ class ListRecords extends Page
public $sortable = true;
public static function getTitle()
{
if (property_exists(static::class, 'title')) return static::$title;
return (string) Str::of(class_basename(static::getModel()))
->kebab()
->replace('-', ' ')
->plural()
->title();
}
public static $view = 'filament::resources.pages.list-records';
public function canCreate()
{
@@ -83,7 +72,9 @@ class ListRecords extends Page
->filterable($this->filterable)
->pagination($this->pagination)
->primaryColumnUrl(function ($record) {
if (! Filament::can('update', $record)) return;
if (! Filament::can('update', $record)) {
return;
}
return $this->getResource()::generateUrl(
$this->recordRoute,
@@ -101,6 +92,19 @@ class ListRecords extends Page
);
}
public static function getTitle()
{
if (property_exists(static::class, 'title')) {
return static::$title;
}
return (string) Str::of(class_basename(static::getModel()))
->kebab()
->replace('-', ' ')
->plural()
->title();
}
public function isAuthorized()
{
return Filament::can('viewAny', static::getModel());
+16 -12
View File
@@ -9,16 +9,6 @@ class Page extends \Filament\Pages\Page
{
public static $resource;
public static function getResource()
{
return static::$resource;
}
public static function routeTo($uri, $name)
{
return new Route(static::class, $uri, $name);
}
public static function getModel()
{
return static::getResource()::getModel();
@@ -29,18 +19,32 @@ class Page extends \Filament\Pages\Page
return static::getModel()::query();
}
public static function getResource()
{
return static::$resource;
}
public static function routeTo($uri, $name)
{
return new Route(static::class, $uri, $name);
}
protected function authorize($action)
{
$method = (string) Str::of($action)->ucfirst()->prepend('can');
if (! method_exists($this, $method)) return true;
if (! method_exists($this, $method)) {
return true;
}
abort_unless($this->{$method}() ?? true, 403);
}
protected function callHook($hook)
{
if (! method_exists($this, $hook)) return;
if (! method_exists($this, $hook)) {
return;
}
$this->{$hook}();
}
+47 -37
View File
@@ -3,8 +3,8 @@
namespace Filament\Resources;
use Filament\Filament;
use Filament\Resources\Tables\Table;
use Filament\Resources\Tables\RecordActions;
use Filament\Resources\Tables\Table;
use Filament\Tables\HasTable;
use Illuminate\Database\Eloquent\Relations;
use Illuminate\Support\Str;
@@ -16,14 +16,14 @@ class RelationManager extends Component
public static $attachButtonLabel = 'filament::resources/relation-manager.buttons.attach.label';
public static $attachModalCancelButtonLabel = 'filament::resources/relation-manager.modals.attach.buttons.cancel.label';
public static $attachModalAttachAnotherButtonLabel = 'filament::resources/relation-manager.modals.attach.buttons.attachAnother.label';
public static $attachModalAttachButtonLabel = 'filament::resources/relation-manager.modals.attach.buttons.attach.label';
public static $attachModalAttachedMessage = 'filament::resources/relation-manager.modals.attach.messages.attached';
public static $attachModalCancelButtonLabel = 'filament::resources/relation-manager.modals.attach.buttons.cancel.label';
public static $attachModalHeading = 'filament::resources/relation-manager.modals.attach.heading';
public static $createButtonLabel = 'filament::resources/relation-manager.buttons.create.label';
@@ -60,12 +60,12 @@ class RelationManager extends Component
public static $editRecordActionLabel = 'filament::resources/pages/list-records.table.recordActions.edit.label';
public static $relationship;
public $filterable = true;
public $owner;
public static $relationship;
public $searchable = true;
public $sortable = true;
@@ -74,34 +74,14 @@ class RelationManager extends Component
'refreshRelationManagerList' => 'refreshList',
];
public static function getPrimaryColumn()
{
return property_exists(static::class, 'primaryColumn') && static::$primaryColumn !== '' ?
static::$primaryColumn :
null;
}
public static function getRelationship()
{
return static::$relationship;
}
public static function getTitle()
{
if (property_exists(static::class, 'title')) return static::$title;
return (string) Str::of(static::$relationship)
->kebab()
->replace('-', ' ')
->title();
}
public function canAttach()
{
if (
$this->isType(Relations\HasMany::class) ||
$this->isType(Relations\MorphMany::class)
) return false;
) {
return false;
}
return true;
}
@@ -129,7 +109,9 @@ class RelationManager extends Component
if (
$this->isType(Relations\HasMany::class) ||
$this->isType(Relations\MorphMany::class)
) return false;
) {
return false;
}
return true;
}
@@ -162,13 +144,32 @@ class RelationManager extends Component
$this->selected = [];
}
public function getModel()
{
return $this->getQuery()->getModel();
}
public static function getPrimaryColumn()
{
return property_exists(static::class, 'primaryColumn') && static::$primaryColumn !== '' ?
static::$primaryColumn :
null;
}
public function getPrimaryColumnAction($record)
{
if (! Filament::can('update', $record)) return;
if (! Filament::can('update', $record)) {
return;
}
return 'openEdit';
}
public function getQuery()
{
return $this->owner->{static::$relationship}();
}
public function getRecordActions()
{
return [
@@ -179,6 +180,11 @@ class RelationManager extends Component
];
}
public static function getRelationship()
{
return static::$relationship;
}
public function getTable()
{
return static::table(
@@ -194,14 +200,16 @@ class RelationManager extends Component
);
}
public function getModel()
public static function getTitle()
{
return $this->getQuery()->getModel();
}
if (property_exists(static::class, 'title')) {
return static::$title;
}
public function getQuery()
{
return $this->owner->{static::$relationship}();
return (string) Str::of(static::$relationship)
->kebab()
->replace('-', ' ')
->title();
}
public function isType($type)
@@ -233,7 +241,9 @@ class RelationManager extends Component
public function refreshList($manager = null)
{
if ($manager !== null && $manager !== static::class) return;
if ($manager !== null && $manager !== static::class) {
return;
}
$this->callMethod('$refresh');
}
+34 -34
View File
@@ -12,14 +12,14 @@ class AttachRecord extends Component
{
use HasForm;
public $cancelButtonLabel;
public $attachAnotherButtonLabel;
public $attachButtonLabel;
public $attachAnotherButtonLabel;
public $attachedMessage;
public $cancelButtonLabel;
public $manager;
public $owner;
@@ -43,37 +43,6 @@ class AttachRecord extends Component
$this->related = null;
}
public function getRelationship()
{
$manager = $this->manager;
return $manager::$relationship;
}
public function getInverseRelationship()
{
$manager = $this->manager;
if (property_exists($manager, 'inverseRelationship')) {
return $manager::$inverseRelationship;
}
return (string) Str::of(class_basename($this->owner))
->lower()
->plural()
->camel();
}
public function getPrimaryColumn()
{
return $this->manager::getPrimaryColumn() ?? $this->owner->getKeyName();
}
public function mount()
{
$this->fillWithFormDefaults();
}
public function getForm()
{
return Form::make()
@@ -105,6 +74,37 @@ class AttachRecord extends Component
]);
}
public function getInverseRelationship()
{
$manager = $this->manager;
if (property_exists($manager, 'inverseRelationship')) {
return $manager::$inverseRelationship;
}
return (string) Str::of(class_basename($this->owner))
->lower()
->plural()
->camel();
}
public function getPrimaryColumn()
{
return $this->manager::getPrimaryColumn() ?? $this->owner->getKeyName();
}
public function getRelationship()
{
$manager = $this->manager;
return $manager::$relationship;
}
public function mount()
{
$this->fillWithFormDefaults();
}
public function render()
{
return view('filament::resources.relation-manager.attach-record');
+8 -6
View File
@@ -59,6 +59,11 @@ class EditRecord extends Component
$this->fillWithFormDefaults();
}
public function render()
{
return view('filament::resources.relation-manager.edit-record');
}
public function save()
{
abort_unless(Filament::can('update', $this->record), 403);
@@ -81,14 +86,11 @@ class EditRecord extends Component
public function switchRecord($manager, $record)
{
if ($manager !== $this->manager) return;
if ($manager !== $this->manager) {
return;
}
$this->record = $this->getQuery()->find($record);
$this->resetTemporaryUploadedFiles();
}
public function render()
{
return view('filament::resources.relation-manager.edit-record');
}
}
+15 -5
View File
@@ -35,7 +35,9 @@ class Resource
public static function generateUrl($name = null, $parameters = [], $absolute = true)
{
if (! $name) $name = static::router()->getIndexRoute()->name;
if (! $name) {
$name = static::router()->getIndexRoute()->name;
}
return route(static::$routeNamePrefix . '.' . static::getSlug() . '.' . $name, $parameters, $absolute);
}
@@ -47,7 +49,9 @@ class Resource
public static function getLabel()
{
if (static::$label) return static::$label;
if (static::$label) {
return static::$label;
}
return (string) Str::of(class_basename(static::getModel()))
->kebab()
@@ -56,7 +60,9 @@ class Resource
public static function getModel()
{
if (static::$model) return static::$model;
if (static::$model) {
return static::$model;
}
return (string) Str::of(class_basename(static::class))
->beforeLast('Resource')
@@ -65,7 +71,9 @@ class Resource
public static function getNavigationLabel()
{
if (static::$navigationLabel) return static::$navigationLabel;
if (static::$navigationLabel) {
return static::$navigationLabel;
}
return (string) Str::title(static::getPluralLabel());
}
@@ -82,7 +90,9 @@ class Resource
public static function getSlug()
{
if (static::$slug) return static::$slug;
if (static::$slug) {
return static::$slug;
}
return (string) Str::of(class_basename(static::getModel()))
->plural()
+15 -11
View File
@@ -15,17 +15,6 @@ class Router
$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)
@@ -37,4 +26,19 @@ class Router
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;
}
}
+9 -9
View File
@@ -122,6 +122,15 @@ class UserResource extends Resource
return parent::navigationItems();
}
public static function routes()
{
return [
Pages\ListUsers::routeTo('/', 'index'),
Pages\CreateUser::routeTo('/create', 'create'),
Pages\EditUser::routeTo('/{record}/edit', 'edit'),
];
}
public static function table(Table $table)
{
$table->columns([
@@ -149,13 +158,4 @@ class UserResource extends Resource
return $table;
}
public static function routes()
{
return [
Pages\ListUsers::routeTo('/', 'index'),
Pages\CreateUser::routeTo('/create', 'create'),
Pages\EditUser::routeTo('/{record}/edit', 'edit'),
];
}
}
@@ -8,11 +8,6 @@ use Illuminate\Support\Facades\Hash;
class CreateUser extends CreateRecord
{
public static function getResource()
{
return Filament::userResource();
}
public function create()
{
$this->validateTemporaryUploadedFiles();
@@ -30,4 +25,9 @@ class CreateUser extends CreateRecord
'record' => $record,
]));
}
public static function getResource()
{
return Filament::userResource();
}
}
+6 -2
View File
@@ -20,7 +20,9 @@ class Authorization
public function except($actions)
{
if (! is_array($actions)) $actions = [$actions];
if (! is_array($actions)) {
$actions = [$actions];
}
$this->exceptActions = array_merge($this->exceptActions, $actions);
@@ -29,7 +31,9 @@ class Authorization
public function only($actions)
{
if (! is_array($actions)) $actions = [$actions];
if (! is_array($actions)) {
$actions = [$actions];
}
$this->onlyActions = array_merge($this->onlyActions, $actions);
+3 -1
View File
@@ -20,7 +20,9 @@ class Role
public static function getLabel()
{
if (static::$label) return static::$label;
if (static::$label) {
return static::$label;
}
return (string) Str::of(class_basename(static::class))
->kebab()
+6 -7
View File
@@ -3,9 +3,8 @@
namespace Filament\View\Components;
use Filament\Filament;
use Illuminate\View\Component;
use Thomaswelton\LaravelGravatar\Facades\Gravatar;
use function Filament\get_image_url;
use Illuminate\View\Component;
class Avatar extends Component
{
@@ -22,6 +21,11 @@ class Avatar extends Component
$this->user = $user;
}
public function render()
{
return view('filament::components.avatar');
}
public function src($dpr = 1)
{
$avatar = $this->user->getFilamentAvatar();
@@ -47,9 +51,4 @@ class Avatar extends Component
->map(fn ($dpr) => $this->src($dpr) . ' ' . $dpr . 'x')
->implode(', ');
}
public function render()
{
return view('filament::components.avatar');
}
}
+6 -6
View File
@@ -2,8 +2,8 @@
namespace Filament\View\Components;
use Illuminate\View\Component;
use function Filament\get_image_url;
use Illuminate\View\Component;
class Image extends Component
{
@@ -20,6 +20,11 @@ class Image extends Component
$this->src = $src;
}
public function render()
{
return view('filament::components.image');
}
public function src($dpr = 1)
{
return get_image_url(
@@ -34,9 +39,4 @@ class Image extends Component
->map(fn ($dpr) => $this->src($dpr) . ' ' . $dpr . 'x')
->implode(', ');
}
public function render()
{
return view('filament::components.image');
}
}
-1
View File
@@ -4,7 +4,6 @@ namespace Filament\View\Components;
use Filament\Filament;
use Filament\NavigationItem;
use Illuminate\Support\Facades\Gate;
use Illuminate\View\Component;
class Nav extends Component
+13 -5
View File
@@ -2,8 +2,8 @@
namespace Filament;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use League\Glide\Urls\UrlBuilderFactory;
if (! function_exists('Filament\format_attributes')) {
@@ -34,15 +34,21 @@ if (! function_exists('Filament\get_asset_id')) {
{
$manifestPath = __DIR__ . '/../dist/mix-manifest.json';
if (! file_exists($manifestPath)) return null;
if (! file_exists($manifestPath)) {
return null;
}
$manifest = json_decode(file_get_contents($manifestPath), true);
if (! array_key_exists($path, $manifest)) return null;
if (! array_key_exists($path, $manifest)) {
return null;
}
$path = $manifest[$path];
if (! str_contains($path, 'id=')) return null;
if (! str_contains($path, 'id=')) {
return null;
}
$id = (string) Str::of($path)->after('id=');
@@ -64,7 +70,9 @@ if (! function_exists('Filament\get_media_contents')) {
{
$disk = Storage::disk(config('filament.default_filesystem_disk'));
if (! $disk->exists($path)) return;
if (! $disk->exists($path)) {
return;
}
return $disk->get($path);
}
+18 -18
View File
@@ -9,14 +9,6 @@ use Livewire\Livewire;
class LoginTest extends TestCase
{
/** @test */
public function can_view_login_page()
{
$this->get(route('filament.auth.login'))
->assertSuccessful()
->assertSeeLivewire('filament.core.auth.login');
}
/** @test */
public function can_login()
{
@@ -32,17 +24,11 @@ class LoginTest extends TestCase
}
/** @test */
public function shows_an_error_when_bad_login_attempt()
public function can_view_login_page()
{
$user = User::factory()->create();
Livewire::test(Login::class)
->set('email', $user->email)
->set('password', 'bad-password')
->call('submit')
->assertHasErrors('email');
$this->assertGuest();
$this->get(route('filament.auth.login'))
->assertSuccessful()
->assertSeeLivewire('filament.core.auth.login');
}
/** @test */
@@ -71,4 +57,18 @@ class LoginTest extends TestCase
->call('submit')
->assertHasErrors(['password' => 'required']);
}
/** @test */
public function shows_an_error_when_bad_login_attempt()
{
$user = User::factory()->create();
Livewire::test(Login::class)
->set('email', $user->email)
->set('password', 'bad-password')
->call('submit')
->assertHasErrors('email');
$this->assertGuest();
}
}
+19 -19
View File
@@ -11,14 +11,6 @@ use Livewire\Livewire;
class RequestPasswordTest extends TestCase
{
/** @test */
public function can_view_password_reset_request_page()
{
$this->get(route('filament.auth.password.request'))
->assertSuccessful()
->assertSeeLivewire('filament.core.auth.request-password');
}
/** @test */
public function can_request_password_reset()
{
@@ -36,18 +28,11 @@ class RequestPasswordTest extends TestCase
}
/** @test */
public function shows_an_error_when_bad_request_attempt()
public function can_view_password_reset_request_page()
{
Notification::fake();
$email = $this->faker->safeEmail;
Livewire::test(RequestPassword::class)
->set('email', $email)
->call('submit')
->assertHasErrors('email');
Notification::assertNothingSent();
$this->get(route('filament.auth.password.request'))
->assertSuccessful()
->assertSeeLivewire('filament.core.auth.request-password');
}
/** @test */
@@ -67,4 +52,19 @@ class RequestPasswordTest extends TestCase
->call('submit')
->assertHasErrors(['email' => 'email']);
}
/** @test */
public function shows_an_error_when_bad_request_attempt()
{
Notification::fake();
$email = $this->faker->safeEmail;
Livewire::test(RequestPassword::class)
->set('email', $email)
->call('submit')
->assertHasErrors('email');
Notification::assertNothingSent();
}
}
+35 -35
View File
@@ -13,16 +13,6 @@ use Livewire\Livewire;
class ResetPasswordTest extends TestCase
{
/** @test */
public function can_view_password_reset_page()
{
$this->get(URL::signedRoute('filament.auth.password.reset', [
'token' => $this->generateToken(),
]))
->assertSuccessful()
->assertSeeLivewire('filament.core.auth.reset-password');
}
/** @test */
public function can_reset_password()
{
@@ -48,28 +38,13 @@ class ResetPasswordTest extends TestCase
}
/** @test */
public function is_forbidden_if_request_is_unsigned()
public function can_view_password_reset_page()
{
$this->get(route('filament.auth.password.reset', [
$this->get(URL::signedRoute('filament.auth.password.reset', [
'token' => $this->generateToken(),
]))
->assertForbidden();
}
/** @test */
public function shows_an_error_when_invalid_token_supplied()
{
$user = User::factory()->create();
$newPassword = Str::random();
Livewire::test(ResetPassword::class, [
'token' => 'invalid-token',
])
->set('email', $user->email)
->set('password', $newPassword)
->set('passwordConfirmation', $newPassword)
->call('submit')
->assertHasErrors('email');
->assertSuccessful()
->assertSeeLivewire('filament.core.auth.reset-password');
}
/** @test */
@@ -95,14 +70,12 @@ class ResetPasswordTest extends TestCase
}
/** @test */
public function password_is_required()
public function is_forbidden_if_request_is_unsigned()
{
Livewire::test(ResetPassword::class, [
$this->get(route('filament.auth.password.reset', [
'token' => $this->generateToken(),
])
->set('password', null)
->call('submit')
->assertHasErrors(['password' => 'required']);
]))
->assertForbidden();
}
/** @test */
@@ -131,6 +104,33 @@ class ResetPasswordTest extends TestCase
->assertHasErrors(['passwordConfirmation' => 'same']);
}
/** @test */
public function password_is_required()
{
Livewire::test(ResetPassword::class, [
'token' => $this->generateToken(),
])
->set('password', null)
->call('submit')
->assertHasErrors(['password' => 'required']);
}
/** @test */
public function shows_an_error_when_invalid_token_supplied()
{
$user = User::factory()->create();
$newPassword = Str::random();
Livewire::test(ResetPassword::class, [
'token' => 'invalid-token',
])
->set('email', $user->email)
->set('password', $newPassword)
->set('passwordConfirmation', $newPassword)
->call('submit')
->assertHasErrors('email');
}
protected function generateToken($user = null)
{
if (! $user) {
+12 -12
View File
@@ -11,18 +11,6 @@ use Livewire\Livewire;
class EditAccountTest extends TestCase
{
/** @test */
public function can_view_account_page()
{
$user = User::factory()->create();
$this->be($user);
$this->get(route('filament.account'))
->assertSuccessful()
->assertSeeLivewire('filament.core.edit-account');
}
/** @test */
public function can_update_account_information()
{
@@ -55,6 +43,18 @@ class EditAccountTest extends TestCase
// ]));
}
/** @test */
public function can_view_account_page()
{
$user = User::factory()->create();
$this->be($user);
$this->get(route('filament.account'))
->assertSuccessful()
->assertSeeLivewire('filament.core.edit-account');
}
/** @test */
public function record_email_is_required()
{
+2 -1
View File
@@ -16,7 +16,8 @@ use Watson\Active\ActiveServiceProvider;
abstract class TestCase extends \Orchestra\Testbench\TestCase
{
use RefreshDatabase, WithFaker;
use RefreshDatabase;
use WithFaker;
protected function setUp(): void
{