@defra/flood-webchat 0.0.1-alpha.2 → 0.0.1-alpha.4

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 CHANGED
@@ -1,9 +1,81 @@
1
1
  # flood-webchat
2
2
 
3
3
  ## Useful Links
4
+
4
5
  - [Development Guide](./docs/development-guide.md)
5
6
  - [How to Publish](./docs/how-to-publish.md)
6
7
 
7
8
  ## Usage
8
- TBC
9
9
 
10
+ ### Installation
11
+
12
+ Run:
13
+
14
+ ```shell
15
+ npm i @defra/flood-webchat
16
+ ```
17
+
18
+ ### Server Side Javascript
19
+
20
+ You will need to implement an endpoint on your server which checks the availability of webchat. An express example can
21
+ be seen below:
22
+
23
+ ```js
24
+
25
+ import getAvailability from '@defra/flood-webchat'
26
+ //... the rest of your server setup
27
+ const webchatOptions = {
28
+ clientId: process.env.CXONE_CLIENT_ID,
29
+ clientSecret: process.env.CXONE_CLIENT_SECRET,
30
+ accessKey: process.env.CXONE_ACCESS_KEY,
31
+ accessSecret: process.env.CXONE_ACCESS_SECRET,
32
+ skillEndpoint: process.env.CXONE_SKILL_ENDPOINT,
33
+ hoursEndpoint: process.env.CXONE_HOURS_ENDPOINT,
34
+ maxQueueCount: process.env.CXONE_MAX_QUEUE_COUNT
35
+ }
36
+
37
+ app.get('/webchat-availability', async (req, res, next) => {
38
+ try {
39
+ const response = await getAvailability(webchatOptions)
40
+ return res.status(200).json(response)
41
+ } catch (err) {
42
+ next(err)
43
+ }
44
+ })
45
+ ```
46
+
47
+ ### Client Side Javascript
48
+
49
+ You will also need to initialise webchat in your client side code:
50
+
51
+ ```js
52
+ import * as webchat from '@defra/flood-webchat';
53
+
54
+ if (document.getElementById('wc-availability')) {
55
+ webchat.init('wc-availability', {
56
+ brandId: 'your brand id',
57
+ channelId: 'your channel id',
58
+ environmentName: 'your environment name',
59
+ availabilityEndpoint: '/webchat-availability'
60
+ })
61
+ }
62
+ ```
63
+
64
+ ### HTML
65
+
66
+ In your html, will need to add the "Start Chat" link with some placeholder text for if webchat is not supported in the
67
+ user's browser.
68
+ ```html
69
+ <div id="wc-availability">
70
+ <p>Webchat is not supported with your browser</p>
71
+ </div>
72
+ ```
73
+
74
+ And finally a script tag, to prevent the webchat widget "flashing" on page load/reload.
75
+ ```html
76
+ <script>
77
+ if (window.location.hash === '#webchat' && window.matchMedia('(max-width: 640px)').matches) {
78
+ document.body.classList.add('wc-hidden')
79
+ }
80
+ </script>
81
+ ```
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ presets: [['@babel/preset-env', { targets: { node: 'current' } }]]
3
+ }
@@ -0,0 +1,554 @@
1
+ (function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["agent-typing.html"] = (function() {
2
+ function root(env, context, frame, runtime, cb) {
3
+ var lineno = 0;
4
+ var colno = 0;
5
+ var output = "";
6
+ try {
7
+ var parentTemplate = null;
8
+ output += "<li class=\"wc-list__item wc-list__item--outbound\" data-wc-agent-typing>\n <div class=\"wc-list__item-meta\">";
9
+ output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"name"), env.opts.autoescape);
10
+ output += " is typing</div>\n <div class=\"wc-list__item-inner\"><svg width=\"28\" height=\"16\" x=\"0px\" y=\"0px\" viewBox=\"0 0 28 16\"><circle stroke=\"none\" cx=\"3\" cy=\"8\" r=\"3\" fill=\"currentColor\"></circle><circle stroke=\"none\" cx=\"14\" cy=\"8\" r=\"3\" fill=\"currentColor\"></circle><circle stroke=\"none\" cx=\"25\" cy=\"8\" r=\"3\" fill=\"currentColor\"></circle></svg></div>\n</li>";
11
+ if(parentTemplate) {
12
+ parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
13
+ } else {
14
+ cb(null, output);
15
+ }
16
+ ;
17
+ } catch (e) {
18
+ cb(runtime.handleError(e, lineno, colno));
19
+ }
20
+ }
21
+ return {
22
+ root: root
23
+ };
24
+
25
+ })();
26
+ })();
27
+ (function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["availability.html"] = (function() {
28
+ function root(env, context, frame, runtime, cb) {
29
+ var lineno = 0;
30
+ var colno = 0;
31
+ var output = "";
32
+ try {
33
+ var parentTemplate = null;
34
+ output += "<div class=\"wc-live\" aria-live=\"polite\" data-wc-availability-live></div>\n";
35
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"isLink")) {
36
+ output += "\n<div class=\"wc-link\" data-wc-link>\n <div class=\"wc-link__inner\">\n <a href=\"#webchat\" id=\"wc-open\" role=\"button\" draggable=\"false\" class=\"wc-open-btn\" data-wc-open-btn data-wc-focus-visible>\n ";
37
+ output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"btnText"), env.opts.autoescape);
38
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"unseen")) {
39
+ output += "<span class=\"wc-open-btn__unseen\">";
40
+ output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"unseen"), env.opts.autoescape);
41
+ output += "</span> <span class=\"govuk-visually-hidden\">new message";
42
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"unseen") > 1) {
43
+ output += "s";
44
+ ;
45
+ }
46
+ output += "</span>";
47
+ ;
48
+ }
49
+ output += "\n </a>\n </div>\n</div>\n";
50
+ ;
51
+ }
52
+ else {
53
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"isText")) {
54
+ output += "\n";
55
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"availability") == "EXISTING" || runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"availability") == "UNAVAILABLE") {
56
+ output += "\n<p class=\"govuk-body\">When it is available, a 'start chat' link will appear.</p>\n";
57
+ ;
58
+ }
59
+ else {
60
+ output += "\n<p class=\"govuk-body\">Checking availability</p>\n";
61
+ ;
62
+ }
63
+ output += "\n";
64
+ ;
65
+ }
66
+ ;
67
+ }
68
+ if(parentTemplate) {
69
+ parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
70
+ } else {
71
+ cb(null, output);
72
+ }
73
+ ;
74
+ } catch (e) {
75
+ cb(runtime.handleError(e, lineno, colno));
76
+ }
77
+ }
78
+ return {
79
+ root: root
80
+ };
81
+
82
+ })();
83
+ })();
84
+ (function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["body.html"] = (function() {
85
+ function root(env, context, frame, runtime, cb) {
86
+ var lineno = 0;
87
+ var colno = 0;
88
+ var output = "";
89
+ try {
90
+ var parentTemplate = null;
91
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "UNAVAILABLE") {
92
+ output += "\n<div class=\"wc-content\">\n ";
93
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"name")) {
94
+ output += "\n <a href=\"#\" class=\"wc-back-link\" data-wc-start-back-btn>Your name and question</a>\n ";
95
+ ;
96
+ }
97
+ output += "\n <h3 id=\"wc-subtitle\" class=\"govuk-heading-m\">Webchat is currently not available</h3>\n <p>Try again later, or call Floodline:</p>\n <p><strong>Floodline helpline</strong><br/>Telephone: 0345 988 1188<br>Textphone: 0345 602 6340<br>Open 24 hours a day, 7 days a week<br><a href=\"https://gov.uk/call-charges\">Find out more about call charges</a></p>\n <p>We’re running webchat as a trial, it will not always be available.</p>\n</div>\n\n";
98
+ ;
99
+ }
100
+ else {
101
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "PRECHAT") {
102
+ output += "\n<div class=\"wc-content\">\n <h3 id=\"wc-subtitle\" class=\"govuk-heading-m\">What you can use webchat for</h3>\n <p>Webchat lets you talk directly to a Floodline adviser.</p>\n <p>You can use webchat to get: </p>\n <ul class=\"govuk-list govuk-list--bullet\">\n <li>current flood warnings and alerts in your area</li>\n <li>information on the flood warning service</li>\n <li>advice on what to do before, during and after a flood</li>\n </ul>\n <p>There are other ways to <a href=\"https://www.gov.uk/sign-up-for-flood-warnings\">sign up for flood warnings</a> and <a href=\"https://defragroup.eu.qualtrics.com/jfe/form/SV_8uMAuaH3kbJl965?Source=https://check-for-flooding.service.gov.uk\">manage your flood warnings account</a>.</p>\n <p>Do not use webchat to <a href=\"https://www.gov.uk/report-flood-cause\">report a flood</a>.</p>\n <button class=\"wc-start-btn govuk-!-margin-top-1\" data-module=\"govuk-button\" data-wc-start-btn>\n Continue\n </button>\n <h3 class=\"govuk-heading-m\">Other flood information</h3>\n <p>Call Floodline for all other flood and flood warning information.</p>\n <p><strong>Floodline helpline</strong><br/>Telephone: 0345 988 1188<br>Textphone: 0345 602 6340<br>Open 24 hours a day, 7 days a week<br><a href=\"https://gov.uk/call-charges\">Find out more about call charges</a></p>\n</div>\n\n";
103
+ ;
104
+ }
105
+ else {
106
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "START") {
107
+ output += "\n<div class=\"wc-content\">\n <a href=\"#\" class=\"wc-back-link\" data-wc-prechat-back-btn>What you can use webchat for</a>\n ";
108
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")) {
109
+ output += "\n <div class=\"govuk-error-summary\" data-module=\"govuk-error-summary\" tabindex=\"-1\" data-wc-error-summary>\n <div role=\"alert\">\n <h3 id=\"wc-error\" class=\"govuk-error-summary__title\">\n There is a problem\n </h2>\n <div class=\"govuk-error-summary__body\">\n <ul class=\"govuk-list govuk-error-summary__list\">\n ";
110
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"nameEmpty")) {
111
+ output += "\n <li>\n <a href=\"#name\" data-wc-error-summary-link>Enter your name</a>\n </li>\n ";
112
+ ;
113
+ }
114
+ output += "\n ";
115
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"questionEmpty")) {
116
+ output += "\n <li>\n <a href=\"#question\" data-wc-error-summary-link>Enter your question</a>\n </li>\n ";
117
+ ;
118
+ }
119
+ output += "\n ";
120
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"questionExceeded")) {
121
+ output += "\n <li>\n <a href=\"#question\" data-wc-error-summary-link>Your question must be 500 characters or less</a>\n </li>\n ";
122
+ ;
123
+ }
124
+ output += "\n </ul>\n </div>\n </div>\n </div>\n ";
125
+ ;
126
+ }
127
+ output += "\n <h3 id=\"wc-subtitle\" class=\"govuk-heading-m\">Your name and question</h3>\n <form data-wc-start-form>\n <div class=\"govuk-form-group ";
128
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"nameEmpty")) {
129
+ output += "govuk-form-group--error";
130
+ ;
131
+ }
132
+ output += "\">\n <label class=\"govuk-label\" for=\"name\">\n Your name\n </label>\n ";
133
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"nameEmpty")) {
134
+ output += "\n <p class=\"govuk-error-message\">\n <span class=\"govuk-visually-hidden\">Error:</span> Enter your name\n </p>\n ";
135
+ ;
136
+ }
137
+ output += "\n <input class=\"govuk-input ";
138
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"nameEmpty")) {
139
+ output += "govuk-input--error";
140
+ ;
141
+ }
142
+ output += "\" id=\"name\" name=\"name\" type=\"text\" value=\"";
143
+ output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"name"), env.opts.autoescape);
144
+ output += "\">\n </div>\n <div class=\"govuk-character-count\" data-module=\"govuk-character-count\" data-maxlength=\"500\">\n <div class=\"govuk-form-group ";
145
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"questionEmpty") || runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"questionExceeded")) {
146
+ output += "govuk-form-group--error";
147
+ ;
148
+ }
149
+ output += "\">\n <label class=\"govuk-label\" for=\"question\">\n Your question\n </label>\n ";
150
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"questionEmpty") || runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"questionExceeded")) {
151
+ output += "\n <p class=\"govuk-error-message\">\n <span class=\"govuk-visually-hidden\">Error:</span>\n ";
152
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"questionEmpty")) {
153
+ output += "\n Enter your question\n ";
154
+ ;
155
+ }
156
+ else {
157
+ output += "\n Your question must be 500 characters or less\n ";
158
+ ;
159
+ }
160
+ output += "\n </p>\n ";
161
+ ;
162
+ }
163
+ output += "\n <textarea class=\"govuk-textarea wc-textarea-question";
164
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"questionEmpty") || runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"questionExceeded")) {
165
+ output += " wc-textarea--error";
166
+ ;
167
+ }
168
+ output += " govuk-js-character-count\" id=\"question\" name=\"question\" rows=\"5\" aria-describedby=\"question-info\">";
169
+ output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"question"), env.opts.autoescape);
170
+ output += "</textarea>\n </div>\n <div id=\"question-info\" class=\"wc-hint govuk-hint govuk-character-count__message\">\n You can enter up to 500 characters\n </div>\n </div>\n <button class=\"wc-submit-btn govuk-!-margin-top-1\" data-module=\"govuk-button\" data-wc-request-chat-btn>\n Request chat\n </button>\n </form>\n</div>\n\n";
171
+ ;
172
+ }
173
+ else {
174
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "OPEN") {
175
+ output += "\n<ul class=\"wc-list\" data-wc-list>\n ";
176
+ frame = frame.push();
177
+ var t_3 = runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"messages");
178
+ if(t_3) {t_3 = runtime.fromIterator(t_3);
179
+ var t_2 = t_3.length;
180
+ for(var t_1=0; t_1 < t_3.length; t_1++) {
181
+ var t_4 = t_3[t_1];
182
+ frame.set("message", t_4);
183
+ frame.set("loop.index", t_1 + 1);
184
+ frame.set("loop.index0", t_1);
185
+ frame.set("loop.revindex", t_2 - t_1);
186
+ frame.set("loop.revindex0", t_2 - t_1 - 1);
187
+ frame.set("loop.first", t_1 === 0);
188
+ frame.set("loop.last", t_1 === t_2 - 1);
189
+ frame.set("loop.length", t_2);
190
+ output += "\n ";
191
+ output += runtime.suppressValue(env.getFilter("safe").call(context, runtime.memberLookup((t_4),"html")), env.opts.autoescape);
192
+ output += "\n ";
193
+ ;
194
+ }
195
+ }
196
+ frame = frame.pop();
197
+ output += "\n</ul>\n\n";
198
+ ;
199
+ }
200
+ else {
201
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "TIMEOUT") {
202
+ output += "\n<div class=\"wc-content\">\n <h3 id=\"wc-subtitle\" class=\"govuk-heading-m\">Your session has timed out</h3>\n <p>You did not do anything for ";
203
+ output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"timeout"), env.opts.autoescape);
204
+ output += ".</p>\n <div class=\"govuk-button-group\">\n <button class=\"wc-submit-feedback-btn\" data-module=\"govuk-button\" data-wc-feedback-btn>Give feedback</button>\n <a href=\"#\" role=\"button\" draggable=\"false\" data-module=\"govuk-button\" data-wc-close-btn>Cancel</a>\n </div>\n</div>\n\n";
205
+ ;
206
+ }
207
+ else {
208
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "END") {
209
+ output += "\n<div class=\"wc-content\">\n <h3 id=\"wc-subtitle\" class=\"govuk-heading-m\">Are you sure you want to end the chat?</h3>\n <div class=\"govuk-button-group\">\n <button class=\"wc-confirm-end-btn\" data-module=\"govuk-button\" data-wc-confirm-end-btn>Yes, end chat</button>\n <a href=\"#\" role=\"button\" draggable=\"false\" data-module=\"govuk-button\" data-wc-resume-btn>No, resume chat</a>\n </div>\n</div>\n\n";
210
+ ;
211
+ }
212
+ else {
213
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "FEEDBACK") {
214
+ output += "\n<div class=\"wc-content\">\n ";
215
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")) {
216
+ output += "\n <div class=\"govuk-error-summary\" data-module=\"govuk-error-summary\" tabindex=\"-1\" data-wc-error-summary>\n <div role=\"alert\">\n <h3 id=\"wc-error\" class=\"govuk-error-summary__title\">\n There is a problem\n </h2>\n <div class=\"govuk-error-summary__body\">\n <ul class=\"govuk-list govuk-error-summary__list\">\n ";
217
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"satisfactionEmpty")) {
218
+ output += "\n <li>\n <a href=\"#satisfaction\" data-wc-error-summary-link>Select how did you feel about webchat</a>\n </li>\n ";
219
+ ;
220
+ }
221
+ output += "\n </ul>\n </div>\n </div>\n </div>\n ";
222
+ ;
223
+ }
224
+ output += "\n <h3 id=\"wc-subtitle\" class=\"govuk-heading-m\">Give feedback</h3>\n <div class=\"govuk-form-group";
225
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"satisfactionEmpty")) {
226
+ output += " govuk-form-group--error";
227
+ ;
228
+ }
229
+ output += "\">\n <fieldset class=\"govuk-fieldset\">\n <legend class=\"govuk-fieldset__legend\">\n Overall, how did you feel about your webchat\n </legend>\n ";
230
+ if(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"error")),"satisfactionEmpty")) {
231
+ output += "\n <p class=\"govuk-error-message\">\n <span class=\"govuk-visually-hidden\">Error:</span> Select how did you feel about your webchat\n </p>\n ";
232
+ ;
233
+ }
234
+ output += "\n <div class=\"govuk-radios govuk-radios--small\" data-module=\"govuk-radios\">\n <div class=\"govuk-radios__item\">\n <input class=\"govuk-radios__input\" id=\"satisfied\" name=\"satisfaction\" type=\"radio\" value=\"Satisfied\">\n <label class=\"govuk-label govuk-radios__label\" for=\"satisfied\">\n Satisfied\n </label>\n </div>\n <div class=\"govuk-radios__item\">\n <input class=\"govuk-radios__input\" id=\"no-opinion\" name=\"satisfaction\" type=\"radio\" value=\"No opinion\">\n <label class=\"govuk-label govuk-radios__label\" for=\"no-opinion\">\n No opinion\n </label>\n </div>\n <div class=\"govuk-radios__item\">\n <input class=\"govuk-radios__input\" id=\"dissatisfied\" name=\"satisfaction\" type=\"radio\" value=\"Dissatisfied\">\n <label class=\"govuk-label govuk-radios__label\" for=\"dissatisfied\">\n Dissatisfied\n </label>\n </div>\n </div>\n </fieldset>\n </div>\n <div class=\"govuk-form-group\">\n <label class=\"govuk-label\" for=\"improvements\">\n How can we improve webchat? (optional)\n </label>\n <textarea class=\"govuk-textarea govuk-!-margin-bottom-4\" id=\"improvements\" name=\"improvements\" rows=\"5\"></textarea>\n </div>\n <div class=\"govuk-button-group\">\n <button class=\"wc-feedback-btn\" data-module=\"govuk-button\" data-wc-submit-feedback-btn>Submit</button>\n <a href=\"#\" role=\"button\" draggable=\"false\" data-module=\"govuk-button\" data-wc-close-btn>Cancel</a>\n </div>\n</div>\n\n";
235
+ ;
236
+ }
237
+ else {
238
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "FINISH") {
239
+ output += "\n<div class=\"wc-content\">\n <h3 id=\"wc-subtitle\" class=\"govuk-heading-m\">Thank you for your feedback</h3>\n <div>\n <a href=\"#\" role=\"button\" draggable=\"false\" data-module=\"govuk-button\" data-wc-focus-visible data-wc-close-btn>Close window</a>\n </div>\n</div>\n\n";
240
+ ;
241
+ }
242
+ else {
243
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "SETTINGS") {
244
+ output += "\n<div class=\"wc-content\">\n <div class=\"govuk-form-group\">\n <fieldset class=\"govuk-fieldset\">\n <legend class=\"govuk-fieldset__legend govuk-fieldset__legend--m\">\n <h3 id=\"wc-subtitle\" class=\"govuk-heading-m\">Change settings</h3>\n </legend>\n <div class=\"govuk-checkboxes govuk-checkboxes--small\" data-module=\"govuk-checkboxes\">\n <div class=\"govuk-checkboxes__item\">\n <input class=\"govuk-checkboxes__input\" id=\"audio\" name=\"audio\" type=\"checkbox\" value=\"audio\"";
245
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"hasAudio")) {
246
+ output += " checked";
247
+ ;
248
+ }
249
+ output += ">\n <label class=\"govuk-label govuk-checkboxes__label\" for=\"audio\">\n Play a sound when receiving a new message\n </label>\n </div>\n <div class=\"govuk-checkboxes__item\">\n <input class=\"govuk-checkboxes__input\" id=\"scroll\" name=\"scroll\" type=\"checkbox\" value=\"scroll\"";
250
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"isScroll")) {
251
+ output += " checked";
252
+ ;
253
+ }
254
+ output += ">\n <label class=\"govuk-label govuk-checkboxes__label\" for=\"scroll\">\n Scroll automatically to a new message\n </label>\n </div>\n </div>\n </fieldset>\n </div>\n <div class=\"govuk-button-group\">\n <button class=\"wc-feedback-btn\" data-module=\"govuk-button\" data-wc-save-settings-btn>Save</button>\n <a href=\"#\" role=\"button\" draggable=\"false\" data-module=\"govuk-button\" data-wc-cancel-settings-btn>Cancel</a>\n </div>\n</div>\n\n";
255
+ ;
256
+ }
257
+ else {
258
+ output += "\n<div class=\"wc-content\">\n <p id=\"wc-subtitle\" class=\"govuk-heading-m\">Connecting to Floodline</p>\n</div>\n";
259
+ ;
260
+ }
261
+ ;
262
+ }
263
+ ;
264
+ }
265
+ ;
266
+ }
267
+ ;
268
+ }
269
+ ;
270
+ }
271
+ ;
272
+ }
273
+ ;
274
+ }
275
+ ;
276
+ }
277
+ if(parentTemplate) {
278
+ parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
279
+ } else {
280
+ cb(null, output);
281
+ }
282
+ ;
283
+ } catch (e) {
284
+ cb(runtime.handleError(e, lineno, colno));
285
+ }
286
+ }
287
+ return {
288
+ root: root
289
+ };
290
+
291
+ })();
292
+ })();
293
+ (function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["footer.html"] = (function() {
294
+ function root(env, context, frame, runtime, cb) {
295
+ var lineno = 0;
296
+ var colno = 0;
297
+ var output = "";
298
+ try {
299
+ var parentTemplate = null;
300
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "OPEN") {
301
+ output += "\n<form class=\"wc-message\" data-wc-message-form>\n <label class=\"wc-message__label";
302
+ if(env.getFilter("length").call(context, runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"textboxValue"))) {
303
+ output += " wc-message__label--hidden";
304
+ ;
305
+ }
306
+ output += "\" for=\"message\">\n ";
307
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"textboxValue")) {
308
+ output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"textboxValue"), env.opts.autoescape);
309
+ ;
310
+ }
311
+ else {
312
+ output += "Your message<span class=\"govuk-visually-hidden\"> (enter key submits)</span>";
313
+ ;
314
+ }
315
+ output += "\n </label>\n <textarea rows=\"1\" aria-required=\"true\" class=\"wc-message__textbox\" id=\"message\" name=\"message\"";
316
+ if(!runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"isMobile")) {
317
+ output += " data-wc-enter-submit";
318
+ ;
319
+ }
320
+ output += " data-wc-focus-parent data-wc-autosize data-wc-textbox></textarea>\n <input type=\"submit\" class=\"wc-message__send\" value=\"Send\" data-wc-send-btn />\n</form>\n<div class=\"wc-settings\">\n <a href=\"#\" class=\"wc-settings-btn\" role=\"button\" data-module=\"govuk-button\" data-wc-settings-btn>Settings</a>\n <!-- <a href=\"#\" class=\"wc-audio-btn\" role=\"button\" data-module=\"govuk-button\" data-wc-audio-btn>Turn audio <span>";
321
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"hasAudio")) {
322
+ output += "off";
323
+ ;
324
+ }
325
+ else {
326
+ output += "on";
327
+ ;
328
+ }
329
+ output += "</span></a> -->\n ";
330
+ if(env.getFilter("length").call(context, runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"messages"))) {
331
+ output += "\n <a href=\"#\" class=\"wc-transcript-btn\" download=\"transcript.txt\" data-wc-transcript-btn>Save chat</a>\n ";
332
+ ;
333
+ }
334
+ output += "\n</div>\n";
335
+ ;
336
+ }
337
+ if(parentTemplate) {
338
+ parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
339
+ } else {
340
+ cb(null, output);
341
+ }
342
+ ;
343
+ } catch (e) {
344
+ cb(runtime.handleError(e, lineno, colno));
345
+ }
346
+ }
347
+ return {
348
+ root: root
349
+ };
350
+
351
+ })();
352
+ })();
353
+ (function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["header.html"] = (function() {
354
+ function root(env, context, frame, runtime, cb) {
355
+ var lineno = 0;
356
+ var colno = 0;
357
+ var output = "";
358
+ try {
359
+ var parentTemplate = null;
360
+ output += "<div class=\"wc-header\">\n ";
361
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"isBack")) {
362
+ output += "\n <button class=\"wc-back-btn\" aria-label=\"Back\" data-wc-back-btn ";
363
+ if(!runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"isMobile")) {
364
+ output += "hidden";
365
+ ;
366
+ }
367
+ output += ">\n <svg aria-hidden=\"true\" focusable=\"false\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\">\n <path d=\"M4.828,11L12.314,18.485L10.899,19.899L1,10L10.899,0.101L12.314,1.515L4.828,9L19,9L19,11L4.828,11Z\" fill=\"currentColor\"/>\n </svg>\n </button> \n ";
368
+ ;
369
+ }
370
+ output += "\n <h2 id=\"wc-title\" class=\"wc-title\">Floodline webchat</h2>\n ";
371
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "OPEN" || runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "END") {
372
+ output += "\n <button class=\"wc-hide-btn\" aria-label=\"Minimise the webchat\" data-wc-hide-btn ";
373
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"isMobile")) {
374
+ output += "hidden";
375
+ ;
376
+ }
377
+ output += ">\n <svg aria-hidden=\"true\" focusable=\"false\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\">\n <path d=\"M10 14.4l-7-7L4.4 6l5.6 5.6L15.6 6 17 7.4l-7 7z\" fill=\"currentColor\"/>\n </svg>\n </button> \n ";
378
+ ;
379
+ }
380
+ else {
381
+ output += "\n <button class=\"wc-close-btn\" aria-label=\"Close the webchat\" data-wc-close-btn ";
382
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"isMobile")) {
383
+ output += "hidden";
384
+ ;
385
+ }
386
+ output += ">\n <svg aria-hidden=\"true\" focusable=\"false\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\">\n <path d=\"M10,8.6L15.6,3L17,4.4L11.4,10L17,15.6L15.6,17L10,11.4L4.4,17L3,15.6L8.6,10L3,4.4L4.4,3L10,8.6Z\" fill=\"currentColor\"></path>\n </svg>\n </button>\n ";
387
+ ;
388
+ }
389
+ output += "\n</div>\n";
390
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"view") == "OPEN") {
391
+ output += "\n<div class=\"wc-status\">\n <div id=\"wc-subtitle\" class=\"wc-status__content\" data-wc-status>\n ";
392
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"availability") == "AVAILABLE" || runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"availability") == "EXISTING") {
393
+ output += "\n ";
394
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"status") == "closed") {
395
+ output += "\n ";
396
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"assignee")) {
397
+ output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"assignee"), env.opts.autoescape);
398
+ output += " ended the session";
399
+ ;
400
+ }
401
+ else {
402
+ output += "Session ended by adviser";
403
+ ;
404
+ }
405
+ output += "\n ";
406
+ ;
407
+ }
408
+ else {
409
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"assignee")) {
410
+ output += "\n You are speaking with ";
411
+ output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"assignee"), env.opts.autoescape);
412
+ output += "\n ";
413
+ ;
414
+ }
415
+ else {
416
+ output += "\n No advisers currently available \n ";
417
+ ;
418
+ }
419
+ ;
420
+ }
421
+ output += "\n ";
422
+ ;
423
+ }
424
+ else {
425
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"availability") == "UNAVAILABLE") {
426
+ output += "\n Webchat is not currently available\n ";
427
+ ;
428
+ }
429
+ else {
430
+ output += "\n Connecting to Floodline\n ";
431
+ ;
432
+ }
433
+ ;
434
+ }
435
+ output += "\n </div>\n <div class=\"wc-status__button\">\n <a href=\"#\" role=\"button\" data-module=\"govuk-button\" class=\"wc-end-btn\" data-wc-end-btn>End chat</a>\n </div>\n</div>\n";
436
+ ;
437
+ }
438
+ output += "\n<div class=\"wc-live\" aria-live=\"polite\" data-wc-panel-live></div>";
439
+ if(parentTemplate) {
440
+ parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
441
+ } else {
442
+ cb(null, output);
443
+ }
444
+ ;
445
+ } catch (e) {
446
+ cb(runtime.handleError(e, lineno, colno));
447
+ }
448
+ }
449
+ return {
450
+ root: root
451
+ };
452
+
453
+ })();
454
+ })();
455
+ (function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["message.html"] = (function() {
456
+ function root(env, context, frame, runtime, cb) {
457
+ var lineno = 0;
458
+ var colno = 0;
459
+ var output = "";
460
+ try {
461
+ var parentTemplate = null;
462
+ output += "<li class=\"wc-list__item wc-list__item--";
463
+ output += runtime.suppressValue(env.getFilter("lower").call(context, runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"direction")), env.opts.autoescape);
464
+ output += "\">\n <div class=\"";
465
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"isGroupStart")) {
466
+ output += "wc-list__item-meta";
467
+ ;
468
+ }
469
+ else {
470
+ output += "govuk-visually-hidden";
471
+ ;
472
+ }
473
+ output += "\">";
474
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"direction") == "outbound") {
475
+ output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"assignee"), env.opts.autoescape);
476
+ ;
477
+ }
478
+ else {
479
+ output += "You";
480
+ ;
481
+ }
482
+ output += "<span class=\"govuk-visually-hidden\">:</span></div>\n <div class=\"wc-list__item-inner\">";
483
+ output += runtime.suppressValue(env.getFilter("safe").call(context, runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"text")), env.opts.autoescape);
484
+ output += "</div>\n</li>";
485
+ if(parentTemplate) {
486
+ parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
487
+ } else {
488
+ cb(null, output);
489
+ }
490
+ ;
491
+ } catch (e) {
492
+ cb(runtime.handleError(e, lineno, colno));
493
+ }
494
+ }
495
+ return {
496
+ root: root
497
+ };
498
+
499
+ })();
500
+ })();
501
+ (function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["panel.html"] = (function() {
502
+ function root(env, context, frame, runtime, cb) {
503
+ var lineno = 0;
504
+ var colno = 0;
505
+ var output = "";
506
+ try {
507
+ var parentTemplate = null;
508
+ output += "<div id=\"wc-panel\" class=\"wc";
509
+ if(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "model")),"isOpen")) {
510
+ output += " wc--open";
511
+ ;
512
+ }
513
+ output += "\" role=\"dialog\" tabindex=\"-1\" aria-labelledby=\"wc-title wc-subtitle\" aria-modal=\"false\" open data-wc>\n <div class=\"wc__inner\">\n <div class=\"wc__header\" data-wc-header></div>\n <div class=\"wc__body\" data-wc-body></div>\n <div class=\"wc__footer\" data-wc-footer></div>\n </div>\n</div>";
514
+ if(parentTemplate) {
515
+ parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
516
+ } else {
517
+ cb(null, output);
518
+ }
519
+ ;
520
+ } catch (e) {
521
+ cb(runtime.handleError(e, lineno, colno));
522
+ }
523
+ }
524
+ return {
525
+ root: root
526
+ };
527
+
528
+ })();
529
+ })();
530
+ (function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["skiplink.html"] = (function() {
531
+ function root(env, context, frame, runtime, cb) {
532
+ var lineno = 0;
533
+ var colno = 0;
534
+ var output = "";
535
+ try {
536
+ var parentTemplate = null;
537
+ output += "<a id=\"wc-skip\" href=\"#webchat\" class=\"govuk-skip-link\" data-module=\"govuk-skip-link\" data-wc-skiplink data-wc-open-btn>\n Skip to webchat\n</a>";
538
+ if(parentTemplate) {
539
+ parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
540
+ } else {
541
+ cb(null, output);
542
+ }
543
+ ;
544
+ } catch (e) {
545
+ cb(runtime.handleError(e, lineno, colno));
546
+ }
547
+ }
548
+ return {
549
+ root: root
550
+ };
551
+
552
+ })();
553
+ })();
554
+
@@ -2,4 +2,5 @@
2
2
 
3
3
  1) Clone the repo
4
4
  2) Run `npm install` to install the dependencies.
5
- 3) Run `npm run dev` to run a demo server with hot module reloading on http://localhost:9000.
5
+ 3) Create a `.env` file in the root of the project (variables are with our other secrets under `node/configLocal/flood-webchat.env`)
6
+ 4) Run `npm run dev` to run a demo server with hot module reloading on http://localhost:9000.