@glue42/feedback-ui-react
Advanced tools
Comparing version 0.0.1 to 0.0.2
@@ -1,2 +0,2 @@ | ||
"use strict";var e=require("react/jsx-runtime"),t=require("react");const s=({className:t,text:s="Feedback Form"})=>e.jsx("p",{className:t?`title ${t}`:"title",children:s}),i=({className:t,children:s,...i})=>e.jsx("div",{className:t?`button-group ${t}`:"button-group",...i,children:s}),r=({className:t,children:s,...i})=>e.jsx("button",{className:t?`button ${t}`:"button",type:"button",...i,children:s}),n=({icon:t,text:s,...i})=>e.jsxs(r,{...i,children:[t&&e.jsx("i",{className:t}),s]}),a=({icon:t="icon icon-close",...s})=>e.jsx(n,{icon:t,...s});function o(e){if(e&&e.errorHandling&&"function"!=typeof e.errorHandling&&"log"!==e.errorHandling&&"silent"!==e.errorHandling&&"throw"!==e.errorHandling)throw new Error('Invalid options passed to createRegistry. Prop errorHandling should be ["log" | "silent" | "throw" | (err) => void], but '+typeof e.errorHandling+" was passed");var t=e&&"function"==typeof e.errorHandling&&e.errorHandling,s={};function i(s,i){var r=s instanceof Error?s:new Error(s);if(t)t(r);else{var n='[ERROR] callback-registry: User callback for key "'+i+'" failed: '+r.stack;if(e)switch(e.errorHandling){case"log":return console.error(n);case"silent":return;case"throw":throw new Error(n)}console.error(n)}}return{add:function(e,t,r){var n=s[e];return n||(n=[],s[e]=n),n.push(t),r&&setTimeout((function(){r.forEach((function(r){var n;if(null===(n=s[e])||void 0===n?void 0:n.includes(t))try{Array.isArray(r)?t.apply(void 0,r):t.apply(void 0,[r])}catch(t){i(t,e)}}))}),0),function(){var i=s[e];i&&(0===(i=i.reduce((function(e,s,i){return s===t&&e.length===i||e.push(s),e}),[])).length?delete s[e]:s[e]=i)}},execute:function(e){for(var t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];var n=s[e];if(!n||0===n.length)return[];var a=[];return n.forEach((function(s){try{var r=s.apply(void 0,t);a.push(r)}catch(t){a.push(void 0),i(t,e)}})),a},clear:function(){s={}},clearKey:function(e){s[e]&&delete s[e]}}}o.default=o;var l=o;var c=new class{issueReport=window.issueReporting;registry=l();config;constructor(){window.onerror=(e,t,s,i,r)=>{this.issueReport.send("error",e,t,s,i,r)},this.issueReport.on("setTheme",(e=>{const t=e.newTheme;this.registry.execute("on-theme-changed",t)})),this.issueReport.on("submitEnded",(e=>{const t=this.convertSubmitResultToPublic(e);this.registry.execute("on-submit-finished",t)}))}async getConfig(){return this.config=await this.issueReport.invoke("config"),this.convertConfigToPublic(this.config)}onThemeChanged(e){return this.registry.add("on-theme-changed",e)}onSubmitFinished(e){return this.registry.add("on-submit-finished",e)}submitReport(e){return new Promise((t=>{e.sendEmail||(e.mailingList=null);const s=this.convertIssueReportToInternal(e),i=this.onSubmitFinished((e=>{i(),t(e)}));this.issueReport.send("submit",s)}))}closeReport(){return this.issueReport.send("cancel")}setBounds(e,t,s,i){return this.issueReport.send("resize",e,t,s,i)}openUrl(e){return this.issueReport.send("openUrl",e)}convertConfigToPublic(e){return{version:e.version,buildVersion:e.buildVersion,region:e.region,env:e.env,theme:e.theme,isError:e.isError,mailingList:e.mailList,createJiraTicket:e.jiraEnabled,sendEmail:e.mailEnabled,attachments:e.attachments,applicationTitle:e.applicationTitle,allowEditRecipients:e.allowEditRecipients,attachmentsViewMode:e.attachmentsViewMode,selectedCategories:e.selectedCategories,errorMessage:e.technicalInfo,environmentInfo:e.environmentDetails,showEnvironmentInfo:e.showEnvironmentInfo}}convertSubmitResultToPublic(e){return{description:e.description,jiraProcessed:e.jiraProcessed,jiraSucceeded:e.jiraSucceeded,jiraDetails:e.jiraDetails,jiraTicketUrl:e.jiraTicketUrl,emailProcessed:e.mailProcessed,emailSucceeded:e.mailSucceeded,emailDetails:e.mailDetails}}convertIssueReportToInternal(e){return{createTicket:e.createJiraTicket,description:e.description,sendMail:e.sendEmail,mailingList:e.mailingList,attachments:e.attachments,attachmentsMode:e.attachmentsViewMode}}};const d=t.createContext({config:{env:"",region:"",version:"",buildVersion:"",theme:"",isError:!1,mailingList:"",createJiraTicket:!0,sendEmail:!1,attachments:[],applicationTitle:"",allowEditRecipients:!0,attachmentsViewMode:"category",environmentInfo:"",selectedCategories:[],errorMessage:"",showEnvironmentInfo:!1},onThemeChanged:e=>{},openUrl:()=>{},submit:()=>Promise.resolve({}),setBounds:()=>{},close:()=>{}}),m=()=>t.useContext(d),u=({className:t,...s})=>{const{close:r}=m();return e.jsx(i,{className:t,...s,children:e.jsx(a,{onClick:r})})},h=({className:t,...i})=>{const{config:r}=m(),{applicationTitle:n}=r;return e.jsxs("div",{className:t?`header ${t}`:"header",...i,children:[e.jsx(s,{className:"draggable",text:n?`Feedback Form - ${n}`:"Feedback Form"}),e.jsx(u,{})]})},p=({className:t,text:s,hint:i,children:r,...n})=>e.jsxs("div",{className:t?`block ${t}`:"block",...n,children:[s&&e.jsx("p",{children:s}),r,i&&e.jsx("small",{children:i})]}),x=({label:t,...s})=>e.jsx("label",{...s,children:t}),g=({className:t,id:s="input",disabled:i,placeholder:r="Please describe your issue...",value:n,label:a,...o})=>e.jsxs("div",{className:t?`form-group ${t}`:"form-group",children:[a&&e.jsx(x,{htmlFor:s,label:a}),e.jsx("input",{type:"text",id:s,name:s,disabled:i,placeholder:r,value:n,...o})]}),b=({className:t,id:s="textarea",disabled:i,rows:r=4,placeholder:n="Please describe your issue...",value:a,label:o,...l})=>e.jsxs("div",{className:t?`form-group ${t}`:"form-group",children:[o&&e.jsx(x,{htmlFor:s,label:o}),e.jsx("textarea",{id:s,name:s,disabled:i,rows:r,placeholder:n,value:a,...l})]}),f=({className:t,id:s="checkbox",disabled:i,checked:r,label:n="Checkbox",...a})=>e.jsxs("div",{className:t?`form-group ${t}`:"form-group",children:[e.jsx("input",{type:"checkbox",id:s,name:s,disabled:i,checked:r,...a}),e.jsx(x,{htmlFor:s,label:n})]}),j=({className:t,categories:s,handleSubmit:i,submitting:r,showMailingList:n,setShowMailingList:a,...o})=>{const{config:l}=m(),{attachments:c,attachmentsViewMode:d,buildVersion:u,createJiraTicket:h,environmentInfo:x,sendEmail:j,showEnvironmentInfo:v,errorMessage:y,selectedCategories:k,mailingList:w}=l;return e.jsx("div",{className:t?`body ${t}`:"body",...o,children:e.jsxs("form",{id:"feedback",onSubmit:e=>i(e),children:[e.jsx(p,{text:`Your feedback will be submitted to the ${u} team and some additional information will be automatically included to help us examine your issue.`}),e.jsx(p,{text:"Description",children:e.jsx(b,{name:"description",disabled:r})}),y&&e.jsx(p,{text:"Technical Information",children:e.jsx(b,{readOnly:!0,disabled:r,name:"errorMessage",value:y})}),x&&v&&e.jsx(p,{text:"Environment",children:e.jsx(b,{readOnly:!0,disabled:r,name:"environmentInfo",value:x})}),c&&c.length>0&&e.jsx(p,{text:"Attachments",children:"file"===d?c&&c.length>0?e.jsx("div",{className:"file-attachments",children:c.map((t=>e.jsx(f,{id:t.id,disabled:r,label:t.name,defaultChecked:-1!==k.indexOf(t.category)},t.id)))}):e.jsx("div",{children:"No Attachments"}):s&&s.length>0?e.jsx("div",{className:"checkbox-wrapper category-attachments",children:s.map((t=>e.jsx(f,{id:t,disabled:r,label:t,defaultChecked:-1!==k.indexOf(t)},t)))}):e.jsx("div",{children:"No Attachments"})}),e.jsx(p,{text:"Settings",children:e.jsxs("div",{className:"checkbox-wrapper",children:[h&&e.jsx(f,{id:"createJiraTicket",disabled:r,defaultChecked:h,label:"Create Jira Ticket"}),j&&e.jsx(f,{onChange:()=>{a(!n)},id:"sendEmail",disabled:r,label:"Send Email",defaultChecked:j})]})}),j&&n&&e.jsx(p,{text:"Email List",hint:"Separate with commas or semicolons.",children:e.jsx(g,{id:"mailingList",disabled:r,defaultValue:w??"",placeholder:"john.doe@somedomain.com; jane.doe@otherdomain.com"})})]})})},v=({className:t,value:s=0,...i})=>e.jsx("div",{className:t?`progress ${t}`:"progress",...i,children:e.jsxs("div",{className:"progress-bar",style:{width:`${s}%`},children:[s,"%"]})}),y=({className:t,type:s="primary",title:i="Alert title",text:r,children:n,...a})=>e.jsx("div",{className:t?`alert ${s} ${t}`:`alert ${s}`,...a,children:i?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:`color-${s}`,children:i}),r&&e.jsx("p",{children:r}),n]}):null}),k=({className:t="primary",text:s="Submit",...i})=>e.jsx(n,{className:t,text:s,...i}),w=({text:t="Cancel",...s})=>e.jsx(n,{text:t,...s}),N=({className:t,submitCompleted:s,...r})=>{const{close:a}=m();return s?e.jsx(i,{className:t,...r,children:e.jsx(n,{onClick:a,className:"primary",text:"Close"})}):e.jsxs(i,{className:t,...r,children:[e.jsx(w,{onClick:a}),e.jsx(k,{form:"feedback",type:"submit"})]})},T=({className:t,submitting:s,submitStatus:i,submitCompleted:r,progressPercent:n,jiraTicketURL:a,...o})=>{const{openUrl:l}=m();return e.jsxs("div",{className:t?`footer ${t}`:"footer",...o,children:[s&&e.jsx(p,{children:e.jsx(v,{value:n})}),e.jsxs(p,{className:"footer-actions",children:[i.title&&e.jsx(y,{type:i.type,title:i.title,text:i.text,children:a&&e.jsx("a",{href:a,onClick:e=>{e.preventDefault(),l(a)},children:a})}),e.jsx(N,{submitCompleted:r})]})]})},C=({className:t,id:s="select",disabled:i,label:r,options:n,...a})=>e.jsxs("div",{className:t?`form-group ${t}`:"form-group",children:[r&&e.jsx(x,{htmlFor:s,label:r}),e.jsx("select",{id:s,name:s,disabled:i,...a,children:n.map((t=>e.jsx("option",{children:t},t)))})]}),E=({className:t,id:s="radio",disabled:i,checked:r,label:n="Radio",...a})=>e.jsxs("div",{className:t?`form-group ${t}`:"form-group",children:[e.jsx("input",{type:"radio",id:s,name:s,disabled:i,checked:r,...a}),e.jsx(x,{htmlFor:s,label:n})]}),S={Header:h,Body:j,Footer:T,Block:p,Title:s,Label:x,Input:g,Select:C,Checkbox:f,Radio:E,Textarea:b,Button:r,ButtonWithIcon:n,ButtonGroup:i,Progress:v,Alert:y,HeaderButtons:u,FooterButtons:N,SubmitButton:k,CancelButton:w,CloseButton:a},R=t.createContext(S),B=t.memo((({children:s,components:i})=>{const r=t.useMemo((()=>({...S,...i})),[i]);return e.jsx(R.Provider,{value:r,children:s})}));B.displayName="ComponentsStore";const I=({className:s,...i})=>{const{Header:r,Body:n,Footer:a}={...t.useContext(R),...o};var o;const{config:l,submit:c}=m(),{attachments:d,attachmentsViewMode:u,sendEmail:h}=l,p=t.useRef(),[x,g]=t.useState(""),[b,f]=t.useState(!1),[j,v]=t.useState(!1),[y,k]=t.useState(!1),[w,N]=t.useState([]),[T,C]=t.useState(0),[E,S]=t.useState({type:"primary",title:"",text:""});t.useEffect((()=>{B(d),v(h)}),[h,d]),t.useEffect((()=>(b&&j&&(p.current=setTimeout((()=>{S({title:"Sending an email. Go to Outlook to allow access.",type:"primary"})}),100)),()=>clearTimeout(p.current))),[b]);const B=e=>{const t=new Set;e.filter((e=>{const s=t.has(e.category);return t.add(e.category),!s})),N(Array.from(t))},I=e=>{e.jiraProcessed&&(S({title:e.jiraDetails,type:"success"}),g(e.jiraTicketUrl)),e.emailProcessed&&S({title:e.emailDetails,type:"success"})},L=(e=0,t=5)=>{let s=e;const i=setInterval((function(){100===s?clearInterval(i):(s+=t,C(s))}),24)};return e.jsxs("div",{className:s?`feedback ${s}`:"feedback",...i,children:[e.jsx(r,{}),e.jsx(n,{handleSubmit:e=>{e.preventDefault();const t=new FormData(e.currentTarget),s=[];if("file"===u){d.filter((e=>"on"===t.get(e.id))).map((e=>s.push(e.id)))}else{const e=w?.filter((e=>"on"===t.get(e))),i=d.reduce(((t,s)=>(-1!==e.indexOf(s.category)&&t.push(s.id),t)),[]);s.push(...i)}const i={createJiraTicket:"on"===t.get("createJiraTicket"),sendEmail:"on"===t.get("sendEmail"),description:t.get("description"),mailingList:t.get("mailingList"),attachments:s,attachmentsViewMode:u};i.createJiraTicket||i.sendEmail?!i.sendEmail||i.mailingList?(i.createJiraTicket&&i.sendEmail&&(S({title:"Submitting an issue to Jira and sending an email...",type:"primary"}),f(!0),L()),i.createJiraTicket?(S({title:"Submitting an issue to Jira...",type:"primary"}),f(!0),L()):(S({title:"Sending an email...",type:"primary"}),f(!0),L()),c(i).then((e=>{I(e),f(!1),k(!0),C(0),clearTimeout(p.current)})).catch((e=>console.log("An error occured while submitting:",e)))):S({title:"No email recipient. Provide at least one valid email address in the Email List field.",type:"error"}):S({title:"Can't send feedback. Issue reporting via Jira and email has been disabled in the system configuration.",type:"error"})},submitting:b,categories:w,showMailingList:j,setShowMailingList:v}),e.jsx(a,{submitting:b,submitStatus:E,submitCompleted:y,progressPercent:T,jiraTicketURL:x})]})};exports.Block=p,exports.Body=j,exports.Button=r,exports.ButtonGroup=i,exports.ButtonWithIcon=n,exports.CancelButton=w,exports.Checkbox=f,exports.CloseButton=a,exports.Feedback=({components:t,...s})=>e.jsx(B,{components:t,children:e.jsx(I,{...s})}),exports.Footer=T,exports.FooterButtons=N,exports.Header=h,exports.HeaderButtons=u,exports.Input=g,exports.IssueReportingProvider=({children:s})=>{const{config:i,onThemeChanged:r,openUrl:n,submit:a,setBounds:o,close:l}=function(){const[e,s]=t.useState({env:"",region:"",version:"",buildVersion:"",theme:"",isError:!1,mailingList:"",createJiraTicket:!0,sendEmail:!1,attachments:[],applicationTitle:"",allowEditRecipients:!0,attachmentsViewMode:"category",environmentInfo:"",selectedCategories:[],errorMessage:"",showEnvironmentInfo:!1});t.useEffect((()=>{c.getConfig().then((e=>{s(e),e.theme?i(e.theme):i("dark")})).catch((e=>{throw new Error("Failed to get Issue Reporting Config:",e)})),c.onThemeChanged((e=>{i(e)}))}),[]);const i=e=>{const t=document.documentElement;return t.className="",t.classList.add(e),()=>{t.classList.remove(e)}};return{config:e,onThemeChanged:e=>c.onThemeChanged(e),openUrl:e=>{c.openUrl(e)},submit:e=>c.submitReport(e),setBounds:(e,t,s,i)=>{c.setBounds(e,t,s,i)},close:()=>{c.closeReport()}}}(),m=t.useMemo((()=>({config:i,onThemeChanged:r,openUrl:n,submit:a,setBounds:o,close:l})),[i,r,a,l]);return e.jsx(d.Provider,{value:m,children:s})},exports.Label=x,exports.Radio=E,exports.Select=C,exports.SubmitButton=k,exports.Textarea=b,exports.Title=s,exports.useIssueReportingContext=m; | ||
"use strict";var e=require("react/jsx-runtime"),t=require("react");const s=({className:t,text:s="Feedback Form"})=>e.jsx("p",{className:t?`title ${t}`:"title",children:s}),i=({className:t,children:s,...i})=>e.jsx("div",{className:t?`button-group ${t}`:"button-group",...i,children:s}),r=({className:t,children:s,...i})=>e.jsx("button",{className:t?`button ${t}`:"button",type:"button",...i,children:s}),n=({icon:t,text:s,...i})=>e.jsxs(r,{...i,children:[t&&e.jsx("i",{className:t}),s]}),a=({icon:t="icon icon-close",...s})=>e.jsx(n,{icon:t,...s});function o(e){if(e&&e.errorHandling&&"function"!=typeof e.errorHandling&&"log"!==e.errorHandling&&"silent"!==e.errorHandling&&"throw"!==e.errorHandling)throw new Error('Invalid options passed to createRegistry. Prop errorHandling should be ["log" | "silent" | "throw" | (err) => void], but '+typeof e.errorHandling+" was passed");var t=e&&"function"==typeof e.errorHandling&&e.errorHandling,s={};function i(s,i){var r=s instanceof Error?s:new Error(s);if(t)t(r);else{var n='[ERROR] callback-registry: User callback for key "'+i+'" failed: '+r.stack;if(e)switch(e.errorHandling){case"log":return console.error(n);case"silent":return;case"throw":throw new Error(n)}console.error(n)}}return{add:function(e,t,r){var n=s[e];return n||(n=[],s[e]=n),n.push(t),r&&setTimeout((function(){r.forEach((function(r){var n;if(null===(n=s[e])||void 0===n?void 0:n.includes(t))try{Array.isArray(r)?t.apply(void 0,r):t.apply(void 0,[r])}catch(t){i(t,e)}}))}),0),function(){var i=s[e];i&&(0===(i=i.reduce((function(e,s,i){return s===t&&e.length===i||e.push(s),e}),[])).length?delete s[e]:s[e]=i)}},execute:function(e){for(var t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];var n=s[e];if(!n||0===n.length)return[];var a=[];return n.forEach((function(s){try{var r=s.apply(void 0,t);a.push(r)}catch(t){a.push(void 0),i(t,e)}})),a},clear:function(){s={}},clearKey:function(e){s[e]&&delete s[e]}}}o.default=o;var l=o;var c=new class{issueReport=window.issueReporting;registry=l();config;constructor(){window.onerror=(e,t,s,i,r)=>{this.issueReport.send("error",e,t,s,i,r)},this.issueReport.on("setTheme",(e=>{const t=e.newTheme;this.registry.execute("on-theme-changed",t)})),this.issueReport.on("submitEnded",(e=>{const t=this.convertSubmitResultToPublic(e);this.registry.execute("on-submit-finished",t)}))}async getConfig(){return this.config=await this.issueReport.invoke("config"),this.convertConfigToPublic(this.config)}onThemeChanged(e){return this.registry.add("on-theme-changed",e)}onSubmitFinished(e){return this.registry.add("on-submit-finished",e)}submitReport(e){return new Promise((t=>{e.sendEmail||(e.mailingList=null);const s=this.convertIssueReportToInternal(e),i=this.onSubmitFinished((e=>{i(),t(e)}));this.issueReport.send("submit",s)}))}closeReport(){return this.issueReport.send("cancel")}setBounds(e,t,s,i){return this.issueReport.send("resize",e,t,s,i)}openUrl(e){return this.issueReport.send("openUrl",e)}convertConfigToPublic(e){return{version:e.version,buildVersion:e.buildVersion,region:e.region,env:e.env,theme:e.theme,isError:e.isError,mailingList:e.mailList,createJiraTicket:e.jiraEnabled,sendEmail:e.mailEnabled,attachments:e.attachments,applicationTitle:e.applicationTitle,allowEditRecipients:e.allowEditRecipients,attachmentsViewMode:e.attachmentsViewMode,selectedCategories:e.selectedCategories,errorMessage:e.technicalInfo,environmentInfo:e.environmentDetails,showEnvironmentInfo:e.showEnvironmentInfo}}convertSubmitResultToPublic(e){return{description:e.description,jiraProcessed:e.jiraProcessed,jiraSucceeded:e.jiraSucceeded,jiraDetails:e.jiraDetails,jiraTicketUrl:e.jiraTicketUrl,emailProcessed:e.mailProcessed,emailSucceeded:e.mailSucceeded,emailDetails:e.mailDetails}}convertIssueReportToInternal(e){return{createTicket:e.createJiraTicket,description:e.description,sendMail:e.sendEmail,mailingList:e.mailingList,attachments:e.attachments,attachmentsMode:e.attachmentsViewMode}}};const d=t.createContext({config:{env:"",region:"",version:"",buildVersion:"",theme:"",isError:!1,mailingList:"",createJiraTicket:!0,sendEmail:!1,attachments:[],applicationTitle:"",allowEditRecipients:!0,attachmentsViewMode:"category",environmentInfo:"",selectedCategories:[],errorMessage:"",showEnvironmentInfo:!1},onThemeChanged:e=>{},openUrl:()=>{},submit:()=>Promise.resolve({}),setBounds:()=>{},close:()=>{}}),m=()=>t.useContext(d),u=({className:t,...s})=>{const{close:r}=m();return e.jsx(i,{className:t,...s,children:e.jsx(a,{onClick:r})})},h=({className:t,...i})=>{const{config:r}=m(),{applicationTitle:n}=r;return e.jsxs("div",{className:t?`header ${t}`:"header",...i,children:[e.jsx(s,{className:"draggable",text:n?`Feedback Form - ${n}`:"Feedback Form"}),e.jsx(u,{})]})},p=({className:t,text:s,hint:i,children:r,...n})=>e.jsxs("div",{className:t?`block ${t}`:"block",...n,children:[s&&e.jsx("p",{children:s}),r,i&&e.jsx("small",{children:i})]}),x=({label:t,...s})=>e.jsx("label",{...s,children:t}),g=({className:t,id:s="input",disabled:i,placeholder:r="Please describe your issue...",value:n,label:a,...o})=>e.jsxs("div",{className:t?`form-group ${t}`:"form-group",children:[a&&e.jsx(x,{htmlFor:s,label:a}),e.jsx("input",{type:"text",id:s,name:s,disabled:i,placeholder:r,value:n,...o})]}),b=({className:t,id:s="textarea",disabled:i,rows:r=4,placeholder:n="Please describe your issue...",value:a,label:o,...l})=>e.jsxs("div",{className:t?`form-group ${t}`:"form-group",children:[o&&e.jsx(x,{htmlFor:s,label:o}),e.jsx("textarea",{id:s,name:s,disabled:i,rows:r,placeholder:n,value:a,...l})]}),f=({className:t,id:s="checkbox",disabled:i,checked:r,label:n="Checkbox",...a})=>e.jsxs("div",{className:t?`form-group ${t}`:"form-group",children:[e.jsx("input",{type:"checkbox",id:s,name:s,disabled:i,checked:r,...a}),e.jsx(x,{htmlFor:s,label:n})]}),j=({className:t,categories:s,handleSubmit:i,submitting:r,showMailingList:n,setShowMailingList:a,...o})=>{const{config:l}=m(),{attachments:c,attachmentsViewMode:d,buildVersion:u,createJiraTicket:h,environmentInfo:x,sendEmail:j,showEnvironmentInfo:v,errorMessage:y,selectedCategories:k,mailingList:w}=l;return e.jsx("div",{className:t?`body ${t}`:"body",...o,children:e.jsxs("form",{id:"feedback",onSubmit:e=>i(e),children:[e.jsx(p,{text:`Your feedback will be submitted to the ${u} team and some additional information will be automatically included to help us examine your issue.`}),e.jsx(p,{text:"Description",children:e.jsx(b,{name:"description",disabled:r})}),y&&e.jsx(p,{text:"Technical Information",children:e.jsx(b,{readOnly:!0,disabled:r,name:"errorMessage",value:y})}),x&&v&&e.jsx(p,{text:"Environment",children:e.jsx(b,{readOnly:!0,disabled:r,name:"environmentInfo",value:x})}),c&&c.length>0&&e.jsx(p,{text:"Attachments",children:"file"===d?c&&c.length>0?e.jsx("div",{className:"file-attachments",children:c.map((t=>e.jsx(f,{id:t.id,disabled:r,label:t.name,defaultChecked:-1!==k.indexOf(t.category)},t.id)))}):e.jsx("div",{children:"No Attachments"}):s&&s.length>0?e.jsx("div",{className:"checkbox-wrapper category-attachments",children:s.map((t=>e.jsx(f,{id:t,disabled:r,label:t,defaultChecked:-1!==k.indexOf(t)},t)))}):e.jsx("div",{children:"No Attachments"})}),e.jsx(p,{text:"Settings",children:e.jsxs("div",{className:"checkbox-wrapper",children:[h&&e.jsx(f,{id:"createJiraTicket",disabled:r,defaultChecked:h,label:"Create Jira Ticket"}),j&&e.jsx(f,{onChange:()=>{a(!n)},id:"sendEmail",disabled:r,label:"Send Email",defaultChecked:j})]})}),j&&n&&e.jsx(p,{text:"Email List",hint:"Separate with commas or semicolons.",children:e.jsx(g,{id:"mailingList",disabled:r,defaultValue:w??"",placeholder:"john.doe@somedomain.com; jane.doe@otherdomain.com"})})]})})},v=({className:t,value:s=0,...i})=>e.jsx("div",{className:t?`progress ${t}`:"progress",...i,children:e.jsxs("div",{className:"progress-bar",style:{width:`${s}%`},children:[s,"%"]})}),y=({className:t,type:s="primary",title:i="Alert title",text:r,children:n,...a})=>e.jsx("div",{className:t?`alert ${s} ${t}`:`alert ${s}`,...a,children:i?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:`color-${s}`,children:i}),r&&e.jsx("p",{children:r}),n]}):null}),k=({className:t="primary",text:s="Submit",...i})=>e.jsx(n,{className:t,text:s,...i}),w=({text:t="Cancel",...s})=>e.jsx(n,{text:t,...s}),N=({className:t,submitCompleted:s,...r})=>{const{close:a}=m();return s?e.jsx(i,{className:t,...r,children:e.jsx(n,{onClick:a,className:"primary",text:"Close"})}):e.jsxs(i,{className:t,...r,children:[e.jsx(w,{onClick:a}),e.jsx(k,{form:"feedback",type:"submit"})]})},T=({className:t,submitting:s,submitStatus:i,submitCompleted:r,progressPercent:n,jiraTicketURL:a,...o})=>{const{openUrl:l}=m();return e.jsxs("div",{className:t?`footer ${t}`:"footer",...o,children:[s&&e.jsx(p,{children:e.jsx(v,{value:n})}),e.jsxs(p,{className:"footer-actions",children:[i.title&&e.jsx(y,{type:i.type,title:i.title,text:i.text,children:a&&e.jsx("a",{href:a,onClick:e=>{e.preventDefault(),l(a)},children:a})}),e.jsx(N,{submitCompleted:r})]})]})},C=({className:t,id:s="select",disabled:i,label:r,options:n,...a})=>e.jsxs("div",{className:t?`form-group ${t}`:"form-group",children:[r&&e.jsx(x,{htmlFor:s,label:r}),e.jsx("select",{id:s,name:s,disabled:i,...a,children:n.map((t=>e.jsx("option",{children:t},t)))})]}),E=({className:t,id:s="radio",disabled:i,checked:r,label:n="Radio",...a})=>e.jsxs("div",{className:t?`form-group ${t}`:"form-group",children:[e.jsx("input",{type:"radio",id:s,name:s,disabled:i,checked:r,...a}),e.jsx(x,{htmlFor:s,label:n})]}),S={Header:h,Body:j,Footer:T,Block:p,Title:s,Label:x,Input:g,Select:C,Checkbox:f,Radio:E,Textarea:b,Button:r,ButtonWithIcon:n,ButtonGroup:i,Progress:v,Alert:y,HeaderButtons:u,FooterButtons:N,SubmitButton:k,CancelButton:w,CloseButton:a},R=t.createContext(S),B=t.memo((({children:s,components:i})=>{const r=t.useMemo((()=>({...S,...i})),[i]);return e.jsx(R.Provider,{value:r,children:s})}));B.displayName="ComponentsStore";const I=({className:s,...i})=>{const{Header:r,Body:n,Footer:a}={...t.useContext(R),...o};var o;const{config:l,submit:c}=m(),{attachments:d,attachmentsViewMode:u,sendEmail:h}=l,p=t.useRef(),[x,g]=t.useState(""),[b,f]=t.useState(!1),[j,v]=t.useState(!1),[y,k]=t.useState(!1),[w,N]=t.useState([]),[T,C]=t.useState(0),[E,S]=t.useState({type:"primary",title:"",text:""});t.useEffect((()=>{B(d),v(h)}),[h,d]),t.useEffect((()=>(b&&j&&(p.current=setTimeout((()=>{S({title:"Sending an email. Go to Outlook to allow access.",type:"primary"})}),100)),()=>clearTimeout(p.current))),[b]);const B=e=>{const t=new Set;e.filter((e=>{const s=t.has(e.category);return t.add(e.category),!s})),N(Array.from(t))},I=e=>{e.jiraProcessed&&(S({title:e.jiraDetails,type:"success"}),g(e.jiraTicketUrl)),e.emailProcessed&&S({title:e.emailDetails,type:"success"})},L=(e=0,t=5)=>{let s=e;const i=setInterval((function(){100===s?clearInterval(i):(s+=t,C(s))}),24)};return e.jsxs("div",{className:s?`feedback ${s}`:"feedback",...i,children:[e.jsx(r,{}),e.jsx(n,{handleSubmit:e=>{e.preventDefault();const t=new FormData(e.currentTarget),s=[];if("file"===u){d.filter((e=>"on"===t.get(e.id))).map((e=>s.push(e.id)))}else{const e=w?.filter((e=>"on"===t.get(e))),i=d.reduce(((t,s)=>(-1!==e.indexOf(s.category)&&t.push(s.id),t)),[]);s.push(...i)}const i={createJiraTicket:"on"===t.get("createJiraTicket"),sendEmail:"on"===t.get("sendEmail"),description:t.get("description"),mailingList:t.get("mailingList"),attachments:s,attachmentsViewMode:u};i.createJiraTicket||i.sendEmail?!i.sendEmail||i.mailingList?(i.createJiraTicket&&i.sendEmail&&(S({title:"Submitting an issue to Jira and sending an email...",type:"primary"}),f(!0),L()),i.createJiraTicket?(S({title:"Submitting an issue to Jira...",type:"primary"}),f(!0),L()):(S({title:"Sending an email...",type:"primary"}),f(!0),L()),c(i).then((e=>{I(e),f(!1),k(!0),C(0),clearTimeout(p.current)})).catch((e=>console.log("An error occured while submitting:",e)))):S({title:"No email recipient. Provide at least one valid email address in the Email List field.",type:"error"}):S({title:"Can't send feedback. Issue reporting via Jira and email has been disabled in the system configuration.",type:"error"})},submitting:b,categories:w,showMailingList:j,setShowMailingList:v}),e.jsx(a,{submitting:b,submitStatus:E,submitCompleted:y,progressPercent:T,jiraTicketURL:x})]})};exports.Alert=y,exports.Block=p,exports.Body=j,exports.Button=r,exports.ButtonGroup=i,exports.ButtonWithIcon=n,exports.CancelButton=w,exports.Checkbox=f,exports.CloseButton=a,exports.Feedback=({components:t,...s})=>e.jsx(B,{components:t,children:e.jsx(I,{...s})}),exports.Footer=T,exports.FooterButtons=N,exports.Header=h,exports.HeaderButtons=u,exports.Input=g,exports.IssueReportingProvider=({children:s})=>{const{config:i,onThemeChanged:r,openUrl:n,submit:a,setBounds:o,close:l}=function(){const[e,s]=t.useState({env:"",region:"",version:"",buildVersion:"",theme:"",isError:!1,mailingList:"",createJiraTicket:!0,sendEmail:!1,attachments:[],applicationTitle:"",allowEditRecipients:!0,attachmentsViewMode:"category",environmentInfo:"",selectedCategories:[],errorMessage:"",showEnvironmentInfo:!1});t.useEffect((()=>{c.getConfig().then((e=>{s(e),e.theme?i(e.theme):i("dark")})).catch((e=>{throw new Error("Failed to get Issue Reporting Config:",e)})),c.onThemeChanged((e=>{i(e)}))}),[]);const i=e=>{const t=document.documentElement;return t.className="",t.classList.add(e),()=>{t.classList.remove(e)}};return{config:e,onThemeChanged:e=>c.onThemeChanged(e),openUrl:e=>{c.openUrl(e)},submit:e=>c.submitReport(e),setBounds:(e,t,s,i)=>{c.setBounds(e,t,s,i)},close:()=>{c.closeReport()}}}(),m=t.useMemo((()=>({config:i,onThemeChanged:r,openUrl:n,submit:a,setBounds:o,close:l})),[i,r,a,l]);return e.jsx(d.Provider,{value:m,children:s})},exports.Label=x,exports.Progress=v,exports.Radio=E,exports.Select=C,exports.SubmitButton=k,exports.Textarea=b,exports.Title=s,exports.useIssueReportingContext=m; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
import{jsx as e,jsxs as t,Fragment as i}from"react/jsx-runtime";import{useState as r,useEffect as n,createContext as a,useMemo as s,useContext as o,memo as l,useRef as c}from"react";const d=({className:t,text:i="Feedback Form"})=>e("p",{className:t?`title ${t}`:"title",children:i}),m=({className:t,children:i,...r})=>e("div",{className:t?`button-group ${t}`:"button-group",...r,children:i}),u=({className:t,children:i,...r})=>e("button",{className:t?`button ${t}`:"button",type:"button",...r,children:i}),h=({icon:i,text:r,...n})=>t(u,{...n,children:[i&&e("i",{className:i}),r]}),p=({icon:t="icon icon-close",...i})=>e(h,{icon:t,...i});function g(e){if(e&&e.errorHandling&&"function"!=typeof e.errorHandling&&"log"!==e.errorHandling&&"silent"!==e.errorHandling&&"throw"!==e.errorHandling)throw new Error('Invalid options passed to createRegistry. Prop errorHandling should be ["log" | "silent" | "throw" | (err) => void], but '+typeof e.errorHandling+" was passed");var t=e&&"function"==typeof e.errorHandling&&e.errorHandling,i={};function r(i,r){var n=i instanceof Error?i:new Error(i);if(t)t(n);else{var a='[ERROR] callback-registry: User callback for key "'+r+'" failed: '+n.stack;if(e)switch(e.errorHandling){case"log":return console.error(a);case"silent":return;case"throw":throw new Error(a)}console.error(a)}}return{add:function(e,t,n){var a=i[e];return a||(a=[],i[e]=a),a.push(t),n&&setTimeout((function(){n.forEach((function(n){var a;if(null===(a=i[e])||void 0===a?void 0:a.includes(t))try{Array.isArray(n)?t.apply(void 0,n):t.apply(void 0,[n])}catch(t){r(t,e)}}))}),0),function(){var r=i[e];r&&(0===(r=r.reduce((function(e,i,r){return i===t&&e.length===r||e.push(i),e}),[])).length?delete i[e]:i[e]=r)}},execute:function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];var a=i[e];if(!a||0===a.length)return[];var s=[];return a.forEach((function(i){try{var n=i.apply(void 0,t);s.push(n)}catch(t){s.push(void 0),r(t,e)}})),s},clear:function(){i={}},clearKey:function(e){i[e]&&delete i[e]}}}g.default=g;var b=g;var f=new class{issueReport=window.issueReporting;registry=b();config;constructor(){window.onerror=(e,t,i,r,n)=>{this.issueReport.send("error",e,t,i,r,n)},this.issueReport.on("setTheme",(e=>{const t=e.newTheme;this.registry.execute("on-theme-changed",t)})),this.issueReport.on("submitEnded",(e=>{const t=this.convertSubmitResultToPublic(e);this.registry.execute("on-submit-finished",t)}))}async getConfig(){return this.config=await this.issueReport.invoke("config"),this.convertConfigToPublic(this.config)}onThemeChanged(e){return this.registry.add("on-theme-changed",e)}onSubmitFinished(e){return this.registry.add("on-submit-finished",e)}submitReport(e){return new Promise((t=>{e.sendEmail||(e.mailingList=null);const i=this.convertIssueReportToInternal(e),r=this.onSubmitFinished((e=>{r(),t(e)}));this.issueReport.send("submit",i)}))}closeReport(){return this.issueReport.send("cancel")}setBounds(e,t,i,r){return this.issueReport.send("resize",e,t,i,r)}openUrl(e){return this.issueReport.send("openUrl",e)}convertConfigToPublic(e){return{version:e.version,buildVersion:e.buildVersion,region:e.region,env:e.env,theme:e.theme,isError:e.isError,mailingList:e.mailList,createJiraTicket:e.jiraEnabled,sendEmail:e.mailEnabled,attachments:e.attachments,applicationTitle:e.applicationTitle,allowEditRecipients:e.allowEditRecipients,attachmentsViewMode:e.attachmentsViewMode,selectedCategories:e.selectedCategories,errorMessage:e.technicalInfo,environmentInfo:e.environmentDetails,showEnvironmentInfo:e.showEnvironmentInfo}}convertSubmitResultToPublic(e){return{description:e.description,jiraProcessed:e.jiraProcessed,jiraSucceeded:e.jiraSucceeded,jiraDetails:e.jiraDetails,jiraTicketUrl:e.jiraTicketUrl,emailProcessed:e.mailProcessed,emailSucceeded:e.mailSucceeded,emailDetails:e.mailDetails}}convertIssueReportToInternal(e){return{createTicket:e.createJiraTicket,description:e.description,sendMail:e.sendEmail,mailingList:e.mailingList,attachments:e.attachments,attachmentsMode:e.attachmentsViewMode}}};const v=a({config:{env:"",region:"",version:"",buildVersion:"",theme:"",isError:!1,mailingList:"",createJiraTicket:!0,sendEmail:!1,attachments:[],applicationTitle:"",allowEditRecipients:!0,attachmentsViewMode:"category",environmentInfo:"",selectedCategories:[],errorMessage:"",showEnvironmentInfo:!1},onThemeChanged:e=>{},openUrl:()=>{},submit:()=>Promise.resolve({}),setBounds:()=>{},close:()=>{}}),y=({children:t})=>{const{config:i,onThemeChanged:a,openUrl:o,submit:l,setBounds:c,close:d}=function(){const[e,t]=r({env:"",region:"",version:"",buildVersion:"",theme:"",isError:!1,mailingList:"",createJiraTicket:!0,sendEmail:!1,attachments:[],applicationTitle:"",allowEditRecipients:!0,attachmentsViewMode:"category",environmentInfo:"",selectedCategories:[],errorMessage:"",showEnvironmentInfo:!1});n((()=>{f.getConfig().then((e=>{t(e),e.theme?i(e.theme):i("dark")})).catch((e=>{throw new Error("Failed to get Issue Reporting Config:",e)})),f.onThemeChanged((e=>{i(e)}))}),[]);const i=e=>{const t=document.documentElement;return t.className="",t.classList.add(e),()=>{t.classList.remove(e)}};return{config:e,onThemeChanged:e=>f.onThemeChanged(e),openUrl:e=>{f.openUrl(e)},submit:e=>f.submitReport(e),setBounds:(e,t,i,r)=>{f.setBounds(e,t,i,r)},close:()=>{f.closeReport()}}}(),m=s((()=>({config:i,onThemeChanged:a,openUrl:o,submit:l,setBounds:c,close:d})),[i,a,l,d]);return e(v.Provider,{value:m,children:t})},k=()=>o(v),w=({className:t,...i})=>{const{close:r}=k();return e(m,{className:t,...i,children:e(p,{onClick:r})})},N=({className:i,...r})=>{const{config:n}=k(),{applicationTitle:a}=n;return t("div",{className:i?`header ${i}`:"header",...r,children:[e(d,{className:"draggable",text:a?`Feedback Form - ${a}`:"Feedback Form"}),e(w,{})]})},T=({className:i,text:r,hint:n,children:a,...s})=>t("div",{className:i?`block ${i}`:"block",...s,children:[r&&e("p",{children:r}),a,n&&e("small",{children:n})]}),E=({label:t,...i})=>e("label",{...i,children:t}),x=({className:i,id:r="input",disabled:n,placeholder:a="Please describe your issue...",value:s,label:o,...l})=>t("div",{className:i?`form-group ${i}`:"form-group",children:[o&&e(E,{htmlFor:r,label:o}),e("input",{type:"text",id:r,name:r,disabled:n,placeholder:a,value:s,...l})]}),C=({className:i,id:r="textarea",disabled:n,rows:a=4,placeholder:s="Please describe your issue...",value:o,label:l,...c})=>t("div",{className:i?`form-group ${i}`:"form-group",children:[l&&e(E,{htmlFor:r,label:l}),e("textarea",{id:r,name:r,disabled:n,rows:a,placeholder:s,value:o,...c})]}),R=({className:i,id:r="checkbox",disabled:n,checked:a,label:s="Checkbox",...o})=>t("div",{className:i?`form-group ${i}`:"form-group",children:[e("input",{type:"checkbox",id:r,name:r,disabled:n,checked:a,...o}),e(E,{htmlFor:r,label:s})]}),S=({className:i,categories:r,handleSubmit:n,submitting:a,showMailingList:s,setShowMailingList:o,...l})=>{const{config:c}=k(),{attachments:d,attachmentsViewMode:m,buildVersion:u,createJiraTicket:h,environmentInfo:p,sendEmail:g,showEnvironmentInfo:b,errorMessage:f,selectedCategories:v,mailingList:y}=c;return e("div",{className:i?`body ${i}`:"body",...l,children:t("form",{id:"feedback",onSubmit:e=>n(e),children:[e(T,{text:`Your feedback will be submitted to the ${u} team and some additional information will be automatically included to help us examine your issue.`}),e(T,{text:"Description",children:e(C,{name:"description",disabled:a})}),f&&e(T,{text:"Technical Information",children:e(C,{readOnly:!0,disabled:a,name:"errorMessage",value:f})}),p&&b&&e(T,{text:"Environment",children:e(C,{readOnly:!0,disabled:a,name:"environmentInfo",value:p})}),d&&d.length>0&&e(T,{text:"Attachments",children:"file"===m?d&&d.length>0?e("div",{className:"file-attachments",children:d.map((t=>e(R,{id:t.id,disabled:a,label:t.name,defaultChecked:-1!==v.indexOf(t.category)},t.id)))}):e("div",{children:"No Attachments"}):r&&r.length>0?e("div",{className:"checkbox-wrapper category-attachments",children:r.map((t=>e(R,{id:t,disabled:a,label:t,defaultChecked:-1!==v.indexOf(t)},t)))}):e("div",{children:"No Attachments"})}),e(T,{text:"Settings",children:t("div",{className:"checkbox-wrapper",children:[h&&e(R,{id:"createJiraTicket",disabled:a,defaultChecked:h,label:"Create Jira Ticket"}),g&&e(R,{onChange:()=>{o(!s)},id:"sendEmail",disabled:a,label:"Send Email",defaultChecked:g})]})}),g&&s&&e(T,{text:"Email List",hint:"Separate with commas or semicolons.",children:e(x,{id:"mailingList",disabled:a,defaultValue:y??"",placeholder:"john.doe@somedomain.com; jane.doe@otherdomain.com"})})]})})},I=({className:i,value:r=0,...n})=>e("div",{className:i?`progress ${i}`:"progress",...n,children:t("div",{className:"progress-bar",style:{width:`${r}%`},children:[r,"%"]})}),L=({className:r,type:n="primary",title:a="Alert title",text:s,children:o,...l})=>e("div",{className:r?`alert ${n} ${r}`:`alert ${n}`,...l,children:a?t(i,{children:[e("p",{className:`color-${n}`,children:a}),s&&e("p",{children:s}),o]}):null}),P=({className:t="primary",text:i="Submit",...r})=>e(h,{className:t,text:i,...r}),$=({text:t="Cancel",...i})=>e(h,{text:t,...i}),M=({className:i,submitCompleted:r,...n})=>{const{close:a}=k();return r?e(m,{className:i,...n,children:e(h,{onClick:a,className:"primary",text:"Close"})}):t(m,{className:i,...n,children:[e($,{onClick:a}),e(P,{form:"feedback",type:"submit"})]})},F=({className:i,submitting:r,submitStatus:n,submitCompleted:a,progressPercent:s,jiraTicketURL:o,...l})=>{const{openUrl:c}=k();return t("div",{className:i?`footer ${i}`:"footer",...l,children:[r&&e(T,{children:e(I,{value:s})}),t(T,{className:"footer-actions",children:[n.title&&e(L,{type:n.type,title:n.title,text:n.text,children:o&&e("a",{href:o,onClick:e=>{e.preventDefault(),c(o)},children:o})}),e(M,{submitCompleted:a})]})]})},j=({className:i,id:r="select",disabled:n,label:a,options:s,...o})=>t("div",{className:i?`form-group ${i}`:"form-group",children:[a&&e(E,{htmlFor:r,label:a}),e("select",{id:r,name:r,disabled:n,...o,children:s.map((t=>e("option",{children:t},t)))})]}),B=({className:i,id:r="radio",disabled:n,checked:a,label:s="Radio",...o})=>t("div",{className:i?`form-group ${i}`:"form-group",children:[e("input",{type:"radio",id:r,name:r,disabled:n,checked:a,...o}),e(E,{htmlFor:r,label:s})]}),J={Header:N,Body:S,Footer:F,Block:T,Title:d,Label:E,Input:x,Select:j,Checkbox:R,Radio:B,Textarea:C,Button:u,ButtonWithIcon:h,ButtonGroup:m,Progress:I,Alert:L,HeaderButtons:w,FooterButtons:M,SubmitButton:P,CancelButton:$,CloseButton:p},U=a(J),V=l((({children:t,components:i})=>{const r=s((()=>({...J,...i})),[i]);return e(U.Provider,{value:r,children:t})}));V.displayName="ComponentsStore";const H=({className:i,...a})=>{const{Header:s,Body:l,Footer:d}={...o(U),...m};var m;const{config:u,submit:h}=k(),{attachments:p,attachmentsViewMode:g,sendEmail:b}=u,f=c(),[v,y]=r(""),[w,N]=r(!1),[T,E]=r(!1),[x,C]=r(!1),[R,S]=r([]),[I,L]=r(0),[P,$]=r({type:"primary",title:"",text:""});n((()=>{M(p),E(b)}),[b,p]),n((()=>(w&&T&&(f.current=setTimeout((()=>{$({title:"Sending an email. Go to Outlook to allow access.",type:"primary"})}),100)),()=>clearTimeout(f.current))),[w]);const M=e=>{const t=new Set;e.filter((e=>{const i=t.has(e.category);return t.add(e.category),!i})),S(Array.from(t))},F=e=>{e.jiraProcessed&&($({title:e.jiraDetails,type:"success"}),y(e.jiraTicketUrl)),e.emailProcessed&&$({title:e.emailDetails,type:"success"})},j=(e=0,t=5)=>{let i=e;const r=setInterval((function(){100===i?clearInterval(r):(i+=t,L(i))}),24)};return t("div",{className:i?`feedback ${i}`:"feedback",...a,children:[e(s,{}),e(l,{handleSubmit:e=>{e.preventDefault();const t=new FormData(e.currentTarget),i=[];if("file"===g){p.filter((e=>"on"===t.get(e.id))).map((e=>i.push(e.id)))}else{const e=R?.filter((e=>"on"===t.get(e))),r=p.reduce(((t,i)=>(-1!==e.indexOf(i.category)&&t.push(i.id),t)),[]);i.push(...r)}const r={createJiraTicket:"on"===t.get("createJiraTicket"),sendEmail:"on"===t.get("sendEmail"),description:t.get("description"),mailingList:t.get("mailingList"),attachments:i,attachmentsViewMode:g};r.createJiraTicket||r.sendEmail?!r.sendEmail||r.mailingList?(r.createJiraTicket&&r.sendEmail&&($({title:"Submitting an issue to Jira and sending an email...",type:"primary"}),N(!0),j()),r.createJiraTicket?($({title:"Submitting an issue to Jira...",type:"primary"}),N(!0),j()):($({title:"Sending an email...",type:"primary"}),N(!0),j()),h(r).then((e=>{F(e),N(!1),C(!0),L(0),clearTimeout(f.current)})).catch((e=>console.log("An error occured while submitting:",e)))):$({title:"No email recipient. Provide at least one valid email address in the Email List field.",type:"error"}):$({title:"Can't send feedback. Issue reporting via Jira and email has been disabled in the system configuration.",type:"error"})},submitting:w,categories:R,showMailingList:T,setShowMailingList:E}),e(d,{submitting:w,submitStatus:P,submitCompleted:x,progressPercent:I,jiraTicketURL:v})]})},D=({components:t,...i})=>e(V,{components:t,children:e(H,{...i})});export{T as Block,S as Body,u as Button,m as ButtonGroup,h as ButtonWithIcon,$ as CancelButton,R as Checkbox,p as CloseButton,D as Feedback,F as Footer,M as FooterButtons,N as Header,w as HeaderButtons,x as Input,y as IssueReportingProvider,E as Label,B as Radio,j as Select,P as SubmitButton,C as Textarea,d as Title,k as useIssueReportingContext}; | ||
import{jsx as e,jsxs as t,Fragment as i}from"react/jsx-runtime";import{useState as r,useEffect as n,createContext as a,useMemo as s,useContext as o,memo as l,useRef as c}from"react";const d=({className:t,text:i="Feedback Form"})=>e("p",{className:t?`title ${t}`:"title",children:i}),m=({className:t,children:i,...r})=>e("div",{className:t?`button-group ${t}`:"button-group",...r,children:i}),u=({className:t,children:i,...r})=>e("button",{className:t?`button ${t}`:"button",type:"button",...r,children:i}),h=({icon:i,text:r,...n})=>t(u,{...n,children:[i&&e("i",{className:i}),r]}),p=({icon:t="icon icon-close",...i})=>e(h,{icon:t,...i});function g(e){if(e&&e.errorHandling&&"function"!=typeof e.errorHandling&&"log"!==e.errorHandling&&"silent"!==e.errorHandling&&"throw"!==e.errorHandling)throw new Error('Invalid options passed to createRegistry. Prop errorHandling should be ["log" | "silent" | "throw" | (err) => void], but '+typeof e.errorHandling+" was passed");var t=e&&"function"==typeof e.errorHandling&&e.errorHandling,i={};function r(i,r){var n=i instanceof Error?i:new Error(i);if(t)t(n);else{var a='[ERROR] callback-registry: User callback for key "'+r+'" failed: '+n.stack;if(e)switch(e.errorHandling){case"log":return console.error(a);case"silent":return;case"throw":throw new Error(a)}console.error(a)}}return{add:function(e,t,n){var a=i[e];return a||(a=[],i[e]=a),a.push(t),n&&setTimeout((function(){n.forEach((function(n){var a;if(null===(a=i[e])||void 0===a?void 0:a.includes(t))try{Array.isArray(n)?t.apply(void 0,n):t.apply(void 0,[n])}catch(t){r(t,e)}}))}),0),function(){var r=i[e];r&&(0===(r=r.reduce((function(e,i,r){return i===t&&e.length===r||e.push(i),e}),[])).length?delete i[e]:i[e]=r)}},execute:function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];var a=i[e];if(!a||0===a.length)return[];var s=[];return a.forEach((function(i){try{var n=i.apply(void 0,t);s.push(n)}catch(t){s.push(void 0),r(t,e)}})),s},clear:function(){i={}},clearKey:function(e){i[e]&&delete i[e]}}}g.default=g;var b=g;var f=new class{issueReport=window.issueReporting;registry=b();config;constructor(){window.onerror=(e,t,i,r,n)=>{this.issueReport.send("error",e,t,i,r,n)},this.issueReport.on("setTheme",(e=>{const t=e.newTheme;this.registry.execute("on-theme-changed",t)})),this.issueReport.on("submitEnded",(e=>{const t=this.convertSubmitResultToPublic(e);this.registry.execute("on-submit-finished",t)}))}async getConfig(){return this.config=await this.issueReport.invoke("config"),this.convertConfigToPublic(this.config)}onThemeChanged(e){return this.registry.add("on-theme-changed",e)}onSubmitFinished(e){return this.registry.add("on-submit-finished",e)}submitReport(e){return new Promise((t=>{e.sendEmail||(e.mailingList=null);const i=this.convertIssueReportToInternal(e),r=this.onSubmitFinished((e=>{r(),t(e)}));this.issueReport.send("submit",i)}))}closeReport(){return this.issueReport.send("cancel")}setBounds(e,t,i,r){return this.issueReport.send("resize",e,t,i,r)}openUrl(e){return this.issueReport.send("openUrl",e)}convertConfigToPublic(e){return{version:e.version,buildVersion:e.buildVersion,region:e.region,env:e.env,theme:e.theme,isError:e.isError,mailingList:e.mailList,createJiraTicket:e.jiraEnabled,sendEmail:e.mailEnabled,attachments:e.attachments,applicationTitle:e.applicationTitle,allowEditRecipients:e.allowEditRecipients,attachmentsViewMode:e.attachmentsViewMode,selectedCategories:e.selectedCategories,errorMessage:e.technicalInfo,environmentInfo:e.environmentDetails,showEnvironmentInfo:e.showEnvironmentInfo}}convertSubmitResultToPublic(e){return{description:e.description,jiraProcessed:e.jiraProcessed,jiraSucceeded:e.jiraSucceeded,jiraDetails:e.jiraDetails,jiraTicketUrl:e.jiraTicketUrl,emailProcessed:e.mailProcessed,emailSucceeded:e.mailSucceeded,emailDetails:e.mailDetails}}convertIssueReportToInternal(e){return{createTicket:e.createJiraTicket,description:e.description,sendMail:e.sendEmail,mailingList:e.mailingList,attachments:e.attachments,attachmentsMode:e.attachmentsViewMode}}};const v=a({config:{env:"",region:"",version:"",buildVersion:"",theme:"",isError:!1,mailingList:"",createJiraTicket:!0,sendEmail:!1,attachments:[],applicationTitle:"",allowEditRecipients:!0,attachmentsViewMode:"category",environmentInfo:"",selectedCategories:[],errorMessage:"",showEnvironmentInfo:!1},onThemeChanged:e=>{},openUrl:()=>{},submit:()=>Promise.resolve({}),setBounds:()=>{},close:()=>{}}),y=({children:t})=>{const{config:i,onThemeChanged:a,openUrl:o,submit:l,setBounds:c,close:d}=function(){const[e,t]=r({env:"",region:"",version:"",buildVersion:"",theme:"",isError:!1,mailingList:"",createJiraTicket:!0,sendEmail:!1,attachments:[],applicationTitle:"",allowEditRecipients:!0,attachmentsViewMode:"category",environmentInfo:"",selectedCategories:[],errorMessage:"",showEnvironmentInfo:!1});n((()=>{f.getConfig().then((e=>{t(e),e.theme?i(e.theme):i("dark")})).catch((e=>{throw new Error("Failed to get Issue Reporting Config:",e)})),f.onThemeChanged((e=>{i(e)}))}),[]);const i=e=>{const t=document.documentElement;return t.className="",t.classList.add(e),()=>{t.classList.remove(e)}};return{config:e,onThemeChanged:e=>f.onThemeChanged(e),openUrl:e=>{f.openUrl(e)},submit:e=>f.submitReport(e),setBounds:(e,t,i,r)=>{f.setBounds(e,t,i,r)},close:()=>{f.closeReport()}}}(),m=s((()=>({config:i,onThemeChanged:a,openUrl:o,submit:l,setBounds:c,close:d})),[i,a,l,d]);return e(v.Provider,{value:m,children:t})},k=()=>o(v),w=({className:t,...i})=>{const{close:r}=k();return e(m,{className:t,...i,children:e(p,{onClick:r})})},N=({className:i,...r})=>{const{config:n}=k(),{applicationTitle:a}=n;return t("div",{className:i?`header ${i}`:"header",...r,children:[e(d,{className:"draggable",text:a?`Feedback Form - ${a}`:"Feedback Form"}),e(w,{})]})},T=({className:i,text:r,hint:n,children:a,...s})=>t("div",{className:i?`block ${i}`:"block",...s,children:[r&&e("p",{children:r}),a,n&&e("small",{children:n})]}),E=({label:t,...i})=>e("label",{...i,children:t}),x=({className:i,id:r="input",disabled:n,placeholder:a="Please describe your issue...",value:s,label:o,...l})=>t("div",{className:i?`form-group ${i}`:"form-group",children:[o&&e(E,{htmlFor:r,label:o}),e("input",{type:"text",id:r,name:r,disabled:n,placeholder:a,value:s,...l})]}),C=({className:i,id:r="textarea",disabled:n,rows:a=4,placeholder:s="Please describe your issue...",value:o,label:l,...c})=>t("div",{className:i?`form-group ${i}`:"form-group",children:[l&&e(E,{htmlFor:r,label:l}),e("textarea",{id:r,name:r,disabled:n,rows:a,placeholder:s,value:o,...c})]}),R=({className:i,id:r="checkbox",disabled:n,checked:a,label:s="Checkbox",...o})=>t("div",{className:i?`form-group ${i}`:"form-group",children:[e("input",{type:"checkbox",id:r,name:r,disabled:n,checked:a,...o}),e(E,{htmlFor:r,label:s})]}),S=({className:i,categories:r,handleSubmit:n,submitting:a,showMailingList:s,setShowMailingList:o,...l})=>{const{config:c}=k(),{attachments:d,attachmentsViewMode:m,buildVersion:u,createJiraTicket:h,environmentInfo:p,sendEmail:g,showEnvironmentInfo:b,errorMessage:f,selectedCategories:v,mailingList:y}=c;return e("div",{className:i?`body ${i}`:"body",...l,children:t("form",{id:"feedback",onSubmit:e=>n(e),children:[e(T,{text:`Your feedback will be submitted to the ${u} team and some additional information will be automatically included to help us examine your issue.`}),e(T,{text:"Description",children:e(C,{name:"description",disabled:a})}),f&&e(T,{text:"Technical Information",children:e(C,{readOnly:!0,disabled:a,name:"errorMessage",value:f})}),p&&b&&e(T,{text:"Environment",children:e(C,{readOnly:!0,disabled:a,name:"environmentInfo",value:p})}),d&&d.length>0&&e(T,{text:"Attachments",children:"file"===m?d&&d.length>0?e("div",{className:"file-attachments",children:d.map((t=>e(R,{id:t.id,disabled:a,label:t.name,defaultChecked:-1!==v.indexOf(t.category)},t.id)))}):e("div",{children:"No Attachments"}):r&&r.length>0?e("div",{className:"checkbox-wrapper category-attachments",children:r.map((t=>e(R,{id:t,disabled:a,label:t,defaultChecked:-1!==v.indexOf(t)},t)))}):e("div",{children:"No Attachments"})}),e(T,{text:"Settings",children:t("div",{className:"checkbox-wrapper",children:[h&&e(R,{id:"createJiraTicket",disabled:a,defaultChecked:h,label:"Create Jira Ticket"}),g&&e(R,{onChange:()=>{o(!s)},id:"sendEmail",disabled:a,label:"Send Email",defaultChecked:g})]})}),g&&s&&e(T,{text:"Email List",hint:"Separate with commas or semicolons.",children:e(x,{id:"mailingList",disabled:a,defaultValue:y??"",placeholder:"john.doe@somedomain.com; jane.doe@otherdomain.com"})})]})})},I=({className:i,value:r=0,...n})=>e("div",{className:i?`progress ${i}`:"progress",...n,children:t("div",{className:"progress-bar",style:{width:`${r}%`},children:[r,"%"]})}),L=({className:r,type:n="primary",title:a="Alert title",text:s,children:o,...l})=>e("div",{className:r?`alert ${n} ${r}`:`alert ${n}`,...l,children:a?t(i,{children:[e("p",{className:`color-${n}`,children:a}),s&&e("p",{children:s}),o]}):null}),P=({className:t="primary",text:i="Submit",...r})=>e(h,{className:t,text:i,...r}),$=({text:t="Cancel",...i})=>e(h,{text:t,...i}),M=({className:i,submitCompleted:r,...n})=>{const{close:a}=k();return r?e(m,{className:i,...n,children:e(h,{onClick:a,className:"primary",text:"Close"})}):t(m,{className:i,...n,children:[e($,{onClick:a}),e(P,{form:"feedback",type:"submit"})]})},F=({className:i,submitting:r,submitStatus:n,submitCompleted:a,progressPercent:s,jiraTicketURL:o,...l})=>{const{openUrl:c}=k();return t("div",{className:i?`footer ${i}`:"footer",...l,children:[r&&e(T,{children:e(I,{value:s})}),t(T,{className:"footer-actions",children:[n.title&&e(L,{type:n.type,title:n.title,text:n.text,children:o&&e("a",{href:o,onClick:e=>{e.preventDefault(),c(o)},children:o})}),e(M,{submitCompleted:a})]})]})},j=({className:i,id:r="select",disabled:n,label:a,options:s,...o})=>t("div",{className:i?`form-group ${i}`:"form-group",children:[a&&e(E,{htmlFor:r,label:a}),e("select",{id:r,name:r,disabled:n,...o,children:s.map((t=>e("option",{children:t},t)))})]}),B=({className:i,id:r="radio",disabled:n,checked:a,label:s="Radio",...o})=>t("div",{className:i?`form-group ${i}`:"form-group",children:[e("input",{type:"radio",id:r,name:r,disabled:n,checked:a,...o}),e(E,{htmlFor:r,label:s})]}),J={Header:N,Body:S,Footer:F,Block:T,Title:d,Label:E,Input:x,Select:j,Checkbox:R,Radio:B,Textarea:C,Button:u,ButtonWithIcon:h,ButtonGroup:m,Progress:I,Alert:L,HeaderButtons:w,FooterButtons:M,SubmitButton:P,CancelButton:$,CloseButton:p},U=a(J),V=l((({children:t,components:i})=>{const r=s((()=>({...J,...i})),[i]);return e(U.Provider,{value:r,children:t})}));V.displayName="ComponentsStore";const H=({className:i,...a})=>{const{Header:s,Body:l,Footer:d}={...o(U),...m};var m;const{config:u,submit:h}=k(),{attachments:p,attachmentsViewMode:g,sendEmail:b}=u,f=c(),[v,y]=r(""),[w,N]=r(!1),[T,E]=r(!1),[x,C]=r(!1),[R,S]=r([]),[I,L]=r(0),[P,$]=r({type:"primary",title:"",text:""});n((()=>{M(p),E(b)}),[b,p]),n((()=>(w&&T&&(f.current=setTimeout((()=>{$({title:"Sending an email. Go to Outlook to allow access.",type:"primary"})}),100)),()=>clearTimeout(f.current))),[w]);const M=e=>{const t=new Set;e.filter((e=>{const i=t.has(e.category);return t.add(e.category),!i})),S(Array.from(t))},F=e=>{e.jiraProcessed&&($({title:e.jiraDetails,type:"success"}),y(e.jiraTicketUrl)),e.emailProcessed&&$({title:e.emailDetails,type:"success"})},j=(e=0,t=5)=>{let i=e;const r=setInterval((function(){100===i?clearInterval(r):(i+=t,L(i))}),24)};return t("div",{className:i?`feedback ${i}`:"feedback",...a,children:[e(s,{}),e(l,{handleSubmit:e=>{e.preventDefault();const t=new FormData(e.currentTarget),i=[];if("file"===g){p.filter((e=>"on"===t.get(e.id))).map((e=>i.push(e.id)))}else{const e=R?.filter((e=>"on"===t.get(e))),r=p.reduce(((t,i)=>(-1!==e.indexOf(i.category)&&t.push(i.id),t)),[]);i.push(...r)}const r={createJiraTicket:"on"===t.get("createJiraTicket"),sendEmail:"on"===t.get("sendEmail"),description:t.get("description"),mailingList:t.get("mailingList"),attachments:i,attachmentsViewMode:g};r.createJiraTicket||r.sendEmail?!r.sendEmail||r.mailingList?(r.createJiraTicket&&r.sendEmail&&($({title:"Submitting an issue to Jira and sending an email...",type:"primary"}),N(!0),j()),r.createJiraTicket?($({title:"Submitting an issue to Jira...",type:"primary"}),N(!0),j()):($({title:"Sending an email...",type:"primary"}),N(!0),j()),h(r).then((e=>{F(e),N(!1),C(!0),L(0),clearTimeout(f.current)})).catch((e=>console.log("An error occured while submitting:",e)))):$({title:"No email recipient. Provide at least one valid email address in the Email List field.",type:"error"}):$({title:"Can't send feedback. Issue reporting via Jira and email has been disabled in the system configuration.",type:"error"})},submitting:w,categories:R,showMailingList:T,setShowMailingList:E}),e(d,{submitting:w,submitStatus:P,submitCompleted:x,progressPercent:I,jiraTicketURL:v})]})},D=({components:t,...i})=>e(V,{components:t,children:e(H,{...i})});export{L as Alert,T as Block,S as Body,u as Button,m as ButtonGroup,h as ButtonWithIcon,$ as CancelButton,R as Checkbox,p as CloseButton,D as Feedback,F as Footer,M as FooterButtons,N as Header,w as HeaderButtons,x as Input,y as IssueReportingProvider,E as Label,I as Progress,B as Radio,j as Select,P as SubmitButton,C as Textarea,d as Title,k as useIssueReportingContext}; | ||
//# sourceMappingURL=index.js.map |
@@ -18,2 +18,3 @@ import * as react from 'react'; | ||
} | ||
declare const Alert: FunctionComponent<AlertProps>; | ||
@@ -23,2 +24,3 @@ interface ProgressProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> { | ||
} | ||
declare const Progress: FunctionComponent<ProgressProps>; | ||
@@ -220,2 +222,2 @@ interface ButtonGroupProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> { | ||
export { Block, BlockProps, Body, BodyProps, Button, ButtonGroup, ButtonGroupProps, ButtonProps, ButtonWithIcon, ButtonWithIconProps, CancelButton, Checkbox, CheckboxProps, CloseButton, Feedback, FeedbackProps, Footer, FooterButtons, FooterButtonsProps, FooterProps, Glue42Attachment, Glue42IssueReport, Glue42IssueReportingConfig, Glue42IssueReportingContext, Glue42ReportSubmitResult, Glue42SubmitStatus, Header, HeaderButtons, HeaderButtonsProps, HeaderProps, Input, InputProps, IssueReportingProvider, Label, LabelProps, Radio, RadioProps, Select, SelectProps, SubmitButton, Textarea, TextareaProps, Title, TitleProps, useIssueReportingContext }; | ||
export { Alert, AlertProps, Block, BlockProps, Body, BodyProps, Button, ButtonGroup, ButtonGroupProps, ButtonProps, ButtonWithIcon, ButtonWithIconProps, CancelButton, Checkbox, CheckboxProps, CloseButton, Feedback, FeedbackProps, Footer, FooterButtons, FooterButtonsProps, FooterProps, Glue42Attachment, Glue42IssueReport, Glue42IssueReportingConfig, Glue42IssueReportingContext, Glue42ReportSubmitResult, Glue42SubmitStatus, Header, HeaderButtons, HeaderButtonsProps, HeaderProps, Input, InputProps, IssueReportingProvider, Label, LabelProps, Progress, ProgressProps, Radio, RadioProps, Select, SelectProps, SubmitButton, Textarea, TextareaProps, Title, TitleProps, useIssueReportingContext }; |
{ | ||
"name": "@glue42/feedback-ui-react", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "React version of the Glue42 Feedback UI library", | ||
@@ -5,0 +5,0 @@ "author": { |
313
README.md
## Overview | ||
The [`@glue42/feedback-ui-react`](https://www.npmjs.com/package/@glue42/feedback-ui-react) library enables you to create your own Feedback App for [**Glue42 Enterprise**](https://glue42.com/enterprise/). The library allows complete customization of the Feedback Form. The provided default components can be replaced or extended with your custom ones. | ||
The default Glue42 Feedback Form: | ||
![Feedback Form](https://docs.glue42.com/images/platform-features/feedback-form.png) | ||
## Prerequisites | ||
@@ -17,12 +23,315 @@ | ||
To use your custom Feedback App built with the [`@glue42/feedback-ui-react`](https://www.npmjs.com/package/@glue42/feedback-ui-react) library, modify (or add) the `"form"` property to the `"issueReporting"` top-level key in the `system.json` file of [**Glue42 Enterprise**](https://glue42.com/enterprise/) located in `%LocalAppData%\Tick42\GlueDesktop\config`. Set the `"url"` property of the `"form"` object to the URL of your custom Feedback App: | ||
```json | ||
{ | ||
"issueReporting": { | ||
"form": { | ||
"url": "http://localhost:3000" | ||
} | ||
} | ||
} | ||
``` | ||
The `"form"` object has the following properties: | ||
| Property | Type | Description | | ||
|----------|------|-------------| | ||
| `"url"` | `string` | URL pointing to the location of the Feedback App. Defaults to `"file://%GDDIR%/assets/issue-reporting/index.html"`. | | ||
| `"width"` | `number` | Width in pixels for the Feedback Form. | | ||
| `"height"` | `number` | Height in pixels for the Feedback Form. | | ||
| `"showEnvironmentInfo"` | `boolean` | If `true`, the Feedback Form will show a field with details about the Glue42 environment. | | ||
*For more available customizations of the Feedback App through configuration, see the [Issue Reporting > Configuration](https://docs.glue42.com/glue42-concepts/glue42-platform-features/index.html#issue_reporting-configuration) documentation.* | ||
## Usage | ||
The [`@glue42/feedback-ui-react`](https://www.npmjs.com/package/@glue42/feedback-ui-react) library provides default components and hooks which you can use to build your own Feedback App by using, modifying or replacing the available components and functionalities. | ||
The [`@glue42/feedback-ui-react`](https://www.npmjs.com/package/@glue42/feedback-ui-react) library enables you to create your own Feedback App for [**Glue42 Enterprise**](https://glue42.com/enterprise/). The library provides [hooks](#hooks) and default [components](#components) which you can use to build your own Feedback App by using, modifying or replacing the available components and functionalities. | ||
### Hooks | ||
The `useIssueReportingContext()` hook provides context information about the Feedback App, as well as methods for the default Feedback functionalities which you can use directly in your custom components: | ||
```javascript | ||
const { | ||
close, | ||
config, | ||
onThemeChanged, | ||
openUrl, | ||
setBounds, | ||
submit, | ||
submitCompleted, | ||
} = useIssueReportingContext(); | ||
``` | ||
| Property | Type | Description | | ||
|----------|------|-------------| | ||
| `close()` | `function` | Closes the Feedback App. | | ||
| `config` | `object` | Object describing the configuration for the Feedback Form. | | ||
| `onThemeChanged()` | `(callback: (theme: string) => void) => void` | Method that can be used to track theme changes. The callback parameter is invoked every time the theme changes and receives as an argument the name of the new theme. | | ||
| `openUrl()` | `(url: string) => void` | Opens a URL in the default browser. Can be used to open the URL of the newly created Jira ticket after the issue report has been submitted. | | ||
| `setBounds()` | `(left: number, top: number, width: number, height: number) => void` | Sets the bounds of the Feedback Form. | | ||
| `submit()` | `function` | Submits an issue report. | | ||
| `submitCompleted` | `boolean` | Boolean flag indicating whether the issue report submit process has been completed. | | ||
The `config` object has the following properties: | ||
| Property | Type | Description | | ||
|----------|------|-------------| | ||
| `allowEditRecipients` | `boolean` | Flag indicating whether the user is allowed to manually add or remove email recipients. | | ||
| `applicationTitle` | `string` | Title of the Feedback App. | | ||
| `attachments` | `object[]` | Array of objects each with `id`, `name` and `category` properties describing the available attachments. | | ||
| `attachmentsViewMode` | `"file"` \| `"category"` | Describes how the attachments are displayed in the Feedback App. | | ||
| `buildVersion` | `string` | Platform build version as specified in the `"build"` top-level key of the `system.json` file of [**Glue42 Enterprise**](https://glue42.com/enterprise/). | | ||
| `createJiraTicket` | `boolean` | Flag indicating whether a Jira ticket will be created when the issue report has been submitted. | | ||
| `env` | `string` | Platform environment as specified in the `"env"` top-level key of the `system.json` configuration file of [**Glue42 Enterprise**](https://glue42.com/enterprise/). | | ||
| `environmentInfo` | `string` | Platform environment details. | | ||
| `errorMessage` | `string` | Error message sent by the platform. | | ||
| `isError` | `boolean` | Flag indicating whether the submitted feedback is about a platform error. | | ||
| `mailingList` | `string` | List of default email recipients. | | ||
| `region` | `string` | Platform region as specified in the `"region"` top-level key of the `system.json` configuration file of [**Glue42 Enterprise**](https://glue42.com/enterprise/). | | ||
| `selectedCategories` | `string[]` | List of selected attachments or attachment categories. | | ||
| `sendEmail` | `boolean` | Flag indicating whether an email with the issue report will be sent to the specified recipients. | | ||
| `showEnvironmentInfo` | `boolean` | Flag indicating whether the Feedback App will show a field with environment details about the platform. | | ||
| `theme` | `string` | The name of the current theme. | | ||
| `version` | `string` | Platform version. | | ||
### Components | ||
All default components can be reused and composed with custom code. If usage of such component has been detected, its default behavior will be applied. For instance, if you use the `<SubmitButton />` component, it will automatically submit the issue report when the button is clicked, without the need of custom code to induce this behavior. If you pass the same component more than once, an error will be thrown. | ||
To remove a component, pass a `<Fragment />` component. If you want to use a default functionality (e.g., for closing the Feedback Form) in your custom components, use the `useIssueReportingContext()` [hook](#hooks) to acquire it and pass it to your component. | ||
In your custom Feedback App, you should place the `<Feedback />` components in the `<IssueReportingProvider />` component. This component is a React context provider component that provides feedback-related data and functionality accessible through the `useIssueReportingContext()` hook. | ||
The following example demonstrates a basic usage of the library: | ||
```javascript | ||
import React from "react"; | ||
import { IssueReportingProvider } from "@glue42/feedback-ui-react"; | ||
import CustomFeedback from "./CustomFeedback"; | ||
const App = () => { | ||
return ( | ||
<IssueReportingProvider> | ||
<CustomFeedback /> | ||
</IssueReportingProvider> | ||
); | ||
}; | ||
export default App; | ||
``` | ||
The `<Header />` component holds the `<Title />` and the `<CloseButton />` button components. The following example demonstrates creating a header for the Feedback App with a custom title and an additional custom header button. The default `<CloseButton />` component is used with its default functionality for closing the Feedback App: | ||
```javascript | ||
import React from "react"; | ||
import { | ||
Title, | ||
CloseButton, | ||
ButtonGroup, | ||
useIssueReportingContext | ||
} from "@glue42/feedback-ui-react"; | ||
import CustomButton from "./CustomButton"; | ||
// Custom header title. | ||
const CustomTitle = () => { | ||
const { config } = useIssueReportingContext(); | ||
const { applicationTitle } = config; | ||
const title = applicationTitle ? `My ${applicationTitle}` : "My Custom Feedback App"; | ||
return <Title className="draggable" text={title} />; | ||
}; | ||
// This component holds the header buttons. | ||
const CustomHeaderButtons = () => { | ||
// Get the deafult funactionality for closing the Feedback App. | ||
const { close } = useIssueReportingContext(); | ||
return ( | ||
<ButtonGroup> | ||
<CustomButton /> | ||
<CloseButton onClick={close} /> | ||
</ButtonGroup> | ||
); | ||
}; | ||
// Custom header for the Feedback App. | ||
const CustomHeader = () => { | ||
return ( | ||
<div> | ||
<CustomTitle /> | ||
<CustomHeaderButtons /> | ||
</div> | ||
); | ||
}; | ||
export default CustomHeader; | ||
``` | ||
To use the custom header for the Feedback App, pass it to the `<Feedback />` component: | ||
```javascript | ||
import React from "react"; | ||
import { Feedback, IssueReportingProvider } from "@glue42/feedback-ui-react"; | ||
import CustomHeader from "./CustomHeader"; | ||
const App = () => { | ||
return ( | ||
<IssueReportingProvider> | ||
<Feedback | ||
components={{ | ||
Header: CustomHeader | ||
}} | ||
/> | ||
</IssueReportingProvider> | ||
); | ||
}; | ||
export default App; | ||
``` | ||
![Custom Header](https://docs.glue42.com/images/platform-features/feedback-custom-header.png) | ||
You can use the `<Body />` component to create a body for the Feedback App containing the desired issue reporting options - e.g., issue description field, attachments, Jira ticket and email options. The [`@glue42/feedback-ui-react`](https://www.npmjs.com/package/@glue42/feedback-ui-react) library provides various components to choose from when constructing the view of your custom form: `<TextArea />`, `<Checkbox />`, `<Block />`, `<Input />`, `<Select />` and more. | ||
The following example demonstrates creating a body for the Feedback App containing custom text informing the user what will happen when they click the "Submit" button, a text area for describing the issue, and a "Settings" section containing only a single restricted option for creating a Jira ticket: | ||
```javascript | ||
import React from "react"; | ||
import { | ||
Block, | ||
Textarea, | ||
Checkbox, | ||
useIssueReportingContext | ||
} from "@glue42/feedback-ui-react"; | ||
// Custom body for the Feedback App. | ||
const CustomBody = ({ handleSubmit, submitting }) => { | ||
const { config } = useIssueReportingContext(); | ||
const { buildVersion, createJiraTicket } = config; | ||
const customText = `Your feedback will be submitted to the ${buildVersion} team` | ||
+ (createJiraTicket ? " and a Jira ticket will be created." : ".") | ||
// The body contains the custom text, a text area for describing the issue, and a "Settings" section. | ||
return ( | ||
<div> | ||
<form onSubmit={event => handleSubmit(event)}> | ||
<Block text={customText} /> | ||
<Block text="Description"> | ||
<Textarea disabled={submitting} /> | ||
</Block> | ||
{createJiraTicket && | ||
<Block text="Settings"> | ||
<Checkbox | ||
disabled={true} | ||
defaultChecked={createJiraTicket} | ||
label="Create Jira Ticket" | ||
/> | ||
</Block>} | ||
</form> | ||
</div> | ||
); | ||
}; | ||
export default CustomBody; | ||
``` | ||
To use the custom body for the Feedback App, pass it to the `<Feedback />` component: | ||
```javascript | ||
import React from "react"; | ||
import { Feedback, IssueReportingProvider } from "@glue42/feedback-ui-react"; | ||
import CustomHeader from "./CustomFooter"; | ||
import CustomBody from "./CustomFooter"; | ||
const App = () => { | ||
return ( | ||
<IssueReportingProvider> | ||
<Feedback | ||
components={{ | ||
Header: CustomHeader, | ||
Body: CustomBody | ||
}} | ||
/> | ||
</IssueReportingProvider> | ||
); | ||
}; | ||
export default App; | ||
``` | ||
![Custom Body](https://docs.glue42.com/images/platform-features/feedback-custom-body.png) | ||
By default, the `<Footer />` component holds the `<FooterButtons />` component that renders conditionally either the `<SubmitButton />` and the `<CancelButton />` components, or a "Close" button based on whether submitting the issue report has been completed. During submission, the `<Footer />` component renders the `<Progress />` component showing the submission progress. When the submission is completed, the `<Footer />` component renders an `<Alert />` component showing the status of the submission, and if creating a Jira ticket has been enabled in the system configuration, a URL pointing to the created Jira ticket is also shown to the user. | ||
The following example demonstrates adding a custom footer button: | ||
```javascript | ||
import React from "react"; | ||
import { | ||
SubmitButton, | ||
CancelButton, | ||
ButtonGroup, | ||
useIssueReportingContext | ||
} from "@glue42/feedback-ui-react"; | ||
import CallSupportButton from "./CallSupportButton"; | ||
// This component holds the footer buttons. | ||
const CustomFooterButtons = () => { | ||
const { close } = useIssueReportingContext(); | ||
return ( | ||
<ButtonGroup> | ||
<SubmitButton form="feedback" type="submit" /> | ||
<CallSupportButton /> | ||
<CancelButton onClick={close} /> | ||
</ButtonGroup> | ||
); | ||
}; | ||
// Custom footer for the Feedback App. | ||
const CustomFooter = () => { | ||
return ( | ||
<div> | ||
<CustomFooterButtons /> | ||
</div> | ||
); | ||
}; | ||
export default CustomFooter; | ||
``` | ||
To use the custom footer for the Feedback App, pass it to the `<Feedback />` component: | ||
```javascript | ||
import React from "react"; | ||
import { Feedback, IssueReportingProvider } from "@glue42/feedback-ui-react"; | ||
import CustomHeader from "./CustomFooter"; | ||
import CustomBody from "./CustomFooter"; | ||
import CustomFooter from "./CustomFooter"; | ||
const App = () => { | ||
return ( | ||
<IssueReportingProvider> | ||
<Feedback | ||
components={{ | ||
Header: CustomHeader, | ||
Body: CustomBody, | ||
Footer: CustomFooter | ||
}} | ||
/> | ||
</IssueReportingProvider> | ||
); | ||
}; | ||
export default App; | ||
``` | ||
![Custom Footer](https://docs.glue42.com/images/platform-features/feedback-custom-footer.png) | ||
## License | ||
MIT © [](https://github.com/) | ||
MIT © [](https://github.com/) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
393682
819
336
1