5454 </card >
5555
5656 <card class =" p-8 space-y-4" >
57- <p v-if =" resource" >
58- Choose which data to fill the appropriate fields of the chosen resource. The columns from your uploaded
59- file have been auto-matched to the resource fields with the same name.
60- </p >
57+ <template v-if =" resource " >
58+ <p >
59+ Choose which data to fill the appropriate fields of the chosen resource. The columns from your uploaded
60+ file have been auto-matched to the resource fields with the same name.
61+ </p >
62+
63+ <p v-if =" resource" >
64+ Use modifiers to modify the value <i >before</i > it gets saved to your resource. Modifiers are combinatory
65+ meaning you can stack them together to do weird and wonderful things with your data
66+ (remember what Uncle Ben said, though!) They are executed in the order defined.
67+ </p >
68+
69+ <p >
70+ <b >TIP</b >: You can drag and drop modifiers to re-order them.
71+ </p >
6172
62- <table cellpadding =" 10" v-if =" resource" >
63- <thead class =" border-b" >
64- <tr >
65- <th >Field</th >
66- <th >Value</th >
67- <!-- <th>Modifier</th> -->
68- </tr >
69- </thead >
70- <tbody >
71- <tr v-for =" field in fields[resource]" >
72- <td class =" pr-2" >
73- <span class =" font-bold" >{{ field.name }}</span ><br >
74- <small class =" text-grey-300" >{{ field.attribute }}</small >
75- </td >
76- <td class =" md:flex" >
77- <SelectControl @change =" (value) => mappings[field.attribute] = value" :selected =" mappings[field.attribute]" >
78- <option value =" " v-if =" field.rules.includes('required')" disabled >- This field is required -</option >
79- <option value =" " v-else >- Leave field empty -</option >
80-
81- <optgroup label =" File columns" >
82- <option v-for =" heading in headings" :value =" heading" >{{ heading }}</option >
83- </optgroup >
84-
85- <optgroup label =" Meta data" >
86- <option value =" meta.file" >File name (with suffix): {{ file }}</option >
87- <option value =" meta.file_name" >File name (without suffix): {{ file_name }}</option >
88- <option value =" meta.original_file" >Original file name (with suffix): {{ config.original_filename }}</option >
89- <option value =" meta.original_file_name" >Original file name (without suffix): {{ original_file_name }}</option >
90- </optgroup >
91-
92- <optgroup label =" Custom" >
93- <option value =" custom" >Single value</option >
94- </optgroup >
95- </SelectControl >
96-
97- <input v-model =" values[field.attribute]" v-if =" mappings[field.attribute] === 'custom'"
98- class =" form-control form-input form-input-bordered ml-4" >
99- </td >
100- </tr >
101- </tbody >
102- </table >
73+ <table cellpadding =" 10" >
74+ <thead class =" border-b" >
75+ <tr >
76+ <th >Field</th >
77+ <th >Value</th >
78+ </tr >
79+ </thead >
80+ <tbody >
81+ <tr v-for =" field in fields[resource]" >
82+ <td class =" pr-2" >
83+ <span class =" font-bold" >{{ field.name }}</span ><br >
84+ <small class =" text-grey-300" >{{ field.attribute }}</small >
85+ </td >
86+ <td class =" space-y-2" >
87+ <SelectControl @change =" (value) => mappings[field.attribute] = value" :selected =" mappings[field.attribute]" >
88+ <option value =" " v-if =" field.rules.includes('required')" disabled >- This field is required -</option >
89+ <option value =" " v-else >- Leave field empty -</option >
90+
91+ <optgroup label =" File columns" >
92+ <option v-for =" heading in headings" :value =" heading" >{{ heading }}</option >
93+ </optgroup >
94+
95+ <optgroup label =" Meta data" >
96+ <option value =" meta.file" >File name (with suffix): {{ file }}</option >
97+ <option value =" meta.file_name" >File name (without suffix): {{ file_name }}</option >
98+ <option value =" meta.original_file" >Original file name (with suffix): {{ config.original_filename }}</option >
99+ <option value =" meta.original_file_name" >Original file name (without suffix): {{ original_file_name }}</option >
100+ </optgroup >
101+
102+ <optgroup label =" Custom" >
103+ <option value =" custom" >Single value</option >
104+ </optgroup >
105+ </SelectControl >
106+
107+ <input v-model =" values[field.attribute]" v-if =" mappings[field.attribute] === 'custom'"
108+ class =" form-control form-input form-input-bordered" >
109+
110+ <draggable
111+ v-model =" modifiers[field.attribute]"
112+ handle =" .handle"
113+ item-key =" modifier" >
114+
115+ <template #item =" { element , index } " >
116+ <div class =" flex mb-2 space-x-2 items-start border-rounded bg-gray-50 p-2 handle" >
117+ <span >{{ index + 1 }}</span >
118+ <div class =" flex flex-col flex-1 space-y-2" >
119+ <SelectControl @change =" (value) => element.name = value" :selected =" element.name" >
120+ <option value =" " >- Do not modify -</option >
121+
122+ <option v-for =" mod in mods" :value =" mod.name" >{{ mod.title }}</option >
123+ </SelectControl >
124+
125+ <label v-for =" (config, name) in mods[element.name].settings"
126+ v-if =" mods[element.name]?.settings" class =" flex items-center space-x-2"
127+ >
128+ <span >{{ config.title }}</span >
129+
130+ <SelectControl v-if =" config.type === 'select'"
131+ @change =" (value) => element.settings[name] = value"
132+ :selected =" element.settings[name]"
133+ >
134+ <option v-for =" (option, value) of config.options" :value =" value"
135+ :selected =" value === config.default"
136+ >
137+ {{ option }}
138+ </option >
139+ </SelectControl >
140+
141+ <input type =" text" v-if =" config.type === 'string'" v-model =" element.settings[name]"
142+ class =" form-control form-input form-input-bordered ml-4" :placeholder =" config.default" >
143+
144+ <input type =" text" v-if =" config.type === 'boolean'" v-model =" element.settings[name]"
145+ class =" checkbox" :checked =" config.default" >
146+
147+ <div class =" help-text" >{{ config.help }}</div >
148+ </label >
149+ </div >
150+ <button @click =" removeModifier(field.attribute, index)" >× ; </button >
151+ </div >
152+ </template >
153+ </draggable >
154+
155+ <button @click =" addModifier(field.attribute)" v-if =" mappings[field.attribute]"
156+ class =" cursor-pointer rounded text-sm font-bold focus:outline-none focus:ring h-7 px-1 md:px-3"
157+ >
158+ Add modifier
159+ </button >
160+ </td >
161+ </tr >
162+ </tbody >
163+ </table >
164+ </template >
103165
104166 <div class =" flex justify-center space-x-2" >
105167 <LinkButton @click =" goBack" >
114176</template >
115177
116178<script >
179+ import draggable from ' vuedraggable'
180+
117181export default {
182+ components: {
183+ draggable,
184+ },
118185
119186 data () {
120187 return {
121188 resource: this .config ? .resource || ' ' ,
122189 mappings: this .config ? .mappings || {},
123190 values: this .config ? .values || {},
191+ modifiers: this .config ? .modifiers || {},
124192 saving: false ,
125193 };
126194 },
@@ -134,6 +202,7 @@ export default {
134202 ' rows' ,
135203 ' total_rows' ,
136204 ' config' ,
205+ ' mods' ,
137206 ],
138207
139208 watch: {
@@ -176,6 +245,10 @@ export default {
176245 },
177246
178247 methods: {
248+ removeModifier (attribute , index ) {
249+ this .modifiers [attribute].splice (index, 1 );
250+ },
251+
179252 saveConfig () {
180253 if (! this .hasValidConfiguration ()) {
181254 return ;
@@ -187,6 +260,7 @@ export default {
187260 resource: this .resource ,
188261 mappings: this .mappings ,
189262 values: this .values ,
263+ modifiers: this .modifiers ,
190264 file: this .file ,
191265 };
192266
@@ -223,9 +297,18 @@ export default {
223297 return this .resource !== ' ' && mappedColumns .length > 0 ;
224298 },
225299
226- url : function (path ) {
300+ url (path ) {
227301 return ' /nova-vendor/laravel-nova-csv-import/' + path;
228- }
302+ },
303+
304+ addModifier (attribute ) {
305+ if (Array .isArray (this .modifiers [attribute])) {
306+ this .modifiers [attribute].push ({name: ' ' , settings: {}});
307+ return ;
308+ }
309+
310+ this .modifiers [attribute] = [{name: ' ' , settings: {}}];
311+ },
229312 },
230313
231314 computed: {
0 commit comments