@@ -39,7 +39,7 @@ Description:
39
39
<q-menu context-menu >
40
40
<q-list color =" black" class =" menu" >
41
41
<q-item clickable v-ripple v-close-popup @click =" handleExportComponent" >
42
- <q-item-section class = " layer " style =" color : white "
42
+ <q-item-section style =" color : white "
43
43
>Export Component</q-item-section
44
44
>
45
45
<q-item-section avatar >
@@ -100,6 +100,7 @@ Description:
100
100
import { mapState , mapActions } from " vuex" ;
101
101
import VueDraggableResizable from " vue-draggable-resizable/src/components/vue-draggable-resizable.vue" ;
102
102
import " vue-draggable-resizable/src/components/vue-draggable-resizable.css" ;
103
+ const { fs , ipcRenderer } = window ;
103
104
104
105
const cloneDeep = require (" lodash.clonedeep" );
105
106
@@ -366,10 +367,215 @@ export default {
366
367
if (! (this .activeComponent === " " )) this .setActiveComponent (" " );
367
368
}
368
369
},
369
- // OVERVUE 6.0: if user right clicks on component, ability to export specific component
370
- handleExportComponent () {
371
-
370
+ showExportDialog () {
371
+ ipcRenderer
372
+ .invoke (" exportComponent" , {
373
+ title: " Choose location to save folder in" ,
374
+ message: " Choose location to save folder in" ,
375
+ nameFieldLabel: " Component Name" ,
376
+ })
377
+ .then ((result ) => this .exportFile (result .filePath ))
378
+ .catch ((err ) => console .log (err));
379
+ },
380
+ /**
381
+ * @description : creates component code <template>, <script>, <style>
382
+ * invokes writeTemplate, writeScript, writeStyle
383
+ */
384
+ createComponentCode (componentLocation , componentName , children ) {
385
+ console .log (" createComponentCode" , componentLocation, componentName, children);
386
+ fs .writeFileSync (
387
+ componentLocation + " .vue" ,
388
+ this .writeTemplate (componentName, children) +
389
+ this .writeScript (componentName, children) +
390
+ this .writeStyle (componentName)
391
+ );
392
+ },
393
+ writeTemplateTag (componentName ) {
394
+ console .log (" writeTemplateTag" , componentName);
395
+ // create reference object
396
+ const htmlElementMap = {
397
+ div: [" <div>" , " </div>" ],
398
+ button: [" <button>" , " </button>" ],
399
+ form: [" <form>" , " </form>" ],
400
+ img: [" <img>" , " " ],
401
+ link: [' <a href="#"/>' , " " ],
402
+ list: [" <li>" , " </li>" ],
403
+ paragraph: [" <p>" , " </p>" ],
404
+ " list-ol" : [" <ol>" , " </ol>" ],
405
+ " list-ul" : [" <ul>" , " </ul>" ],
406
+ input: [" <input />" , " " ],
407
+ navbar: [" <nav>" , " </nav>" ],
408
+ };
409
+ // function to loop through nested elements
410
+ function writeNested (childrenArray , indent ) {
411
+ console .log (" writeNested" , childrenArray, indent);
412
+ if (! childrenArray .length ) {
413
+ return " " ;
414
+ }
415
+ let indented = indent + " " ;
416
+ let nestedString = " " ;
417
+ childrenArray .forEach ((child ) => {
418
+ nestedString += indented;
419
+ if (! child .text ) {
420
+ nestedString += ` <${ child} />\n ` ;
421
+ } else {
422
+ if (child .children .length ) {
423
+ nestedString += htmlElementMap[child .text ][0 ];
424
+ nestedString += " \n " ;
425
+ nestedString += writeNested (child .children , indented);
426
+ nestedString += indented + htmlElementMap[child .text ][1 ];
427
+ nestedString += " \n " ;
428
+ } else {
429
+ nestedString +=
430
+ htmlElementMap[child .text ][0 ] +
431
+ htmlElementMap[child .text ][1 ] +
432
+ " \n " ;
433
+ }
434
+ }
435
+ });
436
+ return nestedString;
437
+ }
438
+ // iterate through component's htmllist
439
+ let htmlArr = this .componentMap [componentName].htmlList ;
440
+ let outputStr = ` ` ;
441
+ // eslint-disable-next-line no-unused-vars
442
+ for (let el of htmlArr) {
443
+ if (! el .text ) {
444
+ outputStr += ` <${ el} />\n ` ;
445
+ } else {
446
+ outputStr += ` ` ;
447
+ if (el .children .length ) {
448
+ outputStr += htmlElementMap[el .text ][0 ];
449
+ outputStr += " \n " ;
450
+ outputStr += writeNested (el .children , ` ` );
451
+ outputStr += ` ` ;
452
+ outputStr += htmlElementMap[el .text ][1 ];
453
+ outputStr += ` \n ` ;
454
+ } else {
455
+ outputStr +=
456
+ htmlElementMap[el .text ][0 ] + htmlElementMap[el .text ][1 ] + " \n " ;
457
+ }
458
+ }
459
+ }
460
+ return outputStr;
461
+ },
462
+ /**
463
+ * @description creates the <router-link> boilerplate for /views/components
464
+ * also creates the <template></template> tag for each component
465
+ */
466
+ writeTemplate (componentName , children ) {
467
+ console .log (" writeTemplate" , componentName, children);
468
+ let str = " " ;
469
+ str += ` <div>\n ` ;
470
+ // writes the HTML tag boilerplate
471
+ let templateTagStr = this .writeTemplateTag (componentName);
472
+ return ` <template>\n\t ${ str}${ templateTagStr} \t </div>\n </template>` ;
473
+ },
474
+ /**
475
+ * @description imports child components into <script>
476
+ */
477
+ writeScript (componentName , children ) {
478
+ console .log (" writeScript" , componentName, children)
479
+ // add import mapstate and mapactions if they exist
480
+ const currentComponent = this .componentMap [componentName];
481
+ let imports = " " ;
482
+ if (currentComponent .actions .length || currentComponent .state .length ) {
483
+ imports += " import { " ;
484
+ if (
485
+ currentComponent .actions .length &&
486
+ currentComponent .state .length
487
+ ) {
488
+ imports += " mapState, mapActions" ;
489
+ } else if (currentComponent .state .length ) imports += " mapState" ;
490
+ else imports += " mapActions" ;
491
+ imports += ' } from "vuex"\n ' ;
492
+ }
493
+ // add imports for children
494
+ children .forEach ((name ) => {
495
+ imports += ` import ${ name} from '@/components/${ name} .vue';\n ` ;
496
+ });
497
+ // add components section
372
498
499
+ // if true add data section and populate with props
500
+ let childrenComponentNames = " " ;
501
+ children .forEach ((name ) => {
502
+ childrenComponentNames += ` ${ name} ,\n ` ;
503
+ });
504
+ // if true add data section and populate with props
505
+ let data = " " ;
506
+ if (currentComponent .props .length ) {
507
+ data += " data () {\n return {" ;
508
+ currentComponent .props .forEach ((prop ) => {
509
+ data += ` \n ${ prop} : "PLACEHOLDER FOR VALUE",` ;
510
+ });
511
+ data += " \n " ;
512
+ data += " }\n " ;
513
+ data += " },\n " ;
514
+ }
515
+ // if true add computed section and populate with state
516
+ let computed = " " ;
517
+ if (currentComponent .state .length ) {
518
+ computed += " computed: {" ;
519
+ computed += " \n ...mapState([" ;
520
+ currentComponent .state .forEach ((state ) => {
521
+ computed += ` \n "${ state} ",` ;
522
+ });
523
+ computed += " \n ]),\n " ;
524
+ computed += " },\n " ;
525
+ }
526
+ // if true add methods section and populate with actions
527
+ let methods = " " ;
528
+ if (currentComponent .actions .length ) {
529
+ methods += " methods: {" ;
530
+ methods += " \n ...mapActions([" ;
531
+ currentComponent .actions .forEach ((action ) => {
532
+ methods += ` \n "${ action} ",` ;
533
+ });
534
+ methods += " \n ]),\n " ;
535
+ methods += " },\n " ;
536
+ }
537
+ // concat all code within script tags
538
+ let output = " \n\n <script>\n " ;
539
+ output +=
540
+ imports + " \n export default {\n name: '" + componentName + " '" ;
541
+ output += " ,\n components: {\n " ;
542
+ output += childrenComponentNames + " },\n " ;
543
+ output += data;
544
+ output += computed;
545
+ output += methods;
546
+ // eslint-disable-next-line no-useless-escape
547
+ output += " };\n <\/ script>" ;
548
+ return output;
549
+ },
550
+ /**
551
+ * @description writes the <style> in vue component
552
+ * if component is 'App', writes css, else returns <style scoped>
553
+ */
554
+ writeStyle (componentName ) {
555
+ console .log (" writeStyle" , componentName);
556
+ return ` \n\n <style scoped>\n </style>` ;
557
+ },
558
+
559
+ exportFile (data ) {
560
+ console .log (" exportFile" , data);
561
+ if (data === undefined ) return ;
562
+ if (! fs .existsSync (data)) {
563
+ fs .mkdirSync (data);
564
+ // console.log(`data: ${data}`); // displays the directory path
565
+ }
566
+ // main logic below for creating components
567
+ // eslint-disable-next-line no-unused-vars
568
+ // TO DO: need to update logic to only look at the component being exported and its children
569
+ this .createComponentCode (
570
+ path .join (data, this .activeComponent ),
571
+ this .activeComponent ,
572
+ this .componentMap [this .activeComponent ].children
573
+ );
574
+ },
575
+ // OVERVUE 6.0: if user right clicks on component, ability to export specific component
576
+ handleExportComponent (event ) {
577
+ console .log (" Export button clicked" );
578
+ this .showExportDialog ();
373
579
},
374
580
375
581
// event handler for copying (ctrl+C)
0 commit comments