Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
anotherfrontendguy committed Nov 28, 2019
0 parents commit 7cf3612
Show file tree
Hide file tree
Showing 13 changed files with 306 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/.idea
/vendor
/node_modules
package-lock.json
composer.phar
composer.lock
phpunit.xml
.phpunit.result.cache
.DS_Store
Thumbs.db
29 changes: 29 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "suenerds/nova-searchable-belongs-to-filter",
"description": "Searchable Filter for Laravel Nova",
"keywords": [
"laravel",
"nova"
],
"license": "MIT",
"require": {
"php": ">=7.1.0"
},
"autoload": {
"psr-4": {
"Suenerds\\NovaSearchableBelongsToFilter\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Suenerds\\NovaSearchableBelongsToFilter\\FilterServiceProvider"
]
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true
}
Empty file added dist/css/filter.css
Empty file.
1 change: 1 addition & 0 deletions dist/js/filter.js

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions dist/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"/js/filter.js": "/js/filter.js",
"/css/filter.css": "/css/filter.css"
}
20 changes: 20 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},
"devDependencies": {
"cross-env": "^5.0.0",
"laravel-mix": "^1.0"
},
"dependencies": {
"laravel-nova": "^1.0.9",
"vue": "^2.5.0"
}
}
124 changes: 124 additions & 0 deletions resources/js/components/Filter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<template>
<div>
<h3 class="text-sm uppercase tracking-wide text-80 bg-30 p-3">
{{ filter.name }}
</h3>

<div class="p-2">
<search-input
@input="performSearch"
@clear="clearSelection"
@selected="selectResource"
:value="selectedResource"
:data="availableResources"
:clearable="false"
trackBy="value"
searchBy="display"
class="mb-3"
>
<div
slot="default"
v-if="selectedResource"
class="flex items-center"
>
<div
v-if="selectedResource.avatar"
class="mr-3"
>
<img
:src="selectedResource.avatar"
class="w-8 h-8 rounded-full block"
/>
</div>

{{ selectedResource.display }}
</div>

<div
slot="option"
slot-scope="{ option, selected }"
class="flex items-center"
>
<div
v-if="option.avatar"
class="mr-3"
>
<img
:src="option.avatar"
class="w-8 h-8 rounded-full block"
/>
</div>

{{ option.display }}
</div>
</search-input>

</div>
</div>
</template>

<script>
import { PerformsSearches } from "laravel-nova"
import storage from '../storage/BelongsToFieldStorage'
export default {
mixins: [PerformsSearches],
props: {
resourceName: {
type: String,
required: true,
},
filterKey: {
type: String,
required: true,
},
},
methods: {
getAvailableResources() {
return storage.fetchAvailableResources(
this.resourceName,
this.fieldAttribute,
{
params: {
search: this.search,
},
}
).then(({ data: { resources } }) => {
this.availableResources = resources;
});
},
selectResource(resource) {
this.selectedResource = resource;
this.handleChange();
},
handleChange() {
this.$store.commit(`${this.resourceName}/updateFilterState`, {
filterClass: this.filterKey,
value: this.selectedResource.value
});
this.$emit("change");
},
},
computed: {
filter() {
return this.$store.getters[`${this.resourceName}/getFilter`](
this.filterKey
);
},
fieldAttribute() {
return this.filter.fieldAttribute;
},
value() {
return this.filter.currentValue;
},
},
};
</script>
3 changes: 3 additions & 0 deletions resources/js/filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Nova.booting((Vue, router, store) => {
Vue.component('nova-searchable-belongs-to-filter', require('./components/Filter'))
})
12 changes: 12 additions & 0 deletions resources/js/storage/BelongsToFieldStorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default {
fetchAvailableResources(resourceName, fieldAttribute, params) {
return Nova.request().get(
`/nova-api/${resourceName}/associatable/${fieldAttribute}`,
params
)
},

determineIfSoftDeletes(resourceName) {
return Nova.request().get(`/nova-api/${resourceName}/soft-deletes`)
},
}
1 change: 1 addition & 0 deletions resources/sass/filter.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Nova Filter CSS
33 changes: 33 additions & 0 deletions src/FilterServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Suenerds\NovaSearchableBelongsToFilter;

use Illuminate\Support\ServiceProvider;
use Laravel\Nova\Events\ServingNova;
use Laravel\Nova\Nova;

class FilterServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Nova::serving(function (ServingNova $event) {
Nova::script('nova-searchable-belongs-to-filter', __DIR__.'/../dist/js/filter.js');
Nova::style('nova-searchable-belongs-to-filter', __DIR__.'/../dist/css/filter.css');
});
}

/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
63 changes: 63 additions & 0 deletions src/NovaSearchableBelongsToFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Suenerds\NovaSearchableBelongsToFilter;

use Illuminate\Http\Request;
use Laravel\Nova\Filters\Filter;

class NovaSearchableBelongsToFilter extends Filter
{
/**
* The filter's component.
*
* @var string
*/
public $component = 'nova-searchable-belongs-to-filter';

public $filterBy;

/**
* Apply the filter to the given query.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Database\Eloquent\Builder $query
* @param mixed $value
* @return \Illuminate\Database\Eloquent\Builder
*/
public function apply(Request $request, $query, $value)
{
return $query->where($this->filterBy, $value);
}

/**
* Get the filter's available options.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function options(Request $request)
{
return [];
}

public function name()
{
return __('Filter by ' . $this->meta()['fieldAttribute']);
}

public function fieldAttribute($attribute)
{
$this->withMeta([
'fieldAttribute' => $attribute,
]);

return $this;
}

public function filterBy($attribute)
{
$this->filterBy = $attribute;

return $this;
}
}
6 changes: 6 additions & 0 deletions webpack.mix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
let mix = require('laravel-mix')

mix
.setPublicPath('dist')
.js('resources/js/filter.js', 'js')
.sass('resources/sass/filter.scss', 'css')

0 comments on commit 7cf3612

Please sign in to comment.