├── .gitignore
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── composer.json
├── dist
└── js
│ ├── field.js
│ └── field.js.map
├── docs
├── demo-2.gif
└── demo.gif
├── mix-manifest.json
├── package.json
├── resources
└── js
│ ├── components
│ ├── DetailField.vue
│ └── FormField.vue
│ └── field.js
├── src
├── ActionHasDependencies.php
├── FieldServiceProvider.php
├── HasChildFields.php
├── HasDependencies.php
├── Http
│ ├── Controllers
│ │ └── ActionController.php
│ └── Requests
│ │ └── ActionRequest.php
└── NovaDependencyContainer.php
└── webpack.mix.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
2 | /vendor
3 | /node_modules
4 | package-lock.json
5 | composer.phar
6 | composer.lock
7 | phpunit.xml
8 | .phpunit.result.cache
9 | .DS_Store
10 | Thumbs.db
11 | .nvmrc
12 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Nova Dependency Container
2 |
3 |
4 |
5 | ### Releases
6 | - [v1.2.10](https://github.com/epartment/nova-dependency-container/releases/tag/1.2.10)
7 | - Fixes a problem with [Whitecubes Flexible Content](https://github.com/whitecube/nova-flexible-content) package where the dependency container would do nothing #93 [whitecube/nova-flexible-content#87](https://github.com/whitecube/nova-flexible-content/issues/87)
8 | - [v1.2.9](https://github.com/epartment/nova-dependency-container/releases/tag/1.2.9)
9 | - Support BelongsToMany field when depending on the seleced resource #52
10 | - [v1.2.8](https://github.com/epartment/nova-dependency-container/releases/tag/1.2.8)
11 | - Ensure that each field resolves on it's own depending on the situation - PR #90
12 | - Fixes #89, #88, #87, #85 and #40
13 | - [v1.2.7](https://github.com/epartment/nova-dependency-container/releases/tag/1.2.7)
14 | - Fix an index error in Nova 2.5.0 where the rules-set array requires a key fields attribute #86
15 | - Support MorphTo controller #62,#85
16 | - Moved releases/changes to `CHANGELOG.md`
17 | - [v1.2.6](https://github.com/epartment/nova-dependency-container/releases/tag/1.2.6)
18 | - Fixes a problem where it should check if a model exist when creating a resource when it's impossible to satisfy dependencies
19 | - [v1.2.5](https://github.com/epartment/nova-dependency-container/releases/tag/1.2.5)
20 | - Fixes a problem where Nova can't resolve custom ActionRequest [#82](https://github.com/epartment/nova-dependency-container/issues/82)
21 | - [v1.2.4](https://github.com/epartment/nova-dependency-container/releases/tag/1.2.4)
22 | - Fixes a problem where fields with same names use previous validation rules when used in multiple containers [#81](https://github.com/epartment/nova-dependency-container/issues/81), [#60](https://github.com/epartment/nova-dependency-container/pull/60) (@melewski)
23 | - [v1.2.3](https://github.com/epartment/nova-dependency-container/releases/tag/1.2.3)
24 | - Fixed belongs-to/morph-to as nested fields [#80](https://github.com/epartment/nova-dependency-container/issues/80)
25 | - Added missing methods in validation rules
26 | - [v1.2.2](https://github.com/epartment/nova-dependency-container/releases/tag/1.2.2)
27 | - fixed fields not resolving when using `displayUsingLabels`, `resolveUsing` or `displayUsing`. (@dbf)
28 | - fixed action fields who do not return a collection (@bsormagec)
29 | - added two new methods `onEmpty` and `onNullOrZero`. (@niektenhoopen, @dbf)
30 | - changed the logic for dependency satisfaction where it is reversed
31 | - changed `field` in two separate names; `field` and `property`, to avoid confusion when being used on a resource or component.
32 | - [v1.2.1](https://github.com/epartment/nova-dependency-container/releases/tag/1.2.1)
33 | - fixed support for [BelongsTo](https://nova.laravel.com/docs/1.0/resources/relationships.html#belongsto) and [MorphTo](https://nova.laravel.com/docs/1.0/resources/relationships.html#morphto) fields (@mikaelpopowicz, @dbf)
34 | - [v1.2.0](https://github.com/epartment/nova-dependency-container/releases/tag/1.2.0)
35 | - working version for Laravel 5.8 | 6 and Nova 2.x. (@FastPointGaming, @spaceo, @cdbeaton, @yaroslawww)
36 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Epartment Ecommerce
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 Field Dependency Container
2 |
3 | [](https://packagist.org/packages/epartment/nova-dependency-container)
4 | [](https://packagist.org/packages/epartment/nova-dependency-container)
5 | [](https://github.com/epartment/nova-dependency-container/blob/master/LICENSE.md)
6 |
7 |
8 |
9 | ### Description
10 |
11 | A container for grouping fields that depend on other field values. Dependencies can be set on any field type or value.
12 |
13 |
14 |
15 | ### Demo
16 |
17 | 
18 |
19 |
20 |
21 | ### Versions
22 |
23 | - install v1.2.x for Laravel v5.8 or v6.x and Nova 2.x
24 | - install v1.1.2 for Laravel v5.7 and Nova v1.x
25 |
26 |
27 |
28 | ### Installation
29 |
30 | The package can be installed through Composer.
31 |
32 | ```bash
33 | composer require epartment/nova-dependency-container
34 | ```
35 |
36 |
37 |
38 | ### Usage
39 |
40 | 1. Add the `Epartment\NovaDependencyContainer\HasDependencies` trait to your Nova Resource.
41 | 2. Add the `Epartment\NovaDependencyContainer\NovaDependencyContainer` to your Nova Resource `fields` method.
42 | 3. Add the `Epartment\NovaDependencyContainer\ActionHasDependencies` trait to your Nova Actions that you wish to use dependencies on.
43 |
44 | ```php
45 | class Page extends Resource
46 | {
47 | use HasDependencies;
48 |
49 | public function fields(Request $request)
50 | {
51 | return [
52 |
53 | Select::make('Name format', 'name_format')->options([
54 | 0 => 'First Name',
55 | 1 => 'First Name / Last Name',
56 | 2 => 'Full Name'
57 | ])->displayUsingLabels(),
58 |
59 | NovaDependencyContainer::make([
60 | Text::make('First Name', 'first_name')
61 | ])->dependsOn('name_format', 0),
62 |
63 | ];
64 | }
65 | }
66 | ```
67 |
68 |
69 |
70 | ### Dependencies
71 |
72 | The package supports four kinds of dependencies:
73 |
74 | 1. `->dependsOn('field', 'value')`
75 | 2. `->dependsOnNot('field', 'value')`
76 | 3. `->dependsOnEmpty('field')`
77 | 4. `->dependsOnNotEmpty('field')`
78 | 5. `->dependsOnNullOrZero('field')`
79 |
80 | These dependencies can be combined by chaining the methods on the `NovaDependencyContainer`:
81 |
82 | ```php
83 | NovaDependencyContainer::make([
84 | // dependency fields
85 | ])
86 | ->dependsOn('field1', 'value1')
87 | ->dependsOnNotEmpty('field2')
88 | ->dependsOn('field3', 'value3')
89 | ```
90 |
91 | The fields used as dependencies can be of any Laravel Nova field type. Currently only two relation field types are supported, `BelongsTo` and `MorphTo`.
92 |
93 | Here is an example using a checkbox:
94 |
95 | 
96 |
97 |
98 |
99 |
100 | ### BelongsTo dependency
101 |
102 | If we follow the example of a *Post model belongsTo a User model*, taken from Novas documentation [BelongsTo](https://nova.laravel.com/docs/2.0/resources/relationships.html#belongsto), the dependency setup has the following construction.
103 |
104 | We use the singular form of the `belongsTo` resource in lower case, in this example `Post` becomes `post`. Then we define in dot notation, the property of the resource we want to depend on. In this example we just use the `id` property, as in `post.id`.
105 |
106 | ```php
107 | BelongsTo::make('Post'),
108 |
109 | NovaDependencyContainer::make([
110 | Boolean::make('Visible')
111 | ])
112 | ->dependsOn('post.id', 2)
113 | ```
114 |
115 | When the `Post` resource with `id` 2 is being selected, a `Boolean` field will appear.
116 |
117 |
118 |
119 | ### BelongsToMany dependency
120 |
121 | A [BelongsToMany](https://nova.laravel.com/docs/2.0/resources/relationships.html#belongstomany) setup is similar to that of a [BelongsTo](https://nova.laravel.com/docs/2.0/resources/relationships.html#belongsto).
122 |
123 | The `dependsOn` method should be pointing to the name of the intermediate table. If it is called `role_user`, the setup should be
124 |
125 | ```php
126 | BelongsToMany::make('Roles')
127 | ->fields(function() {
128 | return [
129 | NovaDependencyContainer::make([
130 | // pivot field rules_all
131 | Boolean::make('Rules All', 'rules_all')
132 | ])
133 | ->dependsOn('role_user', 1)
134 | ]
135 | }),
136 | ```
137 |
138 | If the pivot field name occurs multiple times, consider using [custom intermediate table models](https://laravel.com/docs/6.x/eloquent-relationships#defining-custom-intermediate-table-models) and define it in the appropiate model relation methods. The only reliable solution I found was using mutators to get/set a field which was being used multiple times. Although this may seem ugly, the events which should be fired on the intermediate model instance, when using an Observer, would work unreliable with every new release of Nova.
139 |
140 | > If Nova becomes reliable firing eloquent events on the intermediate table, I will update this examples with a more elegant approach using events instead.
141 |
142 | Here is an (ugly) example of a get/set mutator setup for an intermediate table using a pivot field called `type`.
143 |
144 | ```php
145 | // model User
146 | class User ... {
147 |
148 | public function roles() {
149 | return $this->belongsToMany->using(RoleUser::class)->withPivot('rules_all');
150 | }
151 |
152 | }
153 |
154 | // model Role
155 | class Role ... {
156 |
157 | public function users() {
158 | return $this->belongsToMany->using(RoleUser::class)->withPivot('rules_all');
159 | }
160 |
161 | }
162 |
163 | // intermediate table
164 | use Illuminate\Database\Eloquent\Relations\Pivot;
165 | class RoleUser extends Pivot {
166 |
167 | protected $table 'role_user';
168 |
169 | public function getType1Attribute() {
170 | return $this->type;
171 | }
172 |
173 | public function setType1Attribute($value) {
174 | $this->attributes['type'] = $value;
175 | }
176 |
177 | // ... repeat for as many types as needed
178 | }
179 | ```
180 |
181 | And now for the dependency container.
182 |
183 | ```php
184 | ->fields(function() {
185 | return [
186 | NovaDependencyContainer::make([
187 | // pivot field rules_all
188 | Select::make('Type', 'type_1')
189 | ->options([
190 | /* some options */
191 | ])
192 | ->displayUsingLabels()
193 | ])
194 | ->dependsOn('role_user', 1)
195 | ,
196 |
197 | NovaDependencyContainer::make([
198 | // pivot field rules_all
199 | Select::make('Type', 'type_2')
200 | ->options([
201 | /* different options */
202 | ])
203 | ->displayUsingLabels()
204 | ])
205 | ->dependsOn('role_user', 2)
206 | ,
207 |
208 | // .. and so on
209 | ]
210 | }),
211 | ```
212 |
213 |
214 |
215 | ### MorphTo dependency
216 |
217 | A similar example taken from Novas documentation for [MorphTo](https://nova.laravel.com/docs/2.0/resources/relationships.html#morphto) is called commentable. It uses 3 Models; `Comment`, `Video` and `Post`. Here `Comment` has the morphable fields `commentable_id` and `commentable_type`
218 |
219 | For a `MorphTo` dependency, the following construction is needed.
220 |
221 | `Commentable` becomes lower case `commentable` and the value to depend on is the resource singular form. In this example the dependency container will add two additional fields, `Additional Text` and `Visible`, only when the `Post` resource is selected.
222 |
223 | ```php
224 | MorphTo::make('Commentable')->types([
225 | Post::class,
226 | Video::class,
227 | ]),
228 |
229 | NovaDependencyContainer::make([
230 | Text::make('Additional Text', 'additional'),
231 | Boolean::make('Visible', 'visible')
232 | ])
233 | ->dependsOn('commentable', 'Post')
234 | ```
235 |
236 |
237 |
238 | ### License
239 |
240 | The MIT License (MIT). Please see [License File](https://github.com/epartment/nova-dependency-container/blob/master/LICENSE.md) for more information.
241 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "epartment/nova-dependency-container",
3 | "description": "A Laravel Nova field container allowing to depend on other fields values",
4 | "keywords": [
5 | "laravel",
6 | "nova"
7 | ],
8 | "license": "MIT",
9 | "require": {
10 | "php": ">=7.1.0"
11 | },
12 | "autoload": {
13 | "psr-4": {
14 | "Epartment\\NovaDependencyContainer\\": "src/"
15 | }
16 | },
17 | "extra": {
18 | "laravel": {
19 | "providers": [
20 | "Epartment\\NovaDependencyContainer\\FieldServiceProvider"
21 | ]
22 | }
23 | },
24 | "config": {
25 | "sort-packages": true
26 | },
27 | "minimum-stability": "dev",
28 | "prefer-stable": true
29 | }
30 |
--------------------------------------------------------------------------------
/dist/js/field.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"/dist/js/field.js","sources":["webpack:////dist/js/field.js"],"sourcesContent":["!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:n})},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,\"a\",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p=\"\",r(r.s=1)}([function(e,t){e.exports=function(e,t,r,n,o,i){var u,s=e=e||{},a=typeof e.default;\"object\"!==a&&\"function\"!==a||(u=e,s=e.default);var c,f=\"function\"==typeof s?s.options:s;if(t&&(f.render=t.render,f.staticRenderFns=t.staticRenderFns,f._compiled=!0),r&&(f.functional=!0),o&&(f._scopeId=o),i?(c=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||\"undefined\"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),n&&n.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(i)},f._ssrRegister=c):n&&(c=n),c){var l=f.functional,p=l?f.render:f.beforeCreate;l?(f._injectStyles=c,f.render=function(e,t){return c.call(t),p(e,t)}):f.beforeCreate=p?[].concat(p,c):[c]}return{esModule:u,exports:s,options:f}}},function(e,t,r){e.exports=r(2)},function(e,t,r){Nova.booting(function(e,t){e.component(\"detail-nova-dependency-container\",r(3)),e.component(\"form-nova-dependency-container\",r(6))})},function(e,t,r){var n=r(0)(r(4),r(5),!1,null,null,null);e.exports=n.exports},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.default={props:[\"resource\",\"resourceName\",\"resourceId\",\"field\"],created:function(){this.updateDependencyStatus()},data:function(){return{dependenciesSatisfied:!1}},methods:{updateDependencyStatus:function(){var e=!0,t=!1,r=void 0;try{for(var n,o=this.field.dependencies[Symbol.iterator]();!(e=(n=o.next()).done);e=!0){var i=n.value,u=!0,s=!1,a=void 0;try{for(var c,f=_.values(this.resource.fields)[Symbol.iterator]();!(u=(c=f.next()).done);u=!0){var l=c.value;if(i.field===l.attribute){if(i.hasOwnProperty(\"notEmpty\")&&!l.value)return void(this.dependenciesSatisfied=!1);if(i.hasOwnProperty(\"value\")&&l.value!==i.value)return void(this.dependenciesSatisfied=!1)}}}catch(e){s=!0,a=e}finally{try{!u&&f.return&&f.return()}finally{if(s)throw a}}}}catch(e){t=!0,r=e}finally{try{!e&&o.return&&o.return()}finally{if(t)throw r}}this.dependenciesSatisfied=!0}}}},function(e,t){e.exports={render:function(){var e=this,t=e.$createElement,r=e._self._c||t;return e.dependenciesSatisfied?r(\"div\",e._l(e.field.fields,function(t){return r(\"div\",[r(\"detail-\"+t.component,{ref:\"field-\"+t.attribute,refInFor:!0,tag:\"component\",attrs:{\"resource-id\":e.resourceId,\"resource-name\":e.resourceName,field:t}})],1)})):e._e()},staticRenderFns:[]}},function(e,t,r){var n=r(0)(r(7),r(9),!1,null,null,null);e.exports=n.exports},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n=r(8);r.n(n);t.default={mixins:[n.FormField,n.HandlesValidationErrors],props:[\"resourceName\",\"resourceId\",\"field\"],mounted:function(){this.registerDependencyWatchers(this.$root),this.updateDependencyStatus()},data:function(){return{dependencyValues:{},dependenciesSatisfied:!1}},methods:{registerDependencyWatchers:function(e){var t=this;e.$children.forEach(function(e){t.componentIsDependency(e)&&(e.$watch(\"value\",function(r){t.dependencyValues[e.field.attribute]=r,t.updateDependencyStatus()},{immediate:!0}),t.dependencyValues[e.field.attribute]=e.field.value),t.registerDependencyWatchers(e)})},componentIsDependency:function(e){if(void 0===e.field)return!1;var t=!0,r=!1,n=void 0;try{for(var o,i=this.field.dependencies[Symbol.iterator]();!(t=(o=i.next()).done);t=!0){var u=o.value;if(e.field.attribute===u.field)return console.log(e),!0}}catch(e){r=!0,n=e}finally{try{!t&&i.return&&i.return()}finally{if(r)throw n}}return!1},updateDependencyStatus:function(){var e=!0,t=!1,r=void 0;try{for(var n,o=this.field.dependencies[Symbol.iterator]();!(e=(n=o.next()).done);e=!0){var i=n.value;if(i.hasOwnProperty(\"notEmpty\")&&!this.dependencyValues[i.field])return void(this.dependenciesSatisfied=!1);if(i.hasOwnProperty(\"value\")&&this.dependencyValues[i.field]!==i.value)return void(this.dependenciesSatisfied=!1)}}catch(e){t=!0,r=e}finally{try{!e&&o.return&&o.return()}finally{if(t)throw r}}this.dependenciesSatisfied=!0},fill:function(e){this.dependenciesSatisfied&&this.$children.forEach(function(t){t.fill(e)})}}}},function(e,t,r){var n;n=function(){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.i=function(e){return e},r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:n})},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,\"a\",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p=\"\",r(r.s=47)}([function(e,t,r){\"use strict\";var n=r(46),o=r(158),i=Object.prototype.toString;function u(e){return\"[object Array]\"===i.call(e)}function s(e){return null!==e&&\"object\"==typeof e}function a(e){return\"[object Function]\"===i.call(e)}function c(e,t){if(null!==e&&void 0!==e)if(\"object\"!=typeof e&&(e=[e]),u(e))for(var r=0,n=e.length;r=200&&e<300}};a.headers={common:{Accept:\"application/json, text/plain, */*\"}},n.forEach([\"delete\",\"get\",\"head\"],function(e){a.headers[e]={}}),n.forEach([\"post\",\"put\",\"patch\"],function(e){a.headers[e]=n.merge(i)}),e.exports=a}).call(t,r(73))},function(e,t,r){\"use strict\";t.__esModule=!0;var n,o=r(112),i=(n=o)&&n.__esModule?n:{default:n};t.default=function(e,t,r){return t in e?(0,i.default)(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError(\"Can't call method on \"+e);return e}},function(e,t,r){var n=r(9),o=r(1).document,i=n(o)&&n(o.createElement);e.exports=function(e){return i?o.createElement(e):{}}},function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t){e.exports=!0},function(e,t,r){\"use strict\";var n=r(14);e.exports.f=function(e){return new function(e){var t,r;this.promise=new e(function(e,n){if(void 0!==t||void 0!==r)throw TypeError(\"Bad Promise constructor\");t=e,r=n}),this.resolve=n(t),this.reject=n(r)}(e)}},function(e,t,r){var n=r(11).f,o=r(17),i=r(2)(\"toStringTag\");e.exports=function(e,t,r){e&&!o(e=r?e:e.prototype,i)&&n(e,i,{configurable:!0,value:t})}},function(e,t,r){var n=r(58)(\"keys\"),o=r(63);e.exports=function(e){return n[e]||(n[e]=o(e))}},function(e,t){var r=Math.ceil,n=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?n:r)(e)}},function(e,t,r){var n=r(52),o=r(27);e.exports=function(e){return n(o(e))}},function(e,t,r){var n=r(12).Symbol;e.exports=n},function(e,t,r){var n=r(172),o=r(191);e.exports=function(e,t){var r=o(e,t);return n(r)?r:void 0}},function(e,t){e.exports=function(e,t){return e===t||e!=e&&t!=t}},function(e,t){e.exports=function(e){return e}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.default=[\"1/2\",\"1/3\",\"2/3\",\"1/4\",\"3/4\",\"1/5\",\"2/5\",\"3/5\",\"4/5\",\"1/6\",\"5/6\"]},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n=r(156);Object.defineProperty(t,\"default\",{enumerable:!0,get:function(){return i(n).default}}),Object.defineProperty(t,\"Form\",{enumerable:!0,get:function(){return i(n).default}});var o=r(64);function i(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,\"Errors\",{enumerable:!0,get:function(){return i(o).default}})},function(e,t,r){\"use strict\";(function(t){var n=r(0),o=r(99),i=r(102),u=r(108),s=r(106),a=r(45),c=\"undefined\"!=typeof window&&window.btoa&&window.btoa.bind(window)||r(101);e.exports=function(e){return new Promise(function(f,l){var p=e.data,d=e.headers;n.isFormData(p)&&delete d[\"Content-Type\"];var h=new XMLHttpRequest,v=\"onreadystatechange\",y=!1;if(\"test\"===t.env.NODE_ENV||\"undefined\"==typeof window||!window.XDomainRequest||\"withCredentials\"in h||s(e.url)||(h=new window.XDomainRequest,v=\"onload\",y=!0,h.onprogress=function(){},h.ontimeout=function(){}),e.auth){var g=e.auth.username||\"\",m=e.auth.password||\"\";d.Authorization=\"Basic \"+c(g+\":\"+m)}if(h.open(e.method.toUpperCase(),i(e.url,e.params,e.paramsSerializer),!0),h.timeout=e.timeout,h[v]=function(){if(h&&(4===h.readyState||y)&&(0!==h.status||h.responseURL&&0===h.responseURL.indexOf(\"file:\"))){var t=\"getAllResponseHeaders\"in h?u(h.getAllResponseHeaders()):null,r={data:e.responseType&&\"text\"!==e.responseType?h.response:h.responseText,status:1223===h.status?204:h.status,statusText:1223===h.status?\"No Content\":h.statusText,headers:t,config:e,request:h};o(f,l,r),h=null}},h.onerror=function(){l(a(\"Network Error\",e,null,h)),h=null},h.ontimeout=function(){l(a(\"timeout of \"+e.timeout+\"ms exceeded\",e,\"ECONNABORTED\",h)),h=null},n.isStandardBrowserEnv()){var x=r(104),b=(e.withCredentials||s(e.url))&&e.xsrfCookieName?x.read(e.xsrfCookieName):void 0;b&&(d[e.xsrfHeaderName]=b)}if(\"setRequestHeader\"in h&&n.forEach(d,function(e,t){void 0===p&&\"content-type\"===t.toLowerCase()?delete d[t]:h.setRequestHeader(t,e)}),e.withCredentials&&(h.withCredentials=!0),e.responseType)try{h.responseType=e.responseType}catch(t){if(\"json\"!==e.responseType)throw t}\"function\"==typeof e.onDownloadProgress&&h.addEventListener(\"progress\",e.onDownloadProgress),\"function\"==typeof e.onUploadProgress&&h.upload&&h.upload.addEventListener(\"progress\",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then(function(e){h&&(h.abort(),l(e),h=null)}),void 0===p&&(p=null),h.send(p)})}}).call(t,r(73))},function(e,t,r){\"use strict\";function n(e){this.message=e}n.prototype.toString=function(){return\"Cancel\"+(this.message?\": \"+this.message:\"\")},n.prototype.__CANCEL__=!0,e.exports=n},function(e,t,r){\"use strict\";e.exports=function(e){return!(!e||!e.__CANCEL__)}},function(e,t,r){\"use strict\";var n=r(98);e.exports=function(e,t,r,o,i){var u=new Error(e);return n(u,t,r,o,i)}},function(e,t,r){\"use strict\";e.exports=function(e,t){return function(){for(var r=new Array(arguments.length),n=0;nr;)t.push(arguments[r++]);return g[++y]=function(){s(\"function\"==typeof e?e:Function(e),t)},n(y),y},d=function(e){delete g[e]},\"process\"==r(15)(l)?n=function(e){l.nextTick(u(m,e,1))}:v&&v.now?n=function(e){v.now(u(m,e,1))}:h?(i=(o=new h).port2,o.port1.onmessage=x,n=u(i.postMessage,i,1)):f.addEventListener&&\"function\"==typeof postMessage&&!f.importScripts?(n=function(e){f.postMessage(e+\"\",\"*\")},f.addEventListener(\"message\",x,!1)):n=\"onreadystatechange\"in c(\"script\")?function(e){a.appendChild(c(\"script\")).onreadystatechange=function(){a.removeChild(this),m.call(e)}}:function(e){setTimeout(u(m,e,1),0)}),e.exports={set:p,clear:d}},function(e,t,r){var n=r(34),o=Math.min;e.exports=function(e){return e>0?o(n(e),9007199254740991):0}},function(e,t,r){var n=r(27);e.exports=function(e){return Object(n(e))}},function(e,t){var r=0,n=Math.random();e.exports=function(e){return\"Symbol(\".concat(void 0===e?\"\":e,\")_\",(++r+n).toString(36))}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{};!function(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}(this,e),this.record(t)}return n(e,[{key:\"all\",value:function(){return this.errors}},{key:\"has\",value:function(e){var t=this.errors.hasOwnProperty(e);t||(t=Object.keys(this.errors).filter(function(t){return t.startsWith(e+\".\")||t.startsWith(e+\"[\")}).length>0);return t}},{key:\"first\",value:function(e){return this.get(e)[0]}},{key:\"get\",value:function(e){return this.errors[e]||[]}},{key:\"any\",value:function(){return Object.keys(this.errors).length>0}},{key:\"record\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.errors=e}},{key:\"clear\",value:function(e){if(e){var t=Object.assign({},this.errors);Object.keys(t).filter(function(t){return t===e||t.startsWith(e+\".\")||t.startsWith(e+\"[\")}).forEach(function(e){return delete t[e]}),this.errors=t}else this.errors={}}}]),e}();t.default=o},function(e,t,r){var n=r(179),o=r(231),i=r(13),u=r(232),s=r(68),a=r(233),c=Object.prototype.hasOwnProperty;e.exports=function(e,t){var r=i(e),f=!r&&o(e),l=!r&&!f&&u(e),p=!r&&!f&&!l&&a(e),d=r||f||l||p,h=d?n(e.length,String):[],v=h.length;for(var y in e)!t&&!c.call(e,y)||d&&(\"length\"==y||l&&(\"offset\"==y||\"parent\"==y)||p&&(\"buffer\"==y||\"byteLength\"==y||\"byteOffset\"==y)||s(y,v))||h.push(y);return h}},function(e,t,r){(function(t){var r=\"object\"==typeof t&&t&&t.Object===Object&&t;e.exports=r}).call(t,r(243))},function(e,t){var r=RegExp(\"[\\\\u200d\\\\ud800-\\\\udfff\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe2f\\\\u20d0-\\\\u20ff\\\\ufe0e\\\\ufe0f]\");e.exports=function(e){return r.test(e)}},function(e,t){var r=9007199254740991,n=/^(?:0|[1-9]\\d*)$/;e.exports=function(e,t){var o=typeof e;return!!(t=null==t?r:t)&&(\"number\"==o||\"symbol\"!=o&&n.test(e))&&e>-1&&e%1==0&&e-1&&e%1==0&&e<=r}},function(e,t,r){var n=r(180);e.exports=function(e){return null==e?\"\":n(e)}},function(e,t){var r,n,o=e.exports={};function i(){throw new Error(\"setTimeout has not been defined\")}function u(){throw new Error(\"clearTimeout has not been defined\")}function s(e){if(r===setTimeout)return setTimeout(e,0);if((r===i||!r)&&setTimeout)return r=setTimeout,setTimeout(e,0);try{return r(e,0)}catch(t){try{return r.call(null,e,0)}catch(t){return r.call(this,e,0)}}}!function(){try{r=\"function\"==typeof setTimeout?setTimeout:i}catch(e){r=i}try{n=\"function\"==typeof clearTimeout?clearTimeout:u}catch(e){n=u}}();var a,c=[],f=!1,l=-1;function p(){f&&a&&(f=!1,a.length?c=a.concat(c):l=-1,c.length&&d())}function d(){if(!f){var e=s(p);f=!0;for(var t=c.length;t;){for(a=c,c=[];++l1)for(var r=1;r1&&void 0!==arguments[1]?arguments[1]:null;return this.viaManyToMany?this.detachResources(e):Nova.request({url:\"/nova-api/\"+this.resourceName,method:\"delete\",params:(0,i.default)({},this.queryString,{resources:u(e)})}).then(r||function(){t.deleteModalOpen=!1,t.getResources()})},deleteSelectedResources:function(){this.deleteResources(this.selectedResources)},deleteAllMatchingResources:function(){var e=this;return this.viaManyToMany?this.detachAllMatchingResources():Nova.request({url:this.deleteAllMatchingResourcesEndpoint,method:\"delete\",params:(0,i.default)({},this.queryString,{resources:\"all\"})}).then(function(){e.deleteModalOpen=!1,e.getResources()})},detachResources:function(e){var t=this;return Nova.request({url:\"/nova-api/\"+this.resourceName+\"/detach\",method:\"delete\",params:(0,i.default)({},this.queryString,{resources:u(e)})}).then(function(){t.deleteModalOpen=!1,t.getResources()})},detachAllMatchingResources:function(){var e=this;return Nova.request({url:\"/nova-api/\"+this.resourceName+\"/detach\",method:\"delete\",params:(0,i.default)({},this.queryString,{resources:\"all\"})}).then(function(){e.deleteModalOpen=!1,e.getResources()})},forceDeleteResources:function(e){var t=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;return Nova.request({url:\"/nova-api/\"+this.resourceName+\"/force\",method:\"delete\",params:(0,i.default)({},this.queryString,{resources:u(e)})}).then(r||function(){t.deleteModalOpen=!1,t.getResources()})},forceDeleteSelectedResources:function(){this.forceDeleteResources(this.selectedResources)},forceDeleteAllMatchingResources:function(){var e=this;return Nova.request({url:this.forceDeleteSelectedResourcesEndpoint,method:\"delete\",params:(0,i.default)({},this.queryString,{resources:\"all\"})}).then(function(){e.deleteModalOpen=!1,e.getResources()})},restoreResources:function(e){var t=this,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;return Nova.request({url:\"/nova-api/\"+this.resourceName+\"/restore\",method:\"put\",params:(0,i.default)({},this.queryString,{resources:u(e)})}).then(r||function(){t.restoreModalOpen=!1,t.getResources()})},restoreSelectedResources:function(){this.restoreResources(this.selectedResources)},restoreAllMatchingResources:function(){var e=this;return Nova.request({url:this.restoreAllMatchingResourcesEndpoint,method:\"put\",params:(0,i.default)({},this.queryString,{resources:\"all\"})}).then(function(){e.restoreModalOpen=!1,e.getResources()})}},computed:{deleteAllMatchingResourcesEndpoint:function(){return this.lens?\"/nova-api/\"+this.resourceName+\"/lens/\"+this.lens:\"/nova-api/\"+this.resourceName},forceDeleteSelectedResourcesEndpoint:function(){return this.lens?\"/nova-api/\"+this.resourceName+\"/lens/\"+this.lens+\"/force\":\"/nova-api/\"+this.resourceName+\"/force\"},restoreAllMatchingResourcesEndpoint:function(){return this.lens?\"/nova-api/\"+this.resourceName+\"/lens/\"+this.lens+\"/restore\":\"/nova-api/\"+this.resourceName+\"/restore\"},queryString:function(){return{search:this.currentSearch,filters:this.encodedFilters,trashed:this.currentTrashed,viaResource:this.viaResource,viaResourceId:this.viaResourceId,viaRelationship:this.viaRelationship}}}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n=s(r(26)),o=s(r(110)),i=s(r(228)),u=s(r(230));function s(e){return e&&e.__esModule?e:{default:e}}t.default={data:function(){return{filters:[],currentFilters:[]}},methods:{initializeFilterValuesFromQueryString:function(){this.clearAllFilters(),this.encodedFilters&&(this.currentFilters=JSON.parse(atob(this.encodedFilters)),this.syncFilterValues())},clearAllFilters:function(){this.currentFilters=[],(0,i.default)(this.filters,function(e){e.currentValue=\"\"})},syncFilterValues:function(){var e=this;(0,i.default)(this.filters,function(t){t.currentValue=(0,u.default)(_(e.currentFilters).find(function(e){return t.class==e.class}),\"value\",t.currentValue)})},filterChanged:function(){var e;this.updateQueryString((e={},(0,n.default)(e,this.pageParameter,1),(0,n.default)(e,this.filterParameter,btoa((0,o.default)(this.currentFilters))),e))}},computed:{encodedFilters:function(){return this.$route.query[this.filterParameter]||\"\"}}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.default={props:{resourceName:{},field:{}},data:function(){return{value:\"\"}},mounted:function(){var e=this;this.setInitialValue(),this.field.fill=this.fill,Nova.$on(this.field.attribute+\"-value\",function(t){e.value=t})},destroyed:function(){Nova.$off(this.field.attribute+\"-value\")},methods:{setInitialValue:function(){this.value=void 0!==this.field.value&&null!==this.field.value?this.field.value:\"\"},fill:function(e){e.append(this.field.attribute,this.value||\"\")},handleChange:function(e){this.value=e}}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n=r(41);t.default={props:{errors:{default:function(){return new n.Errors}}},data:function(){return{errorClass:\"border-danger\"}},computed:{errorClasses:function(){return this.hasError?[this.errorClass]:[]},fieldAttribute:function(){return this.field.attribute},hasError:function(){return this.errors.has(this.fieldAttribute)},firstError:function(){if(this.hasError)return this.errors.first(this.fieldAttribute)}}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n=u(r(115)),o=u(r(113)),i=u(r(40));function u(e){return e&&e.__esModule?e:{default:e}}t.default={props:{loadCards:{type:Boolean,default:!0}},data:function(){return{cards:[]}},created:function(){this.fetchCards()},watch:{cardsEndpoint:function(){this.fetchCards()}},methods:{fetchCards:function(){var e=(0,o.default)(n.default.mark(function e(){var t,r;return n.default.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(!this.loadCards){e.next=6;break}return e.next=3,Nova.request().get(this.cardsEndpoint);case 3:t=e.sent,r=t.data,this.cards=r;case 6:case\"end\":return e.stop()}},e,this)}));return function(){return e.apply(this,arguments)}}()},computed:{shouldShowCards:function(){return this.cards.length>0},smallCards:function(){return _.filter(this.cards,function(e){return-1!==i.default.indexOf(e.width)})},largeCards:function(){return _.filter(this.cards,function(e){return\"full\"==e.width})}}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.default={methods:{toAppTimezone:function(e){return e?moment.tz(e,this.userTimezone).clone().tz(Nova.config.timezone).format(\"YYYY-MM-DD HH:mm:ss\"):e},fromAppTimezone:function(e){return e?moment.tz(e,Nova.config.timezone).clone().tz(this.userTimezone).format(\"YYYY-MM-DD HH:mm:ss\"):e},localizeDateTimeField:function(e){if(!e.value)return e.value;var t=moment.tz(e.value,Nova.config.timezone).clone().tz(this.userTimezone);return e.format?t.format(e.format):this.usesTwelveHourTime?t.format(\"YYYY-MM-DD h:mm:ss A\"):t.format(\"YYYY-MM-DD HH:mm:ss\")},localizeDateField:function(e){if(!e.value)return e.value;var t=moment.tz(e.value,Nova.config.timezone).clone().tz(this.userTimezone);return e.format?t.format(e.format):t.format(\"YYYY-MM-DD\")}},computed:{userTimezone:function(){return Nova.config.userTimezone?Nova.config.userTimezone:moment.tz.guess()},usesTwelveHourTime:function(){return _.endsWith((new Date).toLocaleString(),\"AM\")||_.endsWith((new Date).toLocaleString(),\"PM\")}}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n,o=r(227),i=(n=o)&&n.__esModule?n:{default:n};t.default={methods:{updateQueryString:function(e){this.$router.push({query:(0,i.default)(e,this.$route.query)})}}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.default={computed:{resourceInformation:function(){var e=this;return _.find(Nova.config.resources,function(t){return t.uriKey==e.resourceName})},viaResourceInformation:function(){var e=this;if(this.viaResource)return _.find(Nova.config.resources,function(t){return t.uriKey==e.viaResource})},authorizedToCreate:function(){return this.resourceInformation.authorizedToCreate}}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n,o=r(26),i=(n=o)&&n.__esModule?n:{default:n};t.default={methods:{selectPreviousPage:function(){this.updateQueryString((0,i.default)({},this.pageParameter,this.currentPage-1))},selectNextPage:function(){this.updateQueryString((0,i.default)({},this.pageParameter,this.currentPage+1))}},computed:{currentPage:function(){return parseInt(this.$route.query[this.pageParameter]||1)}}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n,o=r(26),i=(n=o)&&n.__esModule?n:{default:n};t.default={data:function(){return{perPage:25}},methods:{initializePerPageFromQueryString:function(){this.perPage=this.currentPerPage},perPageChanged:function(){this.updateQueryString((0,i.default)({},this.perPageParameter,this.perPage))}},computed:{currentPerPage:function(){return this.$route.query[this.perPageParameter]||25}}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n,o=r(226),i=(n=o)&&n.__esModule?n:{default:n};t.default={data:function(){return{search:\"\",selectedResource:\"\",availableResources:[]}},methods:{selectResource:function(e){this.selectedResource=e},handleSearchCleared:function(){this.availableResources=[]},clearSelection:function(){this.selectedResource=\"\",this.availableResources=[]},performSearch:function(e){var t=this;this.search=e;var r=e.trim();\"\"!=r?this.debouncer(function(){t.selectedResource=\"\",t.getAvailableResources(r)},500):this.clearSelection()},debouncer:(0,i.default)(function(e){return e()},500)}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.default={data:function(){return{withTrashed:!1}},methods:{toggleWithTrashed:function(){this.withTrashed=!this.withTrashed},enableWithTrashed:function(){this.withTrashed=!0},disableWithTrashed:function(){this.withTrashed=!1}}}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.default=function(e){return(0,i.default)(e)};var n,o=r(240),i=(n=o)&&n.__esModule?n:{default:n}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n,o=r(48),i=(n=o)&&n.__esModule?n:{default:n};t.default=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100;return i.default.all([e,new i.default(function(e){setTimeout(function(){return e()},t)})]).then(function(e){return e[0]})}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.default=function(e,t){return e>1||0==e?n.Inflector.pluralize(t):n.Inflector.singularize(t)};var n=r(47)},function(e,t,r){\"use strict\";var n={uncountableWords:[\"equipment\",\"information\",\"rice\",\"money\",\"species\",\"series\",\"fish\",\"sheep\",\"moose\",\"deer\",\"news\"],pluralRules:[[new RegExp(\"(m)an$\",\"gi\"),\"$1en\"],[new RegExp(\"(pe)rson$\",\"gi\"),\"$1ople\"],[new RegExp(\"(child)$\",\"gi\"),\"$1ren\"],[new RegExp(\"^(ox)$\",\"gi\"),\"$1en\"],[new RegExp(\"(ax|test)is$\",\"gi\"),\"$1es\"],[new RegExp(\"(octop|vir)us$\",\"gi\"),\"$1i\"],[new RegExp(\"(alias|status)$\",\"gi\"),\"$1es\"],[new RegExp(\"(bu)s$\",\"gi\"),\"$1ses\"],[new RegExp(\"(buffal|tomat|potat)o$\",\"gi\"),\"$1oes\"],[new RegExp(\"([ti])um$\",\"gi\"),\"$1a\"],[new RegExp(\"sis$\",\"gi\"),\"ses\"],[new RegExp(\"(?:([^f])fe|([lr])f)$\",\"gi\"),\"$1$2ves\"],[new RegExp(\"(hive)$\",\"gi\"),\"$1s\"],[new RegExp(\"([^aeiouy]|qu)y$\",\"gi\"),\"$1ies\"],[new RegExp(\"(x|ch|ss|sh)$\",\"gi\"),\"$1es\"],[new RegExp(\"(matr|vert|ind)ix|ex$\",\"gi\"),\"$1ices\"],[new RegExp(\"([m|l])ouse$\",\"gi\"),\"$1ice\"],[new RegExp(\"(quiz)$\",\"gi\"),\"$1zes\"],[new RegExp(\"s$\",\"gi\"),\"s\"],[new RegExp(\"$\",\"gi\"),\"s\"]],singularRules:[[new RegExp(\"(m)en$\",\"gi\"),\"$1an\"],[new RegExp(\"(pe)ople$\",\"gi\"),\"$1rson\"],[new RegExp(\"(child)ren$\",\"gi\"),\"$1\"],[new RegExp(\"([ti])a$\",\"gi\"),\"$1um\"],[new RegExp(\"((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$\",\"gi\"),\"$1$2sis\"],[new RegExp(\"(hive)s$\",\"gi\"),\"$1\"],[new RegExp(\"(tive)s$\",\"gi\"),\"$1\"],[new RegExp(\"(curve)s$\",\"gi\"),\"$1\"],[new RegExp(\"([lr])ves$\",\"gi\"),\"$1f\"],[new RegExp(\"([^fo])ves$\",\"gi\"),\"$1fe\"],[new RegExp(\"([^aeiouy]|qu)ies$\",\"gi\"),\"$1y\"],[new RegExp(\"(s)eries$\",\"gi\"),\"$1eries\"],[new RegExp(\"(m)ovies$\",\"gi\"),\"$1ovie\"],[new RegExp(\"(x|ch|ss|sh)es$\",\"gi\"),\"$1\"],[new RegExp(\"([m|l])ice$\",\"gi\"),\"$1ouse\"],[new RegExp(\"(bus)es$\",\"gi\"),\"$1\"],[new RegExp(\"(o)es$\",\"gi\"),\"$1\"],[new RegExp(\"(shoe)s$\",\"gi\"),\"$1\"],[new RegExp(\"(cris|ax|test)es$\",\"gi\"),\"$1is\"],[new RegExp(\"(octop|vir)i$\",\"gi\"),\"$1us\"],[new RegExp(\"(alias|status)es$\",\"gi\"),\"$1\"],[new RegExp(\"^(ox)en\",\"gi\"),\"$1\"],[new RegExp(\"(vert|ind)ices$\",\"gi\"),\"$1ex\"],[new RegExp(\"(matr)ices$\",\"gi\"),\"$1ix\"],[new RegExp(\"(quiz)zes$\",\"gi\"),\"$1\"],[new RegExp(\"s$\",\"gi\"),\"\"]],nonTitlecasedWords:[\"and\",\"or\",\"nor\",\"a\",\"an\",\"the\",\"so\",\"but\",\"to\",\"of\",\"at\",\"by\",\"from\",\"into\",\"on\",\"onto\",\"off\",\"out\",\"in\",\"over\",\"with\",\"for\"],idSuffix:new RegExp(\"(_ids|_id)$\",\"g\"),underbar:new RegExp(\"_\",\"g\"),spaceOrUnderbar:new RegExp(\"[ _]\",\"g\"),uppercase:new RegExp(\"([A-Z])\",\"g\"),underbarPrefix:new RegExp(\"^_\"),applyRules:function(e,t,r,n){if(n)e=n;else if(!(r.indexOf(e.toLowerCase())>-1))for(var o=0;o>8-s%1*8)){if((r=i.charCodeAt(s+=.75))>255)throw new o;t=t<<8|r}return u}},function(e,t,r){\"use strict\";var n=r(0);function o(e){return encodeURIComponent(e).replace(/%40/gi,\"@\").replace(/%3A/gi,\":\").replace(/%24/g,\"$\").replace(/%2C/gi,\",\").replace(/%20/g,\"+\").replace(/%5B/gi,\"[\").replace(/%5D/gi,\"]\")}e.exports=function(e,t,r){if(!t)return e;var i;if(r)i=r(t);else if(n.isURLSearchParams(t))i=t.toString();else{var u=[];n.forEach(t,function(e,t){null!==e&&void 0!==e&&(n.isArray(e)?t+=\"[]\":e=[e],n.forEach(e,function(e){n.isDate(e)?e=e.toISOString():n.isObject(e)&&(e=JSON.stringify(e)),u.push(o(t)+\"=\"+o(e))}))}),i=u.join(\"&\")}return i&&(e+=(-1===e.indexOf(\"?\")?\"?\":\"&\")+i),e}},function(e,t,r){\"use strict\";e.exports=function(e,t){return t?e.replace(/\\/+$/,\"\")+\"/\"+t.replace(/^\\/+/,\"\"):e}},function(e,t,r){\"use strict\";var n=r(0);e.exports=n.isStandardBrowserEnv()?{write:function(e,t,r,o,i,u){var s=[];s.push(e+\"=\"+encodeURIComponent(t)),n.isNumber(r)&&s.push(\"expires=\"+new Date(r).toGMTString()),n.isString(o)&&s.push(\"path=\"+o),n.isString(i)&&s.push(\"domain=\"+i),!0===u&&s.push(\"secure\"),document.cookie=s.join(\"; \")},read:function(e){var t=document.cookie.match(new RegExp(\"(^|;\\\\s*)(\"+e+\")=([^;]*)\"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,\"\",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}}},function(e,t,r){\"use strict\";e.exports=function(e){return/^([a-z][a-z\\d\\+\\-\\.]*:)?\\/\\//i.test(e)}},function(e,t,r){\"use strict\";var n=r(0);e.exports=n.isStandardBrowserEnv()?function(){var e,t=/(msie|trident)/i.test(navigator.userAgent),r=document.createElement(\"a\");function o(e){var n=e;return t&&(r.setAttribute(\"href\",n),n=r.href),r.setAttribute(\"href\",n),{href:r.href,protocol:r.protocol?r.protocol.replace(/:$/,\"\"):\"\",host:r.host,search:r.search?r.search.replace(/^\\?/,\"\"):\"\",hash:r.hash?r.hash.replace(/^#/,\"\"):\"\",hostname:r.hostname,port:r.port,pathname:\"/\"===r.pathname.charAt(0)?r.pathname:\"/\"+r.pathname}}return e=o(window.location.href),function(t){var r=n.isString(t)?o(t):t;return r.protocol===e.protocol&&r.host===e.host}}():function(){return!0}},function(e,t,r){\"use strict\";var n=r(0);e.exports=function(e,t){n.forEach(e,function(r,n){n!==t&&n.toUpperCase()===t.toUpperCase()&&(e[t]=r,delete e[n])})}},function(e,t,r){\"use strict\";var n=r(0),o=[\"age\",\"authorization\",\"content-length\",\"content-type\",\"etag\",\"expires\",\"from\",\"host\",\"if-modified-since\",\"if-unmodified-since\",\"last-modified\",\"location\",\"max-forwards\",\"proxy-authorization\",\"referer\",\"retry-after\",\"user-agent\"];e.exports=function(e){var t,r,i,u={};return e?(n.forEach(e.split(\"\\n\"),function(e){if(i=e.indexOf(\":\"),t=n.trim(e.substr(0,i)).toLowerCase(),r=n.trim(e.substr(i+1)),t){if(u[t]&&o.indexOf(t)>=0)return;u[t]=\"set-cookie\"===t?(u[t]?u[t]:[]).concat([r]):u[t]?u[t]+\", \"+r:r}}),u):u}},function(e,t,r){\"use strict\";e.exports=function(e){return function(t){return e.apply(null,t)}}},function(e,t,r){e.exports={default:r(116),__esModule:!0}},function(e,t,r){e.exports={default:r(117),__esModule:!0}},function(e,t,r){e.exports={default:r(118),__esModule:!0}},function(e,t,r){\"use strict\";t.__esModule=!0;var n,o=r(48),i=(n=o)&&n.__esModule?n:{default:n};t.default=function(e){return function(){var t=e.apply(this,arguments);return new i.default(function(e,r){return function n(o,u){try{var s=t[o](u),a=s.value}catch(e){return void r(e)}if(!s.done)return i.default.resolve(a).then(function(e){n(\"next\",e)},function(e){n(\"throw\",e)});e(a)}(\"next\")})}}},function(e,t,r){\"use strict\";t.__esModule=!0;var n,o=r(111),i=(n=o)&&n.__esModule?n:{default:n};t.default=i.default||function(e){for(var t=1;tf;)if((s=a[f++])!=s)return!0}else for(;c>f;f++)if((e||f in a)&&a[f]===r)return e||f||0;return!e&&-1}}},function(e,t,r){var n=r(16),o=r(127),i=r(126),u=r(4),s=r(61),a=r(146),c={},f={};(t=e.exports=function(e,t,r,l,p){var d,h,v,y,g=p?function(){return e}:a(e),m=n(r,l,t?2:1),x=0;if(\"function\"!=typeof g)throw TypeError(e+\" is not iterable!\");if(i(g)){for(d=s(e.length);d>x;x++)if((y=t?m(u(h=e[x])[0],h[1]):m(e[x]))===c||y===f)return y}else for(v=g.call(e);!(h=v.next()).done;)if((y=o(v,m,h.value,t))===c||y===f)return y}).BREAK=c,t.RETURN=f},function(e,t,r){e.exports=!r(5)&&!r(29)(function(){return 7!=Object.defineProperty(r(28)(\"div\"),\"a\",{get:function(){return 7}}).a})},function(e,t){e.exports=function(e,t,r){var n=void 0===r;switch(t.length){case 0:return n?e():e.call(r);case 1:return n?e(t[0]):e.call(r,t[0]);case 2:return n?e(t[0],t[1]):e.call(r,t[0],t[1]);case 3:return n?e(t[0],t[1],t[2]):e.call(r,t[0],t[1],t[2]);case 4:return n?e(t[0],t[1],t[2],t[3]):e.call(r,t[0],t[1],t[2],t[3])}return e.apply(r,t)}},function(e,t,r){var n=r(10),o=r(2)(\"iterator\"),i=Array.prototype;e.exports=function(e){return void 0!==e&&(n.Array===e||i[o]===e)}},function(e,t,r){var n=r(4);e.exports=function(e,t,r,o){try{return o?t(n(r)[0],r[1]):t(r)}catch(t){var i=e.return;throw void 0!==i&&n(i.call(e)),t}}},function(e,t,r){\"use strict\";var n=r(133),o=r(57),i=r(32),u={};r(7)(u,r(2)(\"iterator\"),function(){return this}),e.exports=function(e,t,r){e.prototype=n(u,{next:o(1,r)}),i(e,t+\" Iterator\")}},function(e,t,r){var n=r(2)(\"iterator\"),o=!1;try{var i=[7][n]();i.return=function(){o=!0},Array.from(i,function(){throw 2})}catch(e){}e.exports=function(e,t){if(!t&&!o)return!1;var r=!1;try{var i=[7],u=i[n]();u.next=function(){return{done:r=!0}},i[n]=function(){return u},e(i)}catch(e){}return r}},function(e,t){e.exports=function(e,t){return{value:t,done:!!e}}},function(e,t,r){var n=r(1),o=r(60).set,i=n.MutationObserver||n.WebKitMutationObserver,u=n.process,s=n.Promise,a=\"process\"==r(15)(u);e.exports=function(){var e,t,r,c=function(){var n,o;for(a&&(n=u.domain)&&n.exit();e;){o=e.fn,e=e.next;try{o()}catch(n){throw e?r():t=void 0,n}}t=void 0,n&&n.enter()};if(a)r=function(){u.nextTick(c)};else if(!i||n.navigator&&n.navigator.standalone)if(s&&s.resolve){var f=s.resolve(void 0);r=function(){f.then(c)}}else r=function(){o.call(n,c)};else{var l=!0,p=document.createTextNode(\"\");new i(c).observe(p,{characterData:!0}),r=function(){p.data=l=!l}}return function(n){var o={fn:n,next:void 0};t&&(t.next=o),e||(e=o,r()),t=o}}},function(e,t,r){\"use strict\";var n=r(54),o=r(135),i=r(138),u=r(62),s=r(52),a=Object.assign;e.exports=!a||r(29)(function(){var e={},t={},r=Symbol(),n=\"abcdefghijklmnopqrst\";return e[r]=7,n.split(\"\").forEach(function(e){t[e]=e}),7!=a({},e)[r]||Object.keys(a({},t)).join(\"\")!=n})?function(e,t){for(var r=u(e),a=arguments.length,c=1,f=o.f,l=i.f;a>c;)for(var p,d=s(arguments[c++]),h=f?n(d).concat(f(d)):n(d),v=h.length,y=0;v>y;)l.call(d,p=h[y++])&&(r[p]=d[p]);return r}:a},function(e,t,r){var n=r(4),o=r(134),i=r(50),u=r(33)(\"IE_PROTO\"),s=function(){},a=function(){var e,t=r(28)(\"iframe\"),n=i.length;for(t.style.display=\"none\",r(51).appendChild(t),t.src=\"javascript:\",(e=t.contentWindow.document).open(),e.write(\"
45 |
--------------------------------------------------------------------------------
/resources/js/components/FormField.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
158 |
--------------------------------------------------------------------------------
/resources/js/field.js:
--------------------------------------------------------------------------------
1 | Nova.booting((Vue, router) => {
2 | Vue.component('detail-nova-dependency-container', require('./components/DetailField'));
3 | Vue.component('form-nova-dependency-container', require('./components/FormField'));
4 | })
5 |
--------------------------------------------------------------------------------
/src/ActionHasDependencies.php:
--------------------------------------------------------------------------------
1 | fields() as $field) {
17 | if ($field instanceof NovaDependencyContainer) {
18 | // do not add any fields for validation if container is not satisfied
19 | if ($field->areDependenciesSatisfied($request)) {
20 | $availableFields[] = $field;
21 | $this->extractChildFields($field->meta['fields']);
22 | }
23 | } else {
24 | $availableFields[] = $field;
25 | }
26 | }
27 |
28 | if ($this->childFieldsArr) {
29 | $availableFields = array_merge($availableFields, $this->childFieldsArr);
30 | }
31 | }
32 |
33 | /**
34 | * Validate action fields. Mostly a copy paste from Nova
35 | *
36 | * Uses the above to validate only on fields that have satisfied dependencies.
37 | *
38 | * @param \Laravel\Nova\Http\Requests\ActionRequest $request
39 | * @return void
40 | */
41 | public function validateFields(ActionRequest $request)
42 | {
43 | $fields = collect($this->fieldsForValidation($request));
44 |
45 | return Validator::make(
46 | $request->all(),
47 | $fields->mapWithKeys(function ($field) use ($request) {
48 | return $field->getCreationRules($request);
49 | })->all(),
50 | [],
51 | $fields->reject(function ($field) {
52 | return empty($field->name);
53 | })->mapWithKeys(function ($field) {
54 | return [$field->attribute => $field->name];
55 | })->all()
56 | )->after(function ($validator) use ($request) {
57 | $this->afterValidation($request, $validator);
58 | })->validate();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/FieldServiceProvider.php:
--------------------------------------------------------------------------------
1 | bind(
23 | \Laravel\Nova\Http\Controllers\ActionController::class,
24 | \Epartment\NovaDependencyContainer\Http\Controllers\ActionController::class
25 | );
26 | });
27 |
28 | Nova::serving(function (ServingNova $event) {
29 | Nova::script('nova-dependency-container', __DIR__.'/../dist/js/field.js');
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/HasChildFields.php:
--------------------------------------------------------------------------------
1 | extractChildFields($childField->meta['fields']);
18 | } else {
19 | if (array_search($childField->attribute, array_column($this->childFieldsArr, 'attribute')) === false) {
20 | // @todo: we should not randomly apply rules to child-fields.
21 | $childField = $this->applyRulesForChildFields($childField);
22 | $this->childFieldsArr[] = $childField;
23 | }
24 | }
25 | }
26 | }
27 |
28 | /**
29 | * @param [array] $childField
30 | * @return [array] $childField
31 | */
32 | protected function applyRulesForChildFields($childField)
33 | {
34 | if (isset($childField->rules)) {
35 | $childField->rules[] = "sometimes:required:".$childField->attribute;
36 | }
37 | if (isset($childField->creationRules)) {
38 | $childField->creationRules[] = "sometimes:required:".$childField->attribute;
39 | }
40 | if (isset($childField->updateRules)) {
41 | $childField->updateRules[] = "sometimes:required:".$childField->attribute;
42 | }
43 | return $childField;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/HasDependencies.php:
--------------------------------------------------------------------------------
1 | fieldsMethod($request);
21 |
22 | // needs to be filtered once to resolve Panels
23 | $fields = $this->filter($this->{$method}($request));
24 | $availableFields = [];
25 |
26 | foreach ($fields as $field) {
27 | if ($field instanceof NovaDependencyContainer) {
28 | $availableFields[] = $this->filterFieldForRequest($field, $request);
29 | if ($field->areDependenciesSatisfied($request) || $this->extractableRequest($request, $this->model())) {
30 | if ($this->doesRouteRequireChildFields()) {
31 | $this->extractChildFields($field->meta['fields']);
32 | }
33 | }
34 | } else {
35 | $availableFields[] = $this->filterFieldForRequest($field, $request);
36 | }
37 | }
38 |
39 | if ($this->childFieldsArr) {
40 | $availableFields = array_merge($availableFields, $this->childFieldsArr);
41 | }
42 |
43 | $availableFields = new FieldCollection(array_values($this->filter($availableFields)));
44 |
45 | return $availableFields;
46 | }
47 |
48 | /**
49 | * Check if request needs to extract child fields
50 | *
51 | * @param NovaRequest $request
52 | * @param mixed $model
53 | * @return bool
54 | */
55 | protected function extractableRequest(NovaRequest $request, $model)
56 | {
57 | // if form was submitted to update (method === 'PUT')
58 | if ($request->isUpdateOrUpdateAttachedRequest() && $request->method() == 'PUT') {
59 | return false;
60 | }
61 |
62 | // if form was submitted to create and new resource
63 | if ($request->isCreateOrAttachRequest() && $model->id === null) {
64 | return false;
65 | }
66 |
67 | return true;
68 | }
69 |
70 | /**
71 | * @param mixed $field
72 | * @param NovaRequest $request
73 | * @return mixed
74 | *
75 | * @todo: implement
76 | */
77 | public function filterFieldForRequest($field, NovaRequest $request) {
78 | // @todo: filter fields for request, e.g. show/hideOnIndex, create, update or whatever
79 | return $field;
80 | }
81 |
82 | /**
83 | * @return bool
84 | */
85 | protected function doesRouteRequireChildFields() : bool
86 | {
87 | return Str::endsWith(Route::currentRouteAction(), [
88 | 'FieldDestroyController@handle',
89 | 'ResourceUpdateController@handle',
90 | 'ResourceStoreController@handle',
91 | 'AssociatableController@index',
92 | 'MorphableController@index',
93 | ]);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/Http/Controllers/ActionController.php:
--------------------------------------------------------------------------------
1 | action()->fields() as $field) {
22 | if ($field instanceof NovaDependencyContainer) {
23 | // do not add any fields for validation if container is not satisfied
24 | if ($field->areDependenciesSatisfied($this)) {
25 | $availableFields[] = $field;
26 | $this->extractChildFields($field->meta['fields']);
27 | }
28 | } else {
29 | $availableFields[] = $field;
30 | }
31 | }
32 |
33 | if ($this->childFieldsArr) {
34 | $availableFields = array_merge($availableFields, $this->childFieldsArr);
35 | }
36 |
37 | $this->validate(collect($availableFields)->mapWithKeys(function ($field) {
38 | return $field->getCreationRules($this);
39 | })->all());
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/NovaDependencyContainer.php:
--------------------------------------------------------------------------------
1 | withMeta(['fields' => $fields]);
36 | $this->withMeta(['dependencies' => []]);
37 | }
38 |
39 | /**
40 | * Adds a dependency
41 | *
42 | * @param $field
43 | * @param $value
44 | * @return $this
45 | */
46 | public function dependsOn($field, $value)
47 | {
48 | return $this->withMeta([
49 | 'dependencies' => array_merge($this->meta['dependencies'], [
50 | $this->getFieldLayout($field, $value)
51 | ])
52 | ]);
53 | }
54 |
55 | /**
56 | * Adds a dependency for not
57 | *
58 | * @param $field
59 | * @return NovaDependencyContainer
60 | */
61 | public function dependsOnNot($field, $value)
62 | {
63 | return $this->withMeta([
64 | 'dependencies' => array_merge($this->meta['dependencies'], [
65 | array_merge($this->getFieldLayout($field), ['not' => $value])
66 | ])
67 | ]);
68 | }
69 |
70 | /**
71 | * Adds a dependency for not empty
72 | *
73 | * @param $field
74 | * @return NovaDependencyContainer
75 | */
76 | public function dependsOnEmpty($field)
77 | {
78 | return $this->withMeta([
79 | 'dependencies' => array_merge($this->meta['dependencies'], [
80 | array_merge($this->getFieldLayout($field), ['empty' => true])
81 | ])
82 | ]);
83 | }
84 |
85 | /**
86 | * Adds a dependency for not empty
87 | *
88 | * @param $field
89 | * @return NovaDependencyContainer
90 | */
91 | public function dependsOnNotEmpty($field)
92 | {
93 | return $this->withMeta([
94 | 'dependencies' => array_merge($this->meta['dependencies'], [
95 | array_merge($this->getFieldLayout($field), ['notEmpty' => true])
96 | ])
97 | ]);
98 | }
99 |
100 | /**
101 | * Adds a dependency for null or zero (0)
102 | *
103 | * @param $field
104 | * @param $value
105 | * @return $this
106 | */
107 | public function dependsOnNullOrZero($field)
108 | {
109 | return $this->withMeta([
110 | 'dependencies' => array_merge($this->meta['dependencies'], [
111 | array_merge($this->getFieldLayout($field), ['nullOrZero' => true])
112 | ])
113 | ]);
114 | }
115 |
116 | /**
117 | * Get layout for a specified field. Dot notation will result in {field}.{property}. If no dot was found it will
118 | * result in {field}.{field}, as it was in previous versions by default.
119 | *
120 | * @param $field
121 | * @param $value
122 | * @return array
123 | */
124 | protected function getFieldLayout($field, $value = null)
125 | {
126 | if (count( ($field = explode('.', $field)) ) === 1) {
127 | // backwards compatibility, property becomes field
128 | $field[1] = $field[0];
129 | }
130 | return [
131 | // literal form input name
132 | 'field' => $field[0],
133 | // property to compare
134 | 'property' => $field[1],
135 | // value to compare
136 | 'value' => $value,
137 | ];
138 | }
139 |
140 | /**
141 | * Resolve dependency fields for display
142 | *
143 | * @param mixed $resource
144 | * @param null $attribute
145 | */
146 | public function resolveForDisplay($resource, $attribute = null)
147 | {
148 | foreach ($this->meta['fields'] as $field) {
149 | $field->resolveForDisplay($resource);
150 | }
151 |
152 | foreach ($this->meta['dependencies'] as $index => $dependency) {
153 |
154 | $this->meta['dependencies'][$index]['satisfied'] = false;
155 |
156 | if (array_key_exists('empty', $dependency) && empty($resource->{$dependency['property']})) {
157 | $this->meta['dependencies'][$index]['satisfied'] = true;
158 | continue;
159 | }
160 | // inverted `empty()`
161 | if (array_key_exists('notEmpty', $dependency) && !empty($resource->{$dependency['property']})) {
162 | $this->meta['dependencies'][$index]['satisfied'] = true;
163 | continue;
164 | }
165 | // inverted
166 | if (array_key_exists('nullOrZero', $dependency) && in_array($resource->{$dependency['property']}, [null, 0, '0'], true)) {
167 | $this->meta['dependencies'][$index]['satisfied'] = true;
168 | continue;
169 | }
170 |
171 | if (array_key_exists('not', $dependency) && $resource->{$dependency['property']} != $dependency['not']) {
172 | $this->meta['dependencies'][$index]['satisfied'] = true;
173 | continue;
174 | }
175 |
176 | if (array_key_exists('value', $dependency)) {
177 | if (is_array($resource)) {
178 | if (isset($resource[$dependency['property']]) && $dependency['value'] == $resource[$dependency['property']]) {
179 | $this->meta['dependencies'][$index]['satisfied'] = true;
180 | }
181 | continue;
182 | } elseif ($dependency['value'] == $resource->{$dependency['property']}) {
183 | $this->meta['dependencies'][$index]['satisfied'] = true;
184 | continue;
185 | }
186 | // @todo: quickfix for MorphTo
187 | $morphable_attribute = $resource->getAttribute($dependency['property'].'_type');
188 | if ($morphable_attribute !== null && Str::endsWith($morphable_attribute, '\\'.$dependency['value'])) {
189 | $this->meta['dependencies'][$index]['satisfied'] = true;
190 | continue;
191 | }
192 | }
193 |
194 | }
195 | }
196 |
197 | /**
198 | * Resolve dependency fields
199 | *
200 | * @param mixed $resource
201 | * @param string $attribute
202 | * @return array|mixed
203 | */
204 | public function resolve($resource, $attribute = null)
205 | {
206 | foreach ($this->meta['fields'] as $field) {
207 | $field->resolve($resource, $attribute);
208 | }
209 | }
210 |
211 | /**
212 | * Forward fillInto request for each field in this container
213 | *
214 | * @trace fill/fillForAction -> fillInto -> *
215 | *
216 | * @param NovaRequest $request
217 | * @param $model
218 | * @param $attribute
219 | * @param null $requestAttribute
220 | */
221 | public function fillInto(NovaRequest $request, $model, $attribute, $requestAttribute = null)
222 | {
223 | foreach($this->meta['fields'] as $field) {
224 | $field->fill($request, $model);
225 | }
226 | }
227 |
228 | /**
229 | * Checks whether to add validation rules
230 | *
231 | * @param NovaRequest $request
232 | * @return bool
233 | */
234 | public function areDependenciesSatisfied(NovaRequest $request)
235 | {
236 | if (!isset($this->meta['dependencies'])
237 | || !is_array($this->meta['dependencies'])) {
238 | return false;
239 | }
240 |
241 | $satisfiedCounts = 0;
242 | foreach ($this->meta['dependencies'] as $index => $dependency) {
243 |
244 | if (array_key_exists('empty', $dependency) && empty($request->has($dependency['property']))) {
245 | $satisfiedCounts++;
246 | }
247 |
248 | if (array_key_exists('notEmpty', $dependency) && !empty($request->has($dependency['property']))) {
249 | $satisfiedCounts++;
250 | }
251 |
252 | // inverted
253 | if (array_key_exists('nullOrZero', $dependency) && in_array($request->get($dependency['property']), [null, 0, '0'], true)) {
254 | $satisfiedCounts++;
255 | }
256 |
257 | if (array_key_exists('not', $dependency) && $dependency['not'] != $request->get($dependency['property'])) {
258 | $satisfiedCounts++;
259 | }
260 |
261 | if (array_key_exists('value', $dependency) && $dependency['value'] == $request->get($dependency['property'])) {
262 | $satisfiedCounts++;
263 | }
264 | }
265 |
266 | return $satisfiedCounts == count($this->meta['dependencies']);
267 | }
268 |
269 | /**
270 | * Get a rule set based on field property name
271 | *
272 | * @param NovaRequest $request
273 | * @param string $propertyName
274 | * @return array
275 | */
276 | protected function getSituationalRulesSet(NovaRequest $request, string $propertyName = 'rules')
277 | {
278 | $fieldsRules = [$this->attribute => []];
279 | if (!$this->areDependenciesSatisfied($request)
280 | || !isset($this->meta['fields'])
281 | || !is_array($this->meta['fields'])) {
282 | return $fieldsRules;
283 | }
284 |
285 | /** @var Field $field */
286 | foreach ($this->meta['fields'] as $field) {
287 | $fieldsRules[$field->attribute] = is_callable($field->{$propertyName})
288 | ? call_user_func($field->{$propertyName}, $request)
289 | : $field->{$propertyName};
290 | }
291 |
292 | return $fieldsRules;
293 | }
294 |
295 | /**
296 | * Get the validation rules for this field.
297 | *
298 | * @param NovaRequest $request
299 | * @return array
300 | */
301 | public function getRules(NovaRequest $request)
302 | {
303 | return $this->getSituationalRulesSet($request);
304 | }
305 |
306 | /**
307 | * Get the creation rules for this field.
308 | *
309 | * @param NovaRequest $request
310 | * @return array|string
311 | */
312 | public function getCreationRules(NovaRequest $request)
313 | {
314 | $fieldsRules = $this->getSituationalRulesSet($request, 'creationRules');
315 |
316 | return array_merge_recursive(
317 | $this->getRules($request),
318 | $fieldsRules
319 | );
320 | }
321 |
322 | /**
323 | * Get the update rules for this field.
324 | *
325 | * @param NovaRequest $request
326 | * @return array
327 | */
328 | public function getUpdateRules(NovaRequest $request)
329 | {
330 | $fieldsRules = $this->getSituationalRulesSet($request, 'updateRules');
331 |
332 | return array_merge_recursive(
333 | $this->getRules($request),
334 | $fieldsRules
335 | );
336 | }
337 | }
338 |
--------------------------------------------------------------------------------
/webpack.mix.js:
--------------------------------------------------------------------------------
1 | let mix = require('laravel-mix')
2 |
3 | mix.js('resources/js/field.js', 'dist/js')
4 | .webpackConfig({
5 | resolve: {
6 | symlinks: false
7 | }
8 | })
9 |
--------------------------------------------------------------------------------