From 139bf0ddcc124e7a08b45dc1e6e1818f3278ce0c Mon Sep 17 00:00:00 2001 From: Steffen Giers Date: Fri, 17 Jan 2020 13:54:50 +0100 Subject: [PATCH] feat: add reporter section Closes #13 --- README.md | 26 +++++++++++++++++----- index.css | 2 +- index.js | 2 +- index.php | 4 ++++ src/components/SectionView.vue | 40 ++++++++++++++++++++++++++++++++++ src/index.js | 4 ++++ 6 files changed, 71 insertions(+), 7 deletions(-) create mode 100755 src/components/SectionView.vue diff --git a/README.md b/README.md index 853423c..f436350 100755 --- a/README.md +++ b/README.md @@ -20,9 +20,8 @@ Kirby Reporter helps to report *bugs*, *tasks* or *features* to your desired iss ## Installation -After you've installed and configured this plugin correctly, open the panel menu and click the newly available menu entry: - -⚡ New Issue +After you've installed and configured this plugin correctly, open the panel menu and click the newly available menu entry `New Issue`. You can add also add a [section](#section) +to any blueprint. ### Composer @@ -100,11 +99,28 @@ reporter: help: Please be as precise as possible. ``` +You can add any fields you want but you need to adapt the issue template in order to see the fields in your preview. + +### Section + +This plugin provides also a `section` which can be used like any other section in your blueprints. You can learn about adding sections from the [Kirby Docs](https://getkirby.com/docs/guide/blueprints/layout#adding-sections). + +This is a very handy way to collect feedback from anywhere in your panel. + +``` +# site.yml +sections: + reporter: + type: reporter + headline: Report issue + description: My custom description +``` + ### Customizing the Issue Template Create a file named `reporter.php` and save it to `/site/templates/reporter.php`. -Within the template you have access to an array which contains all submitted fields. Each field consists the `key` and the selected `value`. +Within the template you have access to an array of all available fields. Each field consists the `key` and the selected `value`. ```php /** @var array $fields */ @@ -117,7 +133,7 @@ You can and do whatever you want to adapt the output to your needs using `php`. #### Preview -You can use the preview tab to make sure your template is formatted properly. +You can use the preview tab to make sure your template is formatted properly. The preview is rendered using your issue template. #### Default Template diff --git a/index.css b/index.css index 201b707..1af5088 100644 --- a/index.css +++ b/index.css @@ -1 +1 @@ -@keyframes spin{to{transform:rotate(1turn)}}.k-line-field{margin:2rem 0 1rem}.k-kit-form{padding:2rem;margin-top:2rem;margin-bottom:2rem;border:1px solid rgba(0,0,0,.1);background:#fafafa}.k-kit-form .title-field{margin-bottom:2.25rem}.k-kit-form .k-input[data-theme=field][data-invalid]{border:1px solid #ccc;box-shadow:none}.k-kit-form .k-input[data-theme=field][data-invalid]:focus-within{border:1px solid #4271ae;box-shadow:0 0 0 2px rgba(66,113,174,.25)}.k-kit-form textarea{min-height:120px}.k-kit-form--note[data-theme]{margin-bottom:1rem;padding-left:3rem;position:relative}.k-kit-form--note[data-theme] a{border-bottom:1px solid rgba(0,0,0,.3)}.k-kit-form--note[data-theme] .k-icon{position:absolute;margin-left:-2rem;height:100%;top:0}.k-kit-form .k-button .k-icon-loader{animation:spin .8s linear infinite}.k-kit-form .issue-link{margin-left:auto}.vue-tablist{border-bottom:1px solid #ccc;display:flex;margin-bottom:1.25rem}.vue-tab{display:block;cursor:pointer;padding:.7rem 1rem .5rem;color:#737578;position:relative;margin-bottom:-1px}.vue-tab[aria-selected=true]{color:#16171a;background:#fafafa;border-bottom:0}.vue-tab[aria-selected=true]:after{position:absolute;content:"";left:0;top:0;width:100%;height:100%;border-radius:4px 4px 0 0;border:1px solid #ccc;border-bottom:0} \ No newline at end of file +@keyframes spin{to{transform:rotate(1turn)}}.k-line-field{margin:2rem 0 1rem}.k-kit-form{padding:2rem;margin-top:2rem;margin-bottom:2rem;border:1px solid rgba(0,0,0,.1);background:#fafafa}.k-kit-form .title-field{margin-bottom:2.25rem}.k-kit-form .k-input[data-theme=field][data-invalid]{border:1px solid #ccc;box-shadow:none}.k-kit-form .k-input[data-theme=field][data-invalid]:focus-within{border:1px solid #4271ae;box-shadow:0 0 0 2px rgba(66,113,174,.25)}.k-kit-form textarea{min-height:120px}.k-kit-form--note[data-theme]{margin-bottom:1rem;padding-left:3rem;position:relative}.k-kit-form--note[data-theme] a{border-bottom:1px solid rgba(0,0,0,.3)}.k-kit-form--note[data-theme] .k-icon{position:absolute;margin-left:-2rem;height:100%;top:0}.k-kit-form .k-button .k-icon-loader{animation:spin .8s linear infinite}.k-kit-form .issue-link{margin-left:auto}.vue-tablist{border-bottom:1px solid #ccc;display:flex;margin-bottom:1.25rem}.vue-tab{display:block;cursor:pointer;padding:.7rem 1rem .5rem;color:#737578;position:relative;margin-bottom:-1px}.vue-tab[aria-selected=true]{color:#16171a;background:#fafafa;border-bottom:0}.vue-tab[aria-selected=true]:after{position:absolute;content:"";left:0;top:0;width:100%;height:100%;border-radius:4px 4px 0 0;border:1px solid #ccc;border-bottom:0}.k-section-name-reporter .k-kit-form{margin-top:0;padding:1.5rem} \ No newline at end of file diff --git a/index.js b/index.js index edb9879..b9ca531 100644 --- a/index.js +++ b/index.js @@ -1 +1 @@ -(function () {var a={};Object.defineProperty(a,"__esModule",{value:!0});var e={name:"tabs",props:{defaultIndex:{default:0,type:Number},onSelect:{type:Function}},data:function(){return{selectedIndex:this.defaultIndex}},methods:{switchTab:function(t,e,a){a||(this.selectedIndex=e,this.onSelect&&this.onSelect(t,e))}},render:function(){var t=this,e=arguments[0],a=this.$slots.default.filter(function(t){return t.componentOptions}),s=[];return a.forEach(function(a,r){var $=a.componentOptions.propsData,l=$.title,n=$.titleSlot,o=$.disabled,i=n?t.$slots[n]:l,f=!0===o||""===o;s.push(e("li",{class:"vue-tab",attrs:{role:"tab","aria-selected":t.selectedIndex===r?"true":"false","aria-disabled":f?"true":"false"},on:{click:function(e){return t.switchTab(e,r,f)}}},[i]))}),e("div",{class:"vue-tabs",attrs:{role:"tabs"}},[e("ul",{class:"vue-tablist",attrs:{role:"tablist"}},[this.$slots.left,s,this.$slots.right]),a[this.selectedIndex]])}},f={name:"tab",props:["title","titleSlot","disabled"],render:function(){return(0,arguments[0])("div",{class:"vue-tabpanel",attrs:{role:"tabpanel"}},[this.$slots.default])}};function i(t){t.component(e.name,e),t.component(f.name,f)}var g=e;a.Tabs=g;var h=f;a.Tab=h;var j=i;a.install=j;var b={name:"IssuePreview",props:{data:String}};if(typeof b==="function"){b=b.options}Object.assign(b,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _vm.data?_c("k-textarea-field",{attrs:{"label":"Preview","value":_vm.data,"buttons":false,"disabled":""}}):_c("k-text",[_vm._v(_vm._s(_vm.$t("reporter.tab.preview.empty")))])};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());var c={name:"IssueForm",components:{IssuePreview:b,Tabs:g,Tab:h},props:{fields:{type:Object},previewData:{type:String}},computed:{hasResponse(){return Object.keys(this.response).length>1},buttonIcon(){return this.loading?"loader":"check"},successMessage(){return this.$t("reporter.form.success",{issueLink:this.issueLink})},issueLink(){const e=this.response.issueUrl,s=this.response.issueId;return this.$t("reporter.form.issue.link",{issueLink:e,issueId:s})}},data:()=>({errors:[],response:{},loading:!1,previewClicked:!1,dirty:!0,previewData:{},issue:{title:null,formFields:{}}}),mounted(){const e=this.$el.querySelectorAll(".vue-tab")[1];e.addEventListener("click",()=>{this.previewClicked&&this.loadPreview(),this.previewClicked=!0}),e.addEventListener("mouseenter",()=>{this.dirty&&this.loadPreview()}),this.$el.querySelectorAll(".vue-tab")[0].addEventListener("click",()=>{this.dirty=!1,this.previewClicked=!1})},methods:{somethingChanged(){this.dirty=!0},loadPreview(){this.$api.post("reporter/report?preview=true",this.issue).then(e=>{this.previewData=e,this.dirty=!1})},checkForm(){this.errors=[],!this.issue.title&&this.issue.title<3&&this.errors.push(this.$t("reporter.form.error.title")),this.errors.length||this.submit()},submit(){this.loading=!0;const e=this.$api.post("reporter/report",this.issue);e.then(e=>{e.status>=200&&e.status<300?(this.response=e,this.issue={},this.$store.dispatch("notification/success",":)")):401===e.status?(this.errors.push(this.$t("reporter.form.error.authFailed")),this.response={}):400===e.status?(this.errors.push(e.message),this.response={}):404===e.status?(this.errors.push(this.$t("reporter.form.error.repoNotFound")),this.response={}):501===e.status?(this.errors.push(this.$t("reporter.form.error.platform.unsupported")),this.response={}):this.response={},this.loading=!1}),e.catch(e=>{this.errors.push(this.$t(e.message)),this.loading=!1,this.response={}})}}};if(typeof c==="function"){c=c.options}Object.assign(c,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("div",{staticClass:"k-kit-form",on:{"input":function($event){return _vm.somethingChanged()}}},[_vm.errors.length?_c("k-box",{staticClass:"k-kit-form--note",attrs:{"theme":"negative"}},[_c("k-icon",{attrs:{"type":"alert"}}),_vm._l(_vm.errors,function(error){return _c("p",[_vm._v(_vm._s(error))])})],2):_vm._e(),_vm._v(" "),_vm.hasResponse?_c("k-box",{staticClass:"k-kit-form--note",attrs:{"theme":"positive"}},[_c("k-icon",{attrs:{"type":"check"}}),_c("p",{domProps:{"innerHTML":_vm._s(_vm.successMessage)}})],1):_vm._e(),_vm._v(" "),_c("k-form",[_c("k-grid",{staticClass:"title-field"},[_c("k-column",[_c("k-text-field",{attrs:{"name":"title","label":_vm.$t("reporter.form.field.title"),"required":""},model:{value:_vm.issue.title,callback:function($$v){_vm.$set(_vm.issue,"title",$$v)},expression:"issue.title"}})],1)],1),_vm._v(" "),_c("tabs",[_c("tab",{attrs:{"title":_vm.$t("reporter.tab.write")}},[_c("k-fieldset",{attrs:{"fields":_vm.fields},on:{"submit":function($event){$event.preventDefault();return _vm.checkForm($event)}},model:{value:_vm.issue.formFields,callback:function($$v){_vm.$set(_vm.issue,"formFields",$$v)},expression:"issue.formFields"}})],1),_vm._v(" "),_c("tab",{attrs:{"title":_vm.$t("reporter.tab.preview")}},[_c("issue-preview",{attrs:{"data":_vm.previewData}})],1)],1),_vm._v(" "),_c("k-line-field"),_vm._v(" "),_c("k-button",{class:{"is-loading":_vm.loading},attrs:{"disabled":_vm.loading,"icon":_vm.buttonIcon},on:{"click":_vm.checkForm}},[_vm._v(_vm._s(_vm.$t("reporter.form.button.save")))])],1)],1)};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());var d={components:{IssueForm:c},props:{fields:Object},data:()=>({fields:{}}),async created(){this.$api.get("reporter/fields").then(e=>{this.fields=e})}};if(typeof d==="function"){d=d.options}Object.assign(d,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("k-view",{staticClass:"k-issue-tracker-view"},[_c("k-header",[_vm._v(_vm._s(_vm.$t("reporter.headline")))]),_vm._v(" "),_c("k-text",[_vm._v(_vm._s(_vm.$t("reporter.description")))]),_vm._v(" "),_c("issue-form",{attrs:{"fields":_vm.fields}})],1)};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());panel.plugin("gearsdigital/kirby-reporter",{views:{reporter:{component:d,icon:"bolt"}}});})(); \ No newline at end of file +(function () {var b={};Object.defineProperty(b,"__esModule",{value:!0});var f={name:"tabs",props:{defaultIndex:{default:0,type:Number},onSelect:{type:Function}},data:function(){return{selectedIndex:this.defaultIndex}},methods:{switchTab:function(t,e,a){a||(this.selectedIndex=e,this.onSelect&&this.onSelect(t,e))}},render:function(){var t=this,e=arguments[0],a=this.$slots.default.filter(function(t){return t.componentOptions}),s=[];return a.forEach(function(a,r){var $=a.componentOptions.propsData,l=$.title,n=$.titleSlot,o=$.disabled,i=n?t.$slots[n]:l,f=!0===o||""===o;s.push(e("li",{class:"vue-tab",attrs:{role:"tab","aria-selected":t.selectedIndex===r?"true":"false","aria-disabled":f?"true":"false"},on:{click:function(e){return t.switchTab(e,r,f)}}},[i]))}),e("div",{class:"vue-tabs",attrs:{role:"tabs"}},[e("ul",{class:"vue-tablist",attrs:{role:"tablist"}},[this.$slots.left,s,this.$slots.right]),a[this.selectedIndex]])}},g={name:"tab",props:["title","titleSlot","disabled"],render:function(){return(0,arguments[0])("div",{class:"vue-tabpanel",attrs:{role:"tabpanel"}},[this.$slots.default])}};function k(t){t.component(f.name,f),t.component(g.name,g)}var h=f;b.Tabs=h;var i=g;b.Tab=i;var j=k;b.install=j;var e={name:"IssuePreview",props:{data:String}};if(typeof e==="function"){e=e.options}Object.assign(e,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _vm.data?_c("k-textarea-field",{attrs:{"label":"Preview","value":_vm.data,"buttons":false,"disabled":""}}):_c("k-text",[_vm._v(_vm._s(_vm.$t("reporter.tab.preview.empty")))])};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());var a={name:"IssueForm",components:{IssuePreview:e,Tabs:h,Tab:i},props:{fields:{type:Object},previewData:{type:String}},computed:{hasResponse(){return Object.keys(this.response).length>1},buttonIcon(){return this.loading?"loader":"check"},successMessage(){return this.$t("reporter.form.success",{issueLink:this.issueLink})},issueLink(){const e=this.response.issueUrl,s=this.response.issueId;return this.$t("reporter.form.issue.link",{issueLink:e,issueId:s})}},data:()=>({errors:[],response:{},loading:!1,previewClicked:!1,dirty:!0,previewData:{},issue:{title:null,formFields:{}}}),mounted(){const e=this.$el.querySelectorAll(".vue-tab")[1];e.addEventListener("click",()=>{this.previewClicked&&this.loadPreview(),this.previewClicked=!0}),e.addEventListener("mouseenter",()=>{this.dirty&&this.loadPreview()}),this.$el.querySelectorAll(".vue-tab")[0].addEventListener("click",()=>{this.dirty=!1,this.previewClicked=!1})},methods:{somethingChanged(){this.dirty=!0},loadPreview(){this.$api.post("reporter/report?preview=true",this.issue).then(e=>{this.previewData=e,this.dirty=!1})},checkForm(){this.errors=[],!this.issue.title&&this.issue.title<3&&this.errors.push(this.$t("reporter.form.error.title")),this.errors.length||this.submit()},submit(){this.loading=!0;const e=this.$api.post("reporter/report",this.issue);e.then(e=>{e.status>=200&&e.status<300?(this.response=e,this.issue={},this.$store.dispatch("notification/success",":)")):401===e.status?(this.errors.push(this.$t("reporter.form.error.authFailed")),this.response={}):400===e.status?(this.errors.push(e.message),this.response={}):404===e.status?(this.errors.push(this.$t("reporter.form.error.repoNotFound")),this.response={}):501===e.status?(this.errors.push(this.$t("reporter.form.error.platform.unsupported")),this.response={}):this.response={},this.loading=!1}),e.catch(e=>{this.errors.push(this.$t(e.message)),this.loading=!1,this.response={}})}}};if(typeof a==="function"){a=a.options}Object.assign(a,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("div",{staticClass:"k-kit-form",on:{"input":function($event){return _vm.somethingChanged()}}},[_vm.errors.length?_c("k-box",{staticClass:"k-kit-form--note",attrs:{"theme":"negative"}},[_c("k-icon",{attrs:{"type":"alert"}}),_vm._l(_vm.errors,function(error){return _c("p",[_vm._v(_vm._s(error))])})],2):_vm._e(),_vm._v(" "),_vm.hasResponse?_c("k-box",{staticClass:"k-kit-form--note",attrs:{"theme":"positive"}},[_c("k-icon",{attrs:{"type":"check"}}),_c("p",{domProps:{"innerHTML":_vm._s(_vm.successMessage)}})],1):_vm._e(),_vm._v(" "),_c("k-form",[_c("k-grid",{staticClass:"title-field"},[_c("k-column",[_c("k-text-field",{attrs:{"name":"title","label":_vm.$t("reporter.form.field.title"),"required":""},model:{value:_vm.issue.title,callback:function($$v){_vm.$set(_vm.issue,"title",$$v)},expression:"issue.title"}})],1)],1),_vm._v(" "),_c("tabs",[_c("tab",{attrs:{"title":_vm.$t("reporter.tab.write")}},[_c("k-fieldset",{attrs:{"fields":_vm.fields},on:{"submit":function($event){$event.preventDefault();return _vm.checkForm($event)}},model:{value:_vm.issue.formFields,callback:function($$v){_vm.$set(_vm.issue,"formFields",$$v)},expression:"issue.formFields"}})],1),_vm._v(" "),_c("tab",{attrs:{"title":_vm.$t("reporter.tab.preview")}},[_c("issue-preview",{attrs:{"data":_vm.previewData}})],1)],1),_vm._v(" "),_c("k-line-field"),_vm._v(" "),_c("k-button",{class:{"is-loading":_vm.loading},attrs:{"disabled":_vm.loading,"icon":_vm.buttonIcon},on:{"click":_vm.checkForm}},[_vm._v(_vm._s(_vm.$t("reporter.form.button.save")))])],1)],1)};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());var c={components:{IssueForm:a},props:{fields:Object},data:()=>({fields:{}}),async created(){this.$api.get("reporter/fields").then(e=>{this.fields=e})}};if(typeof c==="function"){c=c.options}Object.assign(c,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("k-view",{staticClass:"k-issue-tracker-view"},[_c("k-header",[_vm._v(_vm._s(_vm.$t("reporter.headline")))]),_vm._v(" "),_c("k-text",[_vm._v(_vm._s(_vm.$t("reporter.description")))]),_vm._v(" "),_c("issue-form",{attrs:{"fields":_vm.fields}})],1)};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());var d={components:{IssueForm:a},props:{fields:Object,headline:String},data:()=>({fields:{}}),async created(){this.$api.get("reporter/fields").then(e=>{this.fields=e})}};if(typeof d==="function"){d=d.options}Object.assign(d,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("section",[_c("header",{staticClass:"k-section-header"},[_c("k-headline",[_vm._v(" "+_vm._s(_vm.headline)+" ")])],1),_vm._v(" "),_c("issue-form",{attrs:{"fields":_vm.fields}})],1)};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());panel.plugin("gearsdigital/kirby-reporter",{views:{reporter:{component:c,icon:"bug"}},sections:{reporter:d}});})(); \ No newline at end of file diff --git a/index.php b/index.php index ac848f5..a1d1ed1 100755 --- a/index.php +++ b/index.php @@ -13,6 +13,7 @@ } $url = option('kirby-reporter.repository'); $token = option('kirby-reporter.token'); + /** Kirby\Cms\AppPlugins */ Kirby::plugin( 'gearsdigital/kirby-reporter', @@ -23,6 +24,9 @@ 'templates' => [ 'reporter' => __DIR__.'/templates/reporter.php', ], + 'sections' => [ + 'reporter' => [], + ], 'api' => [ 'routes' => [ [ diff --git a/src/components/SectionView.vue b/src/components/SectionView.vue new file mode 100755 index 0000000..4509123 --- /dev/null +++ b/src/components/SectionView.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/src/index.js b/src/index.js index 0d9acd6..d4aa8ca 100755 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,5 @@ import View from "./components/View"; +import SectionView from "./components/SectionView"; panel.plugin("gearsdigital/kirby-reporter", { views: { @@ -6,5 +7,8 @@ panel.plugin("gearsdigital/kirby-reporter", { component: View, icon: "bolt" } + }, + sections: { + reporter: SectionView } });