From 3d75e4057453c859966daee912fe2bcf06d79cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=2E=20Nagy=20Gerg=C5=91?= Date: Tue, 7 Nov 2023 20:19:47 +0100 Subject: [PATCH 1/4] wip --- resources/views/fields/file-option.blade.php | 4 ++-- src/Actions/Action.php | 6 +++--- src/Actions/Actions.php | 6 +++--- src/Fields/File.php | 11 ++++++++++- src/Models/Medium.php | 2 +- src/Resources/Resource.php | 12 ++++++++++-- 6 files changed, 29 insertions(+), 12 deletions(-) diff --git a/resources/views/fields/file-option.blade.php b/resources/views/fields/file-option.blade.php index 7766394c..c93b227f 100644 --- a/resources/views/fields/file-option.blade.php +++ b/resources/views/fields/file-option.blade.php @@ -1,13 +1,13 @@
@if($isImage) - {{ $label }} + {{ $fileName }} @else @endif - {{ $label }} + {{ $fileName }}
diff --git a/src/Actions/Action.php b/src/Actions/Action.php index 42066138..529b8aad 100644 --- a/src/Actions/Action.php +++ b/src/Actions/Action.php @@ -15,6 +15,7 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Concerns\HasAttributes; +use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; use Illuminate\Routing\Router; use Illuminate\Support\Facades\Redirect; @@ -213,12 +214,11 @@ public function toArray(): array /** * {@inheritdoc} */ - public function toForm(Request $request): array + public function toForm(Request $request, Model $model): array { return array_merge($this->toArray(), [ 'open' => $this->errors($request)->isNotEmpty(), - 'fields' => $this->resolveFields($request) - ->mapToInputs($request, $this->query->getModel()), + 'fields' => $this->resolveFields($request)->mapToInputs($request, $model), ]); } } diff --git a/src/Actions/Actions.php b/src/Actions/Actions.php index 37f8bb35..c74b1ac6 100644 --- a/src/Actions/Actions.php +++ b/src/Actions/Actions.php @@ -40,11 +40,11 @@ public function visible(string|array $context): static } /** - * Map the action to table components. + * Map the action to forms. */ - public function mapToForms(Request $request): array + public function mapToForms(Request $request, Model $model): array { - return $this->map->toForm($request)->all(); + return $this->map->toForm($request, $model)->all(); } /** diff --git a/src/Fields/File.php b/src/Fields/File.php index c6713fb9..df5dc102 100644 --- a/src/Fields/File.php +++ b/src/Fields/File.php @@ -36,6 +36,11 @@ class File extends MorphToMany */ protected string $disk; + /** + * The displayable conversion name. + */ + protected ?string $displayConversion = 'original'; + /** * Create a new field instance. */ @@ -94,7 +99,11 @@ public function collection(string $value): static public function resolveDisplay(Model $related): mixed { if (is_null($this->displayResolver)) { - $this->display('file_name'); + $this->display(function (Medium $related): string { + return $related->isImage + ? sprintf('', $related->getUrl($this->displayConversion)) + : sprintf('%s', $related->getUrl(), $related->file_name); + }); } return parent::resolveDisplay($related); diff --git a/src/Models/Medium.php b/src/Models/Medium.php index 096014fc..a324a7ca 100644 --- a/src/Models/Medium.php +++ b/src/Models/Medium.php @@ -239,7 +239,7 @@ public function getPath(string $conversion = null, bool $absolute = false): stri { $path = sprintf('%s/%s', $this->uuid, $this->file_name); - if (! is_null($conversion)) { + if (! is_null($conversion) && $conversion !== 'original') { $path = substr_replace( $path, "-{$conversion}", -(mb_strlen(Str::afterLast($path, '.')) + 1), -mb_strlen("-{$conversion}") ); diff --git a/src/Resources/Resource.php b/src/Resources/Resource.php index 6c051498..0b518a18 100644 --- a/src/Resources/Resource.php +++ b/src/Resources/Resource.php @@ -334,9 +334,9 @@ public function toIndex(Request $request): array return array_merge($this->toArray(), [ 'title' => $this->getName(), 'actions' => $this->resolveActions($request) - ->authorized($request) + ->authorized($request, $this->getModelInstance()) ->visible('index') - ->mapToForms($request), + ->mapToForms($request, $this->getModelInstance()), 'data' => $this->paginate($request), 'widgets' => $this->resolveWidgets($request) ->authorized($request) @@ -385,6 +385,14 @@ public function toShow(Request $request, Model $model): array ->authorized($request, $model) ->visible('show') ->mapToDisplay($request, $model), + 'actions' => $this->resolveActions($request) + ->authorized($request, $model) + ->visible('show') + ->mapToForms($request, $model), + 'widgets' => $this->resolveWidgets($request) + ->authorized($request, $model) + ->visible('show') + ->toArray(), ]); } From 22d0c1e3d49647dd3b3b8031277812d01990ffcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=2E=20Nagy=20Gerg=C5=91?= Date: Fri, 10 Nov 2023 20:56:08 +0100 Subject: [PATCH 2/4] wip --- resources/views/media/filters.blade.php | 10 ++-- src/Fields/Media.php | 67 ++++++++++++++++++++++++- src/Filters/MediaSearch.php | 31 ++++++++++++ src/Filters/Search.php | 18 +++++-- src/Resources/Resource.php | 6 +-- 5 files changed, 116 insertions(+), 16 deletions(-) create mode 100644 src/Filters/MediaSearch.php diff --git a/resources/views/media/filters.blade.php b/resources/views/media/filters.blade.php index 8614525a..5cb22921 100644 --- a/resources/views/media/filters.blade.php +++ b/resources/views/media/filters.blade.php @@ -1,9 +1,5 @@ diff --git a/src/Fields/Media.php b/src/Fields/Media.php index 85e936c4..9c37ce62 100644 --- a/src/Fields/Media.php +++ b/src/Fields/Media.php @@ -2,10 +2,17 @@ namespace Cone\Root\Fields; +use Closure; +use Cone\Root\Filters\Filter; +use Cone\Root\Filters\Filters; +use Cone\Root\Filters\MediaSearch; +use Cone\Root\Filters\RenderableFilter; +use Cone\Root\Filters\Search; use Cone\Root\Http\Controllers\MediaController; use Cone\Root\Models\Medium; use Cone\Root\Traits\HasMedia; use Cone\Root\Traits\RegistersRoutes; +use Cone\Root\Traits\ResolvesFilters; use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; use Illuminate\Http\UploadedFile; @@ -18,6 +25,7 @@ class Media extends File { + use ResolvesFilters; use RegistersRoutes { RegistersRoutes::registerRoutes as __registerRoutes; } @@ -32,6 +40,11 @@ class Media extends File */ protected string $template = 'root::fields.media'; + /** + * The filters resolver callback. + */ + protected ?Closure $filtersResolver = null; + /** * Get the URI key. */ @@ -77,12 +90,55 @@ public function getModel(): Model }; } + /** + * Define the filters for the object. + */ + public function filters(Request $request): array + { + return [ + new MediaSearch(), + ]; + } + + /** + * Set the filters resolver callback. + */ + public function withFilters(Closure $callback): static + { + $this->filtersResolver = $callback; + + return $this; + } + + /** + * Resolve the filters collection. + */ + public function resolveFilters(Request $request): Filters + { + if (is_null($this->filters)) { + $this->filters = new Filters($this->filters($request)); + + if (! is_null($this->filtersResolver)) { + $this->fields->register( + Arr::wrap(call_user_func_array($this->filtersResolver, [$request])) + ); + } + + $this->filters->each(function (Filter $filter) use ($request): void { + $this->resolveFilter($request, $filter); + }); + } + + return $this->filters; + } + /** * Paginate the results. */ public function paginate(Request $request, Model $model): array { - return $this->resolveRelatableQuery($request, $model) + return $this->resolveFilters($request) + ->apply($request, $this->resolveRelatableQuery($request, $model)) ->latest() ->paginate($request->input('per_page')) ->withQueryString() @@ -203,6 +259,15 @@ public function toInput(Request $request, Model $model): array ]); }, $data['options'] ?? []), 'url' => $this->getUri() ? $this->buildUri($request, $model) : null, + 'filters' => $this->resolveFilters($request) + ->authorized($request) + ->renderable() + ->map(function (RenderableFilter $filter) use ($request, $model): array { + return $filter->toField() + ->removeAttribute('name') + ->toInput($request, $this->getRelation($model)->getRelated()); + }) + ->all(), ]); } } diff --git a/src/Filters/MediaSearch.php b/src/Filters/MediaSearch.php new file mode 100644 index 00000000..4de6b1ed --- /dev/null +++ b/src/Filters/MediaSearch.php @@ -0,0 +1,31 @@ +attributes = $attributes; + } + + /** + * {@inheritdoc} + */ + public function getSearchableAttributes(): array + { + return array_fill_keys($this->attributes, null); + } +} diff --git a/src/Filters/Search.php b/src/Filters/Search.php index 7e378d03..768429ce 100644 --- a/src/Filters/Search.php +++ b/src/Filters/Search.php @@ -28,11 +28,7 @@ public function __construct(Fields $fields) */ public function apply(Request $request, Builder $query, mixed $value): Builder { - $attributes = $this->fields->mapWithKeys(static function (Field $field): array { - return [ - $field->getModelAttribute() => $field instanceof Relation ? $field->getSearchableColumns() : null, - ]; - })->all(); + $attributes = $this->getSearchableAttributes(); if (empty($value) || empty($attributes)) { return $query; @@ -59,6 +55,18 @@ public function apply(Request $request, Builder $query, mixed $value): Builder }); } + /** + * Get the serachable attributes. + */ + public function getSearchableAttributes(): array + { + return $this->fields->mapWithKeys(static function (Field $field): array { + return [ + $field->getModelAttribute() => $field instanceof Relation ? $field->getSearchableColumns() : null, + ]; + })->all(); + } + /** * {@inheritdoc} */ diff --git a/src/Resources/Resource.php b/src/Resources/Resource.php index 0b518a18..f06efd39 100644 --- a/src/Resources/Resource.php +++ b/src/Resources/Resource.php @@ -30,11 +30,11 @@ abstract class Resource implements Arrayable, Form, Table { use AsForm; use Authorizable; + use ResolvesActions; + use ResolvesFilters; use RegistersRoutes { RegistersRoutes::registerRoutes as __registerRoutes; } - use ResolvesActions; - use ResolvesFilters; use ResolvesWidgets; /** @@ -366,7 +366,7 @@ public function toCreate(Request $request): array 'method' => 'POST', 'fields' => $this->resolveFields($request) ->authorized($request, $model) - ->visible('update') + ->visible('create') ->mapToInputs($request, $model), ]); } From c8d82990058c5dd934ff30fe72cdc8a9ff1db801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=2E=20Nagy=20Gerg=C5=91?= Date: Sat, 11 Nov 2023 12:01:10 +0100 Subject: [PATCH 3/4] media filters --- public/build/assets/app-5cfcf402.js | 1 - .../{app-c6af0dee.js => app-c8ab9151.js} | 38 +++++++++---------- public/build/assets/app-e9d1dd12.js | 1 + public/build/assets/dropdown-73a613e0.js | 1 + public/build/assets/dropdown-7dc1f3ea.js | 1 - public/build/assets/editor-73a613e0.js | 1 + public/build/assets/editor-7dc1f3ea.js | 1 - public/build/assets/media-manager-73a613e0.js | 1 + public/build/assets/media-manager-7dc1f3ea.js | 1 - public/build/assets/repeater-73a613e0.js | 1 + public/build/assets/repeater-7dc1f3ea.js | 1 - public/build/manifest.json | 12 +++--- resources/js/media-manager.js | 18 ++++++++- resources/views/fields/media.blade.php | 5 +-- resources/views/media/filters.blade.php | 2 +- resources/views/media/manager.blade.php | 1 - resources/views/media/queued-medium.blade.php | 4 +- src/Fields/Media.php | 11 ++++-- src/Traits/HasAttributes.php | 8 ++-- 19 files changed, 62 insertions(+), 47 deletions(-) delete mode 100644 public/build/assets/app-5cfcf402.js rename public/build/assets/{app-c6af0dee.js => app-c8ab9151.js} (96%) create mode 100644 public/build/assets/app-e9d1dd12.js create mode 100644 public/build/assets/dropdown-73a613e0.js delete mode 100644 public/build/assets/dropdown-7dc1f3ea.js create mode 100644 public/build/assets/editor-73a613e0.js delete mode 100644 public/build/assets/editor-7dc1f3ea.js create mode 100644 public/build/assets/media-manager-73a613e0.js delete mode 100644 public/build/assets/media-manager-7dc1f3ea.js create mode 100644 public/build/assets/repeater-73a613e0.js delete mode 100644 public/build/assets/repeater-7dc1f3ea.js diff --git a/public/build/assets/app-5cfcf402.js b/public/build/assets/app-5cfcf402.js deleted file mode 100644 index c7da4cac..00000000 --- a/public/build/assets/app-5cfcf402.js +++ /dev/null @@ -1 +0,0 @@ -import{a as f}from"./app-c6af0dee.js";export{f as default}; diff --git a/public/build/assets/app-c6af0dee.js b/public/build/assets/app-c8ab9151.js similarity index 96% rename from public/build/assets/app-c6af0dee.js rename to public/build/assets/app-c8ab9151.js index 4f4e9756..bc4ab582 100644 --- a/public/build/assets/app-c6af0dee.js +++ b/public/build/assets/app-c8ab9151.js @@ -1,12 +1,12 @@ -var Rs=!1,Ds=!1,Pt=[],Is=-1;function Hf(n){jf(n)}function jf(n){Pt.includes(n)||Pt.push(n),Vf()}function vc(n){let e=Pt.indexOf(n);e!==-1&&e>Is&&Pt.splice(e,1)}function Vf(){!Ds&&!Rs&&(Rs=!0,queueMicrotask(Uf))}function Uf(){Rs=!1,Ds=!0;for(let n=0;nn.effect(e,{scheduler:t=>{_s?Hf(t):t()}}),Mc=n.raw}function Al(n){En=n}function Wf(n){let e=()=>{};return[r=>{let i=En(r);return n._x_effects||(n._x_effects=new Set,n._x_runEffects=()=>{n._x_effects.forEach(s=>s())}),n._x_effects.add(i),e=()=>{i!==void 0&&(n._x_effects.delete(i),sr(i))},i},()=>{e()}]}function Bn(n,e,t={}){n.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0,cancelable:!0}))}function mt(n,e){if(typeof ShadowRoot=="function"&&n instanceof ShadowRoot){Array.from(n.children).forEach(i=>mt(i,e));return}let t=!1;if(e(n,()=>t=!0),t)return;let r=n.firstElementChild;for(;r;)mt(r,e),r=r.nextElementSibling}function Ye(n,...e){console.warn(`Alpine Warning: ${n}`,...e)}var Nl=!1;function Jf(){Nl&&Ye("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),Nl=!0,document.body||Ye("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's `