├── .eslintrc ├── .github ├── funding.yml └── workflows │ └── compile-with-prettier.yml ├── .prettierrc ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── dist ├── css │ └── entry.css ├── js │ └── entry.js └── mix-manifest.json ├── docs └── input-filter.gif ├── package-lock.json ├── package.json ├── pint.json ├── resources ├── css │ └── entry.css └── js │ ├── components │ └── InputFilter.vue │ └── entry.js ├── src ├── FilterServiceProvider.php └── InputFilter.php ├── tailwind.config.js ├── testbench.yaml ├── testbench.yml ├── webpack.mix.js └── workbench ├── app ├── Models │ └── User.php ├── Nova │ ├── Filters │ │ └── EmailFilter.php │ ├── Resource.php │ └── User.php └── Providers │ ├── NovaServiceProvider.php │ └── WorkbenchServiceProvider.php ├── bootstrap └── app.php ├── database ├── factories │ ├── .gitkeep │ └── UserFactory.php ├── migrations │ └── .gitkeep └── seeders │ └── DatabaseSeeder.php ├── resources └── views │ └── .gitkeep └── routes ├── console.php └── web.php /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "plugin:vue/essential", 4 | "prettier" 5 | ], 6 | "plugins": [ 7 | "prettier" 8 | ], 9 | "rules": { 10 | "prettier/prettier": [ 11 | "error" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.github/funding.yml: -------------------------------------------------------------------------------- 1 | github: outl1ne 2 | -------------------------------------------------------------------------------- /.github/workflows/compile-with-prettier.yml: -------------------------------------------------------------------------------- 1 | name: Prettier 2 | 3 | on: [ push ] 4 | 5 | jobs: 6 | run-prettier: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: Checkout code 11 | uses: actions/checkout@v2 12 | 13 | - name: Use Node.js 14 | uses: actions/setup-node@v1 15 | with: 16 | node-version: 14 17 | 18 | - name: Install Node.js dependencies 19 | run: npm install 20 | 21 | - name: Run prettier 22 | run: npm run format 23 | 24 | - name: Run eslint 25 | run: npm run lint 26 | 27 | - name: Commit changes 28 | uses: stefanzweifel/git-auto-commit-action@v4 29 | with: 30 | commit_message: prettier 31 | 32 | - name: Compile 33 | run: npm run prod 34 | 35 | - name: Commit changes 36 | uses: stefanzweifel/git-auto-commit-action@v4 37 | with: 38 | commit_message: build assets 39 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "singleQuote": true, 4 | "trailingComma": "es5", 5 | "arrowParens": "avoid" 6 | } 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres 6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [2.0.1] - 27-02-2024 9 | 10 | ## What's Changed 11 | 12 | - Update InputFilter.php by @Naoray in https://github.com/outl1ne/nova-input-filter/pull/10 13 | - fix view part for new version Nova + dark theme by @igrik10 in https://github.com/outl1ne/nova-input-filter/pull/11 14 | 15 | ## [2.0.0] - 19-07-2022 16 | 17 | ### Added 18 | 19 | - Nova 4 support 20 | 21 | ### Changed 22 | 23 | - Updated packages 24 | 25 | ## [1.1.0] - 01-10-2021 26 | 27 | ### Added 28 | 29 | - Added `inputType` to allow for numbers explicitly (huge thanks to [@TheDeadCode](https://github.com/TheDeadCode)) 30 | 31 | ### Changed 32 | 33 | - Constructor parameters can now be replaced with `->forColumns([])` and `->withName()` methods (huge thanks to [@TheDeadCode](https://github.com/TheDeadCode)) 34 | - Updated packages 35 | 36 | ## [1.0.1] - 19-02-2021 37 | 38 | ### Changed 39 | 40 | - Changed the padding to better match regular select filter field 41 | 42 | ## [1.0.0] - 18-12-2020 43 | 44 | Initial release. 45 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Outl1ne 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nova Input Filter 2 | 3 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/outl1ne/nova-input-filter.svg?style=flat-square)](https://packagist.org/packages/outl1ne/nova-input-filter) 4 | [![Total Downloads](https://img.shields.io/packagist/dt/outl1ne/nova-input-filter.svg?style=flat-square)](https://packagist.org/packages/outl1ne/nova-input-filter) 5 | 6 | This [Laravel Nova](https://nova.laravel.com/) package allows you to create simple input filters. 7 | 8 | ## Requirements 9 | 10 | - `php: >=8.1` 11 | - `laravel/nova: ^5.0` 12 | 13 | ## Features 14 | 15 | - Out of the box, works like an additional search field. 16 | - Inline usage for simple use-cases. 17 | 18 | ## Screenshots 19 | 20 | ![Input filter](./docs/input-filter.gif) 21 | 22 | ## Installation 23 | 24 | Install the package in to a Laravel app that uses [Nova](https://nova.laravel.com) via composer: 25 | 26 | ```bash 27 | composer require outl1ne/nova-input-filter 28 | ``` 29 | 30 | ## Usage 31 | 32 | Accepts an array of columns as first parameter and filter name as second parameter. Can optionally pass in multiple 33 | columns: `['email', 'id']`, similarly to nova's search. 34 | 35 | ```php 36 | use Outl1ne\NovaInputFilter\InputFilter; 37 | use Laravel\Nova\Http\Requests\NovaRequest; 38 | 39 | // .. 40 | 41 | public function filters(NovaRequest $request): array 42 | { 43 | return [ 44 | InputFilter::make()->forColumns(['email'])->withName('Email'), 45 | 46 | // Or 47 | 48 | InputFilter::make(['email'], 'email'), 49 | ]; 50 | } 51 | ``` 52 | 53 | ## Customizing 54 | 55 | Out of the box, `InputFilter` works exactly like Nova's search field. If you wish to change it, you can extend 56 | the `InputFilter` class and override `apply()` function. 57 | 58 | ```php 59 | 60 | use Outl1ne\NovaInputFilter\InputFilter; 61 | use Illuminate\Contracts\Database\Eloquent\Builder; 62 | use Laravel\Nova\Http\Requests\NovaRequest; 63 | 64 | class ExtendedInputFilter extends InputFilter 65 | { 66 | public function apply(NovaRequest $request, Builder $query, mixed $value) 67 | { 68 | return $query->where('email', 'like', "%$value%"); 69 | } 70 | } 71 | ``` 72 | 73 | ## Credits 74 | 75 | - [Kaspar Rosin](https://github.com/kasparrosin) 76 | 77 | ## License 78 | 79 | Nova Input Filter is open-sourced software licensed under the [MIT license](LICENSE.md). 80 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "outl1ne/nova-input-filter", 3 | "description": "An input filter for Laravel Nova", 4 | "keywords": [ 5 | "laravel", 6 | "nova", 7 | "filter", 8 | "laravel-nova", 9 | "outl1ne", 10 | "input", 11 | "search" 12 | ], 13 | "authors": [ 14 | { 15 | "name": "Kaspar Rosin", 16 | "email": "kaspar@outl1ne.com", 17 | "role": "Developer" 18 | }, 19 | { 20 | "name": "Tarvo Reinpalu", 21 | "email": "tarvo@outl1ne.com", 22 | "role": "Developer" 23 | }, 24 | { 25 | "name": "Outl1ne", 26 | "email": "info@outl1ne.com", 27 | "role": "Maintainer" 28 | } 29 | ], 30 | "license": "MIT", 31 | "require": { 32 | "php": ">=8.1", 33 | "laravel/nova": "^5.0" 34 | }, 35 | "require-dev": { 36 | "laravel/nova-devtool": "^1.0.1", 37 | "laravel/pint": "^1.20" 38 | }, 39 | "autoload": { 40 | "psr-4": { 41 | "Outl1ne\\NovaInputFilter\\": "src/", 42 | "App\\": "workbench/app/", 43 | "Database\\Factories\\": "workbench/database/factories/", 44 | "Database\\Seeders\\": "workbench/database/seeders/" 45 | } 46 | }, 47 | "extra": { 48 | "laravel": { 49 | "providers": [ 50 | "Outl1ne\\NovaInputFilter\\FilterServiceProvider" 51 | ] 52 | } 53 | }, 54 | "config": { 55 | "sort-packages": true 56 | }, 57 | "minimum-stability": "dev", 58 | "prefer-stable": true, 59 | "repositories": [ 60 | { 61 | "type": "composer", 62 | "url": "https://nova.laravel.com" 63 | } 64 | ], 65 | "scripts": { 66 | "post-autoload-dump": [ 67 | "@clear", 68 | "@prepare" 69 | ], 70 | "clear": "@php vendor/bin/testbench package:purge-skeleton --ansi", 71 | "prepare": "@php vendor/bin/testbench package:discover --ansi", 72 | "build": "@php vendor/bin/testbench workbench:build --ansi", 73 | "serve": [ 74 | "Composer\\Config::disableProcessTimeout", 75 | "@build", 76 | "@php vendor/bin/testbench serve --ansi" 77 | ] 78 | }, 79 | "autoload-dev": { 80 | "psr-4": { 81 | "Workbench\\App\\": "workbench/app/", 82 | "Workbench\\Database\\Factories\\": "workbench/database/factories/", 83 | "Workbench\\Database\\Seeders\\": "workbench/database/seeders/" 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /dist/css/entry.css: -------------------------------------------------------------------------------- 1 | .o1-pb-1{padding-bottom:.25rem}.o1-pt-2{padding-top:.5rem} 2 | -------------------------------------------------------------------------------- /dist/js/entry.js: -------------------------------------------------------------------------------- 1 | (()=>{"use strict";var e,t={12:(e,t,n)=>{const r=Vue;var o={class:"o1-pt-2 o1-pb-1"},i={class:"px-3 text-xs uppercase font-bold tracking-wide"},l={class:"p-2"},a=["type","pattern","min","max","placeholder","value"];const u={props:["resourceName","filterKey"],data:function(){return{search:null,debounce:null}},methods:{debounceInput:function(e){var t=this;clearTimeout(this.debounce),this.debounce=setTimeout((function(){t.handleChange(e)}),600)},handleChange:function(e){this.$store.commit("".concat(this.resourceName,"/updateFilterState"),{filterClass:this.filterKey,value:e.target.value}),this.$emit("change")}},computed:{filter:function(){return this.$store.getters["".concat(this.resourceName,"/getFilter")](this.filterKey)},value:function(){return this.filter.currentValue}}};const c=(0,n(262).A)(u,[["render",function(e,t,n,u,c,s){return(0,r.openBlock)(),(0,r.createElementBlock)("div",o,[(0,r.createElementVNode)("h3",i,(0,r.toDisplayString)(s.filter.name),1),(0,r.createElementVNode)("div",l,[(0,r.createElementVNode)("input",{class:"w-full form-control form-input form-control-bordered",type:s.filter.input_type,pattern:!!s.filter.input_integers&&"\\d*",min:s.filter.input_min,max:s.filter.input_max,onInput:t[0]||(t[0]=function(){return s.debounceInput&&s.debounceInput.apply(s,arguments)}),placeholder:s.filter.placeholder||s.filter.name,value:s.value},null,40,a)])])}]]);Nova.booting((function(e){e.component("nova-input-filter",c)}))},497:()=>{},262:(e,t)=>{t.A=(e,t)=>{const n=e.__vccOpts||e;for(const[e,r]of t)n[e]=r;return n}}},n={};function r(e){var o=n[e];if(void 0!==o)return o.exports;var i=n[e]={exports:{}};return t[e](i,i.exports,r),i.exports}r.m=t,e=[],r.O=(t,n,o,i)=>{if(!n){var l=1/0;for(s=0;s=i)&&Object.keys(r.O).every((e=>r.O[e](n[u])))?n.splice(u--,1):(a=!1,i0&&e[s-1][2]>i;s--)e[s]=e[s-1];e[s]=[n,o,i]},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={282:0,153:0};r.O.j=t=>0===e[t];var t=(t,n)=>{var o,i,[l,a,u]=n,c=0;if(l.some((t=>0!==e[t]))){for(o in a)r.o(a,o)&&(r.m[o]=a[o]);if(u)var s=u(r)}for(t&&t(n);cr(12)));var o=r.O(void 0,[153],(()=>r(497)));o=r.O(o)})(); -------------------------------------------------------------------------------- /dist/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/entry.js": "/js/entry.js", 3 | "/css/entry.css": "/css/entry.css" 4 | } 5 | -------------------------------------------------------------------------------- /docs/input-filter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outl1ne/nova-input-filter/0a5d65098507e4587c8a619bc110677c26cee052/docs/input-filter.gif -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "mix", 5 | "watch": "mix watch", 6 | "hot": "mix watch --hot", 7 | "prod": "mix --production", 8 | "format": "prettier --write 'resources/**/*.{css,scss,js,vue}'" 9 | }, 10 | "devDependencies": { 11 | "laravel-nova-devtool": "file:vendor/laravel/nova-devtool", 12 | "prettier": "^2.7.1", 13 | "vue-loader": "^16.8.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /pint.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "psr12" 3 | } 4 | -------------------------------------------------------------------------------- /resources/css/entry.css: -------------------------------------------------------------------------------- 1 | @tailwind utilities; 2 | -------------------------------------------------------------------------------- /resources/js/components/InputFilter.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 53 | -------------------------------------------------------------------------------- /resources/js/entry.js: -------------------------------------------------------------------------------- 1 | import InputFilter from './components/InputFilter'; 2 | 3 | Nova.booting(Vue => { 4 | Vue.component('nova-input-filter', InputFilter); 5 | }); 6 | -------------------------------------------------------------------------------- /src/FilterServiceProvider.php: -------------------------------------------------------------------------------- 1 | forColumns($options); 22 | } 23 | 24 | if (! empty($name)) { 25 | $this->withName($name); 26 | } 27 | } 28 | 29 | public function apply(NovaRequest $request, Builder $query, mixed $value) 30 | { 31 | return $query->where(function ($query) use ($value) { 32 | $model = $query->getModel(); 33 | $connectionType = $query->getModel()->getConnection()->getDriverName(); 34 | 35 | $likeOperator = $connectionType == 'pgsql' ? 'ilike' : 'like'; 36 | 37 | $query->orWhere(function ($query) use ($value, $model, $likeOperator) { 38 | foreach ($this->options as $column) { 39 | $qColumn = $model->qualifyColumn($column); 40 | $qValue = mb_strtoupper($value); 41 | $query->orWhereRaw("UPPER($qColumn) $likeOperator ?", ["%$qValue%"]); 42 | } 43 | }); 44 | }); 45 | } 46 | 47 | public function forColumns($columns) 48 | { 49 | if (! is_array($columns)) { 50 | $columns = [$columns]; 51 | } 52 | $this->options = $columns; 53 | 54 | return $this; 55 | } 56 | 57 | public function withName($name) 58 | { 59 | $this->name = $name; 60 | 61 | return $this; 62 | } 63 | 64 | public function asNumber($number = true, $integersOnly = false) 65 | { 66 | $this->inputType = $number ? 'number' : 'text'; 67 | $this->inputIntegersOnly = $integersOnly; 68 | 69 | return $this; 70 | } 71 | 72 | public function options(NovaRequest $request) 73 | { 74 | return $this->options; 75 | } 76 | 77 | public function key() 78 | { 79 | $isUniqueClass = get_class($this) !== InputFilter::class; 80 | 81 | if (! empty($this->name) && ! $isUniqueClass) { 82 | return get_class($this).str_replace(' ', '', $this->name); 83 | } 84 | 85 | return parent::key(); 86 | } 87 | 88 | public function jsonSerialize(): array 89 | { 90 | return array_merge(parent::jsonSerialize(), [ 91 | 'input_type' => $this->inputType, 92 | 'input_integers' => $this->inputIntegersOnly, 93 | 'input_min' => $this->inputMin, 94 | 'input_max' => $this->inputMax, 95 | ]); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | content: [path.resolve(__dirname, 'resources/**/*.{vue,js,ts,jsx,tsx,scss}')], 5 | prefix: 'o1-', 6 | darkMode: 'class', 7 | safelist: [], 8 | }; 9 | -------------------------------------------------------------------------------- /testbench.yaml: -------------------------------------------------------------------------------- 1 | laravel: '@testbench' 2 | 3 | providers: 4 | - Laravel\Nova\NovaServiceProvider 5 | - Laravel\Nova\NovaCoreServiceProvider 6 | - Workbench\App\Providers\NovaServiceProvider 7 | # - Workbench\App\Providers\WorkbenchServiceProvider 8 | 9 | migrations: true 10 | 11 | seeders: 12 | - Workbench\Database\Seeders\DatabaseSeeder 13 | 14 | workbench: 15 | start: /nova 16 | build: 17 | - package:discover 18 | - asset-publish 19 | - create-sqlite-db 20 | - db:wipe 21 | - migrate:refresh 22 | assets: 23 | - nova-assets 24 | sync: [] 25 | 26 | purge: 27 | directories: 28 | - lang/* 29 | - public/vendor/* 30 | -------------------------------------------------------------------------------- /testbench.yml: -------------------------------------------------------------------------------- 1 | providers: 2 | - Laravel\Nova\NovaCoreServiceProvider 3 | - App\Providers\NovaServiceProvider 4 | - Outl1ne\NovaInputFilter\FilterServiceProvider 5 | 6 | migrations: 7 | - workbench/database/migrations 8 | 9 | workbench: 10 | start: /nova 11 | user: nova@laravel.com 12 | build: 13 | - package:discover 14 | - asset-publish 15 | - create-sqlite-db 16 | - db:wipe 17 | - migrate:refresh: 18 | --seed: true 19 | assets: 20 | - nova-assets 21 | sync: [] 22 | 23 | purge: 24 | directories: 25 | - lang/* 26 | - public/vendor/* 27 | -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | let path = require('path'); 2 | let mix = require('laravel-mix'); 3 | let postcss = require('postcss-import'); 4 | let tailwindcss = require('tailwindcss'); 5 | 6 | mix.extend('nova', new require('./vendor/laravel/nova-devtool')) 7 | 8 | mix 9 | .setPublicPath('dist') 10 | .js('resources/js/entry.js', 'js') 11 | .vue({ version: 3 }) 12 | .webpackConfig({ 13 | externals: { 14 | vue: 'Vue', 15 | }, 16 | output: { 17 | uniqueName: 'outl1ne/nova-input-filter', 18 | }, 19 | }) 20 | .postCss('resources/css/entry.css', 'dist/css/', [postcss(), tailwindcss('tailwind.config.js')]) 21 | .alias({ 22 | 'laravel-nova': path.join(__dirname, 'vendor/laravel/nova/resources/js/mixins/packages.js'), 23 | }); 24 | -------------------------------------------------------------------------------- /workbench/app/Models/User.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | protected $fillable = [ 21 | 'name', 22 | 'email', 23 | 'password', 24 | ]; 25 | 26 | /** 27 | * The attributes that should be hidden for serialization. 28 | * 29 | * @var array 30 | */ 31 | protected $hidden = [ 32 | 'password', 33 | 'remember_token', 34 | ]; 35 | 36 | /** 37 | * The attributes that should be cast. 38 | * 39 | * @var array 40 | */ 41 | protected $casts = [ 42 | 'email_verified_at' => 'datetime', 43 | 'password' => 'hashed', 44 | ]; 45 | } 46 | -------------------------------------------------------------------------------- /workbench/app/Nova/Filters/EmailFilter.php: -------------------------------------------------------------------------------- 1 | where('email', 'like', "%$value%"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /workbench/app/Nova/Resource.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public static $model = \Workbench\App\Models\User::class; 23 | 24 | /** 25 | * The single value that should be used to represent the resource when being displayed. 26 | * 27 | * @var string 28 | */ 29 | public static $title = 'name'; 30 | 31 | /** 32 | * The columns that should be searched. 33 | * 34 | * @var array 35 | */ 36 | public static $search = [ 37 | 'id', 'name', 'email', 38 | ]; 39 | 40 | /** 41 | * Get the fields displayed by the resource. 42 | * 43 | * @return array 44 | */ 45 | public function fields(NovaRequest $request): array 46 | { 47 | return [ 48 | ID::make()->sortable(), 49 | 50 | Text::make('Name') 51 | ->sortable() 52 | ->rules('required', 'max:255'), 53 | 54 | Text::make('Email') 55 | ->sortable() 56 | ->rules('required', 'email', 'max:254') 57 | ->creationRules('unique:users,email') 58 | ->updateRules('unique:users,email,{{resourceId}}'), 59 | 60 | Password::make('Password') 61 | ->onlyOnForms() 62 | ->creationRules($this->passwordRules()) 63 | ->updateRules($this->optionalPasswordRules()), 64 | ]; 65 | } 66 | 67 | /** 68 | * Get the cards available for the request. 69 | * 70 | * @return array 71 | */ 72 | public function cards(NovaRequest $request): array 73 | { 74 | return []; 75 | } 76 | 77 | /** 78 | * Get the filters available for the resource. 79 | * 80 | * @return array 81 | */ 82 | public function filters(NovaRequest $request): array 83 | { 84 | return [ 85 | EmailFilter::make(), 86 | ]; 87 | } 88 | 89 | /** 90 | * Get the lenses available for the resource. 91 | * 92 | * @return array 93 | */ 94 | public function lenses(NovaRequest $request): array 95 | { 96 | return []; 97 | } 98 | 99 | /** 100 | * Get the actions available for the resource. 101 | * 102 | * @return array 103 | */ 104 | public function actions(NovaRequest $request): array 105 | { 106 | return []; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /workbench/app/Providers/NovaServiceProvider.php: -------------------------------------------------------------------------------- 1 | features([ 29 | Features::updatePasswords(), 30 | // Features::emailVerification(), 31 | // Features::twoFactorAuthentication(['confirm' => true, 'confirmPassword' => true]), 32 | ]) 33 | ->register(); 34 | } 35 | 36 | /** 37 | * Register the Nova routes. 38 | */ 39 | protected function routes(): void 40 | { 41 | Nova::routes() 42 | ->withAuthenticationRoutes(default: true) 43 | ->withPasswordResetRoutes() 44 | ->withoutEmailVerificationRoutes() 45 | ->register(); 46 | } 47 | 48 | /** 49 | * Register the Nova gate. 50 | * 51 | * This gate determines who can access Nova in non-local environments. 52 | */ 53 | protected function gate(): void 54 | { 55 | Gate::define('viewNova', function ($user) { 56 | return true; 57 | }); 58 | } 59 | 60 | /** 61 | * Get the dashboards that should be listed in the Nova sidebar. 62 | * 63 | * @return array 64 | */ 65 | protected function dashboards(): array 66 | { 67 | return [ 68 | new \Laravel\Nova\Dashboards\Main(), 69 | ]; 70 | } 71 | 72 | /** 73 | * Get the tools that should be listed in the Nova sidebar. 74 | * 75 | * @return array 76 | */ 77 | public function tools(): array 78 | { 79 | return []; 80 | } 81 | 82 | /** 83 | * Register the application's Nova resources. 84 | */ 85 | protected function resources(): void 86 | { 87 | Nova::resourcesInWorkbench(); 88 | } 89 | 90 | /** 91 | * Register any application services. 92 | */ 93 | public function register(): void 94 | { 95 | parent::register(); 96 | 97 | // 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /workbench/app/Providers/WorkbenchServiceProvider.php: -------------------------------------------------------------------------------- 1 | withRouting( 11 | web: __DIR__.'/../routes/web.php', 12 | commands: __DIR__.'/../routes/console.php', 13 | ) 14 | ->withMiddleware(function (Middleware $middleware) { 15 | // 16 | }) 17 | ->withExceptions(function (Exceptions $exceptions) { 18 | // 19 | })->create(); 20 | -------------------------------------------------------------------------------- /workbench/database/factories/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outl1ne/nova-input-filter/0a5d65098507e4587c8a619bc110677c26cee052/workbench/database/factories/.gitkeep -------------------------------------------------------------------------------- /workbench/database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | class UserFactory extends Factory 16 | { 17 | /** 18 | * The current password being used by the factory. 19 | */ 20 | protected static ?string $password; 21 | 22 | /** 23 | * The name of the factory's corresponding model. 24 | * 25 | * @var class-string 26 | */ 27 | protected $model = User::class; 28 | 29 | /** 30 | * Define the model's default state. 31 | * 32 | * @return array 33 | */ 34 | public function definition(): array 35 | { 36 | return [ 37 | 'name' => fake()->name(), 38 | 'email' => fake()->unique()->safeEmail(), 39 | 'email_verified_at' => now(), 40 | 'password' => static::$password ??= Hash::make('password'), 41 | 'remember_token' => Str::random(10), 42 | ]; 43 | } 44 | 45 | /** 46 | * Indicate that the model's email address should be unverified. 47 | */ 48 | public function unverified(): static 49 | { 50 | return $this->state(fn (array $attributes) => [ 51 | 'email_verified_at' => null, 52 | ]); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /workbench/database/migrations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outl1ne/nova-input-filter/0a5d65098507e4587c8a619bc110677c26cee052/workbench/database/migrations/.gitkeep -------------------------------------------------------------------------------- /workbench/database/seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | create([ 18 | 'name' => 'Laravel Nova', 19 | 'email' => 'nova@laravel.com', 20 | ]); 21 | 22 | UserFactory::new()->times(10)->create(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /workbench/resources/views/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outl1ne/nova-input-filter/0a5d65098507e4587c8a619bc110677c26cee052/workbench/resources/views/.gitkeep -------------------------------------------------------------------------------- /workbench/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 8 | })->purpose('Display an inspiring quote')->hourly(); 9 | -------------------------------------------------------------------------------- /workbench/routes/web.php: -------------------------------------------------------------------------------- 1 |