Add global tools section & export data generator
							parent
							
								
									431cbf53e2
								
							
						
					
					
						commit
						e7e9cbcfa2
					
				|  | @ -144,6 +144,18 @@ $highlight: #f2c94c; | |||
|       } | ||||
|     } | ||||
| 
 | ||||
|     &.is-grouped { | ||||
|       > .control { | ||||
|         &:last-child { | ||||
|           margin: .25rem 0 0; | ||||
|         } | ||||
| 
 | ||||
|         &:not(:last-child) { | ||||
|           margin: .25rem .75rem 0 0; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     .is-changed { | ||||
|       input { | ||||
|         &:not(.vs__search) { | ||||
|  | @ -208,6 +220,18 @@ $highlight: #f2c94c; | |||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .field-body { | ||||
|     &.is-vertical { | ||||
|       flex-direction: column; | ||||
| 
 | ||||
|       > .field { | ||||
|         &:not(:last-child) { | ||||
|           margin-bottom: .75rem; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .checkbox, | ||||
|   .radio { | ||||
|     border-radius: $border-radius; | ||||
|  |  | |||
|  | @ -53,7 +53,7 @@ limitations under the License. | |||
|             <h2>Global config</h2> | ||||
|             <Global :data="global"></Global> | ||||
| 
 | ||||
|             <pre><code>{{ JSON.stringify({ domains: activeDomains, global }, null, 2) }}</code></pre> | ||||
|             <pre><code>{{ exportData }}</code></pre> | ||||
|         </div> | ||||
| 
 | ||||
|         <Footer :text="i18n.templates.app.oss"></Footer> | ||||
|  | @ -65,6 +65,7 @@ limitations under the License. | |||
|     import Header from 'do-vue/src/templates/header'; | ||||
|     import Footer from 'do-vue/src/templates/footer'; | ||||
|     import isChanged from '../util/is_changed'; | ||||
|     import exportData from '../util/export_data'; | ||||
|     import i18n from '../i18n'; | ||||
|     import Domain from './domain'; | ||||
|     import Global from './global'; | ||||
|  | @ -91,6 +92,9 @@ limitations under the License. | |||
|             activeDomains() { | ||||
|                 return this.$data.domains.map((domain, index) => [domain, index]).filter(d => d[0] !== null); | ||||
|             }, | ||||
|             exportData() { | ||||
|                 return JSON.stringify(exportData(this.activeDomains, this.$data.global), null, 2); | ||||
|             }, | ||||
|         }, | ||||
|         methods: { | ||||
|             changes(index) { | ||||
|  |  | |||
|  | @ -5,3 +5,4 @@ export { default as Python } from './python'; | |||
| export { default as Performance } from './performance'; | ||||
| export { default as Logging } from './logging'; | ||||
| export { default as NGINX } from './nginx'; | ||||
| export { default as Tools } from './tools'; | ||||
|  |  | |||
|  | @ -0,0 +1,192 @@ | |||
| <template> | ||||
|     <div> | ||||
|         <div class="field is-horizontal"> | ||||
|             <div class="field-label"> | ||||
|                 <label class="label">Modularized structure</label> | ||||
|             </div> | ||||
|             <div class="field-body"> | ||||
|                 <div class="field"> | ||||
|                     <div :class="`control${modularizedStructureChanged ? ' is-changed' : ''}`"> | ||||
|                         <div class="checkbox"> | ||||
|                             <PrettyCheck v-model="modularizedStructure" class="p-default p-curve p-fill p-icon"> | ||||
|                                 <i slot="extra" class="icon fas fa-check"></i> | ||||
|                                 enable modularized config files | ||||
|                             </PrettyCheck> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="field is-horizontal"> | ||||
|             <div class="field-label"> | ||||
|                 <label class="label">Symlink vhost</label> | ||||
|             </div> | ||||
|             <div class="field-body"> | ||||
|                 <div class="field"> | ||||
|                     <div :class="`control${symlinkVhostChanged ? ' is-changed' : ''}`"> | ||||
|                         <div class="checkbox"> | ||||
|                             <PrettyCheck v-model="symlinkVhost" class="p-default p-curve p-fill p-icon"> | ||||
|                                 <i slot="extra" class="icon fas fa-check"></i> | ||||
|                                 enable symlink from sites-available/ to sites-enabled/ | ||||
|                             </PrettyCheck> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="field is-horizontal"> | ||||
|             <div class="field-label"> | ||||
|                 <label class="label">Share configuration</label> | ||||
|             </div> | ||||
|             <div class="field-body"> | ||||
|                 <div class="field"> | ||||
|                     <div class="control"> | ||||
|                         <input v-model="shareLink" | ||||
|                                class="input" | ||||
|                                type="text" | ||||
|                                disabled="disabled" | ||||
|                         /> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="field is-horizontal"> | ||||
|             <div class="field-label"> | ||||
|                 <label class="label">Reset configuration</label> | ||||
|             </div> | ||||
|             <div class="field-body"> | ||||
|                 <div class="field is-grouped"> | ||||
|                     <div class="control"> | ||||
|                         <a class="button is-danger is-mini" @click="resetGlobal"> | ||||
|                             Reset global config | ||||
|                         </a> | ||||
|                     </div> | ||||
|                     <div v-if="hasDomain" class="control"> | ||||
|                         <a class="button is-danger is-mini" @click="resetDomains"> | ||||
|                             Reset all domains | ||||
|                         </a> | ||||
|                     </div> | ||||
|                     <div v-if="hasDomain" class="control"> | ||||
|                         <a class="button is-danger is-mini" @click="removeDomains"> | ||||
|                             Remove all domains | ||||
|                         </a> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="field is-horizontal"> | ||||
|             <div class="field-label"> | ||||
|             </div> | ||||
|             <div class="field-body is-vertical"> | ||||
|                 <div v-for="domainData in $parent.$parent.activeDomains" class="field is-horizontal"> | ||||
|                     <div class="field-label"> | ||||
|                         <label class="label">{{ domainData[0].server.domain.computed }}</label> | ||||
|                     </div> | ||||
|                     <div class="field-body"> | ||||
|                         <div class="field is-grouped"> | ||||
|                             <div class="control"> | ||||
|                                 <a class="button is-danger is-mini" @click="resetDomain(domainData[1])"> | ||||
|                                     Reset domain config | ||||
|                                 </a> | ||||
|                             </div> | ||||
|                             <div class="control"> | ||||
|                                 <a class="button is-danger is-mini" @click="removeDomain(domainData[1])"> | ||||
|                                     Remove domain | ||||
|                                 </a> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
|     import PrettyCheck from 'pretty-checkbox-vue/check'; | ||||
|     import i18n from '../../i18n'; | ||||
|     import delegatedFromDefaults from '../../util/delegated_from_defaults'; | ||||
|     import computedFromDefaults from '../../util/computed_from_defaults'; | ||||
|     import exportData from '../../util/export_data'; | ||||
| 
 | ||||
|     const defaults = { | ||||
|         modularizedStructure: { | ||||
|             default: true, | ||||
|             enabled: true, | ||||
|         }, | ||||
|         symlinkVhost: { | ||||
|             default: true, | ||||
|             enabled: true, | ||||
|         }, | ||||
|     }; | ||||
| 
 | ||||
|     export default { | ||||
|         name: 'GlobalTools',                            // Component name | ||||
|         display: 'Tools',                               // Display name for tab | ||||
|         key: 'tools',                                   // Key for data in parent | ||||
|         delegated: delegatedFromDefaults(defaults),     // Data the parent will present here | ||||
|         components: { | ||||
|             PrettyCheck, | ||||
|         }, | ||||
|         props: { | ||||
|             data: Object,                               // Data delegated back to us from parent | ||||
|         }, | ||||
|         data () { | ||||
|             return { | ||||
|                 i18n, | ||||
|             }; | ||||
|         }, | ||||
|         computed: { | ||||
|             ...computedFromDefaults(defaults, 'tools'), // Getters & setters for the delegated data | ||||
|             hasDomain() { | ||||
|                 return this.$parent.$parent.activeDomains.length > 0; | ||||
|             }, | ||||
|             shareLink() { | ||||
|                 return JSON.stringify(exportData(this.$parent.$parent.activeDomains, this.$parent.$props.data)); | ||||
|             }, | ||||
|         }, | ||||
|         methods: { | ||||
|             // TODO: These all need confirmation prompts! | ||||
|             resetGlobal() { | ||||
|                 Object.values(this.$parent.$props.data).forEach(category => { | ||||
|                     Object.values(category).forEach(property => { | ||||
|                         property.value = property.default; | ||||
|                         property.computed = property.default; | ||||
|                     }); | ||||
|                 }); | ||||
|             }, | ||||
|             resetDomain(index) { | ||||
|                 if (index >= this.$parent.$parent.$data.domains.length) return; | ||||
| 
 | ||||
|                 const domain = this.$parent.$parent.$data.domains[index]; | ||||
|                 if (!domain) return; | ||||
| 
 | ||||
|                 Object.values(domain).forEach(category => { | ||||
|                     Object.values(category).forEach(property => { | ||||
|                         property.value = property.default; | ||||
|                         property.computed = property.default; | ||||
|                     }); | ||||
|                 }); | ||||
|             }, | ||||
|             removeDomain(index) { | ||||
|                 if (index >= this.$parent.$parent.$data.domains.length) return; | ||||
| 
 | ||||
|                 this.$set(this.$parent.$parent.$data.domains, index, null); | ||||
|             }, | ||||
|             resetDomains() { | ||||
|                 for (let i = 0; i < this.$parent.$parent.$data.domains.length; i++) { | ||||
|                     this.resetDomain(i); | ||||
|                 } | ||||
|             }, | ||||
|             removeDomains() { | ||||
|                 for (let i = 0; i < this.$parent.$parent.$data.domains.length; i++) { | ||||
|                     this.removeDomain(i); | ||||
|                 } | ||||
|             }, | ||||
|         }, | ||||
|     }; | ||||
| </script> | ||||
|  | @ -0,0 +1,42 @@ | |||
| const categoriesExport = (categories) => { | ||||
|     const categoriesData = {}; | ||||
| 
 | ||||
|     // Work through each category
 | ||||
|     for (const category in categories) { | ||||
|         const categoryData = {}; | ||||
| 
 | ||||
|         // Go over each property in the category
 | ||||
|         for (const property in categories[category]) { | ||||
| 
 | ||||
|             // If the user input differs from the default, they changed it, so we save it
 | ||||
|             const propertyData = categories[category][property]; | ||||
|             if (propertyData.value !== propertyData.default) { | ||||
|                 categoryData[property] = propertyData.value; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // If there were any property changes, save the category
 | ||||
|         if (Object.keys(categoryData).length) { | ||||
|             categoriesData[category] = categoryData; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return categoriesData; | ||||
| }; | ||||
| 
 | ||||
| export default (domains, global) => { | ||||
|     const exportData = {}; | ||||
| 
 | ||||
|     // Handle domains
 | ||||
|     // Always save changes, even if none, so we can replicate the correct number of domains
 | ||||
|     exportData.domains = domains.map(domain => categoriesExport(domain[0])); | ||||
| 
 | ||||
|     // Handle global
 | ||||
|     // If there were any category changes, save global changes
 | ||||
|     const globalData = categoriesExport(global); | ||||
|     if (Object.keys(globalData).length) { | ||||
|         exportData.global = globalData; | ||||
|     } | ||||
| 
 | ||||
|     return exportData; | ||||
| }; | ||||
		Loading…
	
		Reference in New Issue
	
	 MattIPv4
						MattIPv4