@snf/access-qa-bot 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +181 -0
- package/build/asset-manifest.json +15 -0
- package/build/favicon.ico +0 -0
- package/build/index.html +1 -0
- package/build/logo192.png +0 -0
- package/build/logo512.png +0 -0
- package/build/manifest.json +25 -0
- package/build/robots.txt +3 -0
- package/build/static/css/main.css +2 -0
- package/build/static/css/main.css.map +1 -0
- package/build/static/js/453.chunk.js +2 -0
- package/build/static/js/453.chunk.js.map +1 -0
- package/build/static/js/main.js +3 -0
- package/build/static/js/main.js.LICENSE.txt +69 -0
- package/build/static/js/main.js.map +1 -0
- package/dist/access-qa-bot.js +56 -0
- package/dist/access-qa-bot.js.map +1 -0
- package/dist/access-qa-bot.standalone.js +48 -0
- package/dist/access-qa-bot.standalone.js.map +1 -0
- package/dist/access-qa-bot.umd.cjs +56 -0
- package/dist/access-qa-bot.umd.cjs.map +1 -0
- package/dist/access-qa-bot.umd.js +56 -0
- package/dist/access-qa-bot.umd.js.map +1 -0
- package/dist/index.esm.js +56 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +56 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/preact.esm.js +2 -0
- package/dist/preact.esm.js.map +1 -0
- package/dist/preact.js +2 -0
- package/dist/preact.js.map +1 -0
- package/dist/preact.umd.js +2 -0
- package/dist/preact.umd.js.map +1 -0
- package/dist/qa-bot-element.js +241 -0
- package/dist/qa-bot-element.js.map +1 -0
- package/dist/qa-bot-element.min.js +2 -0
- package/dist/qa-bot-element.min.js.map +1 -0
- package/dist/qa-bot-standalone.js +34372 -0
- package/dist/qa-bot-standalone.js.map +1 -0
- package/dist/qa-bot-standalone.min.js +105 -0
- package/dist/qa-bot-standalone.min.js.map +1 -0
- package/dist/web-component.js +56 -0
- package/dist/web-component.js.map +1 -0
- package/dist/web-components.js +228 -0
- package/dist/web-components.js.map +1 -0
- package/dist/web-components.min.js +2 -0
- package/dist/web-components.min.js.map +1 -0
- package/dist/web-components.umd.js +239 -0
- package/dist/web-components.umd.js.map +1 -0
- package/index.d.ts +51 -0
- package/package.json +84 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{h as e,render as t}from"preact";import o from"react-chatbotify";const s=t=>{const s=t.welcome||"Hello! What can I help you with?",a=t.prompt||"Questions should stand alone and not refer to previous ones.",i=t.embedded||!1,r=void 0!==t.isLoggedIn&&t.isLoggedIn,n=void 0!==t.disabled?t.disabled:!r,l=void 0!==t.isOpen&&t.isOpen,c=t.onClose,d=t.apiKey||process.env.REACT_APP_API_KEY;let p=!1;const m={start:{message:s,path:"loop"},loop:{message:async e=>{await(async e=>{try{const t={method:"POST",headers:{"Content-Type":"application/json","X-API-KEY":d},body:JSON.stringify({query:e.userInput})},o=await fetch("https://access-ai.ccs.uky.edu/api/query",t),s=(await o.json()).response;for(let t=0;t<s.length;t++)await e.streamMessage(s.slice(0,t+1)),await new Promise((e=>setTimeout(e,2)))}catch(t){await e.injectMessage("Unable to contact the Q&A Bot. Please try again later."),p=!0}})(e)},path:()=>p?"start":"loop"}},h=e("div",null,"Find out more ",e("a",{href:"https://support.access-ci.org/tools/access-qa-tool"},"about this tool")," or ",e("a",{href:"https://docs.google.com/forms/d/e/1FAIpQLSeWnE1r738GU1u_ri3TRpw9dItn6JNPi7-FH7QFB9bAHSVN0w/viewform"},"give us feedback"),".");return e("div",{className:"access-qa-bot"},e(o,{options:{theme:{primaryColor:"#1a5b6e",secondaryColor:"#107180",fontFamily:"Arial, sans-serif",embedded:i},header:{title:"ACCESS Q&A Bot",avatar:"https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg"},chatInput:{enabledPlaceholderText:a,disabledPlaceholderText:"Please log in to ask questions.",disabled:n},chatHistory:{disabled:!0},botBubble:{simStream:!0,dangerouslySetInnerHtml:!0},isOpen:l,onClose:c,chatButton:{icon:"https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg"},tooltip:{text:"Ask me about ACCESS! 😊"},audio:{disabled:!0},emoji:{disabled:!0},fileAttachment:{disabled:!0},notification:{disabled:!0},footer:{text:h}},flow:m}))};function a(o){const{target:a,version:i,isLoggedIn:r,isOpen:n,...l}=o;if(a&&a instanceof HTMLElement)return t(e(s,{isLoggedIn:r,isOpen:n,...l}),a),()=>{t(null,a)};console.error("QA Bot: A valid target DOM element is required")}export{s as QABot,a as default,a as qAndATool};
|
|
2
|
+
//# sourceMappingURL=preact.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preact.esm.js","sources":["../src/preact-wrapper.js"],"sourcesContent":["// This file provides a Preact-compatible wrapper around our QA Bot component\nimport { h, render } from 'preact';\nimport ChatBot from \"react-chatbotify\";\n\n// Main QA Bot component adapted for Preact\nconst QABot = (props) => {\n const welcome = props.welcome || 'Hello! What can I help you with?';\n const prompt = props.prompt || 'Questions should stand alone and not refer to previous ones.';\n const embedded = props.embedded || false;\n const isLoggedIn = props.isLoggedIn !== undefined ? props.isLoggedIn : false;\n const disabled = props.disabled !== undefined ? props.disabled : !isLoggedIn;\n const isOpen = props.isOpen !== undefined ? props.isOpen : false;\n const onClose = props.onClose;\n const apiKey = props.apiKey || process.env.REACT_APP_API_KEY;\n let hasError = false;\n\n const handleQuery = async (params) => {\n try {\n const requestOptions = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-KEY': apiKey\n },\n body: JSON.stringify({ query: params.userInput })\n };\n\n const response = await fetch('https://access-ai.ccs.uky.edu/api/query', requestOptions);\n const body = await response.json();\n const text = body.response;\n\n for (let i = 0; i < text.length; i++) {\n await params.streamMessage(text.slice(0, i + 1));\n await new Promise(resolve => setTimeout(resolve, 2));\n }\n } catch (error) {\n await params.injectMessage(\"Unable to contact the Q&A Bot. Please try again later.\");\n hasError = true;\n }\n };\n\n const flow = {\n start: {\n message: welcome,\n path: 'loop'\n },\n loop: {\n message: async (params) => {\n await handleQuery(params);\n },\n path: () => {\n if (hasError) {\n return 'start';\n }\n return 'loop';\n }\n }\n };\n\n const footerText = h('div', null,\n 'Find out more ',\n h('a', { href: 'https://support.access-ci.org/tools/access-qa-tool' }, 'about this tool'),\n ' or ',\n h('a', { href: 'https://docs.google.com/forms/d/e/1FAIpQLSeWnE1r738GU1u_ri3TRpw9dItn6JNPi7-FH7QFB9bAHSVN0w/viewform' }, 'give us feedback'),\n '.'\n );\n\n return h(\n 'div',\n { className: 'access-qa-bot' },\n h(ChatBot, {\n options: {\n theme: {\n primaryColor: '#1a5b6e',\n secondaryColor: '#107180',\n fontFamily: 'Arial, sans-serif',\n embedded: embedded,\n },\n header: {\n title: 'ACCESS Q&A Bot',\n avatar: 'https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg',\n },\n chatInput: {\n enabledPlaceholderText: prompt,\n disabledPlaceholderText: 'Please log in to ask questions.',\n disabled: disabled\n },\n chatHistory: { disabled: true },\n botBubble: {\n simStream: true,\n dangerouslySetInnerHtml: true\n },\n isOpen: isOpen,\n onClose: onClose,\n chatButton: {\n icon: 'https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg',\n },\n tooltip: {\n text: 'Ask me about ACCESS! 😊',\n },\n audio: {\n disabled: true,\n },\n emoji: {\n disabled: true,\n },\n fileAttachment: {\n disabled: true,\n },\n notification: {\n disabled: true,\n },\n footer: {\n text: footerText,\n },\n },\n flow: flow\n })\n );\n};\n\n// Function-based API for non-Preact environments\nexport function qAndATool(config) {\n const { target, version, isLoggedIn, isOpen, ...otherProps } = config;\n\n if (!target || !(target instanceof HTMLElement)) {\n console.error('QA Bot: A valid target DOM element is required');\n return;\n }\n\n render(\n h(QABot, {\n isLoggedIn: isLoggedIn,\n isOpen: isOpen,\n ...otherProps\n }),\n target\n );\n\n // Return a cleanup function\n return () => {\n // Unmount by rendering null\n render(null, target);\n };\n}\n\nexport { QABot };\nexport default qAndATool;"],"names":["QABot","props","welcome","prompt","embedded","isLoggedIn","undefined","disabled","isOpen","onClose","apiKey","process","env","REACT_APP_API_KEY","hasError","flow","start","message","path","loop","async","requestOptions","method","headers","body","JSON","stringify","query","params","userInput","response","fetch","text","json","i","length","streamMessage","slice","Promise","resolve","setTimeout","error","injectMessage","handleQuery","footerText","h","href","className","ChatBot","options","theme","primaryColor","secondaryColor","fontFamily","header","title","avatar","chatInput","enabledPlaceholderText","disabledPlaceholderText","chatHistory","botBubble","simStream","dangerouslySetInnerHtml","chatButton","icon","tooltip","audio","emoji","fileAttachment","notification","footer","qAndATool","config","target","version","otherProps","HTMLElement","render","console"],"mappings":"uEAKMA,MAAAA,EAASC,IACb,MAAMC,EAAUD,EAAMC,SAAW,mCAC3BC,EAASF,EAAME,QAAU,+DACzBC,EAAWH,EAAMG,WAAY,EAC7BC,OAAkCC,IAArBL,EAAMI,YAA2BJ,EAAMI,WACpDE,OAA8BD,IAAnBL,EAAMM,SAAyBN,EAAMM,UAAYF,EAC5DG,OAA0BF,IAAjBL,EAAMO,QAAuBP,EAAMO,OAC5CC,EAAUR,EAAMQ,QAChBC,EAAST,EAAMS,QAAUC,QAAQC,IAAIC,kBAC3C,IAAIC,GAAW,EAEf,MAyBMC,EAAO,CACXC,MAAO,CACLC,QAASf,EACTgB,KAAM,QAERC,KAAM,CACJF,QAASG,eA/BOA,WAClB,IACE,MAAMC,EAAiB,CACrBC,OAAQ,OACRC,QAAS,CACP,eAAgB,mBAChB,YAAab,GAEfc,KAAMC,KAAKC,UAAU,CAAEC,MAAOC,EAAOC,aAGjCC,QAAiBC,MAAM,0CAA2CV,GAElEW,SADaF,EAASG,QACVH,SAElB,IAAK,IAAII,EAAI,EAAGA,EAAIF,EAAKG,OAAQD,UACzBN,EAAOQ,cAAcJ,EAAKK,MAAM,EAAGH,EAAI,UACvC,IAAII,SAAQC,GAAWC,WAAWD,EAAS,IAEpD,CAAC,MAAOE,SACDb,EAAOc,cAAc,0DAC3B5B,GAAW,CACb,GAUU6B,CAAYf,EAAO,EAE3BV,KAAMA,IACAJ,EACK,QAEF,SAKP8B,EAAaC,EAAE,MAAO,KAC1B,iBACAA,EAAE,IAAK,CAAEC,KAAM,sDAAwD,mBACvE,OACAD,EAAE,IAAK,CAAEC,KAAM,uGAAyG,oBACxH,KAGF,OAAOD,EACL,MACA,CAAEE,UAAW,iBACbF,EAAEG,EAAS,CACTC,QAAS,CACPC,MAAO,CACLC,aAAc,UACdC,eAAgB,UAChBC,WAAY,oBACZjD,SAAUA,GAEZkD,OAAQ,CACNC,MAAO,iBACPC,OAAQ,yFAEVC,UAAW,CACTC,uBAAwBvD,EACxBwD,wBAAyB,kCACzBpD,SAAUA,GAEZqD,YAAa,CAAErD,UAAU,GACzBsD,UAAW,CACTC,WAAW,EACXC,yBAAyB,GAE3BvD,OAAQA,EACRC,QAASA,EACTuD,WAAY,CACVC,KAAM,yFAERC,QAAS,CACPlC,KAAM,2BAERmC,MAAO,CACL5D,UAAU,GAEZ6D,MAAO,CACL7D,UAAU,GAEZ8D,eAAgB,CACd9D,UAAU,GAEZ+D,aAAc,CACZ/D,UAAU,GAEZgE,OAAQ,CACNvC,KAAMY,IAGV7B,KAAMA,IAET,EAII,SAASyD,EAAUC,GACxB,MAAMC,OAAEA,EAAMC,QAAEA,EAAOtE,WAAEA,EAAUG,OAAEA,KAAWoE,GAAeH,EAE/D,GAAKC,GAAYA,aAAkBG,YAenC,OAVAC,EACEjC,EAAE7C,EAAO,CACPK,WAAYA,EACZG,OAAQA,KACLoE,IAELF,GAIK,KAELI,EAAO,KAAMJ,EAAO,EAhBpBK,QAAQtC,MAAM,iDAkBlB"}
|
package/dist/preact.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("preact"),t=require("react-chatbotify");const o=o=>{const s=o.welcome||"Hello! What can I help you with?",a=o.prompt||"Questions should stand alone and not refer to previous ones.",i=o.embedded||!1,r=void 0!==o.isLoggedIn&&o.isLoggedIn,n=void 0!==o.disabled?o.disabled:!r,l=void 0!==o.isOpen&&o.isOpen,c=o.onClose,d=o.apiKey||process.env.REACT_APP_API_KEY;let p=!1;const h={start:{message:s,path:"loop"},loop:{message:async e=>{await(async e=>{try{const t={method:"POST",headers:{"Content-Type":"application/json","X-API-KEY":d},body:JSON.stringify({query:e.userInput})},o=await fetch("https://access-ai.ccs.uky.edu/api/query",t),s=(await o.json()).response;for(let t=0;t<s.length;t++)await e.streamMessage(s.slice(0,t+1)),await new Promise((e=>setTimeout(e,2)))}catch(t){await e.injectMessage("Unable to contact the Q&A Bot. Please try again later."),p=!0}})(e)},path:()=>p?"start":"loop"}},u=e.h("div",null,"Find out more ",e.h("a",{href:"https://support.access-ci.org/tools/access-qa-tool"},"about this tool")," or ",e.h("a",{href:"https://docs.google.com/forms/d/e/1FAIpQLSeWnE1r738GU1u_ri3TRpw9dItn6JNPi7-FH7QFB9bAHSVN0w/viewform"},"give us feedback"),".");return e.h("div",{className:"access-qa-bot"},e.h(t,{options:{theme:{primaryColor:"#1a5b6e",secondaryColor:"#107180",fontFamily:"Arial, sans-serif",embedded:i},header:{title:"ACCESS Q&A Bot",avatar:"https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg"},chatInput:{enabledPlaceholderText:a,disabledPlaceholderText:"Please log in to ask questions.",disabled:n},chatHistory:{disabled:!0},botBubble:{simStream:!0,dangerouslySetInnerHtml:!0},isOpen:l,onClose:c,chatButton:{icon:"https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg"},tooltip:{text:"Ask me about ACCESS! 😊"},audio:{disabled:!0},emoji:{disabled:!0},fileAttachment:{disabled:!0},notification:{disabled:!0},footer:{text:u}},flow:h}))};function s(t){const{target:s,version:a,isLoggedIn:i,isOpen:r,...n}=t;if(s&&s instanceof HTMLElement)return e.render(e.h(o,{isLoggedIn:i,isOpen:r,...n}),s),()=>{e.render(null,s)};console.error("QA Bot: A valid target DOM element is required")}exports.QABot=o,exports.default=s,exports.qAndATool=s;
|
|
2
|
+
//# sourceMappingURL=preact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preact.js","sources":["../src/preact-wrapper.js"],"sourcesContent":["// This file provides a Preact-compatible wrapper around our QA Bot component\nimport { h, render } from 'preact';\nimport ChatBot from \"react-chatbotify\";\n\n// Main QA Bot component adapted for Preact\nconst QABot = (props) => {\n const welcome = props.welcome || 'Hello! What can I help you with?';\n const prompt = props.prompt || 'Questions should stand alone and not refer to previous ones.';\n const embedded = props.embedded || false;\n const isLoggedIn = props.isLoggedIn !== undefined ? props.isLoggedIn : false;\n const disabled = props.disabled !== undefined ? props.disabled : !isLoggedIn;\n const isOpen = props.isOpen !== undefined ? props.isOpen : false;\n const onClose = props.onClose;\n const apiKey = props.apiKey || process.env.REACT_APP_API_KEY;\n let hasError = false;\n\n const handleQuery = async (params) => {\n try {\n const requestOptions = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-KEY': apiKey\n },\n body: JSON.stringify({ query: params.userInput })\n };\n\n const response = await fetch('https://access-ai.ccs.uky.edu/api/query', requestOptions);\n const body = await response.json();\n const text = body.response;\n\n for (let i = 0; i < text.length; i++) {\n await params.streamMessage(text.slice(0, i + 1));\n await new Promise(resolve => setTimeout(resolve, 2));\n }\n } catch (error) {\n await params.injectMessage(\"Unable to contact the Q&A Bot. Please try again later.\");\n hasError = true;\n }\n };\n\n const flow = {\n start: {\n message: welcome,\n path: 'loop'\n },\n loop: {\n message: async (params) => {\n await handleQuery(params);\n },\n path: () => {\n if (hasError) {\n return 'start';\n }\n return 'loop';\n }\n }\n };\n\n const footerText = h('div', null,\n 'Find out more ',\n h('a', { href: 'https://support.access-ci.org/tools/access-qa-tool' }, 'about this tool'),\n ' or ',\n h('a', { href: 'https://docs.google.com/forms/d/e/1FAIpQLSeWnE1r738GU1u_ri3TRpw9dItn6JNPi7-FH7QFB9bAHSVN0w/viewform' }, 'give us feedback'),\n '.'\n );\n\n return h(\n 'div',\n { className: 'access-qa-bot' },\n h(ChatBot, {\n options: {\n theme: {\n primaryColor: '#1a5b6e',\n secondaryColor: '#107180',\n fontFamily: 'Arial, sans-serif',\n embedded: embedded,\n },\n header: {\n title: 'ACCESS Q&A Bot',\n avatar: 'https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg',\n },\n chatInput: {\n enabledPlaceholderText: prompt,\n disabledPlaceholderText: 'Please log in to ask questions.',\n disabled: disabled\n },\n chatHistory: { disabled: true },\n botBubble: {\n simStream: true,\n dangerouslySetInnerHtml: true\n },\n isOpen: isOpen,\n onClose: onClose,\n chatButton: {\n icon: 'https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg',\n },\n tooltip: {\n text: 'Ask me about ACCESS! 😊',\n },\n audio: {\n disabled: true,\n },\n emoji: {\n disabled: true,\n },\n fileAttachment: {\n disabled: true,\n },\n notification: {\n disabled: true,\n },\n footer: {\n text: footerText,\n },\n },\n flow: flow\n })\n );\n};\n\n// Function-based API for non-Preact environments\nexport function qAndATool(config) {\n const { target, version, isLoggedIn, isOpen, ...otherProps } = config;\n\n if (!target || !(target instanceof HTMLElement)) {\n console.error('QA Bot: A valid target DOM element is required');\n return;\n }\n\n render(\n h(QABot, {\n isLoggedIn: isLoggedIn,\n isOpen: isOpen,\n ...otherProps\n }),\n target\n );\n\n // Return a cleanup function\n return () => {\n // Unmount by rendering null\n render(null, target);\n };\n}\n\nexport { QABot };\nexport default qAndATool;"],"names":["QABot","props","welcome","prompt","embedded","isLoggedIn","undefined","disabled","isOpen","onClose","apiKey","process","env","REACT_APP_API_KEY","hasError","flow","start","message","path","loop","async","requestOptions","method","headers","body","JSON","stringify","query","params","userInput","response","fetch","text","json","i","length","streamMessage","slice","Promise","resolve","setTimeout","error","injectMessage","handleQuery","footerText","h","href","className","ChatBot","options","theme","primaryColor","secondaryColor","fontFamily","header","title","avatar","chatInput","enabledPlaceholderText","disabledPlaceholderText","chatHistory","botBubble","simStream","dangerouslySetInnerHtml","chatButton","icon","tooltip","audio","emoji","fileAttachment","notification","footer","qAndATool","config","target","version","otherProps","HTMLElement","render","console"],"mappings":"0HAKMA,MAAAA,EAASC,IACb,MAAMC,EAAUD,EAAMC,SAAW,mCAC3BC,EAASF,EAAME,QAAU,+DACzBC,EAAWH,EAAMG,WAAY,EAC7BC,OAAkCC,IAArBL,EAAMI,YAA2BJ,EAAMI,WACpDE,OAA8BD,IAAnBL,EAAMM,SAAyBN,EAAMM,UAAYF,EAC5DG,OAA0BF,IAAjBL,EAAMO,QAAuBP,EAAMO,OAC5CC,EAAUR,EAAMQ,QAChBC,EAAST,EAAMS,QAAUC,QAAQC,IAAIC,kBAC3C,IAAIC,GAAW,EAEf,MAyBMC,EAAO,CACXC,MAAO,CACLC,QAASf,EACTgB,KAAM,QAERC,KAAM,CACJF,QAASG,eA/BOA,WAClB,IACE,MAAMC,EAAiB,CACrBC,OAAQ,OACRC,QAAS,CACP,eAAgB,mBAChB,YAAab,GAEfc,KAAMC,KAAKC,UAAU,CAAEC,MAAOC,EAAOC,aAGjCC,QAAiBC,MAAM,0CAA2CV,GAElEW,SADaF,EAASG,QACVH,SAElB,IAAK,IAAII,EAAI,EAAGA,EAAIF,EAAKG,OAAQD,UACzBN,EAAOQ,cAAcJ,EAAKK,MAAM,EAAGH,EAAI,UACvC,IAAII,SAAQC,GAAWC,WAAWD,EAAS,IAEpD,CAAC,MAAOE,SACDb,EAAOc,cAAc,0DAC3B5B,GAAW,CACb,GAUU6B,CAAYf,EAAO,EAE3BV,KAAMA,IACAJ,EACK,QAEF,SAKP8B,EAAaC,EAAAA,EAAE,MAAO,KAC1B,iBACAA,EAACA,EAAC,IAAK,CAAEC,KAAM,sDAAwD,mBACvE,OACAD,EAAAA,EAAE,IAAK,CAAEC,KAAM,uGAAyG,oBACxH,KAGF,OAAOD,EAAAA,EACL,MACA,CAAEE,UAAW,iBACbF,EAAAA,EAAEG,EAAS,CACTC,QAAS,CACPC,MAAO,CACLC,aAAc,UACdC,eAAgB,UAChBC,WAAY,oBACZjD,SAAUA,GAEZkD,OAAQ,CACNC,MAAO,iBACPC,OAAQ,yFAEVC,UAAW,CACTC,uBAAwBvD,EACxBwD,wBAAyB,kCACzBpD,SAAUA,GAEZqD,YAAa,CAAErD,UAAU,GACzBsD,UAAW,CACTC,WAAW,EACXC,yBAAyB,GAE3BvD,OAAQA,EACRC,QAASA,EACTuD,WAAY,CACVC,KAAM,yFAERC,QAAS,CACPlC,KAAM,2BAERmC,MAAO,CACL5D,UAAU,GAEZ6D,MAAO,CACL7D,UAAU,GAEZ8D,eAAgB,CACd9D,UAAU,GAEZ+D,aAAc,CACZ/D,UAAU,GAEZgE,OAAQ,CACNvC,KAAMY,IAGV7B,KAAMA,IAET,EAII,SAASyD,EAAUC,GACxB,MAAMC,OAAEA,EAAMC,QAAEA,EAAOtE,WAAEA,EAAUG,OAAEA,KAAWoE,GAAeH,EAE/D,GAAKC,GAAYA,aAAkBG,YAenC,OAVAC,EAAMA,OACJjC,EAACA,EAAC7C,EAAO,CACPK,WAAYA,EACZG,OAAQA,KACLoE,IAELF,GAIK,KAELI,EAAMA,OAAC,KAAMJ,EAAO,EAhBpBK,QAAQtC,MAAM,iDAkBlB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("preact"),require("react-chatbotify")):"function"==typeof define&&define.amd?define(["exports","preact","react-chatbotify"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).accessQABotPreact={},e.preact,e.ChatBot)}(this,(function(e,t,o){"use strict";const s=e=>{const s=e.welcome||"Hello! What can I help you with?",a=e.prompt||"Questions should stand alone and not refer to previous ones.",i=e.embedded||!1,n=void 0!==e.isLoggedIn&&e.isLoggedIn,r=void 0!==e.disabled?e.disabled:!n,c=void 0!==e.isOpen&&e.isOpen,d=e.onClose,l=e.apiKey||process.env.REACT_APP_API_KEY;let p=!1;const h={start:{message:s,path:"loop"},loop:{message:async e=>{await(async e=>{try{const t={method:"POST",headers:{"Content-Type":"application/json","X-API-KEY":l},body:JSON.stringify({query:e.userInput})},o=await fetch("https://access-ai.ccs.uky.edu/api/query",t),s=(await o.json()).response;for(let t=0;t<s.length;t++)await e.streamMessage(s.slice(0,t+1)),await new Promise((e=>setTimeout(e,2)))}catch(t){await e.injectMessage("Unable to contact the Q&A Bot. Please try again later."),p=!0}})(e)},path:()=>p?"start":"loop"}},u=t.h("div",null,"Find out more ",t.h("a",{href:"https://support.access-ci.org/tools/access-qa-tool"},"about this tool")," or ",t.h("a",{href:"https://docs.google.com/forms/d/e/1FAIpQLSeWnE1r738GU1u_ri3TRpw9dItn6JNPi7-FH7QFB9bAHSVN0w/viewform"},"give us feedback"),".");return t.h("div",{className:"access-qa-bot"},t.h(o,{options:{theme:{primaryColor:"#1a5b6e",secondaryColor:"#107180",fontFamily:"Arial, sans-serif",embedded:i},header:{title:"ACCESS Q&A Bot",avatar:"https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg"},chatInput:{enabledPlaceholderText:a,disabledPlaceholderText:"Please log in to ask questions.",disabled:r},chatHistory:{disabled:!0},botBubble:{simStream:!0,dangerouslySetInnerHtml:!0},isOpen:c,onClose:d,chatButton:{icon:"https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg"},tooltip:{text:"Ask me about ACCESS! 😊"},audio:{disabled:!0},emoji:{disabled:!0},fileAttachment:{disabled:!0},notification:{disabled:!0},footer:{text:u}},flow:h}))};function a(e){const{target:o,version:a,isLoggedIn:i,isOpen:n,...r}=e;if(o&&o instanceof HTMLElement)return t.render(t.h(s,{isLoggedIn:i,isOpen:n,...r}),o),()=>{t.render(null,o)};console.error("QA Bot: A valid target DOM element is required")}e.QABot=s,e.default=a,e.qAndATool=a,Object.defineProperty(e,"__esModule",{value:!0})}));
|
|
2
|
+
//# sourceMappingURL=preact.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preact.umd.js","sources":["../src/preact-wrapper.js"],"sourcesContent":["// This file provides a Preact-compatible wrapper around our QA Bot component\nimport { h, render } from 'preact';\nimport ChatBot from \"react-chatbotify\";\n\n// Main QA Bot component adapted for Preact\nconst QABot = (props) => {\n const welcome = props.welcome || 'Hello! What can I help you with?';\n const prompt = props.prompt || 'Questions should stand alone and not refer to previous ones.';\n const embedded = props.embedded || false;\n const isLoggedIn = props.isLoggedIn !== undefined ? props.isLoggedIn : false;\n const disabled = props.disabled !== undefined ? props.disabled : !isLoggedIn;\n const isOpen = props.isOpen !== undefined ? props.isOpen : false;\n const onClose = props.onClose;\n const apiKey = props.apiKey || process.env.REACT_APP_API_KEY;\n let hasError = false;\n\n const handleQuery = async (params) => {\n try {\n const requestOptions = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-KEY': apiKey\n },\n body: JSON.stringify({ query: params.userInput })\n };\n\n const response = await fetch('https://access-ai.ccs.uky.edu/api/query', requestOptions);\n const body = await response.json();\n const text = body.response;\n\n for (let i = 0; i < text.length; i++) {\n await params.streamMessage(text.slice(0, i + 1));\n await new Promise(resolve => setTimeout(resolve, 2));\n }\n } catch (error) {\n await params.injectMessage(\"Unable to contact the Q&A Bot. Please try again later.\");\n hasError = true;\n }\n };\n\n const flow = {\n start: {\n message: welcome,\n path: 'loop'\n },\n loop: {\n message: async (params) => {\n await handleQuery(params);\n },\n path: () => {\n if (hasError) {\n return 'start';\n }\n return 'loop';\n }\n }\n };\n\n const footerText = h('div', null,\n 'Find out more ',\n h('a', { href: 'https://support.access-ci.org/tools/access-qa-tool' }, 'about this tool'),\n ' or ',\n h('a', { href: 'https://docs.google.com/forms/d/e/1FAIpQLSeWnE1r738GU1u_ri3TRpw9dItn6JNPi7-FH7QFB9bAHSVN0w/viewform' }, 'give us feedback'),\n '.'\n );\n\n return h(\n 'div',\n { className: 'access-qa-bot' },\n h(ChatBot, {\n options: {\n theme: {\n primaryColor: '#1a5b6e',\n secondaryColor: '#107180',\n fontFamily: 'Arial, sans-serif',\n embedded: embedded,\n },\n header: {\n title: 'ACCESS Q&A Bot',\n avatar: 'https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg',\n },\n chatInput: {\n enabledPlaceholderText: prompt,\n disabledPlaceholderText: 'Please log in to ask questions.',\n disabled: disabled\n },\n chatHistory: { disabled: true },\n botBubble: {\n simStream: true,\n dangerouslySetInnerHtml: true\n },\n isOpen: isOpen,\n onClose: onClose,\n chatButton: {\n icon: 'https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg',\n },\n tooltip: {\n text: 'Ask me about ACCESS! 😊',\n },\n audio: {\n disabled: true,\n },\n emoji: {\n disabled: true,\n },\n fileAttachment: {\n disabled: true,\n },\n notification: {\n disabled: true,\n },\n footer: {\n text: footerText,\n },\n },\n flow: flow\n })\n );\n};\n\n// Function-based API for non-Preact environments\nexport function qAndATool(config) {\n const { target, version, isLoggedIn, isOpen, ...otherProps } = config;\n\n if (!target || !(target instanceof HTMLElement)) {\n console.error('QA Bot: A valid target DOM element is required');\n return;\n }\n\n render(\n h(QABot, {\n isLoggedIn: isLoggedIn,\n isOpen: isOpen,\n ...otherProps\n }),\n target\n );\n\n // Return a cleanup function\n return () => {\n // Unmount by rendering null\n render(null, target);\n };\n}\n\nexport { QABot };\nexport default qAndATool;"],"names":["QABot","props","welcome","prompt","embedded","isLoggedIn","undefined","disabled","isOpen","onClose","apiKey","process","env","REACT_APP_API_KEY","hasError","flow","start","message","path","loop","async","requestOptions","method","headers","body","JSON","stringify","query","params","userInput","response","fetch","text","json","i","length","streamMessage","slice","Promise","resolve","setTimeout","error","injectMessage","handleQuery","footerText","h","href","className","ChatBot","options","theme","primaryColor","secondaryColor","fontFamily","header","title","avatar","chatInput","enabledPlaceholderText","disabledPlaceholderText","chatHistory","botBubble","simStream","dangerouslySetInnerHtml","chatButton","icon","tooltip","audio","emoji","fileAttachment","notification","footer","qAndATool","config","target","version","otherProps","HTMLElement","render","console"],"mappings":"0VAKMA,MAAAA,EAASC,IACb,MAAMC,EAAUD,EAAMC,SAAW,mCAC3BC,EAASF,EAAME,QAAU,+DACzBC,EAAWH,EAAMG,WAAY,EAC7BC,OAAkCC,IAArBL,EAAMI,YAA2BJ,EAAMI,WACpDE,OAA8BD,IAAnBL,EAAMM,SAAyBN,EAAMM,UAAYF,EAC5DG,OAA0BF,IAAjBL,EAAMO,QAAuBP,EAAMO,OAC5CC,EAAUR,EAAMQ,QAChBC,EAAST,EAAMS,QAAUC,QAAQC,IAAIC,kBAC3C,IAAIC,GAAW,EAEf,MAyBMC,EAAO,CACXC,MAAO,CACLC,QAASf,EACTgB,KAAM,QAERC,KAAM,CACJF,QAASG,eA/BOA,WAClB,IACE,MAAMC,EAAiB,CACrBC,OAAQ,OACRC,QAAS,CACP,eAAgB,mBAChB,YAAab,GAEfc,KAAMC,KAAKC,UAAU,CAAEC,MAAOC,EAAOC,aAGjCC,QAAiBC,MAAM,0CAA2CV,GAElEW,SADaF,EAASG,QACVH,SAElB,IAAK,IAAII,EAAI,EAAGA,EAAIF,EAAKG,OAAQD,UACzBN,EAAOQ,cAAcJ,EAAKK,MAAM,EAAGH,EAAI,UACvC,IAAII,SAAQC,GAAWC,WAAWD,EAAS,IAEpD,CAAC,MAAOE,SACDb,EAAOc,cAAc,0DAC3B5B,GAAW,CACb,GAUU6B,CAAYf,EAAO,EAE3BV,KAAMA,IACAJ,EACK,QAEF,SAKP8B,EAAaC,EAAAA,EAAE,MAAO,KAC1B,iBACAA,EAACA,EAAC,IAAK,CAAEC,KAAM,sDAAwD,mBACvE,OACAD,EAAAA,EAAE,IAAK,CAAEC,KAAM,uGAAyG,oBACxH,KAGF,OAAOD,EAAAA,EACL,MACA,CAAEE,UAAW,iBACbF,EAAAA,EAAEG,EAAS,CACTC,QAAS,CACPC,MAAO,CACLC,aAAc,UACdC,eAAgB,UAChBC,WAAY,oBACZjD,SAAUA,GAEZkD,OAAQ,CACNC,MAAO,iBACPC,OAAQ,yFAEVC,UAAW,CACTC,uBAAwBvD,EACxBwD,wBAAyB,kCACzBpD,SAAUA,GAEZqD,YAAa,CAAErD,UAAU,GACzBsD,UAAW,CACTC,WAAW,EACXC,yBAAyB,GAE3BvD,OAAQA,EACRC,QAASA,EACTuD,WAAY,CACVC,KAAM,yFAERC,QAAS,CACPlC,KAAM,2BAERmC,MAAO,CACL5D,UAAU,GAEZ6D,MAAO,CACL7D,UAAU,GAEZ8D,eAAgB,CACd9D,UAAU,GAEZ+D,aAAc,CACZ/D,UAAU,GAEZgE,OAAQ,CACNvC,KAAMY,IAGV7B,KAAMA,IAET,EAII,SAASyD,EAAUC,GACxB,MAAMC,OAAEA,EAAMC,QAAEA,EAAOtE,WAAEA,EAAUG,OAAEA,KAAWoE,GAAeH,EAE/D,GAAKC,GAAYA,aAAkBG,YAenC,OAVAC,EAAMA,OACJjC,EAACA,EAAC7C,EAAO,CACPK,WAAYA,EACZG,OAAQA,KACLoE,IAELF,GAIK,KAELI,EAAMA,OAAC,KAAMJ,EAAO,EAhBpBK,QAAQtC,MAAM,iDAkBlB"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// qa-bot-element.js
|
|
2
|
+
class QABotElement extends HTMLElement {
|
|
3
|
+
constructor() {
|
|
4
|
+
super();
|
|
5
|
+
this.attachShadow({
|
|
6
|
+
mode: 'open'
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
// Create a container for React to render into
|
|
10
|
+
this.container = document.createElement('div');
|
|
11
|
+
this.container.className = 'qa-bot-container';
|
|
12
|
+
|
|
13
|
+
// Flag to track if React is loaded
|
|
14
|
+
this.reactLoaded = false;
|
|
15
|
+
|
|
16
|
+
// Button element for the chat toggle (visible before React loads)
|
|
17
|
+
this.chatButton = document.createElement('button');
|
|
18
|
+
this.chatButton.className = 'qa-bot-button';
|
|
19
|
+
this.chatButton.innerHTML = `
|
|
20
|
+
<img src="https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg"
|
|
21
|
+
alt="ACCESS Q&A Bot" width="24" height="24">
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
// Add basic styles to the shadow DOM
|
|
25
|
+
const style = document.createElement('style');
|
|
26
|
+
style.textContent = `
|
|
27
|
+
.qa-bot-container {
|
|
28
|
+
width: 100%;
|
|
29
|
+
height: 100%;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.qa-bot-button {
|
|
33
|
+
position: fixed;
|
|
34
|
+
bottom: 20px;
|
|
35
|
+
right: 20px;
|
|
36
|
+
width: 50px;
|
|
37
|
+
height: 50px;
|
|
38
|
+
border-radius: 50%;
|
|
39
|
+
background-color: #1a5b6e;
|
|
40
|
+
border: none;
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
|
43
|
+
display: flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: center;
|
|
46
|
+
z-index: 9999;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.qa-bot-button img {
|
|
50
|
+
width: 60%;
|
|
51
|
+
height: 60%;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.embedded .qa-bot-button {
|
|
55
|
+
display: none;
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
// Append elements to shadow DOM
|
|
60
|
+
this.shadowRoot.appendChild(style);
|
|
61
|
+
this.shadowRoot.appendChild(this.container);
|
|
62
|
+
|
|
63
|
+
// Only add the button in non-embedded mode
|
|
64
|
+
if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {
|
|
65
|
+
this.shadowRoot.appendChild(this.chatButton);
|
|
66
|
+
} else {
|
|
67
|
+
this.container.classList.add('embedded');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Bind methods
|
|
71
|
+
this.loadReact = this.loadReact.bind(this);
|
|
72
|
+
this.handleButtonClick = this.handleButtonClick.bind(this);
|
|
73
|
+
|
|
74
|
+
// Add event listeners
|
|
75
|
+
this.chatButton.addEventListener('click', this.handleButtonClick);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// When element is added to the DOM
|
|
79
|
+
connectedCallback() {
|
|
80
|
+
// For embedded mode, load React immediately
|
|
81
|
+
if (this.hasAttribute('embedded') && this.getAttribute('embedded') === 'true') {
|
|
82
|
+
this.loadReact();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Handle button click to load React and open the chat
|
|
87
|
+
handleButtonClick() {
|
|
88
|
+
if (!this.reactLoaded) {
|
|
89
|
+
this.loadReact(true); // true = open chat after loading
|
|
90
|
+
} else {
|
|
91
|
+
// If React is already loaded, just toggle the chat
|
|
92
|
+
if (window.qAndATool && this.cleanup) {
|
|
93
|
+
// Unmount current instance
|
|
94
|
+
this.cleanup();
|
|
95
|
+
this.cleanup = null;
|
|
96
|
+
// Hide button if we're closing in non-embedded mode
|
|
97
|
+
if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {
|
|
98
|
+
this.chatButton.style.display = 'flex';
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
// Create new instance and open it
|
|
102
|
+
this.renderQABot(true);
|
|
103
|
+
// Hide button when chat is open in non-embedded mode
|
|
104
|
+
if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {
|
|
105
|
+
this.chatButton.style.display = 'none';
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Lazy load React and dependencies
|
|
112
|
+
loadReact(openAfterLoad = false) {
|
|
113
|
+
if (this.reactLoaded) return;
|
|
114
|
+
|
|
115
|
+
// Show loading indicator
|
|
116
|
+
this.container.innerHTML = '<div style="text-align: center; padding: 20px;">Loading...</div>';
|
|
117
|
+
|
|
118
|
+
// Function to load script
|
|
119
|
+
const loadScript = src => {
|
|
120
|
+
return new Promise((resolve, reject) => {
|
|
121
|
+
const script = document.createElement('script');
|
|
122
|
+
script.src = src;
|
|
123
|
+
script.async = true;
|
|
124
|
+
script.onload = resolve;
|
|
125
|
+
script.onerror = reject;
|
|
126
|
+
document.head.appendChild(script);
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// Function to load stylesheet
|
|
131
|
+
const loadStylesheet = href => {
|
|
132
|
+
return new Promise(resolve => {
|
|
133
|
+
const link = document.createElement('link');
|
|
134
|
+
link.rel = 'stylesheet';
|
|
135
|
+
link.href = href;
|
|
136
|
+
link.onload = resolve;
|
|
137
|
+
document.head.appendChild(link);
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// Determine the base URL for loading resources
|
|
142
|
+
const getBaseUrl = () => {
|
|
143
|
+
// Try to get from the script tag that loaded this file
|
|
144
|
+
const scripts = document.querySelectorAll('script');
|
|
145
|
+
for (const script of scripts) {
|
|
146
|
+
if (script.src && script.src.includes('qa-bot-element.js')) {
|
|
147
|
+
return script.src.substring(0, script.src.lastIndexOf('/') + 1);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Fallback to the current page's path
|
|
151
|
+
return window.location.href.substring(0, window.location.href.lastIndexOf('/') + 1);
|
|
152
|
+
};
|
|
153
|
+
const baseUrl = this.getAttribute('base-url') || getBaseUrl();
|
|
154
|
+
|
|
155
|
+
// Load CSS first
|
|
156
|
+
loadStylesheet(`${baseUrl}static/css/main.css`).then(() => {
|
|
157
|
+
// Then load the main JS bundle
|
|
158
|
+
return loadScript(`${baseUrl}static/js/main.js`);
|
|
159
|
+
}).then(() => {
|
|
160
|
+
// Then load any chunk files
|
|
161
|
+
return loadScript(`${baseUrl}static/js/453.chunk.js`);
|
|
162
|
+
}).then(() => {
|
|
163
|
+
this.reactLoaded = true;
|
|
164
|
+
this.renderQABot(openAfterLoad);
|
|
165
|
+
}).catch(error => {
|
|
166
|
+
console.error('Failed to load QA Bot resources:', error);
|
|
167
|
+
this.container.innerHTML = '<div style="color: red; text-align: center; padding: 20px;">Failed to load QA Bot</div>';
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Render the React component
|
|
172
|
+
renderQABot(isOpen = false) {
|
|
173
|
+
if (!this.reactLoaded || !window.qAndATool) {
|
|
174
|
+
console.error('QA Bot resources not loaded');
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Configure the QA Bot
|
|
179
|
+
const config = {
|
|
180
|
+
target: this.container,
|
|
181
|
+
embedded: this.hasAttribute('embedded') && this.getAttribute('embedded') === 'true',
|
|
182
|
+
welcome: this.getAttribute('welcome') || 'Hello! What can I help you with?',
|
|
183
|
+
prompt: this.getAttribute('prompt') || 'Ask me a question...',
|
|
184
|
+
isLoggedIn: this.hasAttribute('logged-in') ? this.getAttribute('logged-in') === 'true' : true,
|
|
185
|
+
disabled: this.hasAttribute('disabled') ? this.getAttribute('disabled') === 'true' : false,
|
|
186
|
+
isOpen: isOpen,
|
|
187
|
+
apiKey: this.getAttribute('api-key') || undefined,
|
|
188
|
+
onClose: () => {
|
|
189
|
+
// When chat is closed, show the button again in non-embedded mode
|
|
190
|
+
if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {
|
|
191
|
+
this.chatButton.style.display = 'flex';
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Dispatch a custom event
|
|
195
|
+
this.dispatchEvent(new CustomEvent('qa-bot-closed'));
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// Initialize the QA Bot
|
|
200
|
+
this.cleanup = window.qAndATool(config);
|
|
201
|
+
|
|
202
|
+
// Hide button when chat is open in non-embedded mode
|
|
203
|
+
if (isOpen && (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true')) {
|
|
204
|
+
this.chatButton.style.display = 'none';
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Dispatch a custom event
|
|
208
|
+
this.dispatchEvent(new CustomEvent('qa-bot-loaded'));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Handle attribute changes
|
|
212
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
213
|
+
// Only update if React is loaded and the value has changed
|
|
214
|
+
if (this.reactLoaded && oldValue !== newValue) {
|
|
215
|
+
// Re-render with new configuration
|
|
216
|
+
if (this.cleanup) {
|
|
217
|
+
this.cleanup();
|
|
218
|
+
}
|
|
219
|
+
this.renderQABot(this.hasAttribute('is-open') && this.getAttribute('is-open') === 'true');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// List of observed attributes
|
|
224
|
+
static get observedAttributes() {
|
|
225
|
+
return ['welcome', 'prompt', 'embedded', 'logged-in', 'disabled', 'api-key', 'is-open'];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Clean up when element is removed
|
|
229
|
+
disconnectedCallback() {
|
|
230
|
+
if (this.cleanup) {
|
|
231
|
+
this.cleanup();
|
|
232
|
+
}
|
|
233
|
+
this.chatButton.removeEventListener('click', this.handleButtonClick);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Register the custom element
|
|
238
|
+
customElements.define('qa-bot', QABotElement);
|
|
239
|
+
|
|
240
|
+
export { QABotElement as default };
|
|
241
|
+
//# sourceMappingURL=qa-bot-element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-bot-element.js","sources":["../src/web-components/qa-bot-element.js"],"sourcesContent":["// qa-bot-element.js\nclass QABotElement extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n\n // Create a container for React to render into\n this.container = document.createElement('div');\n this.container.className = 'qa-bot-container';\n\n // Flag to track if React is loaded\n this.reactLoaded = false;\n\n // Button element for the chat toggle (visible before React loads)\n this.chatButton = document.createElement('button');\n this.chatButton.className = 'qa-bot-button';\n this.chatButton.innerHTML = `\n <img src=\"https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg\"\n alt=\"ACCESS Q&A Bot\" width=\"24\" height=\"24\">\n `;\n\n // Add basic styles to the shadow DOM\n const style = document.createElement('style');\n style.textContent = `\n .qa-bot-container {\n width: 100%;\n height: 100%;\n }\n\n .qa-bot-button {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 50px;\n height: 50px;\n border-radius: 50%;\n background-color: #1a5b6e;\n border: none;\n cursor: pointer;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 9999;\n }\n\n .qa-bot-button img {\n width: 60%;\n height: 60%;\n }\n\n .embedded .qa-bot-button {\n display: none;\n }\n `;\n\n // Append elements to shadow DOM\n this.shadowRoot.appendChild(style);\n this.shadowRoot.appendChild(this.container);\n\n // Only add the button in non-embedded mode\n if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {\n this.shadowRoot.appendChild(this.chatButton);\n } else {\n this.container.classList.add('embedded');\n }\n\n // Bind methods\n this.loadReact = this.loadReact.bind(this);\n this.handleButtonClick = this.handleButtonClick.bind(this);\n\n // Add event listeners\n this.chatButton.addEventListener('click', this.handleButtonClick);\n }\n\n // When element is added to the DOM\n connectedCallback() {\n // For embedded mode, load React immediately\n if (this.hasAttribute('embedded') && this.getAttribute('embedded') === 'true') {\n this.loadReact();\n }\n }\n\n // Handle button click to load React and open the chat\n handleButtonClick() {\n if (!this.reactLoaded) {\n this.loadReact(true); // true = open chat after loading\n } else {\n // If React is already loaded, just toggle the chat\n if (window.qAndATool && this.cleanup) {\n // Unmount current instance\n this.cleanup();\n this.cleanup = null;\n // Hide button if we're closing in non-embedded mode\n if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {\n this.chatButton.style.display = 'flex';\n }\n } else {\n // Create new instance and open it\n this.renderQABot(true);\n // Hide button when chat is open in non-embedded mode\n if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {\n this.chatButton.style.display = 'none';\n }\n }\n }\n }\n\n // Lazy load React and dependencies\n loadReact(openAfterLoad = false) {\n if (this.reactLoaded) return;\n\n // Show loading indicator\n this.container.innerHTML = '<div style=\"text-align: center; padding: 20px;\">Loading...</div>';\n\n // Function to load script\n const loadScript = (src) => {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = src;\n script.async = true;\n script.onload = resolve;\n script.onerror = reject;\n document.head.appendChild(script);\n });\n };\n\n // Function to load stylesheet\n const loadStylesheet = (href) => {\n return new Promise((resolve) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = href;\n link.onload = resolve;\n document.head.appendChild(link);\n });\n };\n\n // Determine the base URL for loading resources\n const getBaseUrl = () => {\n // Try to get from the script tag that loaded this file\n const scripts = document.querySelectorAll('script');\n for (const script of scripts) {\n if (script.src && script.src.includes('qa-bot-element.js')) {\n return script.src.substring(0, script.src.lastIndexOf('/') + 1);\n }\n }\n // Fallback to the current page's path\n return window.location.href.substring(0, window.location.href.lastIndexOf('/') + 1);\n };\n\n const baseUrl = this.getAttribute('base-url') || getBaseUrl();\n\n // Load CSS first\n loadStylesheet(`${baseUrl}static/css/main.css`)\n .then(() => {\n // Then load the main JS bundle\n return loadScript(`${baseUrl}static/js/main.js`);\n })\n .then(() => {\n // Then load any chunk files\n return loadScript(`${baseUrl}static/js/453.chunk.js`);\n })\n .then(() => {\n this.reactLoaded = true;\n this.renderQABot(openAfterLoad);\n })\n .catch((error) => {\n console.error('Failed to load QA Bot resources:', error);\n this.container.innerHTML = '<div style=\"color: red; text-align: center; padding: 20px;\">Failed to load QA Bot</div>';\n });\n }\n\n // Render the React component\n renderQABot(isOpen = false) {\n if (!this.reactLoaded || !window.qAndATool) {\n console.error('QA Bot resources not loaded');\n return;\n }\n\n // Configure the QA Bot\n const config = {\n target: this.container,\n embedded: this.hasAttribute('embedded') && this.getAttribute('embedded') === 'true',\n welcome: this.getAttribute('welcome') || 'Hello! What can I help you with?',\n prompt: this.getAttribute('prompt') || 'Ask me a question...',\n isLoggedIn: this.hasAttribute('logged-in') ? this.getAttribute('logged-in') === 'true' : true,\n disabled: this.hasAttribute('disabled') ? this.getAttribute('disabled') === 'true' : false,\n isOpen: isOpen,\n apiKey: this.getAttribute('api-key') || undefined,\n onClose: () => {\n // When chat is closed, show the button again in non-embedded mode\n if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {\n this.chatButton.style.display = 'flex';\n }\n\n // Dispatch a custom event\n this.dispatchEvent(new CustomEvent('qa-bot-closed'));\n }\n };\n\n // Initialize the QA Bot\n this.cleanup = window.qAndATool(config);\n\n // Hide button when chat is open in non-embedded mode\n if (isOpen && (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true')) {\n this.chatButton.style.display = 'none';\n }\n\n // Dispatch a custom event\n this.dispatchEvent(new CustomEvent('qa-bot-loaded'));\n }\n\n // Handle attribute changes\n attributeChangedCallback(name, oldValue, newValue) {\n // Only update if React is loaded and the value has changed\n if (this.reactLoaded && oldValue !== newValue) {\n // Re-render with new configuration\n if (this.cleanup) {\n this.cleanup();\n }\n this.renderQABot(this.hasAttribute('is-open') && this.getAttribute('is-open') === 'true');\n }\n }\n\n // List of observed attributes\n static get observedAttributes() {\n return ['welcome', 'prompt', 'embedded', 'logged-in', 'disabled', 'api-key', 'is-open'];\n }\n\n // Clean up when element is removed\n disconnectedCallback() {\n if (this.cleanup) {\n this.cleanup();\n }\n this.chatButton.removeEventListener('click', this.handleButtonClick);\n }\n}\n\n// Register the custom element\ncustomElements.define('qa-bot', QABotElement);\n\n// Export for module usage\nexport default QABotElement;"],"names":["QABotElement","HTMLElement","constructor","attachShadow","mode","container","document","createElement","className","reactLoaded","chatButton","innerHTML","style","textContent","shadowRoot","appendChild","hasAttribute","getAttribute","classList","add","loadReact","bind","handleButtonClick","addEventListener","connectedCallback","window","qAndATool","cleanup","display","renderQABot","openAfterLoad","loadScript","src","Promise","resolve","reject","script","async","onload","onerror","head","loadStylesheet","href","link","rel","getBaseUrl","scripts","querySelectorAll","includes","substring","lastIndexOf","location","baseUrl","then","catch","error","console","isOpen","config","target","embedded","welcome","prompt","isLoggedIn","disabled","apiKey","undefined","onClose","dispatchEvent","CustomEvent","attributeChangedCallback","name","oldValue","newValue","observedAttributes","disconnectedCallback","removeEventListener","customElements","define"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(){"use strict";class t extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this.container=document.createElement("div"),this.container.className="qa-bot-container",this.reactLoaded=!1,this.chatButton=document.createElement("button"),this.chatButton.className="qa-bot-button",this.chatButton.innerHTML='\n <img src="https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg"\n alt="ACCESS Q&A Bot" width="24" height="24">\n ';const t=document.createElement("style");t.textContent="\n .qa-bot-container {\n width: 100%;\n height: 100%;\n }\n\n .qa-bot-button {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 50px;\n height: 50px;\n border-radius: 50%;\n background-color: #1a5b6e;\n border: none;\n cursor: pointer;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 9999;\n }\n\n .qa-bot-button img {\n width: 60%;\n height: 60%;\n }\n\n .embedded .qa-bot-button {\n display: none;\n }\n ",this.shadowRoot.appendChild(t),this.shadowRoot.appendChild(this.container),this.hasAttribute("embedded")&&"true"===this.getAttribute("embedded")?this.container.classList.add("embedded"):this.shadowRoot.appendChild(this.chatButton),this.loadReact=this.loadReact.bind(this),this.handleButtonClick=this.handleButtonClick.bind(this),this.chatButton.addEventListener("click",this.handleButtonClick)}connectedCallback(){this.hasAttribute("embedded")&&"true"===this.getAttribute("embedded")&&this.loadReact()}handleButtonClick(){this.reactLoaded?window.qAndATool&&this.cleanup?(this.cleanup(),this.cleanup=null,this.hasAttribute("embedded")&&"true"===this.getAttribute("embedded")||(this.chatButton.style.display="flex")):(this.renderQABot(!0),this.hasAttribute("embedded")&&"true"===this.getAttribute("embedded")||(this.chatButton.style.display="none")):this.loadReact(!0)}loadReact(t=!1){if(this.reactLoaded)return;this.container.innerHTML='<div style="text-align: center; padding: 20px;">Loading...</div>';const e=t=>new Promise(((e,n)=>{const i=document.createElement("script");i.src=t,i.async=!0,i.onload=e,i.onerror=n,document.head.appendChild(i)})),n=this.getAttribute("base-url")||(()=>{const t=document.querySelectorAll("script");for(const e of t)if(e.src&&e.src.includes("qa-bot-element.js"))return e.src.substring(0,e.src.lastIndexOf("/")+1);return window.location.href.substring(0,window.location.href.lastIndexOf("/")+1)})();var i;(i=`${n}static/css/main.css`,new Promise((t=>{const e=document.createElement("link");e.rel="stylesheet",e.href=i,e.onload=t,document.head.appendChild(e)}))).then((()=>e(`${n}static/js/main.js`))).then((()=>e(`${n}static/js/453.chunk.js`))).then((()=>{this.reactLoaded=!0,this.renderQABot(t)})).catch((t=>{console.error("Failed to load QA Bot resources:",t),this.container.innerHTML='<div style="color: red; text-align: center; padding: 20px;">Failed to load QA Bot</div>'}))}renderQABot(t=!1){if(!this.reactLoaded||!window.qAndATool)return void console.error("QA Bot resources not loaded");const e={target:this.container,embedded:this.hasAttribute("embedded")&&"true"===this.getAttribute("embedded"),welcome:this.getAttribute("welcome")||"Hello! What can I help you with?",prompt:this.getAttribute("prompt")||"Ask me a question...",isLoggedIn:!this.hasAttribute("logged-in")||"true"===this.getAttribute("logged-in"),disabled:!!this.hasAttribute("disabled")&&"true"===this.getAttribute("disabled"),isOpen:t,apiKey:this.getAttribute("api-key")||void 0,onClose:()=>{this.hasAttribute("embedded")&&"true"===this.getAttribute("embedded")||(this.chatButton.style.display="flex"),this.dispatchEvent(new CustomEvent("qa-bot-closed"))}};this.cleanup=window.qAndATool(e),!t||this.hasAttribute("embedded")&&"true"===this.getAttribute("embedded")||(this.chatButton.style.display="none"),this.dispatchEvent(new CustomEvent("qa-bot-loaded"))}attributeChangedCallback(t,e,n){this.reactLoaded&&e!==n&&(this.cleanup&&this.cleanup(),this.renderQABot(this.hasAttribute("is-open")&&"true"===this.getAttribute("is-open")))}static get observedAttributes(){return["welcome","prompt","embedded","logged-in","disabled","api-key","is-open"]}disconnectedCallback(){this.cleanup&&this.cleanup(),this.chatButton.removeEventListener("click",this.handleButtonClick)}}customElements.define("qa-bot",t)}();
|
|
2
|
+
//# sourceMappingURL=qa-bot-element.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-bot-element.min.js","sources":["../src/web-components/qa-bot-element.js"],"sourcesContent":["// qa-bot-element.js\nclass QABotElement extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n\n // Create a container for React to render into\n this.container = document.createElement('div');\n this.container.className = 'qa-bot-container';\n\n // Flag to track if React is loaded\n this.reactLoaded = false;\n\n // Button element for the chat toggle (visible before React loads)\n this.chatButton = document.createElement('button');\n this.chatButton.className = 'qa-bot-button';\n this.chatButton.innerHTML = `\n <img src=\"https://support.access-ci.org/themes/contrib/asp-theme/images/icons/ACCESS-arrrow.svg\"\n alt=\"ACCESS Q&A Bot\" width=\"24\" height=\"24\">\n `;\n\n // Add basic styles to the shadow DOM\n const style = document.createElement('style');\n style.textContent = `\n .qa-bot-container {\n width: 100%;\n height: 100%;\n }\n\n .qa-bot-button {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 50px;\n height: 50px;\n border-radius: 50%;\n background-color: #1a5b6e;\n border: none;\n cursor: pointer;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 9999;\n }\n\n .qa-bot-button img {\n width: 60%;\n height: 60%;\n }\n\n .embedded .qa-bot-button {\n display: none;\n }\n `;\n\n // Append elements to shadow DOM\n this.shadowRoot.appendChild(style);\n this.shadowRoot.appendChild(this.container);\n\n // Only add the button in non-embedded mode\n if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {\n this.shadowRoot.appendChild(this.chatButton);\n } else {\n this.container.classList.add('embedded');\n }\n\n // Bind methods\n this.loadReact = this.loadReact.bind(this);\n this.handleButtonClick = this.handleButtonClick.bind(this);\n\n // Add event listeners\n this.chatButton.addEventListener('click', this.handleButtonClick);\n }\n\n // When element is added to the DOM\n connectedCallback() {\n // For embedded mode, load React immediately\n if (this.hasAttribute('embedded') && this.getAttribute('embedded') === 'true') {\n this.loadReact();\n }\n }\n\n // Handle button click to load React and open the chat\n handleButtonClick() {\n if (!this.reactLoaded) {\n this.loadReact(true); // true = open chat after loading\n } else {\n // If React is already loaded, just toggle the chat\n if (window.qAndATool && this.cleanup) {\n // Unmount current instance\n this.cleanup();\n this.cleanup = null;\n // Hide button if we're closing in non-embedded mode\n if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {\n this.chatButton.style.display = 'flex';\n }\n } else {\n // Create new instance and open it\n this.renderQABot(true);\n // Hide button when chat is open in non-embedded mode\n if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {\n this.chatButton.style.display = 'none';\n }\n }\n }\n }\n\n // Lazy load React and dependencies\n loadReact(openAfterLoad = false) {\n if (this.reactLoaded) return;\n\n // Show loading indicator\n this.container.innerHTML = '<div style=\"text-align: center; padding: 20px;\">Loading...</div>';\n\n // Function to load script\n const loadScript = (src) => {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = src;\n script.async = true;\n script.onload = resolve;\n script.onerror = reject;\n document.head.appendChild(script);\n });\n };\n\n // Function to load stylesheet\n const loadStylesheet = (href) => {\n return new Promise((resolve) => {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = href;\n link.onload = resolve;\n document.head.appendChild(link);\n });\n };\n\n // Determine the base URL for loading resources\n const getBaseUrl = () => {\n // Try to get from the script tag that loaded this file\n const scripts = document.querySelectorAll('script');\n for (const script of scripts) {\n if (script.src && script.src.includes('qa-bot-element.js')) {\n return script.src.substring(0, script.src.lastIndexOf('/') + 1);\n }\n }\n // Fallback to the current page's path\n return window.location.href.substring(0, window.location.href.lastIndexOf('/') + 1);\n };\n\n const baseUrl = this.getAttribute('base-url') || getBaseUrl();\n\n // Load CSS first\n loadStylesheet(`${baseUrl}static/css/main.css`)\n .then(() => {\n // Then load the main JS bundle\n return loadScript(`${baseUrl}static/js/main.js`);\n })\n .then(() => {\n // Then load any chunk files\n return loadScript(`${baseUrl}static/js/453.chunk.js`);\n })\n .then(() => {\n this.reactLoaded = true;\n this.renderQABot(openAfterLoad);\n })\n .catch((error) => {\n console.error('Failed to load QA Bot resources:', error);\n this.container.innerHTML = '<div style=\"color: red; text-align: center; padding: 20px;\">Failed to load QA Bot</div>';\n });\n }\n\n // Render the React component\n renderQABot(isOpen = false) {\n if (!this.reactLoaded || !window.qAndATool) {\n console.error('QA Bot resources not loaded');\n return;\n }\n\n // Configure the QA Bot\n const config = {\n target: this.container,\n embedded: this.hasAttribute('embedded') && this.getAttribute('embedded') === 'true',\n welcome: this.getAttribute('welcome') || 'Hello! What can I help you with?',\n prompt: this.getAttribute('prompt') || 'Ask me a question...',\n isLoggedIn: this.hasAttribute('logged-in') ? this.getAttribute('logged-in') === 'true' : true,\n disabled: this.hasAttribute('disabled') ? this.getAttribute('disabled') === 'true' : false,\n isOpen: isOpen,\n apiKey: this.getAttribute('api-key') || undefined,\n onClose: () => {\n // When chat is closed, show the button again in non-embedded mode\n if (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true') {\n this.chatButton.style.display = 'flex';\n }\n\n // Dispatch a custom event\n this.dispatchEvent(new CustomEvent('qa-bot-closed'));\n }\n };\n\n // Initialize the QA Bot\n this.cleanup = window.qAndATool(config);\n\n // Hide button when chat is open in non-embedded mode\n if (isOpen && (!this.hasAttribute('embedded') || this.getAttribute('embedded') !== 'true')) {\n this.chatButton.style.display = 'none';\n }\n\n // Dispatch a custom event\n this.dispatchEvent(new CustomEvent('qa-bot-loaded'));\n }\n\n // Handle attribute changes\n attributeChangedCallback(name, oldValue, newValue) {\n // Only update if React is loaded and the value has changed\n if (this.reactLoaded && oldValue !== newValue) {\n // Re-render with new configuration\n if (this.cleanup) {\n this.cleanup();\n }\n this.renderQABot(this.hasAttribute('is-open') && this.getAttribute('is-open') === 'true');\n }\n }\n\n // List of observed attributes\n static get observedAttributes() {\n return ['welcome', 'prompt', 'embedded', 'logged-in', 'disabled', 'api-key', 'is-open'];\n }\n\n // Clean up when element is removed\n disconnectedCallback() {\n if (this.cleanup) {\n this.cleanup();\n }\n this.chatButton.removeEventListener('click', this.handleButtonClick);\n }\n}\n\n// Register the custom element\ncustomElements.define('qa-bot', QABotElement);\n\n// Export for module usage\nexport default QABotElement;"],"names":["QABotElement","HTMLElement","constructor","super","this","attachShadow","mode","container","document","createElement","className","reactLoaded","chatButton","innerHTML","style","textContent","shadowRoot","appendChild","hasAttribute","getAttribute","classList","add","loadReact","bind","handleButtonClick","addEventListener","connectedCallback","window","qAndATool","cleanup","display","renderQABot","openAfterLoad","loadScript","src","Promise","resolve","reject","script","async","onload","onerror","head","baseUrl","getBaseUrl","scripts","querySelectorAll","includes","substring","lastIndexOf","location","href","link","rel","then","catch","error","console","isOpen","config","target","embedded","welcome","prompt","isLoggedIn","disabled","apiKey","undefined","onClose","dispatchEvent","CustomEvent","attributeChangedCallback","name","oldValue","newValue","observedAttributes","disconnectedCallback","removeEventListener","customElements","define"],"mappings":"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"}
|