diff options
Diffstat (limited to 'src/App.vue')
-rw-r--r-- | src/App.vue | 390 |
1 files changed, 199 insertions, 191 deletions
diff --git a/src/App.vue b/src/App.vue index 2509d77..a3ff23a 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,204 +1,212 @@ <template> <div id="issuetemplate" class="section"> - <h2 class="inlineblock">{{ t('issuetemplate', 'Issue reporting') }}</h2> - - <p> - For reporting potential security issues please see - <a href="https://nextcloud.com/security/">https://nextcloud.com/security/</a> - </p> - - <div> - - <form-wizard @on-complete="onComplete" - shape="tab" - color="#0082c9" - error-color="#a94442" - ref="wizard"> - <div slot="title"></div> - - - <tab-content title="Affected component" icon="icon-category-customization icon-invert" :before-change="validateAppSelect"> - <app-selector v-on:select="selectComponent"></app-selector> - </tab-content> - - <tab-content title="Issue description" icon="icon-user icon-invert" :before-change="validateIssueDescription"> - <vue-form-generator :model="model" :schema="firstTabSchema" :options="formOptions" ref="firstTabForm"></vue-form-generator> - </tab-content> - - <tab-content v-for="tab in tabs" v-if="model.component" :key="tab.identifier" :title="tab.title" icon="icon-settings icon-invert" :before-change="()=>validateDetails(tab)"> - <detail-section :app="getAppId()" :section="tab.identifier" :ref="tab.identifier" :model="model"></detail-section> - </tab-content> - - <tab-content title="Check issue report" icon="icon-checkmark icon-invert" v-if="tabs.length"> - <h4>Check your bug report before submitting it</h4> - <div class="panel-body"> - <p> - <strong>Please always check if the automatically filled out information is correct and there is nothing important missing, before reporting the issue.</strong> - </p> - - <p> - <strong>This report will be submitted to nextcloud/server</strong> - </p> - - <div id="preview" v-html="preview.rendered"> - + <h2 class="inlineblock"> + {{ t('issuetemplate', 'Issue reporting') }} + </h2> + + <p> + For reporting potential security issues please see + <a href="https://nextcloud.com/security/">https://nextcloud.com/security/</a> + </p> + + <div> + <form-wizard ref="wizard" + shape="tab" + color="#0082c9" + error-color="#a94442" + @on-complete="onComplete"> + <div slot="title" /> + + <tab-content title="Affected component" icon="icon-category-customization icon-invert" :before-change="validateAppSelect"> + <app-selector @select="selectComponent" /> + </tab-content> + + <tab-content title="Issue description" icon="icon-user icon-invert" :before-change="validateIssueDescription"> + <vue-form-generator ref="firstTabForm" + :model="model" + :schema="firstTabSchema" + :options="formOptions" /> + </tab-content> + + <tab-content v-for="tab in tabs" + v-show="model.component" + :key="tab.identifier" + :title="tab.title" + icon="icon-settings icon-invert" + :before-change="()=>validateDetails(tab)"> + <detail-section :ref="tab.identifier" + :app="getAppId()" + :section="tab.identifier" + :model="model" /> + </tab-content> + + <tab-content v-if="tabs.length" title="Check issue report" icon="icon-checkmark icon-invert"> + <h4>Check your bug report before submitting it</h4> + <div class="panel-body"> + <p> + <strong>Please always check if the automatically filled out information is correct and there is nothing important missing, before reporting the issue.</strong> + </p> + + <p> + <strong>This report will be submitted to nextcloud/server</strong> + </p> + + <div id="preview" v-html="preview.rendered" /> + <textarea id="preview" v-model="preview.markdown" /> </div> - <textarea id="preview" v-model="preview.markdown"> - - </textarea> - </div> - </tab-content> + </tab-content> - <template slot="footer" slot-scope="props"> - <div class="wizard-footer-left"> - <button v-if="props.activeTabIndex > 0 && !props.isLastStep" @click="props.prevTab()">Previous</button> - </div> - <div class="wizard-footer-right"> - <button v-if="!props.isLastStep" @click="props.nextTab()" class="primary">Next</button> - <button v-if="props.isLastStep" v-clipboard:copy="preview.markdown" class="">Copy issue text</button> - <button v-if="props.isLastStep && preview.markdown && preview.markdown.length<4096" @click="openIssue()" class="">Open a new issue</button> - </div> - </template> - - </form-wizard> - - - </div> + <template slot="footer" slot-scope="props"> + <div class="wizard-footer-left"> + <button v-if="props.activeTabIndex > 0 && !props.isLastStep" @click="props.prevTab()"> + Previous + </button> + </div> + <div class="wizard-footer-right"> + <button v-if="!props.isLastStep" class="primary" @click="props.nextTab()"> + Next + </button> + <button v-if="props.isLastStep" v-clipboard:copy="preview.markdown" class=""> + Copy issue text + </button> + <button v-if="props.isLastStep && preview.markdown && preview.markdown.length<4096" class="" @click="openIssue()"> + Open a new issue + </button> + </div> + </template> + </form-wizard> + </div> </div> </template> <script> - import AppSelector from './components/appselector.vue'; - import DetailSection from './components/detailsection.vue'; - import VueFormGenerator from 'vue-form-generator'; - - export default { - name: 'App', - components: { - 'app-selector': AppSelector, - 'detail-section': DetailSection, +import axios from '@nextcloud/axios' +import { generateUrl } from '@nextcloud/router' +import VueFormGenerator from 'vue-form-generator' + +import AppSelector from './components/AppSelector.vue' +import DetailSection from './components/DetailSection.vue' + +export default { + name: 'App', + components: { + 'app-selector': AppSelector, + 'detail-section': DetailSection, + }, + data() { + return { + color: '#aaaaaa', + tabs: [], + model: {}, + preview: {}, + formOptions: { + validationErrorClass: 'has-error', + validationSuccessClass: 'has-success', + validateAfterChanged: true, + }, + firstTabSchema: { + fields: [ + { + type: 'input', + inputType: 'text', + label: 'Issue title', + model: 'title', + // required: true, + validator: VueFormGenerator.validators.string, + styleClasses: 'col-sm-12', + }, + { + type: 'textArea', + inputType: 'text', + label: 'Steps to reproduce', + model: 'stepsToReproduce', + required: true, + validator: VueFormGenerator.validators.string, + styleClasses: 'col-sm-12', + }, + { + type: 'textArea', + inputType: 'text', + label: 'Expected behaviour', + model: 'expectedBehaviour', + required: true, + validator: VueFormGenerator.validators.string, + styleClasses: 'col-sm-6', + }, + { + type: 'textArea', + inputType: 'text', + label: 'Actual behaviour', + model: 'actualBehaviour', + required: true, + validator: VueFormGenerator.validators.string, + styleClasses: 'col-sm-6', + }, + ], + }, + } + }, + mounted() { + this.resetWizard() + }, + methods: { + async updateSections() { + this.tabs = [] + try { + const { data } = await axios.get(generateUrl('/apps/issuetemplate/sections/' + this.getAppId())) + this.tabs = data + } catch (e) { + console.error(e) + this.tabs = [] + } + }, + getAppId() { + if (this.model.component !== null) { + return this.model.component.id + } + return null }, - mounted: function () { - this.resetWizard(); + selectComponent(component) { + this.model.component = component + this.updateSections() + this.$refs.wizard.nextTab() }, - data() { - return { - color: '#aaaaaa', - tabs: [], - model: {}, - preview: {}, - formOptions: { - validationErrorClass: "has-error", - validationSuccessClass: "has-success", - validateAfterChanged: true - }, - firstTabSchema: { - fields: [ - { - type: "input", - inputType: "text", - label: "Issue title", - model: "title", - //required: true, - validator: VueFormGenerator.validators.string, - styleClasses: 'col-sm-12' - }, - { - type: "textArea", - inputType: "text", - label: "Steps to reproduce", - model: "stepsToReproduce", - required: true, - validator: VueFormGenerator.validators.string, - styleClasses: 'col-sm-12' - }, - { - type: "textArea", - inputType: "text", - label: "Expected behaviour", - model: "expectedBehaviour", - required: true, - validator: VueFormGenerator.validators.string, - styleClasses: 'col-sm-6' - }, - { - type: "textArea", - inputType: "text", - label: "Actual behaviour", - model: "actualBehaviour", - required: true, - validator: VueFormGenerator.validators.string, - styleClasses: 'col-sm-6' - } - ] - } + onComplete() { + this.resetWizard() + }, + resetWizard() { + this.model = { + component: null, + title: '', + stepsToReproduce: '', + expectedBehaviour: '', + actualBehaviour: '', + details: {}, } }, - methods: { - updateSections: function () { - var self = this; - self.tabs = []; - $.ajax({ - url: OC.generateUrl('/apps/issuetemplate/sections/' + this.getAppId()), - method: 'GET', - success: function (data) { - self.tabs = data; - }, - error: function (error) { - self.tabs = []; - } - }); - }, - getAppId: function () { - if (this.model.component !== null) { - return this.model.component.id; - } - return null; - }, - selectComponent: function (component) { - this.model.component = component; - this.updateSections(); - this.$refs.wizard.nextTab(); - }, - onComplete: function(){ - this.resetWizard(); - }, - resetWizard: function() { - this.model = { - component: null, - title: '', - stepsToReproduce: '', - expectedBehaviour: '', - actualBehaviour: '', - details: {} - }; - }, - validateAppSelect: function() { - return this.getAppId() !== null; - }, - validateIssueDescription: function(){ - return this.$refs.firstTabForm.validate(); - }, - validateDetails: function(tab){ - var self = this; - var updates = this.$refs[tab.identifier][0].fetchUpdates(); - if (updates === false) { - return false; - } - this.model.details[tab.identifier] = updates[tab.identifier]; - $.ajax({ - url: OC.generateUrl('/apps/issuetemplate/render'), - data: this.model, - method: 'POST', - success: function (data) { - self.preview = data; - } - }); - return true; - }, - openIssue: function() { - var urlComplete = this.model.component.bugs + "/new/?title=" + encodeURIComponent(this.model.title) + "&body=" + encodeURIComponent(this.preview.markdown); - window.open(urlComplete); + validateAppSelect() { + return this.getAppId() !== null + }, + validateIssueDescription() { + return this.$refs.firstTabForm.validate() + }, + async validateDetails(tab) { + const updates = this.$refs[tab.identifier][0].fetchUpdates() + if (updates === false) { + return false } - } - } + this.model.details[tab.identifier] = updates[tab.identifier] + try { + const { data } = await axios.post(generateUrl('/apps/issuetemplate/render'), this.model) + this.preview = data + } catch (e) { + console.error(e) + } + return true + }, + openIssue() { + const urlComplete = this.model.component.bugs + '/new/?title=' + encodeURIComponent(this.model.title) + '&body=' + encodeURIComponent(this.preview.markdown) + window.open(urlComplete) + }, + }, +} </script> |